--- /dev/null
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 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 licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU 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. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), 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 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 show them these terms so they know 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.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ 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 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 derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 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 License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+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.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary 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
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 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 Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing 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 for copying, distributing or modifying
+the Program or works based on it.
+
+ 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.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. 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 this 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
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. 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
+
+ 11. 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.
+
+ 12. 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 the public, 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 2 of the License, 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) 19yy 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 is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
--- /dev/null
+/COPYING/1.2/Wed Jun 12 01:03:49 2002//
+/README/1.3/Thu Jun 13 04:19:09 2002//
+D/data////
+D/doc////
+D/scripts////
+D/src////
+D/timeseal////
+D/web////
+D/tests////
+D/bots////
+D/games////
+D/testplay////
--- /dev/null
+Introduction
+------------
+
+This is an enhanced version of the 'lasker' internet chess server. I
+started to enhance Lasker when I needed a working chess server for a
+local school. You can get the original 'lasker' release from
+http://chessd.sourceforge.net/ and you can get my enhanced version
+from http://chess.samba.org/
+
+Here is a list of some of the new features in this version:
+
+ - lots and lots of bugs fixed
+ - timeseal support added (see timeseal/README for details)
+ - server configuration via 'aconfig' command instead of config.h
+ - added multi-part command parsing (commands separated by ';')
+ - enhanced aliases
+ - build/install process fixed
+ - fixed help system
+ - transparent server reload (upgrade without disturbing connections or games)
+
+
+Installation
+------------
+
+First you need to configure and compile the chessd server. Do
+something like the following:
+
+ cd src
+ ./configure --prefix=/usr/local
+ make
+
+Then to install the server run "make install". That will install a
+basic skeleton installation in /usr/local/chessd.
+
+Setting up
+----------
+
+Next you will want to launch your chess server using the command:
+ bin/chessd -f -p 5000
+while in the chessd/ directory. This will launch the chess server
+using the skeleton data you installed above.
+
+I highly recommend creating a separate account on your machine to run
+the chess daemon. This user should own all files in the chessd
+directory.
+
+After you launch chessd for the first time you will need to login as
+the special user 'admin'. That username will be recognised as the
+server administrator and you will be logged in with the rather unusual
+combination of a head administrator who is also an unregistered
+player.
+
+The first thing you will want to do as the admin user is create a
+proper 'admin' account with a password. Use the command 'addplayer'
+while logged in as the admin user to create the admin account. You
+will be told the password. Then you should immediately logout and log
+back in using the admin password you have just been given. You will
+probably want to change this password using the 'asetpass' command.
+
+You may also find the following commands useful:
+ ahelp addplayer
+ ahelp asetpass
+ ahelp commands
+
+
+Securing your server
+--------------------
+
+The source code for this chess server has been hacked on by dozens of
+people over the years. It almost certainly has exploitable buffer
+overruns or other security holes. If you are like me then you won't
+like the idea of running an insecure program like that on your server.
+
+To make it a lot more secure you can choose to run the chess server in
+a chroot jail. This makes it much harder for an attacker to gain a
+foothold on your server. It won't prevent them from crashing the
+chessd process but it will prevent them from gaining access to other
+parts of the system.
+
+To run chessd in a chroot jail you need to do the following:
+
+ 1) chessd needs to be setuid root. I know this sounds bizarre, but
+ it needs root privileges to use the chroot() system
+ call. Immediately after the chroot chessd will permanently lose
+ its root privileges and instead become the user that launched
+ chessd. To make chessd setuid root do this as root:
+ chown root chessd
+ chmod u+s chessd
+
+ 2) pass the command line option -R to tell chessd that it should
+ chroot to the current directory. So to launch chessd you can use
+ this:
+ chessd -p 5000 -T /usr/local/bin/timeseal_decoder -R /usr/local/chessd
+
+ You may also like to look at the start_chessd script in the
+ scripts directory. This is the script I use to keep chessd
+ always running on my machine.
+
+If you do use the -R option then I also recommend that you don't place
+any of the chess server binaries (or any other binaries or libraries)
+inside the chessd directory. That will increase the security of your
+server a little.
+
+
+Email spool
+-----------
+
+This chess server does not send emails directly, instead it puts
+outgoing emails in the spool/ directory and waits for some external
+program or script to deliver them. I designed it this way as it makes
+it possible to send email from a chess server in a chroot jail, and
+offers more flexibility in how email is handled (as that tends to vary
+a lot between systems).
+
+If you run sendmail then the sample script in scripts/spool_sendmail
+might be good enough. Just run this script at startup and it will send
+all spooled mail every minute.
+
+
+Server reload
+-------------
+
+This version of chessd supports reloading the server code without
+having to shutdown the server or disturb any games that are in
+progress. This allows for on the fly upgrades, hopefully without the
+users even noticing that the system is being upgraded.
+
+In order to support this functionality I had to make the source code
+rather more Linux specific than it was previously, but I think that is
+worth it for the functionality. It would be possible to port the code
+to many other platforms, but I have not yet done so.
+
+To reload the server use the command 'areload'. You must be at the
+ADMIN_GOD admin level to issue this command.
+
+Updates
+-------
+
+Updates will be available on http://chess.samba.org/
+
+You may wish to use the cvs version to enable you to update more
+easily. I will only be doing tar ball releases occasionally.
+
+License
+-------
+
+This chess server release is under the GNU General Public License,
+which is the license used by the original chess server written by
+Richard Nash. Various parts of the server are under different
+licenses, depending on who wrote what part, but I believe that all of
+the licenses are compatible with the GPL.
+
+The reason I chose the GPL for this release is that I don't want this
+code to become proprietary again. This has happened at least 3 times
+in the past with this source code and while I'm sure there were very
+good reasons at the time, it does mean that the freely available chess
+servers have not benefited from the considerable development that has
+happened over the past seven years.
+
+I also chose the GPL because it allows me to incorporate source code
+from other GPLd projects. This saved me quite a lot of time, and is
+sure to be useful again.
+
+
+--------------------------------
+Andrew Tridgell
+tridge@chess.samba.org June 2002
+--------------------------------
--- /dev/null
+D/mamer////
--- /dev/null
+lasker/bots
--- /dev/null
+/Command.cc/1.9/Tue Jul 2 00:05:19 2002//
+/Command.hh/1.5/Thu Sep 10 19:58:31 1998//
+/CommandEntry.cc/1.15/Tue Jul 2 00:05:19 2002//
+/CommandEntry.hh/1.11/Thu Sep 10 19:58:31 1998//
+/Game.cc/1.4/Tue Jul 2 00:05:19 2002//
+/Game.hh/1.5/Tue Jul 2 00:05:19 2002//
+/Makefile/1.8/Fri Sep 11 15:47:50 1998//
+/Mamer.cc/1.19/Tue Jul 2 00:05:19 2002//
+/Mamer.hh/1.13/Tue Jul 2 00:05:19 2002//
+/Player.cc/1.4/Thu Sep 10 19:57:17 1998//
+/Player.hh/1.4/Tue Jul 2 00:02:40 2002//
+/Storage.cc/1.1/Thu Sep 10 19:57:17 1998//
+/Storage.hh/1.1/Thu Sep 10 19:58:41 1998//
+/Tourney.cc/1.12/Tue Jul 2 00:02:40 2002//
+/Tourney.hh/1.12/Tue Jul 2 00:02:40 2002//
+/TourneyParameters.cc/1.2/Thu Sep 10 19:57:17 1998//
+/TourneyParameters.hh/1.3/Thu Sep 10 19:58:41 1998//
+/TourneyPlayers.cc/1.7/Thu Sep 10 19:57:17 1998//
+/TourneyPlayers.hh/1.6/Thu Sep 10 19:58:41 1998//
+/User.cc/1.10/Thu Sep 10 19:57:17 1998//
+/User.hh/1.8/Thu Sep 10 19:58:41 1998//
+/command_list.h/1.2/Wed Oct 8 21:03:08 1997//
+/config.h/1.5/Thu Sep 10 19:58:20 1998//
+/link.cc/1.5/Thu Sep 10 19:57:17 1998//
+/link.hh/1.2/Wed Apr 15 16:56:34 1998//
+/linklist.hh/1.3/Thu Sep 10 19:58:41 1998//
+/main.cc/1.4/Thu Sep 10 19:57:17 1998//
+/mamer.config/1.1/Thu Sep 10 19:59:41 1998//
+/types.h/1.11/Thu Sep 10 19:58:20 1998//
+D/bin////
+D/data////
+D/help////
+D/logs////
+D/template////
--- /dev/null
+lasker/bots/mamer
--- /dev/null
+//--------------------------------------------------------------------------
+// Command.cc - Source file for the Command class
+//
+// Matthew E. Moses
+//
+// $Revision: 1.9 $
+// $Date: 2002/07/02 00:05:19 $
+//
+// $Author: tridge $
+// $Locker: $
+//
+// $Log: Command.cc,v $
+// Revision 1.9 2002/07/02 00:05:19 tridge
+// got rid of a bunch of RCS tags now that its in CVS
+//
+// Revision 1.8 1998/09/10 19:57:17 mlong
+// lots of little bug fixes and a few new features
+//
+// Revision 1.7 1998/04/15 16:56:17 mlong
+// *** empty log message ***
+//
+// Revision 1.6 1998/02/12 18:43:26 mlong
+// *** empty log message ***
+//
+// Revision 1.5 1997/05/15 18:27:53 chess
+// added pending and TourneyPlayers support
+// added HandleGetPlayerInfo & HandleGetGameInfo
+//
+// Revision 1.4 1997/04/13 03:14:35 chess
+// command class changed to have a parameter list.
+//
+// Revision 1.3 1997/04/07 22:21:49 chess
+// *** empty log message ***
+//
+// Revision 1.2 1996/10/03 18:11:10 moses
+// made sure string are null termindated
+//
+// Revision 1.1 1996/10/01 20:14:43 moses
+// Initial revision
+//
+//
+//--------------------------------------------------------------------------
+
+#include "Command.hh"
+
+//- constructor -----------------------------------------------------------
+Command::Command() {
+ name = alias = description = NULL;
+ managerLevel = USER;
+ userFunction = 0;
+ tournFunction = 0;
+} //- End of constructor
+
+Command::Command(char *n, char *a, ranks m, char *d, char *paramTypeList, USERFP u) {
+ name = new char[strlen(n)+1];
+
+ if(NULL == name) return;
+ memset(name, '\0', strlen(n));
+ strncpy(name, n, strlen(n));
+ name[strlen(n)] = '\0';
+
+ memset(parameterList, '\0', MAXNUMPARAMS);
+ strncpy(parameterList, paramTypeList, strlen(paramTypeList));
+ parameterList[strlen(paramTypeList)] = '\0';
+
+ alias = new char[strlen(a)+1];
+ if(NULL == alias) return;
+ memset(alias, '\0', strlen(a));
+ strncpy(alias, a, strlen(a));
+ alias[strlen(a)] = '\0';
+
+ managerLevel = m;
+
+ description = new char[strlen(d)+1];
+ if(NULL == description) return;
+ memset(description, '\0', strlen(d));
+ strncpy(description, d, strlen(d));
+ description[strlen(d)] = '\0';
+
+ userFunction = u;
+} //- End of constructor
+
+Command::Command(char *n, char *a, ranks m, char *d, char *paramTypeList, TOURNFP t) {
+ name = new char[strlen(n)+1];
+ if(NULL == name) return;
+ memset(name, '\0', strlen(n));
+ strncpy(name, n, strlen(n));
+ name[strlen(n)] = '\0';
+
+ memset(parameterList, '\0', MAXNUMPARAMS);
+ strncpy(parameterList, paramTypeList, strlen(paramTypeList));
+ parameterList[strlen(paramTypeList)] = '\0';
+
+ alias = new char[strlen(a)+1];
+ if(NULL == alias) return;
+ memset(alias, '\0', strlen(a));
+ strncpy(alias, a, strlen(a));
+ alias[strlen(a)] = '\0';
+
+ managerLevel = m;
+
+ description = new char[strlen(d)+1];
+ if(NULL == description) return;
+ memset(description, '\0', strlen(d));
+ strncpy(description, d, strlen(d));
+ description[strlen(d)] = '\0';
+
+ tournFunction = t;
+} //- End of constructor
+
+//- deconstructor ---------------------------------------------------------
+Command::~Command() {
+ if(NULL != name)
+ delete [] name;
+
+ if(NULL != alias)
+ delete [] alias;
+
+ if(NULL != description)
+ delete [] description;
+} //- End of deconstructor
+
+//- IsCommand ------------------------------------------------------
+int Command::IsCommand(char *comm) {
+ int length = strlen(comm);
+ if((0 == strncasecmp(comm, name, MIN(length, (int)strlen(name)))) ||
+ (0 == strncasecmp(comm, alias, MIN(length, (int)strlen(alias)))))
+ return(1);
+
+ return(0);
+} //- End of IsCommand
+
+//- GetCommandName ------------------------------------------------
+char *Command::GetCommandName() {
+ return name;
+} //- End of GetCommandName
+
+//- GetCommandDescription ------------------------------------------------
+char *Command::GetCommandDescription() {
+ return description;
+} //- End of GetCommandDescription
+
+//- GetCommandAlias ------------------------------------------------
+char *Command::GetCommandAlias() {
+ return alias;
+} //- End of GetCommandAlias
+
+//- GetManagerLevel -----------------------------------------------
+ranks Command::GetManagerLevel() {
+ return managerLevel;
+} //- End of GetManagerLevel
+
+//- SetManagerLevel -----------------------------------------------
+void Command::SetManagerLevel(ranks newvalue) {
+ managerLevel = newvalue;
+} //- end of SetManagerLevel
--- /dev/null
+//--------------------------------------------------------------------------
+// Command.hh - Class header for the Command class
+//
+// Matthew E. Moses
+//
+// $Revision: 1.5 $
+// $Date: 1998/09/10 19:58:31 $
+//
+// $Author: mlong $
+// $Locker: $
+//
+// $Log: Command.hh,v $
+// Revision 1.5 1998/09/10 19:58:31 mlong
+// *** empty log message ***
+//
+// Revision 1.4 1997/05/15 18:29:12 chess
+// added pending and TourneyPlayers support
+// added HandleGetPlayerInfo & HandleGetGameInfo
+//
+// Revision 1.3 1997/04/13 03:21:32 chess
+// constructor changed to accomodate the params list
+//
+// Revision 1.2 1997/04/07 22:21:43 chess
+// *** empty log message ***
+//
+// Revision 1.1 1996/10/01 20:14:43 moses
+// Initial revision
+//
+//
+//--------------------------------------------------------------------------
+
+#ifndef _COMMAND_
+#define _COMMAND_
+
+extern "C" {
+ #include <stdlib.h>
+ #include <string.h>
+}
+
+#include "link.hh"
+#include "types.h"
+#include "User.hh"
+
+class Command : public Link {
+public:
+ Command();
+ Command(char *, char *, ranks, char *, char *, USERFP);
+ Command(char *, char *, ranks, char *, char *, TOURNFP);
+ ~Command();
+
+ int IsCommand(char *);
+ ranks GetManagerLevel();
+ void SetManagerLevel(ranks);
+ char *GetCommandName();
+ char *GetCommandAlias();
+ char *GetCommandDescription();
+
+ private:
+
+ public:
+ USERFP userFunction;
+ TOURNFP tournFunction;
+
+ char parameterList[MAXNUMPARAMS];
+ param_list params;
+ reasons badUsage;
+
+ private:
+ char *name;
+ char *alias;
+
+ ranks managerLevel;
+ char *description;
+
+};
+
+#endif
--- /dev/null
+//--------------------------------------------------------------------------
+// CommandEntry.cc - Source file for the CommandEntry
+//
+// Matthew E. Moses & Michael A. Long
+//
+// $Log: CommandEntry.cc,v $
+// Revision 1.15 2002/07/02 00:05:19 tridge
+// got rid of a bunch of RCS tags now that its in CVS
+//
+// Revision 1.14 2002/07/02 00:02:40 tridge
+// - fixed compile on g++ 2.96
+// - updated for lasker 'rmatch'
+//
+// Revision 1.13 1998/09/10 19:57:17 mlong
+// lots of little bug fixes and a few new features
+//
+// Revision 1.12 1998/06/18 18:41:30 mlong
+// prepairing for yet another move.
+//
+// Revision 1.11 1998/06/08 20:41:17 mlong
+// changes to the list tournies function
+//
+// Revision 1.10 1998/04/29 15:23:19 mlong
+// prepairing for the move to daimi
+// new sorting routine.
+//
+// Revision 1.9 1998/04/18 18:46:04 mlong
+// fixed delete bug &
+// added delete tourney function
+//
+// Revision 1.5 1997/10/08 21:03:35 chess
+// preparing for move to oracle machine at eworks.
+//
+// Revision 1.4 1997/05/15 18:27:53 chess
+// added Player and TourneyPlayers support
+// added HandleGetPlayerInfo & HandleGetGameInfo
+//
+// Revision 1.3 1997/04/13 03:14:35 chess
+// commands to do user statistic manipulationn added:
+// setinfo - sets a whole line of information
+// setstat - sets a particular stat
+// addabuse - adds (or deletes) abuse points.
+//
+// Revision 1.2 1997/03/21 15:32:36 moses
+// added the shutdown command.
+//
+// Revision 1.1 1996/10/01 20:14:43 moses
+// Initial revision
+//
+//--------------------------------------------------------------------------
+
+#include "CommandEntry.hh"
+#include "Mamer.hh"
+
+extern Mamer gMamer;
+
+//- AddAbuse -------------------------------------------------------
+int CommandEntry::AddAbuse(User *user, param_list params) {
+ User *u = NULL;
+ char name[MAX_WORD_SIZE];
+ int needToDelete=0;
+
+ if(params[0].type == TYPE_WORD) {
+ strcpy(name, params[0].val.word);
+ }
+
+ u = gMamer.FindUser(name);
+ if(u == NULL) {
+ u = new User();
+ u->LoadPlayer(gMamer.userFilePath, name); // Loads the player info into memory and saves current info to disk
+ needToDelete = 1;
+ }
+
+ if((u->GetManagerLevel() >= user->GetManagerLevel()) &&
+ (user->GetManagerLevel() != PRESIDENT)) {
+ if(needToDelete) delete u;
+ gMamer.TellUser(NoPermissions, user->name);
+ return 0;
+ }
+
+ if(u != NULL) {
+ if(params[1].type == TYPE_INT) {
+ u->AddAbuse(params[1].val.integer);
+ } else {
+ u->AddAbuse(10);
+ }
+ u->SavePlayer(gMamer.userFilePath);
+ if(u->GetAbuse() >= MAX_CHAOS_POINTS)
+ gMamer.XServerCom("%s %s%s", "+ censor", u->name, "\n");
+ gMamer.TellUser(ChangedAbuse, user->name, u->name, u->GetAbuse());
+ } else {
+ gMamer.TellUser(NotFound, user->name, name);
+ }
+ if(needToDelete) delete u;
+
+ return(1);
+} //- End of AddAbuse
+
+//- FingerUser -------------------------------------------------------
+int CommandEntry::FingerUser(User *user, param_list params) {
+ User *u = NULL;
+ int notFound=1;
+ char name[32];
+
+ memset(name, '\0', 32);
+ if(params[0].type == TYPE_WORD) {
+ strncpy(name, params[0].val.word, MIN(31, (int)strlen(params[0].val.word)));
+ } else {
+ strcpy(name, user->name);
+ }
+
+ u = gMamer.FindUser(name);
+ if(u != NULL) notFound = 0;
+
+ if(notFound) {
+ u = new User();
+ notFound = u->LoadPlayer(gMamer.userFilePath, name);
+ notFound = !notFound;
+ }
+ if(!notFound) {
+ gMamer.XServerCom("%s %s %s%s%s", "qtell", user->name, "\\n", u->name, "'s Stats:\\n\\n");
+ gMamer.XServerCom("%-17s %5s %4s %4s %3s %3s %3s %3s %5s %6s%-17s %4s %3s %3s %3s %3s %3s %3s %5s %6s",
+ "Name", " Tnys", " W ", " L ", " D ", "1st", "2nd", "3rd", "Chaos", "Rating\\n",
+ "-----------------", "-----", "----", "----", "---", "---", "---", "---", "-----","------\\n");
+ gMamer.XServerCom("%-17s %5ld %4ld %4ld %3ld %3ld %3ld %3ld %5d %6.2f %s",
+ u->name, u->GetPlayedTourneys(), u->GetWins(), u->GetLosses(), u->GetDraws(),
+ u->GetFirsts(), u->GetSeconds(), u->GetThirds(), u->GetAbuse(), u->GetRating(), "\\n");
+ if(u->GetManagerLevel() > USER) {
+ gMamer.XServerCom("%s %d %s %d %s", "\\nManager Level:", u->GetManagerLevel(),
+ " Managed Tourneys:", u->GetManagedTourneys(), "\\n");
+ }
+ gMamer.XServerCom("%s", "\n");
+ } else {
+ gMamer.TellUser(NotFound, user->name, name);
+ }
+ if(notFound) delete u;
+
+ return(1);
+} //- End of FingerUser
+
+//- ListRank ----------------------------------------------------------
+int CommandEntry::ListRank(User *user, param_list params) {
+ float rating=0;
+ int start=0, i=0, end=0, tourneys=0, counter=0;
+ char filename[128], name[32], name2[32];
+ FILE *theFile;
+
+ memset(name, '\0', 32);
+ memset(name2, '\0', 32);
+ switch (params[0].type) {
+ case TYPE_WORD:
+ strcpy(name, params[0].val.word);
+ break;
+ case TYPE_INT:
+ start = params[0].val.integer;
+ if(start <= 0) {start = 1;}
+ break;
+ default:
+ strcpy(name, user->name);
+ break;
+ }
+
+ sprintf(filename, "%s/rank", gMamer.dataFilePath);
+ if(params[0].type != TYPE_INT) {
+ if((theFile = fopen(filename, "r"))) {
+ while(fscanf(theFile, "%s %d %f", name2, &tourneys, &rating) > 0) {
+ if(!(strncasecmp(name2, name, strlen(name)))) {
+ start = i+1;
+ break;
+ }
+ i++;
+ }
+ fclose(theFile);
+ } else {
+ gMamer.TellUser(NotFound, user->name, filename);
+ return(0);
+ }
+ }
+ if(!(start)) {
+ gMamer.TellUser(NotFound, user->name, name);
+ return(1);
+ }
+ start = start - 10;
+ end = start + 20;
+ if(start <= 0) {start = 1; end = 21;}
+ gMamer.XServerCom("%s %s %s %s%s %-5s %-18s %5s %6s %5s %-18s %5s %6s", "qtell", user->name, "\\n", gMamer.username,
+ "'s Rankings:\\n\\n", "Rank", "Name", "Trnys", "Rating\\n",
+ "-----", "------------------", "-----", "------\n");
+ gMamer.XServerCom("%s %s %s", "qtell", user->name, "\\n");
+ if(!(theFile = fopen(filename, "r"))) { return(0); }
+ i = 1; counter = 1;
+ while(fscanf(theFile, "%s %d %f", name2, &tourneys, &rating) > 0) {
+ if((i >= start) && (i < end)) {
+ if(i == start) { counter = 1; }
+ gMamer.XServerCom(" %-5d %-18s %5d %6.2f\\n", i, name2, tourneys, rating);
+ if(((counter % 10) == 0) && (counter > 0)) {
+ gMamer.XServerCom("%s", "\n");
+ if(i != (end -1)) {
+ gMamer.XServerCom("%s %s %s", "qtell", user->name, "\\n");
+ }
+ }
+ }
+ if(i > end) { break; }
+ i++; counter++;
+ }
+ fclose(theFile);
+
+ if(i <= end) { gMamer.XServerCom("%s", "\n"); }
+
+ return(1);
+}
+
+//- ListManagers ------------------------------------------------------
+int CommandEntry::ListManagers(User *user, param_list params) {
+ int i=1, needToDelete=0;
+ long last;
+ char filename[256], manager[NAMELEN], date[16];
+ User *u=NULL, *newUser = NULL;
+ struct tm *tmpDate;
+ FILE *theFile;
+
+ i = params[0].type; // just to get rid of the compiler messages
+ sprintf(filename, "%s/managers", gMamer.dataFilePath);
+ if((theFile = fopen(filename, "r"))) {
+ gMamer.XServerCom("%s %s %s %s%s", "qtell", user->name, "\\n", gMamer.username, "'s Manager List:\\n\\n");
+ gMamer.XServerCom("%2s%-18s %3s %4s %-8s%2s%-18s %3s %4s %-8s%s",
+ "","Name","Lvl","Tnys","Last", "","Name","Lvl","Tnys","Last", "\\n");
+ gMamer.XServerCom(" %-18s %3s %4s %-8s%2s%-18s %3s %4s %-8s%s",
+ "-----------------", "---", "----", "--------", "",
+ "-----------------", "---", "----", "--------", "", "\\n");
+ i=1;
+ memset(date, '\0', 64);
+ gMamer.XServerCom("\n%s %s ", "qtell", user->name);
+ while(fscanf(theFile, "%s", manager) > 0) {
+ needToDelete = 0;
+ u = gMamer.FindUser(manager);
+ if(u == NULL) {
+ needToDelete = 1;
+ newUser = new User();
+ u = newUser;
+ }
+ if(0 != u->LoadPlayer(gMamer.userFilePath, manager)) {
+ last = u->GetLast();
+ if(last) {
+ tmpDate = localtime(&last);
+ sprintf(date, "%02d/%02d/%02d", tmpDate->tm_mon+1, tmpDate->tm_mday, tmpDate->tm_year);
+ } else {
+ sprintf(date, "none");
+ }
+ } else {
+ sprintf(date, "%s", "none");
+ }
+ gMamer.XServerCom("%2s%-18s %3d %4d %8s%s",
+ ((gMamer.UserIsLoaded(manager)) ? "+" : " "),
+ manager, u->GetManagerLevel(), u->GetManagedTourneys(), date, (i%2)==0 ? "\\n":"");
+ if(((i % 20) == 0) && (i > 0)) {
+ i = 0;
+ gMamer.XServerCom("%s %s %s %s", "\n", "qtell", user->name, "\\n");
+ }
+ i++;
+ if(needToDelete) {
+ u = NULL;
+ delete(newUser);
+ }
+ }
+ fclose(theFile);
+ gMamer.XServerCom("%s", "\n");
+
+ return(1);
+ }
+ gMamer.TellUser(NotFound, user->name, filename);
+ return(0);
+}
+
+//- LoadedUsers -------------------------------------------------------
+int CommandEntry::LoadedUsers(User *user, param_list params) {
+ User *u = NULL;
+ LinkListIter<User> userIter(gMamer.userList);
+ int i, count=0;
+
+ i = params[0].type;
+ i = 1;
+
+ gMamer.XServerCom("qtell %s \\nLoaded Users:\\n\\n", user->name);
+ while((u = userIter.Next())) {
+ count++;
+ gMamer.XServerCom(" %18s%s", u->name, (i%3)==0 ? "\\n":"");
+ if(((i % 30) == 0) && (i > 0)) {
+ i = 0;
+ gMamer.XServerCom("%s %s %s %s", "\n", "qtell", user->name, "\\n");
+ }
+ i++;
+ }
+ gMamer.XServerCom("%sTotal: %i%s", "\\n", count, "\n");
+
+ return(1);
+} //- End of LoadedUser
+
+//- SetCommandLevel ----------------------------------------------------
+int CommandEntry::SetCommandLevel(User *user, param_list params) {
+ Command *c = NULL;
+
+ c = gMamer.FindCommand(params[0].val.word, user->name);
+
+ if(c != NULL) {
+ if((c->GetManagerLevel() <= user->GetManagerLevel()) &&
+ (params[1].val.integer <= user->GetManagerLevel())) {
+ c->SetManagerLevel((ranks)params[1].val.integer);
+ gMamer.TellUser(ChangedCommandLevel, user->name, params[0].val.word, params[1].val.integer);
+ } else
+ gMamer.TellUser(NoPermissions, user->name);
+ } else
+ return 0;
+
+ return 1;
+}
+
+//- SetInfo -------------------------------------------------------
+int CommandEntry::SetInfo(User *user, param_list params) {
+ User *u = NULL;
+ int notFound=1, i;
+ char name[32];
+
+ memset(name, '\0', 32);
+ if(params[0].type == TYPE_WORD) {
+ strncpy(name, params[0].val.word, MIN(31, (int)strlen(params[0].val.word)));
+ }
+
+ u = gMamer.FindUser(name);
+ if(u != NULL) notFound = 0;
+
+ if(notFound) {
+ u = new User();
+ u->LoadPlayer(gMamer.userFilePath, name);
+ }
+
+ if(u != NULL) {
+ if((u->GetManagerLevel() >= user->GetManagerLevel()) &&
+ (user->GetManagerLevel() != PRESIDENT)) {
+ if(notFound) delete u;
+ gMamer.TellUser(NoPermissions, user->name);
+ return 0;
+ }
+ for(i=1; i<=7; i++)
+ u->SetStatistic(i, params[i].val.integer);
+ u->SavePlayer(gMamer.userFilePath);
+ gMamer.TellUser(ChangedInfo, user->name, u->name);
+ } else {
+ gMamer.TellUser(NotFound, user->name, name);
+ }
+ if(notFound) delete u;
+
+ return(1);
+} //- End of SetInfo
+
+//- SetManagerLevel -------------------------------------------------------
+int CommandEntry::SetManagerLevel(User *user, param_list params) {
+ User *u = NULL;
+ int notFound=1, new_level=1, length=0, i=0;
+ char name[32];
+
+ if(params[0].type == TYPE_WORD) {
+ length = strlen(params[0].val.word);
+ memset(name, '\0', 32);
+ while((i < 31) && (i < length)) {
+ name[i] = tolower(params[0].val.word[i]);
+ i++;
+ }
+ }
+ new_level = params[1].val.integer;
+
+ u = gMamer.FindUser(name);
+ if(u != NULL) notFound = 0;
+
+ if(notFound) {
+ u = new User();
+ u->LoadPlayer(gMamer.userFilePath, name);
+ }
+ if(((u->GetManagerLevel() >= user->GetManagerLevel()) ||
+ (new_level >= user->GetManagerLevel())) &&
+ (user->GetManagerLevel() != PRESIDENT)) {
+ if(notFound) delete u;
+ gMamer.TellUser(NoPermissions, user->name);
+ return 0;
+ }
+
+ if(u != NULL) {
+ u->ChangeManagerLevel(new_level);
+ u->SavePlayer(gMamer.userFilePath);
+ gMamer.TellUser(ChangedManagerLevel, user->name, u->name, new_level);
+ } else {
+ gMamer.TellUser(NotFound, user->name, name);
+ }
+ if(notFound) delete u;
+
+ if(new_level > 0)
+ return(1);
+ else
+ return -1;
+} //- End of SetManagerLevel
+
+
+//- SetStat -------------------------------------------------------
+int CommandEntry::SetStat(User *user, param_list params) {
+ User *u = NULL;
+ int notFound=1, new_value, i, ret=0, size=0, counter=0;
+ char which_stat[64], name[32];
+ strings statAliases[] = {
+ {"tourneys", 1}, {"tnys", 1},
+ {"wins", 2},
+ {"losses", 3}, {"lose", 3},
+ {"draws", 4},
+ {"firsts", 5}, {"1sts", 5},
+ {"seconds", 6}, {"2nds", 6},
+ {"thirds", 7}, {"3rds", 7},
+ {"abuse", 8},
+ {"rating", 9},
+ {"managedtourneys", 10},
+ {NULL}
+ };
+
+ memset(which_stat, '\0', 64);
+ if(params[0].type == TYPE_WORD) { strcpy(name, params[0].val.word); }
+ if(params[1].type == TYPE_WORD) { strncpy(which_stat, params[1].val.word, MIN(63, strlen(params[1].val.word))); }
+ size = strlen(which_stat);
+ new_value = params[2].val.integer;
+
+ u = gMamer.FindUser(name);
+ if(u != NULL) notFound = 0;
+
+ if(notFound) {
+ u = new User();
+ u->LoadPlayer(gMamer.userFilePath, name);
+ }
+ if(u != NULL) {
+ if((u->GetManagerLevel() >= user->GetManagerLevel()) &&
+ (user->GetManagerLevel() != PRESIDENT)) {
+ if(notFound) delete u;
+ gMamer.TellUser(NoPermissions, user->name);
+ return 0;
+ }
+ i=0;
+ while(statAliases[i].string != NULL) {
+ if (!(strncasecmp(statAliases[i].string, which_stat, MIN(size, (int)strlen(statAliases[i].string))))) {
+ counter++;
+ if(counter > 1) break;
+ }
+ i++;
+ }
+ if(counter > 1) {
+ gMamer.TellUser(CanNotChange, user->name, u->name, which_stat, new_value);
+ } else if(counter == 0) {
+ gMamer.TellUser(NotFound, user->name, which_stat);
+ } else {
+ i=0;
+ while(statAliases[i].string != NULL) {
+ if (!(strncasecmp(statAliases[i].string, which_stat, MIN(size, (int)strlen(statAliases[i].string))))) {
+ ret = u->SetStatistic(statAliases[i].number, new_value);
+ memset(which_stat, '\0', 64);
+ strcpy(which_stat, statAliases[i].string);
+ break;
+ }
+ i++;
+ }
+ u->SavePlayer(gMamer.userFilePath);
+ if(ret)
+ gMamer.TellUser(ChangedInfo, user->name, u->name, which_stat, new_value);
+ else
+ gMamer.TellUser(NotFound, user->name, which_stat);
+ }
+ } else {
+ gMamer.TellUser(NotFound, user->name, name);
+ }
+ if(notFound) delete u;
+
+ return(1);
+} //- End of SetStat
+
+//- ShowCommands --------------------------------------------
+int CommandEntry::ShowCommands(User *user, param_list params) {
+ Command *c = NULL;
+ LinkListIter<Command> commIter(gMamer.commandList);
+ char *command;
+ int i;
+
+ if(params[0].type == TYPE_WORD) {
+ command = params[0].val.word;
+ while((c = commIter.Next())) if(1 == c->IsCommand(command)) break;
+ if(c == NULL) {
+ gMamer.TellUser(NotFound, user->name, command);
+ return 0;
+ }
+ gMamer.XServerCom("qtell %s %s Notes: %-16s | %-5s | %3d | %s \n",
+ user->name, gMamer.username, c->GetCommandName(),
+ c->GetCommandAlias(), c->GetManagerLevel(), c->GetCommandDescription());
+ return(1);
+ }
+ gMamer.XServerCom("qtell %s %s's Command List:\\n\\n", user->name, gMamer.username);
+ i = 0;
+ while((c = commIter.Next())) {
+ gMamer.XServerCom(" %-16s | %-5s | %3d | %s\\n",
+ c->GetCommandName(), c->GetCommandAlias(), c->GetManagerLevel(), c->GetCommandDescription());
+ if((!(i % 9)) && (i > 0)) {
+ i = 0;
+ gMamer.XServerCom("%s", "\n");
+ gMamer.XServerCom("qtell %s \\n", user->name);
+ }
+ i++;
+ }
+ gMamer.XServerCom("%s", "\n");
+ return(1);
+}
+
+//- ShowHelp -----------------------------------------------
+int CommandEntry::ShowHelp(User *user, param_list params) {
+ int i=1;
+ char tmpBuffer[1024], request[128], filename[256];
+ FILE *theFile;
+
+ memset(request, '\0', 128);
+ if(params[0].type == TYPE_WORD) {
+ strcpy(request, params[0].val.word);
+ } else {
+ strcpy(request, "index");
+ }
+ sprintf(filename, "%s/%s", gMamer.helpFilePath, request);
+ if((theFile = fopen(filename, "r"))) {
+ gMamer.XServerCom("qtell %s \\nThe %s Help File:\\n\\n", user->name, request);
+ i=1;
+ memset(filename, '\0', 256);
+ while(fgets(filename, 79, theFile)) { /* Just reusing the variable filename could be any char [] */
+ memset(tmpBuffer, '\0', 1024);
+ strcpy(tmpBuffer, gMamer.s_and_r(filename, "\n", "\\n"));
+ gMamer.XServerCom("%s", tmpBuffer);
+ if(((i % 10) == 0) && (i > 0)) {
+ i = 0;
+ gMamer.XServerCom("\nqtell %s \\n", user->name);
+ }
+ i++;
+ memset(filename, '\0', 256);
+ }
+ fclose(theFile);
+ gMamer.XServerCom("\n");
+
+ return(1);
+ }
+ gMamer.TellUser(NotFound, user->name, request);
+ return(0);
+}//- End of ShowHelp
+
+//- CreateTourney ------------------------------------------------------------
+int CommandEntry::CreateTourney(User *user, param_list params) {
+ Tourney *t = NULL;
+ int num = gMamer.GenerateTourneyNumber();
+
+ params[0].type = params[0].type; // Just to stop the annoying unused variable messages during compile.
+ t = new Tourney(num, user, &(gMamer.tourneyParams));
+ gMamer.tourneyList.Append(t);
+ gMamer.XServerCom("%s %s %s %d %s", "xtell", user->name, "Created tourney number: ", t->number, "\n");
+ return(1);
+}//- End CreateTourney
+
+//- OpenTourney ------------------------------------------------------------
+int CommandEntry::OpenTourney(User *user, param_list params) {
+ Tourney *tourn = NULL;
+
+ tourn = gMamer.FindTourney(params[0].val.integer);
+ if(NULL != tourn) {
+ if(tourn->Open()) {
+ tourn->Announce();
+ return(1);
+ }
+ }
+ gMamer.TellUser(NotFound, user->name, "tourney");
+ return(0);
+}//- End OpenTourney
+
+//- AnnounceTourney ----------------------------------------------------------
+int CommandEntry::AnnounceTourney(User *user, param_list params) {
+ Tourney *tourn = NULL;
+
+ tourn = gMamer.FindTourney(params[0].val.integer);
+ if(NULL != tourn) {
+ if(tourn->GetStatus() == OPEN) {
+ tourn->Announce();
+ return(1);
+ } else {
+ gMamer.TellUser(TourneyNotOpen, user->name, params[0].val.integer);
+ return 0;
+ }
+ } else {
+ gMamer.TellUser(NotFound, user->name, "tourney");
+ return(0);
+ }
+}//- AnnounceTourney ---------------------------------------------------------
+
+//- KeepTourney ------------------------------------------------------------
+int CommandEntry::KeepTourney(User *user, param_list params) {
+ Tourney *t = NULL;
+
+ t = gMamer.FindTourney(params[0].val.integer);
+ if(NULL != t) {
+ if(params[1].type != TYPE_NULL)
+ if(params[1].type == TYPE_WORD) {
+ if(strncasecmp("y", params[1].val.word, 1) == 0) {
+ t->SetPersist(1);
+ gMamer.TellUser(WillKeepTourney, user->name, params[0].val.integer);
+ } else {
+ t->SetPersist(0);
+ gMamer.TellUser(NotKeepTourney, user->name, params[0].val.integer);
+ }
+ } else if(params[1].type == TYPE_INT) {
+ t->SetPersist(params[1].val.integer);
+ if(params[1].val.integer)
+ gMamer.TellUser(WillKeepTourney, user->name, params[0].val.integer);
+ else
+ gMamer.TellUser(NotKeepTourney, user->name, params[0].val.integer);
+ } else {
+ gMamer.TellUser(NotFound, user->name, "tourney");
+ return(0);
+ }
+ return(1);
+ }
+
+ gMamer.TellUser(NotFound, user->name, "tourney");
+ return(0);
+}//- End KeepTourney
+
+//- DeleteTourney ------------------------------------------------------------
+int CommandEntry::DeleteTourney(User *user, param_list params) {
+ Tourney *t = NULL;
+ TourneyPlayers *tp = NULL;
+
+ t = gMamer.FindTourney(params[0].val.integer);
+ if(NULL != t) {
+ if(t->GetStatus() != DONE) {
+ LinkListIter<TourneyPlayers> playerIter(t->playerList);
+ playerIter.Reset();
+ while((tp = playerIter.Next())) {
+ gMamer.XServerCom("%s %s %d%s", "tournset", tp->name, 0, "\n");
+ gMamer.XServerCom("tell %s Tourney#%d has been deleted.%s", tp->name, t->number, "\n");
+ }
+ gMamer.XServerCom("%s %d %s%d %s", "tell", gMamer.channelNumber,
+ "Tourney #", params[0].val.integer, "has been deleted.\n");
+ }
+ gMamer.tourneyList.Delete(t); // delete the tourney
+ return(1);
+ }
+
+ gMamer.TellUser(NotFound, user->name, "tourney");
+ return(0);
+}//- End DeleteTourney
+
+//- CloseTourney ------------------------------------------------------------
+int CommandEntry::CloseTourney(User *user, param_list params) {
+ Tourney *tourn = NULL;
+
+ tourn = gMamer.FindTourney(params[0].val.integer);
+ if(NULL != tourn) {
+ if(tourn->GetPlayerCount() >= MINIMUM_PLAYERS) {
+ if(tourn->GetStatus() == OPEN) {
+ tourn->CloseAndStart();
+ gMamer.XServerCom("qtell %s %s Notes: %s %d %s",
+ user->name,gMamer.username,"Tourney #",
+ tourn->number, " is now closed.\n");
+ return(1);
+ } else {
+ gMamer.TellUser(TourneyNotOpen, user->name, tourn->number);
+ }
+ } else {
+ gMamer.TellUser(NotEnoughPlayers, user->name, tourn->number);
+ }
+ } else {
+ gMamer.TellUser(TourneyNotFound, user->name, params[0].val.integer);
+ }
+
+ return(0);
+}//- End CloseTourney
+
+int CommandEntry::ListTourneys(User *user, param_list params) {
+ Tourney *t = NULL;
+ LinkListIter<Tourney> tournIter(gMamer.tourneyList);
+ int notourneys = 1, Tstatus=0, i=3;
+ long stDate, enDate, timeNow;
+ struct tm *start, *end;
+ char outStart[128], outEnd[128], outStatus[128];
+
+ params[0].type = params[0].type; // Just to stop the annoying unused var messages in compile.
+ while((t = tournIter.Next())) notourneys = 0;
+
+ if(notourneys == 0) {
+ gMamer.XServerCom("qtell %s %s Notes: \\n", user->name, gMamer.username);
+ gMamer.XServerCom(" %3s %3s %3s %4s %3s %2s %4s %9s %6s %-14s %-14s\\n",
+ "No.","Rds","Sty", "Time", "Inc", "Md", "Vrnt", "Rtng Rnge", "Status"," Started at ", " Ended at ");
+ gMamer.XServerCom(" %3s %3s %3s %4s %3s %2s %4s %9s %6s %-14s %-14s\\n",
+ "---","---","---", "----", "---", "--", "----", "---------", "------","--------------", "--------------");
+ tournIter.Reset();
+ while((t = tournIter.Next())) {
+ stDate = t->GetStartDate();
+ enDate = t->GetEndDate();
+ Tstatus = t->GetStatus();
+ if((Tstatus == DONE) && (t->GetPersist() == 0)){
+ timeNow = time(0);
+ if((timeNow - enDate) > KEEP_TOURNEY_TIME) {
+ gMamer.tourneyList.Delete(t);
+ continue;
+ }
+ }
+ if(stDate > 0) {
+ start = localtime(&stDate);
+ sprintf(outStart, "%02d:%02d %02d/%02d/%02d",
+ start->tm_hour, start->tm_min, start->tm_mon+1, start->tm_mday, start->tm_year);
+ } else { strcpy(outStart, "n/a"); }
+ if(enDate > 0) {
+ end = localtime(&enDate);
+ sprintf(outEnd, "%02d:%02d %02d/%02d/%02d",
+ end->tm_hour, end->tm_min, end->tm_mon+1, end->tm_mday, end->tm_year);
+ } else { strcpy(outEnd, "n/a"); }
+ if(Tstatus == NEW)
+ sprintf(outStatus, "%s", "new");
+ else if(Tstatus == OPEN)
+ sprintf(outStatus, "%s", "open");
+ else if(Tstatus == CLOSED)
+ sprintf(outStatus, "%s", "closed");
+ else if(Tstatus == DONE)
+ sprintf(outStatus, "%s", "done");
+ else
+ memset(outStatus, '\0', 128);
+
+ gMamer.XServerCom(" %3d %3d %3c %4d %3d %2c %4c %4d-%4d %6s %-14s %-14s\\n",
+ t->number, t->params.rounds, t->params.style, t->params.time, t->params.inc,
+ t->params.mode, t->params.variant, t->params.ratingLow, t->params.ratingHigh,
+ outStatus, outStart, outEnd);
+ if(((i % 12) == 0) && (i > 0)) {
+ i = 0;
+ gMamer.XServerCom("%s %s %s %s", "\n", "qtell", user->name, "\\n");
+ }
+ i++;
+ }
+ gMamer.XServerCom("%s", "\n");
+ } else {
+ gMamer.XServerCom("qtell %s %s Notes: %s", user->name, gMamer.username, "No tourneys right now.\n");
+ }
+
+ return (1);
+}
+
+//- JoinTourney ------------------------------------------------------------
+int CommandEntry::JoinTourney(User *user, param_list params) {
+ Tourney *tourn = NULL;
+ Player *newEntry = NULL;
+
+ tourn = gMamer.FindTourney(params[0].val.integer);
+
+ if(NULL != tourn) {
+ newEntry = new Player(user->name, params[0].val.integer);
+ gMamer.pendingList.Append(newEntry);
+ gMamer.XServerCom("getpi %s%s", user->name, "\n");
+ return(1);
+ }
+
+ gMamer.TellUser(TourneyNotFound, user->name, params[0].val.integer);
+ return(0);
+}
+
+//- AddToTourney ------------------------------------------------------------
+int CommandEntry::AddToTourney(User *user, param_list params) {
+ Tourney *tourn = NULL;
+ Player *newEntry = NULL;
+
+ tourn = gMamer.FindTourney(params[1].val.integer);
+
+ if(NULL != tourn) {
+ newEntry = new Player(params[0].val.word, params[1].val.integer);
+ gMamer.pendingList.Append(newEntry);
+ gMamer.XServerCom("getpi %s%s", params[0].val.word, "\n");
+ return(1);
+ }
+
+ gMamer.TellUser(TourneyNotFound, user->name, params[1].val.integer);
+ return(0);
+}
+
+//- RemoveFromTourney ------------------------------------------------------------
+int CommandEntry::RemoveFromTourney(User *user, param_list params) {
+ Tourney *tourn = NULL;
+ TourneyPlayers *tp=NULL;
+ char name[NAMELEN], reason[64];
+ int num=0;
+ User *u=NULL;
+ int chaosPointsEarned=0, needToDelete=0;
+
+ memset(name, '\0', NAMELEN);
+ memset(reason, '\0', 64);
+ if(params[0].type == TYPE_INT) { // if we are withdrawing ourselves
+ tourn = gMamer.FindTourney(params[0].val.integer);
+ strcpy(name, user->name);
+ u = user;
+ num = params[0].val.integer;
+ strcpy(reason, "withdrew");
+ } else { // if a manager is forfeiting us
+ tourn = gMamer.FindTourney(params[1].val.integer);
+ strcpy(name, params[0].val.word);
+ u = gMamer.FindUser(params[0].val.word);
+ num = params[1].val.integer;
+ strcpy(reason, "was forfeited");
+ }
+
+ if(NULL == tourn) {
+ gMamer.TellUser(TourneyNotFound, user->name, num);
+ return 0;
+ }
+ if(tourn->GetStatus() == DONE) {
+ gMamer.TellUser(TourneyDone, user->name, num);
+ return 0;
+ }
+ tp = tourn->GetPlayer(name); //Get the players info
+ if(tp == NULL) {
+ gMamer.TellUser(NotFound, user->name, name, num);// Player is not found in this tourney
+ return 0;
+ }
+
+ gMamer.XServerCom("%s %s %d%s", "tournset", name, 0, "\n");
+ if(tourn->IsNotClosed()) { //If we get past this check it will cost the user chaos points
+ tourn->playerList.Delete(tp);
+ tourn->CalculateAverage();
+ gMamer.TellUser(PlayerRemoved, user->name, name, num);
+ gMamer.XServerCom("%s %d %s %s %s%d %d%s\n","tell", gMamer.channelNumber, name, reason, "from tourney #",
+ tourn->number, tourn->GetPlayerCount(), " player(s) now");
+ return 0;
+ } // otherwise tourney is closed and started
+
+ chaosPointsEarned = tourn->RemovePlayer(name); // RemovePlayer will return the number of rounds
+ if(chaosPointsEarned >= 0) { // that were disturbed
+ if(NULL == u) {
+ u = new User(gMamer.userFilePath, name); // Make a new user - this will create a file but there
+ needToDelete = 1; // should already be one cause they are in the tourney
+ }
+ u->AddAbuse(chaosPointsEarned * PENALTY_PER_ROUND); // add the choas points and save them
+ u->SavePlayer(gMamer.userFilePath);
+ if(u->GetAbuse() >= MAX_CHAOS_POINTS)
+ gMamer.XServerCom("%s %s%s", "+ censor", u->name, "\n");
+ if(needToDelete) delete(u); // we created a new user so we should delete him here
+ gMamer.TellUser(PlayerRemoved, user->name, name, num);
+ gMamer.XServerCom("%s %d %s %s %s%d\n","tell",gMamer.channelNumber,name, reason,
+ "from tourney #", tourn->number);
+ return 1;
+ }
+ return 1;
+}
+
+//- ListTourneyGames ------------------------------------------------------------
+int CommandEntry::ListTourneyGames(User *user, param_list params) {
+ Tourney *t = NULL;
+ TourneyPlayers *white, *black;
+ int i = 0;
+ Game *g = NULL;
+
+ t = gMamer.FindTourney(params[0].val.integer);
+ if(NULL != t) {
+ LinkListIter<Game> gameIter(t->gameList);
+ gameIter.Reset();
+ gMamer.XServerCom("%s %s %s %d %s", "qtell", user->name, "Tourney Games for Round #", t->GetRound(), "\\n\\n");
+ gMamer.XServerCom("%3s %18s %6s %6s %2s %-18s %6s %6s %s",
+ "", "White", "[SCR ]", "[Rtng]", "vs", "Black", "[SCR ]", "[Rtng]",
+ "\\n---------------------------------------------------------------------------\\n");
+ while((g = gameIter.Next())) {
+ if(!(i % 10) && (i>0)) {
+ gMamer.XServerCom("\nqtell %s %s", user->name, "\\n");
+ }
+
+ white = t->GetPlayer(g->whiteName);
+ black = t->GetPlayer(g->blackName);
+
+ if(g->gameNumber > 0) {
+ gMamer.XServerCom("%3d %18s [%4.1f] [%4i] vs %-18s [%4.1f] [%4i] %3i%s",
+ i+1, g->whiteName, white->score, white->rating,
+ g->blackName, black->score, black->rating, g->gameNumber, "\\n");
+ } else {
+ gMamer.XServerCom("%3d %18s [%4.1f] [%4i] vs %-18s [%4.1f] [%4i] none%s",
+ i+1, g->whiteName, white->score, white->rating,
+ g->blackName, black->score, black->rating, "\\n");
+ }
+ i++;
+ }
+ gMamer.XServerCom("%s", "\\n\n");
+ return(1);
+ }
+
+ gMamer.TellUser(TourneyNotFound, user->name, params[0].val.integer);
+ return(0);
+}//- End of ListTourneyGames
+
+//- ListTourneyPlayers ------------------------------------------------------------
+int CommandEntry::ListTourneyPlayers(User *user, param_list params) {
+ Tourney *t = NULL;
+ Player *p = NULL, *opp=NULL;
+ TourneyPlayers *tp = NULL;
+ char color, result;
+ int i = 0, counter = 0;
+
+ t = gMamer.FindTourney(params[0].val.integer);
+ if(NULL != t) {
+ if(t->GetPlayerCount() == 0) {
+ gMamer.TellUser(NoPlayers, user->name, params[0].val.integer);
+ return 0;
+ }
+ t->SortPlayers();
+ gMamer.XServerCom("%s %s %s %s %d %s %d %s %3s %-17s %6s %5s %6s %-6s %-7s %s %3s %-17s %6s %5s %6s %6s %-7s %s",
+ "qtell", user->name, "Tourney Players:", "Round", t->GetRound(), "of", t->params.rounds,
+ "\\n\\n", "", "Name", "Rating", "Score", "Perfrm", "Upset ", "Results", "\\n",
+ "", "-----------------", "------", "-----", "------", "------", "-------", "\\n");
+ LinkListIter<TourneyPlayers> playerIter(t->playerList);
+ playerIter.Reset();
+ while((tp = playerIter.Next())) { counter++; } // count the number of players
+ for(i=1; i<=counter; i++) {
+ p = t->GetSortPlayer(i);
+ tp = t->GetPlayer(p->name);
+ if(tp->activeFlag > 0)
+ gMamer.XServerCom("%3d %s%-17s [%4d] %3.1f [%4d] [%4d] ",
+ i, ((tp->location == ONLINE) ? "+" : "-"),
+ tp->name, tp->rating, tp->score, tp->perform, tp->upset);
+ else
+ gMamer.XServerCom("%3d %s%-17s [%4s] %3.1f [%4d] [%4d] ",
+ i, ((tp->location == ONLINE) ? "+" : "-"),
+ tp->name, "forf", tp->score, tp->perform, tp->upset);
+ LinkListIter<Player> opponentIter(tp->opponentList); // List of opponents this player has had
+ opponentIter.Reset();
+ while((opp = opponentIter.Next())) {
+ p = t->GetSortPlayer(opp->name);
+ if(opp->value) { color = 'w'; } else { color = 'b'; }
+ if(opp->floatValue == 1.0) {
+ result = '+';
+ } else if(opp->floatValue == 0.5) {
+ result = '=';
+ } else if(opp->floatValue == 0.0) {
+ result = '-';
+ } else {
+ result = '*';
+ }
+ gMamer.XServerCom("%c%-0.2d%c ", result, p->value, color);
+ }
+ if(((i % 9) == 0) && (i > 0)) {
+ gMamer.XServerCom("%s %s %s %s", "\n", "qtell", user->name, "\\n");
+ } else {
+ gMamer.XServerCom("%s", "\\n");
+ }
+ }
+ gMamer.XServerCom("%-24s %6.1f %s", "\\n Average Rating", t->GetAverageRating(), "\\n\n");
+ return(1);
+ }
+
+ gMamer.TellUser(TourneyNotFound, user->name, params[0].val.integer);
+ return(0);
+}//- End of ListTourneyPlayers
+
+//- ListTourneyVars -----------------------------------------------------
+int CommandEntry::ListTourneyVars(User *user, param_list params) {
+ Tourney *tourn = NULL;
+
+ tourn = gMamer.FindTourney(params[0].val.integer);
+
+ if(NULL != tourn) {
+ gMamer.XServerCom("%s %s %s", "qtell", user->name, "\\n");
+ gMamer.XServerCom(" %18s %4d %s", "(T)ime: ", tourn->params.time, "\\n");
+ gMamer.XServerCom(" %18s %4d %s", "(I)ncrement: ", tourn->params.inc, "\\n");
+ gMamer.XServerCom(" %18s %4d %s", "(R)ounds: ", tourn->params.rounds, "\\n");
+ gMamer.XServerCom(" %18s %4d %s", "Max (P)layers: ", tourn->params.maxPlayers, "\\n");
+ gMamer.XServerCom(" %18s %4c %s", "(M)ode: ", tourn->params.mode, "(r)ated or (u)nrated\\n");
+ gMamer.XServerCom(" %18s %4c %s", "(S)tyle: ", tourn->params.style, "(s)wiss or (r)oundrobin\\n");
+ gMamer.XServerCom(" %18s %4c %s","(V)ariant: ",tourn->params.variant, "(w)ild, (r)egular, (b)ug, or (s)uicide\\n");
+ if(tourn->params.variant == 'w')
+ gMamer.XServerCom(" %18s %4d %s",
+ "(W)ild Type: ",
+ tourn->params.wild, "(0), (1), (2), (3), (4), (5), (8), (9)8a, (10)fr\\n");
+ gMamer.XServerCom(" %18s %4d %s", "Rating (L)ow: ", tourn->params.ratingLow, "\\n");
+ gMamer.XServerCom(" %18s %4d %s", "Rating (H)igh: ", tourn->params.ratingHigh, "\\n\\n");
+ gMamer.XServerCom(" %18s %-18s %s", "Manager: ", tourn->manager, "\\n\n");
+ } else {
+ gMamer.TellUser(NotFound, user->name, "tourney");
+ }
+
+ return 1;
+}//- End ListTourneyVars
+
+//- MessageManagers -----------------------------------------------------
+int CommandEntry::MessageManagers(User *user, param_list params) {
+ int i, level, tourneys;
+ long last;
+ char filename[256], manager[NAMELEN];
+ FILE *theFile;
+
+ i = 1;
+ level = params[0].type;
+ sprintf(filename, "%s/managers", gMamer.dataFilePath);
+ if((theFile = fopen(filename, "r"))) {
+ while(fscanf(theFile, "%s %d %d %ld", manager, &level, &tourneys, &last) > 0) {
+ gMamer.XServerCom("%s %s %s %s", "message", manager, params[0].val.string, "\n");
+ }
+ fclose(theFile);
+
+ return(1);
+ }
+ gMamer.TellUser(NotFound, user->name, "Manager List");
+ return(0);
+}//- MessageManagers
+
+//- SetResult ------------------------------------------------------------
+int CommandEntry::SetResult(User *user, param_list params) {
+ Tourney *t;
+ int result, return_val = 0;
+ char answer[128];
+
+ t = gMamer.FindTourney(params[0].val.integer);
+
+ if(NULL != t) {
+ switch (params[3].type) { // try and set the result
+ case TYPE_INT:
+ switch(params[3].val.integer) {
+ case 1: result = 1; break;
+ case 0: result = 0; break;
+
+ }
+ break;
+ case TYPE_WORD:
+ if(!strcmp("=", params[3].val.word)) { result = 2;
+ } else if(!strcmp("draw", params[3].val.word)) { result = 2;
+ } else if(!strcmp("win", params[3].val.word)) { result = 1;
+ } else if(!strcmp("white", params[3].val.word)) { result = 1;
+ } else if(!strcmp("loss", params[3].val.word)) { result = 0;
+ } else if(!strcmp("black", params[3].val.word)) { result = 0;
+ } else {
+ gMamer.TellUser(GameResultNotFound, user->name, params[3].val.word);
+ return 0;
+ }
+ break;
+ default:
+ gMamer.TellUser(GameResultNotFound, user->name, params[3].val.string);
+ return 0;
+ break;
+ }
+ return_val = t->SetGameResult(params[1].val.word, params[2].val.word, result);
+ }
+ switch (return_val) {
+ case 0:
+ sprintf(answer, "a game with %s as white and %s as black", params[1].val.word, params[2].val.word);
+ gMamer.TellUser(NotFound, user->name, answer);
+ break;
+ default:
+ gMamer.TellUser(GameResultSet, user->name, params[1].val.word, params[2].val.word, result);
+ switch (result) {
+ case 1:
+ sprintf(answer, "1-0");
+ break;
+ case 0:
+ sprintf(answer, "0-1");
+ break;
+ default:
+ sprintf(answer, "1/2-1/2");
+ break;
+ }
+ gMamer.XServerCom("%s %d The game %s vs. %s in tourney #%d has been set %s by %s\n", "tell", gMamer.channelNumber,
+ params[1].val.word, params[2].val.word, t->number, answer, user->name);
+ break;
+ }
+ return return_val;
+}//- End of SetResult
+
+//- SetTourneyVariable -----------------------------------------------------
+int CommandEntry::SetTourneyVariable(User *user, param_list params) {
+ Tourney *tourn = NULL;
+ int i=0;
+ char which_var[16];
+ strings varAliases[] = {
+ {"time", 0}, {"t", 0}, {"inc", 1}, {"i", 1}, {"rounds", 2}, {"r", 2},
+ {"style", 3}, {"s", 3}, {"variant", 4}, {"v", 4}, {"mode", 5}, {"m", 5},
+ {"wild", 6}, {"w", 6},
+ {"ratingLow", 7}, {"l", 7}, {"ratingHigh", 8}, {"h", 8}, {"maxplayers", 9}, {"p", 9}, {NULL} };
+
+ tourn = gMamer.FindTourney(params[0].val.integer); // what tourney are we talking about
+ if(NULL == tourn) {
+ gMamer.TellUser(NotFound, user->name, "tourney"); // wrong tourney number
+ return 0;
+ }
+ if(FALSE == tourn->IsNotClosed()) {
+ gMamer.TellUser(TourneyClosed, user->name, params[0].val.integer);
+ return 0;
+ }
+ if(TRUE == tourn->IsNotNew()) {
+ if((0 != strncasecmp(params[1].val.word, "rounds", strlen(params[1].val.word))) && // even if it is open
+ (0 != strncasecmp(params[1].val.word, "r", strlen(params[1].val.word))) && // we can still change rounds
+ (0 != strncasecmp(params[1].val.word, "maxplayers", strlen(params[1].val.word))) && // or max players
+ (0 != strncasecmp(params[1].val.word, "p", strlen(params[1].val.word))) && //
+ (0 != strncasecmp(params[1].val.word, "style", strlen(params[1].val.word))) && // or style (rr) to (ss)
+ (0 != strncasecmp(params[1].val.word, "s", strlen(params[1].val.word)))) {
+ gMamer.TellUser(TourneyNotNew, user->name, params[0].val.integer);
+ return(0);
+ }
+ }
+ if(strcasecmp(user->name, tourn->manager) != 0) {
+ gMamer.TellUser(NoPermissions, user->name, params[0].val.integer);
+ return(0);
+ }
+ while(varAliases[i].string != NULL) {
+ if (!(strcasecmp(varAliases[i].string, params[1].val.word))) { //lets check the vars
+ if(strlen(varAliases[i].string) == 1)
+ strcpy(which_var, varAliases[i-1].string);
+ else //copy the whole word
+ strcpy(which_var, varAliases[i].string);
+
+ if((varAliases[i].number <= 2) || (varAliases[i].number >= 6))
+ if(params[2].type == TYPE_INT) { // if var is one that should be int
+ tourn->SetVariable(varAliases[i].number, params[2].val.integer);
+ gMamer.TellUser(ChangedInfo, user->name, which_var, params[2].val.integer);
+ return 1;
+ } else {
+ gMamer.TellUser(CanNotChange, user->name, which_var, params[2].val.word);
+ return 0;
+ }
+ else
+ if(params[2].type == TYPE_WORD) {
+ tourn->SetVariable(varAliases[i].number, params[2].val.word);
+ gMamer.TellUser(ChangedInfo, user->name, which_var, params[2].val.word);
+ return 1;
+ } else {
+ gMamer.TellUser(CanNotChange, user->name, which_var, params[2].val.integer);
+ return 0;
+ }
+ }
+ i++;
+ }
+
+ gMamer.TellUser(NotFound, user->name, params[1].val.word); // Bad Variable
+ return 0;
+}
+
+//- ShutdownCommand ----------------------------------------------------------
+int CommandEntry::Shutdown(User *user, param_list params) {
+ int i;
+
+ i = params[0].type;
+ i = user->GetManagerLevel();
+
+ gMamer.Shutdown();
+ exit(0);
+
+ return(1);
+} //- end of Shutdown
--- /dev/null
+//--------------------------------------------------------------------------
+// CommandEntry.hh - Class definition for CommandEntry
+//
+// Matthew E. Moses
+//
+// $Revision: 1.11 $
+// $Date: 1998/09/10 19:58:31 $
+//
+// $Author: mlong $
+// $Locker: $
+//
+// $Log: CommandEntry.hh,v $
+// Revision 1.11 1998/09/10 19:58:31 mlong
+// *** empty log message ***
+//
+// Revision 1.10 1998/06/18 18:41:52 mlong
+// prepairing for yet another move.
+//
+// Revision 1.9 1998/04/29 15:24:07 mlong
+// prepairing for the move to daimi
+// new sorting routine.
+//
+// Revision 1.8 1998/04/18 18:46:31 mlong
+// fixed delete bug and
+// added delete tourney function
+//
+// Revision 1.7 1998/02/12 18:44:25 mlong
+// *** empty log message ***
+//
+// Revision 1.6 1997/10/28 21:03:48 mlong
+// *** empty log message ***
+//
+// Revision 1.5 1997/10/23 20:13:37 mlong
+// *** empty log message ***
+//
+// Revision 1.5 1997/10/23 19:56:12 chess
+// *** empty log message ***
+//
+// Revision 1.4 1997/05/15 18:29:12 chess
+// added pending and TourneyPlayers support
+// added HandleGetPlayerInfo & HandleGetGameInfo
+//
+// Revision 1.3 1997/04/13 03:21:32 chess
+// new commands added SetInfo SetStat AddAbuse
+//
+// Revision 1.2 1997/03/21 15:32:36 moses
+// added the shutdown command.
+//
+// Revision 1.1 1996/10/01 20:14:43 moses
+// Initial revision
+//
+//--------------------------------------------------------------------------
+
+#ifndef _UserCommands_
+#define _UserCommands_
+
+#include "types.h"
+#include "User.hh"
+#include "Tourney.hh"
+
+class CommandEntry {
+ public:
+ int AddAbuse(User *, param_list);
+ int AnnounceTourney(User *, param_list);
+ int CreateTourney(User *, param_list);
+ int CloseTourney(User *, param_list);
+ int DeleteTourney(User *, param_list);
+ int FingerUser(User *, param_list);
+ int JoinTourney(User *, param_list);
+ int KeepTourney(User *, param_list);
+ int AddToTourney(User *, param_list);
+ int RemoveFromTourney(User *, param_list);
+ int ListRank(User *, param_list);
+ int ListManagers(User *, param_list);
+ int ListTourneys(User *, param_list);
+ int ListTourneyPlayers(User *, param_list);
+ int ListTourneyGames(User *, param_list);
+ int ListTourneyVars(User *, param_list);
+ int LoadedUsers(User *, param_list);
+ int MessageManagers(User *, param_list);
+ int OpenTourney(User *, param_list);
+ int SetCommandLevel(User *, param_list);
+ int SetInfo(User *, param_list);
+ int SetManagerLevel(User *, param_list);
+ int SetResult(User *, param_list);
+ int SetStat(User *, param_list);
+ int SetTourneyVariable(User *, param_list);
+ int ShowCommands(User *, param_list);
+ int ShowHelp(User *, param_list);
+ int Shutdown(User *, param_list);
+ int Withdraw(User *, param_list);
+
+};
+
+#endif
+
+
+
--- /dev/null
+//--------------------------------------------------------------------------
+// Game.cc - Source file for the Game class
+//
+// Matthew E. Moses && Michael A. Long
+//
+// $Revision: 1.4 $
+// $Date: 2002/07/02 00:05:19 $
+//
+// $Author: tridge $
+// $Locker: $
+//
+// $Log: Game.cc,v $
+// Revision 1.4 2002/07/02 00:05:19 tridge
+// got rid of a bunch of RCS tags now that its in CVS
+//
+// Revision 1.3 1998/09/10 19:57:17 mlong
+// lots of little bug fixes and a few new features
+//
+// Revision 1.2 1998/04/29 15:23:19 mlong
+// prepairing for the move to daimi
+// new sorting routine.
+//
+// Revision 1.1 1997/07/18 15:42:13 chess
+// Initial revision
+//
+//
+//--------------------------------------------------------------------------
+
+#include "Game.hh"
+
+//- Constructor -----------------------------------------------------------
+Game::Game(char *wn, char *bn, int t, int i, int r, char v) {
+ strcpy(whiteName, wn);
+ strcpy(blackName, bn);
+ time = t;
+ inc = i;
+ rated = r;
+ variation = v;
+
+ gameNumber = -1;
+}
+
+//- DeConstructor ---------------------------------------------------------
+Game::~Game() {
+}
+
+//- IsGame -----------------------------------------------------------------
+int Game::IsGame(char *whiteUser, char *blackUser, int t, int i, int r, char v) {
+ if(
+ (0 == strcasecmp(whiteUser, whiteName)) &&
+ (0 == strcasecmp(blackUser, blackName)) &&
+ (time == t) &&
+ (inc == i) &&
+ (rated == r) &&
+ (variation == v))
+ return(1);
+ else
+ return(0);
+} //- End of IsGame
--- /dev/null
+//--------------------------------------------------------------------------
+// Game.hh - Class header for the Game class
+//
+// Matthew E. Moses & Michael A. Long
+//
+// $Revision: 1.5 $
+// $Date: 2002/07/02 00:05:19 $
+//
+// $Log: Game.hh,v $
+// Revision 1.5 2002/07/02 00:05:19 tridge
+// got rid of a bunch of RCS tags now that its in CVS
+//
+// Revision 1.4 2002/07/02 00:02:40 tridge
+// - fixed compile on g++ 2.96
+// - updated for lasker 'rmatch'
+//
+// Revision 1.3 1998/09/10 19:58:41 mlong
+// lots of little bug fixes and a few new features.
+//
+// Revision 1.2 1998/04/29 15:24:07 mlong
+// prepairing for the move to daimi
+// new sorting routine.
+//
+// Revision 1.1 1997/07/18 15:42:58 chess
+// Initial revision
+//
+//
+//--------------------------------------------------------------------------
+
+#ifndef _Game_
+#define _Game_
+
+#include <fstream.h>
+#include <iostream.h>
+
+extern "C" {
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <sys/stat.h>
+
+#include <time.h>
+#include <unistd.h>
+}
+
+#include "config.h"
+#include "User.hh"
+#include "link.hh"
+#include "linklist.hh"
+
+class Game : public Link {
+public:
+
+ Game(char *, char *, int, int, int, char);
+ ~Game();
+
+int IsGame(char *, char *, int, int, int, char);
+
+private:
+
+public:
+
+ char whiteName[NAMELEN];
+ char blackName[NAMELEN];
+ int rated;
+ int time;
+ int inc;
+ char variation;
+ int gameNumber;
+
+private:
+
+};
+
+
+#endif
+
+
+
+
+
+
--- /dev/null
+#!make
+#
+# $Revision: 1.8 $
+# $Author: mlong $
+#
+# $Date: 1998/09/11 15:47:50 $
+#
+# $Locker: $
+#
+
+ifeq (${USE_INSURE}, 1)
+ CFLAGS = -Wall -ggdb
+ C++FLAGS = -Wall -ggdb
+ CC = insure
+ C++ = insure
+else
+ ifeq (${USE_CHECKER}, 1)
+ CFLAGS = -Wall ##-ggdb
+ CC = checker -gcc
+ C++ = checker -g++
+ else
+ CFLAGS = -Wall -ggdb
+ C++FLAGS = -Wall -ggdb
+ CC = gcc
+ C++ = g++
+ endif
+endif
+
+
+#DEFINES = -DSUN
+
+#LDFLAGS = -lsocket -lnls -lnsl
+
+MAMER=mamer
+MAMER-HEADERS = config.h Mamer.hh User.hh Tourney.hh link.hh linklist.hh\
+ Command.hh CommandEntry.hh TourneyParameters.hh TourneyPlayers.hh\
+ Game.hh Player.hh Storage.hh
+MAMER-SRCS = main.cc Mamer.cc User.cc Tourney.cc link.cc Command.cc\
+ CommandEntry.cc TourneyParameters.cc TourneyPlayers.cc\
+ Game.cc Player.cc Storage.cc
+MAMER-OBJS = main.o Mamer.o User.o Tourney.o link.o Command.o \
+ CommandEntry.o TourneyParameters.o TourneyPlayers.o\
+ Game.o Player.o Storage.o
+
+HEADERS = $(MAMER-HEADERS)
+SRCS = $(MAMER-SRCS)
+OBJS = $(MAMER-OBJS)
+
+default:: $(MAMER)
+
+all:: $(MAMER)
+
+# Object file rules
+%.o: %.cc
+ $(C++) $(DEFINES) $(C++FLAGS) -c $<
+
+%.o: %.c
+ $(CC) $(DEFINES) $(CFLAGS) -c $<
+
+$(MAMER): $(MAMER-OBJS)
+ $(C++) $(C++FLAGS) -o bin/$@ $(MAMER-OBJS) $(LDFLAGS)
+
+clean:
+ rm -f $(OBJS) bin/mamer *~ #*
+
+count:
+ wc -l $(HEADERS) $(SRCS)
+
+tar:
+ make clean
+ (cd ..; tar -cf mamer.tar mamer; gzip -f mamer.tar; mv mamer.tar.gz mamer)
+
+bak:
+ mv bin/mamer bin/mamer_bak
+
+# File Dependencies
+
+main.o: main.cc\
+ Mamer.hh\
+ config.h
+
+Mamer.o: Mamer.cc\
+ Mamer.hh\
+ User.hh\
+ Tourney.hh\
+ config.h\
+ link.hh\
+ linklist.hh\
+ CommandEntry.hh\
+ TourneyParameters.hh\
+ Player.hh\
+ Game.hh\
+ Storage.hh
+
+User.o: User.cc\
+ User.hh\
+ config.h\
+ link.hh
+
+Tourney.o: Tourney.cc\
+ Tourney.hh\
+ config.h\
+ link.hh\
+ TourneyParameters.hh\
+ TourneyPlayers.hh\
+ Player.hh\
+ Game.hh\
+ Storage.hh
+
+Command.o: Command.cc\
+ Command.hh\
+ config.h\
+ link.hh\
+ types.h\
+ Game.hh
+
+CommandEntry.o: CommandEntry.cc\
+ CommandEntry.hh\
+ User.hh\
+ types.h\
+ Game.hh
+
+TourneyParameters.o: TourneyParameters.cc\
+ TourneyParameters.hh
+
+TourneyPlayers.o: TourneyPlayers.cc\
+ TourneyPlayers.hh
+
+Storage.o: Storage.cc\
+ Storage.hh
+
+Player.o: Player.cc\
+ Player.hh
+
+Game.o: Game.cc\
+ Game.hh
--- /dev/null
+//--------------------------------------------------------------------------
+// Mamer.cc - Source file for the Mamer class
+//
+// Matthew E. Moses & Michael A. Long
+//
+// $Revision: 1.19 $
+// $Date: 2002/07/02 00:05:19 $
+//
+//--------------------------------------------------------------------------
+
+#include "Mamer.hh"
+
+extern void HandleSignals(int);
+
+//- Constructor ------------------------------------------------------------
+Mamer::Mamer() {
+ time_t theTime;
+ struct tm *timeStruct;
+
+ theTime = time((time_t *)NULL);
+ timeStruct = localtime(&theTime);
+
+ loggedInFlag = FALSE;
+
+ memset(configFilename, '\0', MAXPATHLEN);
+ strncpy(configFilename, CONFIG_FILENAME, MIN(strlen(CONFIG_FILENAME), MAXPATHLEN));
+
+ channelNumber = DEFAULT_CHANNEL;
+ memset(hostname, '\0', 256);
+ strncpy(hostname, DEFAULT_HOSTNAME, MIN(strlen(DEFAULT_HOSTNAME), 256));
+ portNumber = DEFAULT_PORT;
+
+ debugLevel = 0;
+
+ memset(username, '\0', 80);
+ memset(password, '\0', 80);
+ strncpy(username, DEFAULT_USERNAME, MIN(strlen(DEFAULT_USERNAME), 80));
+ strncpy(password, DEFAULT_PASSWORD, MIN(strlen(DEFAULT_PASSWORD), 80));
+
+ sprintf(logFilename, "%s/%s.%04d%02d%02d",
+ DEFAULT_PATH, DEFAULT_LOG_FILE,
+ 1900 + timeStruct->tm_year, timeStruct->tm_mon + 1,
+ timeStruct->tm_mday);
+
+ sprintf(userFilePath, "%s/%s", DEFAULT_PATH, DEFAULT_USER_PATH);
+ sprintf(dataFilePath, "%s/%s", DEFAULT_PATH, DEFAULT_DATA_PATH);
+ sprintf(homeFilePath, "%s", DEFAULT_PATH);
+
+ tourneyParams.time = DEFAULT_TIME;
+ tourneyParams.inc = DEFAULT_INCREMENT;
+ tourneyParams.mode = 'r';
+ tourneyParams.style = 's';
+ tourneyParams.variant = 'r';
+ tourneyParams.rounds = DEFAULT_ROUNDS;
+ tourneyParams.ratingHigh = 9999;
+ tourneyParams.ratingLow = 0;
+ tourneyParams.maxPlayers = DEFAULT_MAX_PLAYERS;
+
+} //- End of Mamer
+
+//- Deconstructor ----------------------------------------------------------
+Mamer::~Mamer() {
+ User *u = NULL;
+ Tourney *t = NULL;
+ Command *c = NULL;
+
+ while(0 != (u = userList.Head()))
+ userList.Delete();
+
+ while(0 != (t = tourneyList.Head()))
+ tourneyList.Delete();
+
+ while(0 != (c = commandList.Head()))
+ commandList.Delete();
+
+} //- End of ~Mamer
+
+//- Initialize -------------------------------------------------------------
+int Mamer::Initialize(int argc, char **argv) {
+ struct stat statBuffer;
+ char c;
+
+ LoadConfigurationFile();
+
+ while(EOF != (c = getopt(argc, argv,
+ "d:D:c:C:s:S:p:P:u:U:l:L:hHa:A:n:N:"))) {
+ switch(c) {
+ case 'd':
+ case 'D':
+ debugLevel = atoi(optarg);
+ break;
+ case 'c':
+ case 'C':
+ channelNumber = atoi(optarg);
+ break;
+ case 's':
+ case 'S':
+ memset(hostname, '\0', 256);
+ strncpy(hostname, optarg, MIN(strlen(optarg), 256));
+ break;
+ case 'n':
+ case 'N':
+ portNumber = atoi(optarg);
+ break;
+ case 'u':
+ case 'U':
+ memset(userFilePath, '\0', MAXPATHLEN);
+ strncpy(userFilePath, optarg, MIN(strlen(optarg), MAXPATHLEN));
+ break;
+ case 'l':
+ case 'L':
+ memset(userFilePath, '\0', MAXPATHLEN);
+ strncpy(logFilename, optarg, MIN(strlen(optarg), MAXPATHLEN));
+ break;
+ case 'a':
+ case 'A':
+ memset(username, '\0', 80);
+ strncpy(username, optarg, MIN(strlen(optarg), 80));
+ break;
+ case 'p':
+ case 'P':
+ memset(password, '\0', 80);
+ strncpy(password, optarg, MIN(strlen(optarg), 80));
+ break;
+ case 'h':
+ case 'H':
+ default:
+ Usage();
+ exit(0);
+ }
+ }
+
+ if(-1 == stat(userFilePath, &statBuffer)) {
+ switch(errno) {
+ case ENOENT:
+ if(-1 == mkdir(userFilePath, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IXOTH)) {
+ perror("create user file path");
+ return(0);
+ }
+ }
+ }
+
+ if(10 <= debugLevel)
+ DumpConfiguration();
+
+ signal(SIGPIPE, SIG_IGN);
+ signal(SIGTERM, HandleSignals);
+ signal(SIGKILL, HandleSignals);
+ signal(SIGUSR1, HandleSignals);
+ signal(SIGUSR2, HandleSignals);
+
+ BuildCommandList();
+
+ return(1);
+} //- End of Initialize
+
+//- s_and_r - Search and Replace a string within a string ------------
+char *Mamer::s_and_r(char *s, char *tofind, char *toreplace) {
+ char *toReturn = NULL;
+ int currSize = 0;
+ char *return_offset;
+ char *replace_offset;
+ int find_len;
+ int toreplace_len;
+ register int x;
+
+ /* if nothing to look at, and nothing to replace.... return nothing */
+ if ( s == NULL || tofind == NULL)
+ return NULL;
+
+ find_len = strlen(tofind);
+ if ( toreplace != NULL )
+ toreplace_len = strlen(toreplace);
+ else
+ toreplace_len = 0; /* allow us to have nothing to replace... acts the same a delstring */
+
+ currSize = (strlen(s) * 2) + 100; /* add the 100 in case s is small */
+ toReturn = (char*)malloc(currSize);
+ return_offset = toReturn;
+ while ( *s != '\0' ) {
+ if ( *s == *tofind && strncmp(s, tofind, MIN(find_len, (int)strlen(s))) == 0 ) {
+ /* if the first letter matches, and so does the rest.. */
+ /* copy in the replace string */
+ replace_offset = toreplace;
+ for ( x = 0; x < toreplace_len; x++ ) {
+ *return_offset = *replace_offset;
+ return_offset++;
+ replace_offset++;
+ }
+ /* and move up the current position in s to just past the find string */
+ s += find_len;
+ } else { /* it doesn't match.... just copy to the return and continue */
+ *return_offset = *s;
+ return_offset++;
+ s++;
+ }
+ }
+ *return_offset = '\0';
+
+ return toReturn;
+}
+
+//- OpenServerConnection ---------------------------------------------------
+int Mamer::OpenServerConnection(void) {
+ struct sockaddr_in socketAddr;
+ struct hostent *hostEntry = NULL;
+// char mesg[MAXPATHLEN] = {'\0'};
+ unsigned long inAddr;
+
+ //- Check is we have a decimal notation host address
+ socketAddr.sin_family = AF_INET;
+ if((unsigned long)INADDR_NONE != (inAddr = inet_addr(hostname)))
+ socketAddr.sin_addr.s_addr = inAddr;
+ else { //- Try to query a namserver to get an address
+ if(NULL == (hostEntry = gethostbyname(hostname))) {
+ cerr << "ERROR: can't resolve hostname '" << hostname
+ << "'." << endl;
+ cerr << endl;
+ return(0);
+ }
+
+ bcopy(hostEntry->h_addr, (char *)&socketAddr.sin_addr,
+ hostEntry->h_length);
+ }
+
+ serverSocket = socket(AF_INET, SOCK_STREAM, 0);
+ if(0 > serverSocket) {
+ cerr << "ERROR: can't create TCP socket." << endl;
+ cerr << endl;
+ return(0);
+ }
+
+ socketAddr.sin_port = htons(portNumber);
+ if(0 > connect(serverSocket, (struct sockaddr *)&socketAddr,
+ sizeof(struct sockaddr_in))) {
+ cerr << "ERROR: can't create connection to server '"
+ << hostname << "' on port " << portNumber << "." << endl;
+ cerr << " " << strerror(errno) << endl;
+ cerr << endl;
+ return(0);
+ }
+
+ return(1);
+} //- End of OpenServerConnection
+
+//- ListenLoop -------------------------------------------------------------
+void Mamer::ListenLoop(void) {
+ struct timeval timeout;
+ char readBuffer[4096], writeBuffer[4096], commandBuffer[4096], channelCmpStr[16];
+ char *p = NULL, *buffer = NULL, *tmpBuffer = NULL;
+ fd_set fdMask;
+ long size = 0;
+ int i = 0, j = 0;
+
+ sprintf(channelCmpStr, "(%d): ", channelNumber);
+ buffer = new char[4096];
+ if(NULL == buffer) {
+ cerr << "ERROR: problems allocating memory" << endl;
+ cerr << endl;
+ return;
+ }
+
+ tmpBuffer = new char[4096];
+ if(NULL == tmpBuffer) {
+ cerr << "ERROR: problems allocating memory" << endl;
+ cerr << endl;
+ return;
+ }
+
+ timeout.tv_sec = timeout.tv_usec = 0;
+
+ while(1) {
+ FD_ZERO(&fdMask);
+ FD_SET(serverSocket, &fdMask);
+
+#ifdef HPUX
+ select(serverSocket + 3, (int *)&fdMask, (int *)0, (int *)0, &timeout);
+#else
+ select(serverSocket + 3, &fdMask, (fd_set *)0, (fd_set *)0, &timeout);
+#endif
+
+ if(FD_ISSET(serverSocket, &fdMask)) {
+ size = 0;
+ memset(readBuffer, '\0', 4096);
+ memset(writeBuffer, '\0', 4096);
+ size = read(serverSocket, readBuffer, (sizeof(readBuffer) - 1));
+
+ if(size > 0) {
+ //- fix newlines/linefeeds
+ memset(buffer, '\0', 4096);
+ strncpy(buffer, readBuffer, size);
+ buffer[size] = '\0';
+
+ if(NULL != (strstr(buffer, "\n\r\\ "))) {
+ strcpy(tmpBuffer, s_and_r(buffer, "\n\r\\ ", ""));
+ memset(buffer, '\0', 4096);
+ strcpy(buffer, tmpBuffer);
+ size = strlen(buffer);
+ }
+
+ if(NULL != (strstr(buffer, "\r\n\\ "))) {
+ strcpy(tmpBuffer, s_and_r(buffer, "\r\n\\ ", ""));
+ memset(buffer, '\0', 4096);
+ strcpy(buffer, tmpBuffer);
+ size = strlen(buffer);
+ }
+
+ if(NULL != (strstr(buffer, "\n\r "))) {
+ strcpy(tmpBuffer, s_and_r(buffer, "\n\r ", ""));
+ memset(buffer, '\0', 4096);
+ strcpy(buffer, tmpBuffer);
+ size = strlen(buffer);
+ }
+
+ if((FALSE == loggedInFlag) &&
+ (NULL != strstr(buffer, "login:"))) {
+ sprintf(writeBuffer, "%s\n", username);
+ write(serverSocket, writeBuffer, strlen(writeBuffer));
+ } else if((FALSE == loggedInFlag) &&
+ (NULL != strstr(buffer, "password:"))) {
+ sprintf(writeBuffer,
+ "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s %d\n",
+ password,
+ "set prompt %",
+ "set pinform 1",
+ "set ginform 1",
+ "set mamer 1",
+ "set shout 0",
+ "set cshout 0",
+ "set seek 0",
+ "set open 0",
+ "admin",
+ "set tell 0",
+ "+ channel ",
+ channelNumber
+ );
+ write(serverSocket, writeBuffer, strlen(writeBuffer));
+ FILE *theFile;
+ char manager[NAMELEN], filename[128];
+ sprintf(filename, "%s/managers", dataFilePath);
+ if((theFile = fopen(filename, "r"))) {
+ while(fscanf(theFile, "%s", manager) > 0) {
+ XServerCom("qtell %s %s %s %s",
+ manager, "Howdy, ", username, " is here!\n");
+ }
+ }
+ fclose(theFile);
+
+ loggedInFlag = TRUE;
+ }
+ else if(TRUE == loggedInFlag) {
+ i = 0;
+ while(i < size) {
+ while(('\r' == buffer[i]) ||
+ ('\n' == buffer[i]) ||
+ ('%' == buffer[i]) ||
+ (' ' == buffer[i]))
+ i++;
+ j = 0;
+ while(('\r' != buffer[i]) &&
+ ('\n' != buffer[i]) &&
+ (i < size))
+ commandBuffer[j++] = buffer[i++];
+ commandBuffer[j] = '\0';
+
+ if(NULL != (p = strstr(commandBuffer, channelCmpStr)))
+ HandleChannel(commandBuffer);
+ else if(NULL != (p = strstr(commandBuffer, "tells you:")))
+ HandleTell(commandBuffer);
+ else if(NULL != (p = strstr(commandBuffer, "has connected")))
+ HandleConnect(commandBuffer);
+ else if(NULL != (p = strstr(commandBuffer, "has disconnected")))
+ HandleDisconnect(commandBuffer);
+ else if(0 == strncmp(commandBuffer, "{Game ", 6))
+ HandleGame(commandBuffer);
+ else if(0 == strncmp(commandBuffer, "*qtell ", 7))
+ HandleQtell(commandBuffer);
+ else if(0 == strncmp(commandBuffer, "*getgi ", 7))
+ HandleGameInfo(commandBuffer);
+ else if(0 == strncmp(commandBuffer, "*getpi ", 7))
+ HandlePlayerInfo(commandBuffer);
+ else {
+ /*
+ cout << "Unsupported: " << commandBuffer << endl;
+ cout << endl;
+ */
+ }
+
+ while(('\r' == buffer[i]) ||
+ ('\n' == buffer[i]) ||
+ ('%' == buffer[i]) ||
+ (' ' == buffer[i]))
+ i++;
+ }
+ }
+ } else {
+ if((errno == EINTR) || (errno == EAGAIN) || (errno == EIO) ||
+ (errno == EBADF) || (errno == EINVAL) || (errno == EFAULT)) {
+ switch (errno) {
+ case EINTR:
+ printf("Error = %s\n", "EINTR");
+ break;
+ case EAGAIN:
+ printf("Error = %s\n", "EAGAIN");
+ break;
+ case EIO:
+ printf("Error = %s\n", "EIO");
+ break;
+ case EBADF:
+ printf("Error = %s\n", "EBADF");
+ break;
+ case EINVAL:
+ printf("Error = %s\n", "EINVAL");
+ break;
+ case EFAULT:
+ printf("Error = %s\n", "EFAULT");
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ }
+ }
+ sleep(1);
+ } //- end while(1)
+
+ if(NULL != buffer)
+ delete [] buffer;
+
+ if(NULL != tmpBuffer)
+ delete [] tmpBuffer;
+
+} //- End of ListenLoop
+
+//- Start of GivePlace ----------------------------
+int Mamer::GivePlace(int i, Tourney *t) {
+ TourneyPlayers *tp = NULL, *place = NULL;
+ User *u = NULL;
+ Player *opp = NULL;
+ LinkListIter<TourneyPlayers> playerIter(t->playerList);
+ float score=0.0;
+ int counter=0;
+ char placeName[7];
+
+ memset(placeName, '\0', 7);
+ switch(i) {
+ case 1:
+ strcpy(placeName, "First");
+ break;
+ case 2:
+ strcpy(placeName, "Second");
+ break;
+ case 3:
+ strcpy(placeName, "Third");
+ break;
+ default:
+ break;
+ }
+
+ XServerCom("%s %i %s %s %s%i %s ", "tell", channelNumber, "Tourney Results:", placeName,
+ "place in tourney #", t->number, "goes to: ");
+
+ opp = t->GetSortPlayer(i);
+ place = t->GetPlayer(opp->name);
+ score = place->score;
+
+ while((tp = playerIter.Next())) {
+ if(tp->score == score) {
+ XServerCom("%s ", tp->name);
+ counter++;
+ u = FindUser(tp->name);
+ if(u == NULL) {
+ CheckUser(tp->name);
+ u = FindUser(tp->name);
+ }
+ // if(NULL != u)
+ u->AddStat(i); // Adds a first/second/third place finish to everyone with the same score as the 1st
+ }
+ }
+ XServerCom("\n");
+
+ return counter;
+}
+
+//- Start of AnnounceTourneyEnd
+void Mamer::AnnounceTourneyEnd(Tourney *t) {
+ TourneyPlayers *tp = NULL;
+ int first=0, second=0, third=0;
+ int numberOfPlayers = 0;
+
+ t->EndTourney();
+ t->SortPlayers();
+ t->SetEndDate();
+
+ LinkListIter<TourneyPlayers> playerIter(t->playerList);
+
+ while((tp = playerIter.Next())) {
+ if((tp->activeFlag) && (strcasecmp(tp->name, "_BYE_") != 0))
+ numberOfPlayers++;
+ }
+
+ first = GivePlace(1, t); //first = number of people tied for first
+
+ if(numberOfPlayers >= 5) {
+ if(first == 1) { second = GivePlace(2, t); }
+ if(first == 2) { third = GivePlace(3, t); }
+ if(numberOfPlayers >= 7) {
+ if(second == 1) { third = GivePlace(3, t); }
+ }
+ }
+}
+
+//- savePlayerData --------------------------------------------------------------
+void Mamer::savePlayerData(Tourney *t) {
+ LinkListIter<TourneyPlayers> playerIter(t->playerList);
+ TourneyPlayers *tp = NULL, *tmpOpp = NULL;
+ User *u = NULL, *manager=NULL;
+ Player *opp;
+ int w, d, l;
+ float r, tourn_expect=0.0, pre_expect=0.0, delta = 0.0;
+
+ manager = FindUser(t->manager); // save the manager info
+ if(manager == NULL) {
+ manager = new User(userFilePath, t->manager); // manager isn't online
+ manager->SetLast(time(0)); // so we have to load him/her
+ manager->AddManagedTourney();
+ manager->SavePlayer(userFilePath);
+ delete(manager);
+ } else { // manager is online
+ manager->SetLast(time(0));
+ manager->AddManagedTourney();
+ manager->SavePlayer(userFilePath);
+ }
+
+ while((tp = playerIter.Next())) {
+ tourn_expect = 0.0;
+ u = FindUser(tp->name);
+ if(u == NULL) {
+ User *newUser = NULL;
+ newUser = new User(userFilePath, tp->name);
+ u = newUser;
+ }
+ if(debugLevel >= 5)
+ cout << "savePlayerData::" << tp->name << " " << u->name << endl;
+ r = u->GetRating();
+ w = u->GetWins();
+ l = u->GetLosses();
+ d = u->GetDraws();
+ pre_expect = ((float)w + (0.5 * (float)d)) / r;
+
+ LinkListIter<Player> opponentIter(tp->opponentList); // List of opponents this player has had
+ while((opp = opponentIter.Next())) {
+ tmpOpp = t->GetPlayer(opp->name); // need the player's information to do tourn_expect
+ delta = (float)(((tp->rating != 0) ? tp->rating : 1600) -
+ ((tmpOpp->rating != 0) ? tmpOpp->rating : 1600)); // difference in rating
+ tourn_expect = tourn_expect + (1 / (1+pow(10,(delta/400.0))));
+ u->AddStat(opp->floatValue);
+ }
+ u->AddPlayedTourney();
+ if(tp->activeFlag) { // If I didn't withdraw or get forfeited reduce my abuse points
+ u->AddAbuse(-1 * t->GetRound()); // This will be the # of rounds played because the tourney is DONE
+ XServerCom("%s %s %d%s", "tournset", tp->name, 0, "\n");
+ }
+ u->CalculateRating(tourn_expect, pre_expect);
+ u->SavePlayer(userFilePath);
+ }
+} //- End of savePlayerData ------------------------------------------
+
+//- Shutdown --------------------------------------------------------------
+void Mamer::Shutdown(void) {
+ LinkListIter<User> userIter(userList);
+ User *u = NULL;
+
+ while((u = userIter.Next())) {
+ // u->SavePlayer(userFilePath);
+ userList.Delete(u);
+ }
+
+ write(serverSocket, "exit\n", 5);
+ close(serverSocket);
+ exit(0);
+} //- End of Shutdown
+
+//- Usage -----------------------------------------------------------------
+void Mamer::Usage(void) {
+ cerr << "Usage: mamer [-c channel] [-s server] [-n port number] " << endl;
+ cerr << " [-d debug level] [-u users database filename] "
+ << endl;
+ cerr << " [-l log filename] [-a mamer account name] " << endl;
+ cerr << " [-p mamer password] [-h help] " << endl;
+ cerr << endl;
+ cerr << "\t-h show usage information." << endl;
+ cerr << "\t-c sets which channel mamer should work on.\n\t (default = "
+ << channelNumber << ")" << endl;
+ cerr << "\t-s sets the server hostname that mamer connects to.\n\t"
+ << " (default = " << hostname << ")" << endl;
+ cerr << "\t-n sets the port number on the server to connect to.\n\t"
+ << " (default = " << portNumber << ")" << endl;
+ cerr << "\t-a sets the username for the account to mamer logs in as.\n\t"
+ << " (default = " << username << ")" << endl;
+ cerr << "\t-p sets the password for the mamer account.\n\t"
+ << " (default = " << password << ")" << endl;
+ cerr << "\t-d sets the debugging level. This determines how much of "
+ << "the\n\t activity of mamer is written to the logs." << endl;
+ cerr << "\t-u set the location of the users database file.\n\t"
+ << " (default = " << userFilePath << ")" << endl;
+ cerr << "\t-l sets the location of the log file.\n\t (default = "
+ << logFilename << ")" << endl;
+ cerr << endl;
+} //- End of Usage
+
+//- LoadConfigurationFile -------------------------------------------------
+void Mamer::LoadConfigurationFile(void) {
+ struct stat statBuffer;
+ int length=0;
+
+ if(-1 != stat(configFilename, &statBuffer)) {
+ char *buffer = NULL;
+ fstream theFile(configFilename, ios::in);
+
+ buffer = new char[MAXPATHLEN + 80];
+ if(NULL == buffer)
+ return;
+
+ memset(buffer, '\0', MAXPATHLEN + 80);
+
+ while(theFile.good()) {
+ theFile.getline(buffer, MAXPATHLEN + 80 - 1, '\n');
+
+ if(buffer[0] == '#') continue;
+ length = strlen(buffer);
+
+ if(length >= 4) {
+ if(0 == strncasecmp(buffer, "HOST", 4)) {
+ buffer += 4;
+ while(isspace(buffer[0])) buffer++;
+
+ memset(hostname, '\0', MAXPATHLEN);
+ strncpy(hostname, buffer, MIN(length, MAXPATHLEN));
+ } else if(0 == strncasecmp(buffer, "DATA", 4)) {
+ buffer += 4;
+ while(isspace(buffer[0])) buffer++;
+
+ memset(dataFilePath, '\0', MAXPATHLEN);
+ strncpy(dataFilePath, buffer, MIN(length, MAXPATHLEN));
+ } else if(0 == strncasecmp(buffer, "HOME", 4)) {
+ buffer += 4;
+ while(isspace(buffer[0])) buffer++;
+
+ memset(homeFilePath, '\0', MAXPATHLEN);
+ strncpy(homeFilePath, buffer, MIN(length, MAXPATHLEN));
+ } else if(0 == strncasecmp(buffer, "HELP", 4)) {
+ buffer += 4;
+ while(isspace(buffer[0])) buffer++;
+
+ memset(helpFilePath, '\0', MAXPATHLEN);
+ strncpy(helpFilePath, buffer, MIN(length, MAXPATHLEN));
+ } else if(0 == strncasecmp(buffer, "USER", 4)) {
+ buffer += 4;
+ while(isspace(buffer[0])) buffer++;
+
+ memset(username, '\0', 80);
+ strncpy(username, buffer, MIN(length, 80));
+ } else if(0 == strncasecmp(buffer, "PASS", 4)) {
+ buffer += 4;
+ while(isspace(buffer[0])) buffer++;
+
+ memset(password, '\0', 80);
+ strncpy(password, buffer, MIN(length, 80));
+ } else if(0 == strncasecmp(buffer, "PORT", 4)) {
+ buffer += 4;
+ while(isspace(buffer[0])) buffer++;
+
+ portNumber = atoi(buffer);
+ } else if(0 == strncasecmp(buffer, "CHAN", 4)) {
+ buffer += 4;
+ while(isspace(buffer[0])) buffer++;
+
+ channelNumber = atoi(buffer);
+ } else if(0 == strncasecmp(buffer, "DBUG", 4)) {
+ buffer += 4;
+ while(isspace(buffer[0])) buffer++;
+
+ debugLevel = atoi(buffer);
+ }
+ }
+ if(length >= 3) {
+ if(0 == strncasecmp(buffer, "LOG", 3)) {
+ buffer += 3;
+ while(isspace(buffer[0])) buffer++;
+
+ memset(logFilename, '\0', MAXPATHLEN);
+ strncpy(logFilename, buffer, MIN(length, MAXPATHLEN));
+ } else if((strlen(buffer) > 3) && (0 == strncasecmp(buffer, "UDB", 3))) {
+ buffer += 3;
+ while(isspace(buffer[0])) buffer++;
+
+ memset(userFilePath, '\0', MAXPATHLEN);
+ strncpy(userFilePath, buffer, MIN(length, MAXPATHLEN));
+ }
+ }
+ } //- theFile.good()
+ }
+ else {
+ switch(errno) {
+ case EACCES:
+ cerr << "ERROR: permission denied for configuration file '"
+ << configFilename << "' using compiled defaults." << endl;
+ cerr << endl;
+ break;
+ case ENOENT:
+ cerr << "WARNING: configuration file '" << configFilename
+ << "' doesn't exist, using " << endl;
+ cerr << " compiled defaults." << endl;
+ cerr << endl;
+ break;
+ }
+ }
+
+} //- End of LoadConfigurationFile
+
+//- DumpConfiguration -----------------------------------------------------
+void Mamer::DumpConfiguration(void) {
+ cout << "Mamer Configuration" << endl;
+ cout << "-------------------" << endl;
+ cout << "Hostname : " << hostname << endl;
+ cout << "Port : " << portNumber << endl;
+ cout << "Channel : " << channelNumber << endl;
+ cout << endl;
+ cout << "Username : " << username << endl;
+ cout << "Password : " << password << endl;
+ cout << endl;
+ cout << "Home Path: " << homeFilePath << endl;
+ cout << "Data Path: " << dataFilePath << endl;
+ cout << "Help Path: " << helpFilePath << endl;
+ cout << "User File: " << userFilePath << endl;
+ cout << "Log File : " << logFilename << endl;
+ cout << endl;
+ cout << "Debug Lvl: " << debugLevel << endl;
+ cout << endl;
+
+} //- End of DumpConfiguration
+
+//- HandleQtell ------------------------------------------------------------
+int Mamer::HandleQtell(char *message) {
+ char name[NAMELEN];
+ int isOnline; // Opposite of what is returned in qtell report
+
+ sscanf(message, "*qtell %s %d*", name, &isOnline);
+ isOnline = !isOnline;
+
+ User *u = NULL;
+ u = FindUser(name);
+
+ if(isOnline) {
+ if(NULL == u) {
+ CheckUser(name);
+ }
+ }
+
+ return 1;
+}
+
+//- HandleTell ------------------------------------------------------------
+int Mamer::HandleTell(char *message) {
+ char *p = NULL, *q = NULL, *command = NULL, *tmpCom=NULL;
+ char user[32] = {'\0'};
+ int i=0, pos = 0, tmp=0, len = 0, ret = 0, tellSize=12; /* size of " tells you:" */
+
+ //- Parse apart tell message
+ //- <user> tells you: <mesg>
+ //- <user>(*) tells you: <mesg>
+ //- <user>(TM)(GM)(*)..... tells you: <mesg>
+ if((p = strstr(message, "(")) && (q = strstr(message, " tells you:")) && (strlen(p) > strlen(q))) {
+ tmp = strlen(p) - strlen(q); /* get the diff to add back in later */
+ pos = strlen(message) - strlen(p);
+ memset(user, '\0', 32);
+ strncpy(user, message, MIN(pos, 31));
+ pos += (tellSize + tmp);
+ } else {
+ p = strstr(message, " tells you:");
+ pos = strlen(message) - strlen(p);
+ memset(user, '\0', 32);
+ strncpy(user, message, MIN(pos, 31));
+ pos += tellSize;
+ }
+
+ CheckUser(user);
+
+ len = strlen(&(message[pos]));
+ command = new char[len + 1]; memset(command, '\0', (len + 1));
+ tmpCom = new char[len + 1]; memset(tmpCom, '\0', (len + 1));
+ if(NULL == command) {
+ cerr << "ERROR: problems allocating memory" << endl;
+ cerr << endl;
+ return(ret);
+ }
+ strncpy(command, &(message[pos]), len);
+ command[len] = '\0';
+ while((command[i] != '\0') && (command[i] != ' ')) tmpCom[i] = command[i++];
+ tmpCom[i] = '\0';
+
+ Command *comm = NULL;
+ comm = FindCommand(tmpCom, user);
+ if(comm == NULL) {
+ if(NULL != command)
+ delete [] command;
+ if(NULL != tmpCom)
+ delete [] tmpCom;
+ return 0;
+ }
+
+ if(10 <= debugLevel) {
+ cout << "Tell Msg: " << message << endl;
+ cout << "User is: " << user << " Command is: " << command<< "\n" << endl;
+ }
+
+ if(ParseParams(comm, command) == COM_BADPARAMETERS) {
+ TellUser(comm, user);
+ if(NULL != command)
+ delete [] command;
+ if(NULL != tmpCom)
+ delete [] tmpCom;
+ return 0;
+ }
+
+ if(NULL != comm) {
+ User *u = NULL;
+ u = FindUser(user);
+ if(NULL == u) {
+ CheckUser(user); // This should never happen because we did it above.
+ u = FindUser(user);
+ if(NULL == u)
+ abort();
+ }
+ if((u->GetManagerLevel()) >= (comm->GetManagerLevel())) {
+ ret = (this->*(comm->userFunction))(u, comm->params);
+ if(debugLevel >= 5)
+ cout << comm->GetCommandName() << " return value " << ret << endl;
+ if(((ret == 2) && (!(strcasecmp(comm->GetCommandName(), "setres")))) ||
+ ((ret == 1) && (!(strcasecmp(comm->GetCommandName(), "withdraw")))) ||
+ ((ret == 1) && (!(strcasecmp(comm->GetCommandName(), "forfeit"))))) {
+ NextRound();
+ } else if ((ret != 0) && (!(strcasecmp(comm->GetCommandName(), "setmanagerlevel")))) {
+ AdjustManagerList(ret, comm->params[0].val.word);
+ }
+ } else {
+ TellUser(NoPermissions, user);
+ }
+ }
+
+ if(NULL != command)
+ delete [] command;
+ if(NULL != tmpCom)
+ delete [] tmpCom;
+
+ return(ret);
+} //- End of HandleTell
+
+//- HandleChannel ------------------------------------------------------------
+int Mamer::HandleChannel(char *message) {
+ char *q, *p = NULL, channel[8], mess[1024];
+ char user[NAMELEN] = {'\0'};
+ int pos = 0, index=0;
+ char *hilist[] = {"hi ", "hello ", "howdy ", "aloha ", "hola ", "bonjour ", "tag ", NULL };
+ char *thanklist[] = {"thanks ", "thank you ", "thanx ", "gracias ", NULL };
+ char *byelist[] = {"bye ", "later ", "caio ", "adios ", "hasta la vista ", NULL };
+ char *swearlist[] = {"fuck", "shit", "god damn", "asshole", "cunt", "cock", "bullshit", "nigger", "asswipe", NULL };
+
+ //- Parse apart channel message
+ //- <user>(1): <mesg>
+ //- <user>(*)(24): <mesg>
+ //- <user>(TM)(49): <mesg>
+ if((p = strchr(message, '('))) {
+ pos = strlen(message) - strlen(p);
+ memset(user, '\0', NAMELEN);
+ strncpy(user, message, MIN(pos, NAMELEN-1));
+ } else
+ return 0;
+
+ if(0 == strcasecmp(user, username)) return 1;
+ CheckUser(user);
+ p = strchr(message, ':');
+ while(*p != '(') p--;
+ q = channel; p++;
+ while(*p != ')') { *q++ = *p++; }
+ *q = '\0';
+
+ p = strchr(message, ':'); p++;
+ q = mess;
+ while(*p != '\0') { *q++ = *p++; }
+ *q = '\0';
+
+ if(debugLevel >= 5)
+ printf("%s %s %s\n", user, channel, mess);
+
+ mess[strlen(mess)] = '\0';
+ stolower(mess);
+
+ pos = 0;
+ index=0;
+ while (swearlist[index] != NULL) {
+ if (strstr(mess, swearlist[index])) {
+ printf("ABUSE - %s %s\n", user, mess);
+ XServerCom("%s %s\n", "+ c49muzzle", user);
+ pos = 1;
+ }
+ index++;
+ }
+ if ((strstr(mess, username)) && (pos == 0)) {
+ pos = 0;
+ index = 0;
+ while (hilist[index] != NULL) {
+ if (strstr(mess, hilist[index])) {
+ XServerCom("%s %s Hi %s :-)\n", "tell", channel, user);
+ pos = 1;
+ }
+ index++;
+ }
+ index = 0;
+ if(pos == 0)
+ while (thanklist[index] != NULL) {
+ if (strstr(mess, thanklist[index])) {
+ XServerCom("%s %s You're welcome %s!\n", "tell", channel, user);
+ pos = 1;
+ }
+ index++;
+ }
+ index = 0;
+ if(pos == 0)
+ while (byelist[index] != NULL) {
+ if (strstr(mess, byelist[index])) {
+ XServerCom("%s %s Sad to see you going, %s :(\n", "tell", channel, user);
+ pos = 1;
+ }
+ index++;
+ }
+ }
+ if (strstr(mess, "tourn"))
+ XServerCom("%s %s %s %s %s\n",
+ "tell", channel, "To see a list of tourneys type: tell", username, "lt");
+
+ return(1);
+} //- End of HandleChannel
+
+//- HandleConnect ------------------------------------------------------------
+int Mamer::HandleConnect(char *message) {
+ char *p = NULL, *reg = NULL, user[80] = {'\0'}, output[256] = {'\0'}, tmp[32] = {'\0'};
+ Tourney *t = NULL;
+ TourneyPlayers *tp = NULL;
+ LinkListIter<Tourney> tourneyIter(tourneyList);
+ int announceConnect = 0;
+
+ //- Parse apart connect message
+ //- [<user> (R: 123.123.123.123) has connected.]
+ if(5 <= debugLevel)
+ cout << "\nConnect Msg: " << message << endl;
+
+ if((p = strstr(message, " (U:"))) { return(1); }
+ if(!(p = strstr(message, " (R: "))) { return(1); }
+ strncpy(user, &(message[1]), MIN(strlen(message) - strlen(p) - 1, 79));
+ reg = strstr(message, " (R: ");
+ if(reg) { //If this is a registered user
+ CheckUser(user);
+ while((t = tourneyIter.Next())) {
+ if((tp = t->GetPlayer(user))) {
+ tp->location = ONLINE;
+ announceConnect = 1;
+ }
+ }
+ if(announceConnect) { // If the player arriving is in a tourney tell us he is arriving.
+ announceConnect = 0;
+ sprintf(output, "%s %d %s %s", "tell", channelNumber, user, "has connected. Entered in tourney(s):");
+ tourneyIter.Reset();
+ while((t = tourneyIter.Next())) {
+ if(t->GetStatus() != DONE) {
+ if((tp = t->GetPlayer(user))) {
+ sprintf(tmp, " %d", t->number);
+ strcat(output, tmp);
+ announceConnect = 1;
+ }
+ }
+ }
+ if(announceConnect) {
+ XServerCom("%s %s %d%s", "tournset", user, 1, "\n");
+ XServerCom("%s%s", output, "\n");
+ }
+ }
+ } else {
+ if(15 <= debugLevel) {
+ cout << "\nConnect Msg: " << message << endl;
+ cout << "Ignoring User: " << user << endl;
+ }
+ }
+ return(1);
+} //- End of HandleConnect
+
+//- HandleDisconnect --------------------------------------------------------
+int Mamer::HandleDisconnect(char *message) {
+ char *p = NULL, user[80] = {'\0'}, output[256] = {'\0'}, tmp[32] = {'\0'};
+ Tourney *t = NULL;
+ TourneyPlayers *tp = NULL;
+ LinkListIter<Tourney> tourneyIter(tourneyList);
+ int announceDisconnect = 0;
+
+ //- Parse apart disconnect message
+ //- [<user> has disconnected.]
+ p = strstr(message, " has disconnected.");
+ strncpy(user, &(message[1]), MIN(strlen(message) - strlen(p) - 1, 79));
+
+ if(10 <= debugLevel) {
+ cout << "Disconnect Msg: " << message << endl;
+ cout << "User is: " << user << "\n" << endl;
+ }
+
+ LinkListIter<User> userIter(userList);
+ User *u = NULL;
+ while((u = userIter.Next()))
+ if(1 == u->IsUser(user))
+ break;
+
+ if(NULL != u) {
+ tourneyIter.Reset();
+ while((t = tourneyIter.Next())) {
+ if((tp = t->GetPlayer(user))) {
+ tp->location = GONE;
+ announceDisconnect = 1;
+ }
+ }
+ if(announceDisconnect) { // If the player arriving is in a tourney tell us he is arriving.
+ announceDisconnect = 0;
+ sprintf(output, "%s %d %s %s", "tell", channelNumber, user, "has disconnected. Entered in tourney(s):");
+ tourneyIter.Reset();
+ while((t = tourneyIter.Next())) {
+ if(t->GetStatus() != DONE) {
+ if((tp = t->GetPlayer(user))) {
+ sprintf(tmp, " %d", t->number);
+ strcat(output, tmp);
+ announceDisconnect = 1;
+ }
+ }
+ }
+ if(announceDisconnect) {
+ XServerCom("%s %s %d%s", "tournset", user, 1, "\n");
+ XServerCom("%s%s", output, "\n");
+ }
+ }
+ u->SavePlayer(userFilePath);
+ userList.Delete(u);
+ }
+
+ return(1);
+} //- End of HandleDisconnect
+
+//- AdjustManagerList ----------------------
+void Mamer::AdjustManagerList(int value, char *name) {
+ Storage *tmp=NULL, *newName=NULL;
+ LinkListIter<Storage> managerIter(storageList);
+ FILE *theFile=NULL;
+ char filename[128], manager[NAMELEN];
+ int added=0, needToAdd=1;
+
+ memset(filename, '\0', 128);
+ sprintf(filename, "%s/managers", dataFilePath);
+ theFile = fopen(filename, "r");
+ if(theFile == NULL) return;
+
+ memset(manager, '\0', NAMELEN);
+ while(fscanf(theFile, "%s", manager) > 0) { // build the temporary list
+ tmp = new Storage(manager, 0);
+ storageList.Append(tmp);
+ tmp = NULL;
+ memset(manager, '\0', NAMELEN);
+ }
+ fclose(theFile);
+
+ switch(value) {
+ case -1:
+ managerIter.Reset(); // remove a manager from the list that is printed later
+ while((tmp = managerIter.Next()))
+ if(strlen(tmp->name) == strlen(name))
+ if(0 == (strcasecmp(tmp->name, name)))
+ storageList.Delete(tmp);
+ XServerCom("%s %s\n", "- mamermgr", name);
+ break;
+ case 1:
+ newName = new Storage(name, 0);
+ added = 0; // Add a user to the manager list that is later printed
+ needToAdd = 1;
+ managerIter.Reset(); // Got through the list see if the name is there
+ while((tmp = managerIter.Next()))
+ if(strlen(tmp->name) == strlen(newName->name))
+ if(0 == strcasecmp(tmp->name, newName->name)) {
+ needToAdd = 0;
+ break;
+ }
+ if(needToAdd) { // If its not there we have to add it
+ managerIter.Reset();
+ while((tmp = managerIter.Next())) // if the name in the list is > new name
+ if((strncasecmp(tmp->name, newName->name, MIN(strlen(tmp->name), strlen(newName->name)))) > 0) {
+ added = 1;
+ storageList.Insert(tmp, newName); // insert the new name before the list name
+ break;
+ }
+ if(!added) storageList.Append(newName);
+ XServerCom("%s %s\n", "+ mamermgr", name);
+ }
+ break;
+ default:
+ break;
+ }
+ theFile = fopen(filename, "w");
+ if(!theFile) return;
+ managerIter.Reset(); // Lets write the new manager file
+ while((tmp = managerIter.Next())) {
+ fprintf(theFile, "%s\n", tmp->name);
+ storageList.Delete(tmp);
+ }
+ fclose(theFile);
+ // if(newName != NULL) delete(newName);
+}
+
+//- UserIsLoaded --------------------------
+int Mamer::UserIsLoaded(char *uname) {
+ User *u = NULL;
+ LinkListIter<User> userIter(userList);
+
+ while((u = userIter.Next())) {
+ if(0 == strcasecmp(u->name, uname))
+ return 1;
+ }
+
+ return 0;
+}//- end UserIsLoaded ------------------------------------------------------
+
+/* this function checks if the user is loaded and if not loads the user */
+//- CheckUser ---------------------------------------------------------------
+void Mamer::CheckUser(char *user) {
+ if(!UserIsLoaded(user)) {
+ if(debugLevel >= 5)
+ cout << "CheckUser - Adding User:" << user << ":" << endl;
+
+ User *newUser = NULL;
+ newUser = new User(userFilePath, user);
+ if(NULL != newUser)
+ userList.Append(newUser);
+ }
+}//- end of CheckUser -----------------------------------------------------
+
+//- HandleGame ------------------------------------------------------------
+int Mamer::HandleGame(char *message) {
+ char *p, *q, user1[NAMELEN], user2[NAMELEN], action[256], result[8], tmp[256];
+ int gameNumber, clocktime, inc, rated, isPrivate, result_code, moreGames=1, moreRounds=1, madeMoreGames=0, gameType=-2;
+ Tourney *t = NULL;
+ Game *g = NULL;
+ TourneyPlayers *tp = NULL;
+
+ // {Game 8 (Blammor vs. Havard) Blammor resigns} 0-1
+
+ sscanf(message, "{Game %d (%s vs. %s", &gameNumber, user1, user2);
+ user2[strlen(user2)-1] = '\0';
+
+ if((p = strchr(message, ')'))) {
+ q = action; p++; p++;
+ while((*p != '\0') && (*p != '}')) { *q++ = *p++; }
+ *q = '\0';
+ } else { return 0; }
+
+ memset(result, '\0', 8);
+ if((p = strchr(message, '}')) &&
+ ((strstr(message, ") Creating ") == NULL) && (strstr(message, ") Continuing ") == NULL))) {
+ // sscanf(p, "} %s [%d %d %d %d", result, &clocktime, &inc, &rated, &isPrivate);
+ sscanf(p, "} %s [%d %d %d %d %d", result, &clocktime, &inc, &rated, &isPrivate, &gameType);
+
+ if(!strcmp(result, "1-0")) { result_code = 1;
+ } else if(!strcmp(result, "0-1")) { result_code = 0;
+ } else if(!strcmp(result, "1/2-1/2")) { result_code = 2;
+ } else { result_code = -1; }
+
+ if(debugLevel >= 5)
+ // printf("\nGame #%d %s vs. %s action=%s result=%s time=%d inc=%d rated=%d private=%d\n",
+ // gameNumber, user1, user2, action, result, clocktime, inc, rated, isPrivate);
+ printf("\nGame #%d %s vs. %s action=%s result=%s time=%d inc=%d rated=%d private=%d gameType=%d\n",
+ gameNumber, user1, user2, action, result, clocktime, inc, rated, isPrivate, gameType);
+
+ LinkListIter<Tourney> tourneyIter(tourneyList);
+ tourneyIter.Reset();
+ while((t = tourneyIter.Next())) {
+ if(t->GetStatus() != CLOSED) continue;
+ LinkListIter<Game> gameIter(t->gameList);
+ gameIter.Reset();
+ while((g = gameIter.Next())) {
+ if(g->IsGame(user1, user2, clocktime, inc, rated, 'r')) { //- There is room to add isPrivate later
+ XServerCom("%s %i %s %s %s %s%i %s %s %s\n", "tell", channelNumber, g->whiteName, "vs.", g->blackName,
+ "a game in tourney #", t->number, "just ended. ", action, result);
+ if(strcmp(result, "*") == 0) {
+ g->gameNumber = -1;
+ continue;
+ }
+ moreGames = t->SetGameResult(user1, user2, result_code); //- SetGameResult deletes the game for us
+ if(moreGames == 2) {
+ moreRounds = (t->GetRoundsRemaining());
+ LinkListIter<TourneyPlayers> playerIter(t->playerList);
+ playerIter.Reset();
+ if(moreRounds) {
+ madeMoreGames = t->MakeAssignments();
+ while((tp = playerIter.Next())) {
+ sprintf(tmp, "%s tells you: listplayers %d\n", tp->name, t->number);
+ HandleTell(tmp);
+ }
+ if(madeMoreGames) {
+ t->TellThemWhoTheyPlay();
+ } else { // tourney over!
+ AnnounceTourneyEnd(t);
+ savePlayerData(t);
+ }
+ } else { // tourney over!
+ /*
+ while((tp = playerIter.Next())) {
+ sprintf(tmp, "%s tells you: listplayers %d\n", tp->name, t->number);
+ HandleTell(tmp);
+ }
+ */
+ AnnounceTourneyEnd(t);
+ savePlayerData(t);
+ }
+ }
+ break;
+ }
+ }
+ }
+ } else {
+ XServerCom("%s %s %s", "getgi", user1, "\n");
+ }
+ return(1);
+} //- End of HandleGame
+
+//- HandleGameInfo ----------------------------------------------------------
+int Mamer::HandleGameInfo(char *message) {
+ char white[NAMELEN], black[NAMELEN], player[NAMELEN];
+ int gameNumber, gameTime, inc, rated, isPrivate;
+ Tourney *t=NULL;
+ Game *g=NULL;
+
+ sscanf(message, "*getgi %s %s %s %d %d %d %d %d*", player, white, black,
+ &gameNumber, &gameTime, &inc, &rated, &isPrivate);
+
+ gameTime = gameTime / 600; // Values for getgi are in micro and nano seconds
+ inc = inc / 10;
+
+ LinkListIter<Tourney> tourneyIter(tourneyList);
+ tourneyIter.Reset();
+ while((t = tourneyIter.Next())) {
+ if(t->GetStatus() != CLOSED) continue;
+ LinkListIter<Game> gameIter(t->gameList);
+ gameIter.Reset();
+ while((g = gameIter.Next())) {
+ if(g->IsGame(white, black, gameTime, inc, rated, 'r')) { //- There is room to add isPrivate later
+ if(g->gameNumber < 0){
+ XServerCom("%s %i %s %s %s %s%i %s\n", "tell", channelNumber, white, "vs.", black,
+ "a game in tourney #", t->number, "just started.");
+ } else {
+ XServerCom("%s %i %s %s %s %s%i %s\n", "tell", channelNumber, white, "vs.", black,
+ "a game in tourney #", t->number, "just Restarted.");
+ }
+ g->gameNumber = gameNumber;
+ }
+ }
+ }
+ return(1);
+} //- End of HandleGameInfo
+
+//- HandlePlayerInfo --------------------------------------------------------
+int Mamer::HandlePlayerInfo(char *message) {
+ char player[NAMELEN];
+ int ratings[6], return_from_AddPlayer, tourneyNumber;
+ Tourney *t = NULL;
+ Player *p = NULL;
+
+ sscanf(message, "*getpi %s %d %d %d %d %d %d*", // Scan in the info
+ player, &ratings[0], &ratings[2], &ratings[3], &ratings[1], &ratings[4], &ratings[5]);
+
+ if(debugLevel >=15)
+ printf("Get Player Info: %s blitz=%d stand=%d light=%d wild=%d bug=%d suicide=%d\n",
+ player, ratings[2], ratings[3], ratings[1], ratings[0], ratings[4], ratings[5]);
+
+ p = FindPending(player);
+
+ if(p != NULL) {
+ tourneyNumber = p->value; // find out which tourney we want
+ t = FindTourney(tourneyNumber); // Get the tourney. If its in the list it should be valid
+ } else {
+ return 0;
+ } //Check for valid tourney is done in CommandEntry::JoinTourney
+
+ return_from_AddPlayer = t->AddPlayer(player, ratings[t->GetVariant()], 0.0);
+ TellUser(JoinedTourney, player, return_from_AddPlayer);
+ if(return_from_AddPlayer == 1)
+ XServerCom("%s %s %d%s", "tournset", player, 1, "\n");
+ pendingList.Delete(p); //This is safe cause to get here we had to find a Player p
+
+ return 1;
+} //- End of HandlePlayerInfo
+
+//- FindPending ---------------------------------------------------------------
+Player *Mamer::FindPending(char *user) {
+ Player *p = NULL;
+ LinkListIter<Player> pendingIter(pendingList);
+
+ while((p = pendingIter.Next()))
+ if(1 == p->IsPlayer(user))
+ break;
+
+ return(p);
+} //- End of FindPending
+
+//- FindUser ---------------------------------------------------------------
+User *Mamer::FindUser(char *user) {
+ User *u = NULL;
+ LinkListIter<User> userIter(userList);
+
+ // printf("FindUser: %18s\n", user);
+
+ while((u = userIter.Next()))
+ if(1 == u->IsUser(user))
+ break;
+
+ return(u);
+} //- End of FindUser
+
+//- FindTourney ------------------------------------------------------------
+Tourney *Mamer::FindTourney(int tourn) {
+ Tourney *t = NULL;
+ LinkListIter<Tourney> tourneyIter(tourneyList);
+
+ while((t = tourneyIter.Next())) {
+ if(1 == t->IsTourney(tourn))
+ break;
+ }
+ return(t);
+} //- End of FindUser
+
+//- FindCommand ---------------------------------------------------------------
+Command *Mamer::FindCommand(char *comm, char *user) {
+ Command *c = NULL, *cnull=NULL;
+ LinkListIter<Command> commIter(commandList);
+ int commandsFound=0;
+ char* output = NULL;
+
+ output = new char[MAX_LINE_SIZE];
+ memset(output, '\0', MAX_LINE_SIZE);
+ commIter.Reset();
+ while((c = commIter.Next())) {
+ if(c->IsCommand(comm)) {
+ commandsFound++;
+ if((int)(strlen(output) + strlen(c->GetCommandName())) < (MAX_LINE_SIZE - 1))
+ sprintf(output, "%s %s", output, c->GetCommandName());
+ }
+ }
+ output[strlen(output)] = '\0';
+
+ commIter.Reset();
+ while((c = commIter.Next()))
+ if(1 == c->IsCommand(comm))
+ break;
+
+ switch (commandsFound) {
+ case 0:
+ TellUser(BadCommand, user);
+ return(cnull);
+ case 1:
+ return(c);
+ default:
+ TellUser(MultiCommand, user, output);
+ return(cnull);
+ }
+} //- End of FindUser
+
+/*
+ Parameter string format
+ w - a word
+ o - an optional word
+ d - integer
+ p - optional integer
+ i - word or integer
+ n - optional word or integer
+ s - string to end
+ t - optional string to end
+
+ If the parameter option is given in lower case then the parameter is
+ converted to lower case before being passsed to the function. If it is
+ in upper case, then the parameter is passed as typed.
+
+ Calling these Appends adds commands to the link list. They are called with:
+ 1) the text command Mamer should look for
+ 2) an alias or substitute for that text
+ 3) the manager level one needs to be to execute this command
+ 4) a BRIEF description of the command's function
+ 5) the parameter types for each parameter (see comments above)
+ 6) what code to use when telling the user they did something wrong (see TellUser)
+ 7) and the function pointer to the CommandEntry.cc code that is this command */
+
+//- BuildCommandList ---------------------------------------------------------
+void Mamer::BuildCommandList(void) {
+ commandList.Append(new Command("addchaos", "ac", MANAGER, "Adds (or subs) chaos points.",
+ "wp", (USERFP)&Mamer::AddAbuse));
+
+ commandList.Append(new Command("announce", "ann", DIRECTOR, "Announce the tournament to the working channel.",
+ "d", (USERFP)&Mamer::AnnounceTourney));
+
+ commandList.Append(new Command("addtotourney", "att", VICE, "Add a user to a tourney.",
+ "Wd", (USERFP)&Mamer::AddToTourney));
+
+ commandList.Append(new Command("create", "cr", DIRECTOR, "Creates a new tournament.",
+ "", (USERFP)&Mamer::CreateTourney));
+
+ commandList.Append(new Command("close", "cl", DIRECTOR, "Closes and starts a tournament.",
+ "d", (USERFP)&Mamer::CloseTourney));
+
+ commandList.Append(new Command("delete", "del", DIRECTOR, "Deletes a tournament.",
+ "d", (USERFP)&Mamer::DeleteTourney));
+
+ commandList.Append(new Command("finger", "fi", USER, "Displays the stats for a user.",
+ "O", (USERFP)&Mamer::FingerUser));
+
+ commandList.Append(new Command("forfeit", "fo", DIRECTOR, "Remove a user from a tourney.",
+ "wd", (USERFP)&Mamer::RemoveFromTourney));
+
+ commandList.Append(new Command("join", "j", USER, "Request to enter a tourney.",
+ "d", (USERFP)&Mamer::JoinTourney));
+
+ commandList.Append(new Command("keep", "k", MANAGER, "Keep a tourney in memory.",
+ "di", (USERFP)&Mamer::KeepTourney));
+
+ commandList.Append(new Command("listmanagers", "lm", USER, "Displays the Managers list.",
+ "", (USERFP)&Mamer::ListManagers));
+
+ commandList.Append(new Command("listtourneys", "lt", USER, "Displays the tournament list.",
+ "", (USERFP)&Mamer::ListTourneys));
+
+ commandList.Append(new Command("listtourneyvars", "vars", USER, "Displays the tournament variables.",
+ "d", (USERFP)&Mamer::ListTourneyVars));
+
+ commandList.Append(new Command("listtourneygames", "games", USER, "Displays the tournament games.",
+ "d", (USERFP)&Mamer::ListTourneyGames));
+
+ commandList.Append(new Command("listplayers", "lp", USER, "Displays the players in the tourney.",
+ "d", (USERFP)&Mamer::ListTourneyPlayers));
+
+ commandList.Append(new Command("listrank", "rank", USER, "Displays player rank.",
+ "n", (USERFP)&Mamer::ListRank));
+
+ commandList.Append(new Command("loadedusers", "lu", MANAGER, "Displays the loaded users.",
+ "", (USERFP)&Mamer::LoadedUsers));
+
+ commandList.Append(new Command("messman", "mm", VICE, "Message all of the Managers.",
+ "s", (USERFP)&Mamer::MessageManagers));
+
+ commandList.Append(new Command("open", "ot", DIRECTOR, "Opens the tournament to players.",
+ "d", (USERFP)&Mamer::OpenTourney));
+
+ commandList.Append(new Command("setcommandlevel", "setcl", VICE, "Set the level required to execute a command.",
+ "wd", (USERFP)&Mamer::SetCommandLevel));
+
+ commandList.Append(new Command("setinfo", "si", VICE, "Set a user's finger info.",
+ "Wddddddd", (USERFP)&Mamer::SetInfo));
+
+ commandList.Append(new Command("setmanagerlevel", "sml", VICE, "Sets manager's level.",
+ "Wd", (USERFP)&Mamer::SetManagerLevel));
+
+ commandList.Append(new Command("setres", "sr", DIRECTOR, "Sets the result of a game.",
+ "dWWi", (USERFP)&Mamer::SetResult));
+
+ commandList.Append(new Command("setstat", "ss", VICE, "Sets a specific finger stat.",
+ "Wwd", (USERFP)&Mamer::SetStat));
+
+ commandList.Append(new Command("settourneyvar", "stv", DIRECTOR, "Sets a Tourney's Variables.",
+ "dwi", (USERFP)&Mamer::SetTourneyVariable));
+
+ commandList.Append(new Command("showcommands", "sc", USER, "List commands and descripts.",
+ "o", (USERFP)&Mamer::ShowCommands));
+
+ commandList.Append(new Command("showhelpfile", "shf", USER, "Shows a help file.",
+ "o", (USERFP)&Mamer::ShowHelp));
+
+ commandList.Append(new Command("help", "help", USER, "Shows a help file.",
+ "o", (USERFP)&Mamer::ShowHelp));
+
+ commandList.Append(new Command("shutdown", "sd", VICE, "Shuts down Mamer.",
+ "", (USERFP)&Mamer::Shutdown));
+
+ commandList.Append(new Command("who", "who", USER, "Displays the tournament games.",
+ "d", (USERFP)&Mamer::ListTourneyPlayers));
+
+ commandList.Append(new Command("withdraw", "with", USER, "Remove yourself from a tourney.",
+ "d", (USERFP)&Mamer::RemoveFromTourney));
+
+} //- End of BuildCommandList
+
+//- NextRound -------------------------
+void Mamer::NextRound() {
+ int moreGames=0, moreRounds=1, madeMoreGames=0;
+ Tourney *t = NULL;
+ Game *g = NULL;
+
+ LinkListIter<Tourney> tourneyIter(tourneyList);
+ tourneyIter.Reset();
+ while((t = tourneyIter.Next())) {
+ if(t->GetStatus() != CLOSED) continue;
+ moreRounds = (t->GetRoundsRemaining());
+ moreGames = 0;
+ LinkListIter<Game> gameIter(t->gameList);
+ gameIter.Reset();
+ while((g = gameIter.Next())) moreGames++;
+
+ if(moreGames == 0) {
+ if(debugLevel >= 10)
+ cout << "No more games! Next Round Please! From Next Round" << endl;
+ cerr << "No more games! Next Round Please! From Next Round" << endl;
+ if(moreRounds) {
+ madeMoreGames = t->MakeAssignments();
+ if(madeMoreGames)
+ t->TellThemWhoTheyPlay();
+ else { // tourney over!
+ cerr << "Coulnd't make any more games. End of Tourney. From Next Round" << endl;
+ AnnounceTourneyEnd(t);
+ savePlayerData(t);
+ }
+ } else { // tourney over!
+ cerr << "No more rounds. End of Tourney. From Next Round" << endl;
+ AnnounceTourneyEnd(t);
+ savePlayerData(t);
+ }
+ }
+ }
+} //- End of NextRound
+
+//- XServerCom ---------------------------------------------
+int Mamer::XServerCom(char *fmt, ...)
+{
+ va_list argptr;
+ char buffer[1024];
+ int count;
+
+ va_start(argptr, fmt);
+ count = vsprintf(buffer, fmt, argptr);
+ write(serverSocket, buffer, strlen(buffer));
+ va_end(argptr);
+
+ /* returns number of elements written */
+ return (count);
+}
+//- End of XServerCom
+
+//- TellUser ------------------------------------------------
+void Mamer::TellUser(reasons reason, char *name) {
+ switch (reason) {
+ case NoPermissions:
+ XServerCom("qtell %s %s notes: Sorry you do not have permission to do that.\n", name, username);
+ break;
+ case BadCommand:
+ XServerCom("qtell %s %s notes: Command not found.\n", name, username);
+ break;
+ default:
+ break;
+ }
+}//- End of TellUser
+
+//- TellUser ------------------------------------------------
+void Mamer::TellUser(reasons reason, char *name, int number) {
+ switch (reason) {
+ case JoinedTourney:
+ switch (number) {
+ case 0:
+ XServerCom("qtell %s %s notes: %s\n", name, username,
+ "Can not join\\nYour rating does not fit into current limits. <check tourney vars>");
+ break;
+ case 1:
+ XServerCom("qtell %s %s notes: %s\n", name, username, "You joined the tournament.");
+ break;
+ case 2:
+ XServerCom("qtell %s %s notes: %s\n", name, username, "You are already in this tourney.");
+ break;
+ case 3:
+ XServerCom("qtell %s %s notes: %s\n", name, username, "You can not join. Tourney is not open.");
+ break;
+ default:
+ break;
+ }
+ break;
+ case NotEnoughPlayers:
+ XServerCom("qtell %s %s notes: Tourney#%d %s\n", name, username, number, "does not have enough players.");
+ break;
+ case NoPlayers:
+ XServerCom("qtell %s %s notes: Tourney#%d %s\n", name, username, number, "has no players.");
+ break;
+ case WillKeepTourney:
+ XServerCom("qtell %s %s notes: Tourney#%d %s\n", name, username, number, "will be kept.");
+ break;
+ case NotKeepTourney:
+ XServerCom("qtell %s %s notes: Tourney#%d %s\n", name, username, number, "will not be kept.");
+ break;
+ case TourneyNotFound:
+ XServerCom("qtell %s %s notes: %s%d %s\n", name, username, "Tourney #", number, "not found.");
+ break;
+ case NotFound:
+ XServerCom("qtell %s %s notes: %s%d\n", name, username, "Player not found in tourney #", number);
+ break;
+ case GameResultNotFound:
+ XServerCom("qtell %s %s notes: %s%d\n", name, username, "Can not set result to ", number);
+ break;
+ case NoPermissions:
+ XServerCom("qtell %s %s notes: You don't have change permissions for tourney #%d.\n", name, username, number);
+ break;
+ case TourneyNotNew:
+ XServerCom("qtell %s %s notes: %s %s%d %s\n", name, username, "Can not do that right now.",
+ "Tourney #", number, "is not new.");
+ break;
+ case TourneyNotOpen:
+ XServerCom("qtell %s %s notes: %s %s%d %s\n", name, username, "Can not do that right now.",
+ "Tourney #", number, "is not open.");
+ break;
+ case TourneyNotClosed:
+ XServerCom("qtell %s %s notes: %s %s%d %s\n", name, username, "Can not do that right now.",
+ "Tourney #", number, "is not closed.");
+ break;
+ case TourneyDone:
+ XServerCom("qtell %s %s notes: %s %s%d %s\n", name, username, "Can not do that anymore.",
+ "Tourney #", number, "is done.");
+ break;
+ case TourneyClosed:
+ XServerCom("qtell %s %s notes: %s %s%d %s\n", name, username, "Can not do that anymore.",
+ "Tourney #", number, "is closed.");
+ break;
+ case TourneyDeleted:
+ XServerCom("qtell %s %s Notes: %s %s%d %s\n", name, username, "\\n", "Tourney #",
+ number, " has been deleted.");
+ break;
+ default:
+ break;
+ }
+}//- End of TellUser
+
+//- TellUser ------------------------------------------------
+void Mamer::TellUser(Command *comm, char *name) {
+ char line[512];
+ int i, length=strlen(comm->parameterList);
+
+ sprintf(line, "qtell %s %s notes: Usage: %s ", name, username, comm->GetCommandName());
+
+ for(i=0; i<length; i++) {
+ switch (comm->parameterList[i]) {
+ case 'w':
+ strcat(line, "<word> ");
+ break;
+ case 'o':
+ strcat(line, "<optional word> ");
+ break;
+ case 'd':
+ strcat(line, "<integer> ");
+ break;
+ case 'p':
+ strcat(line, "<optional int> ");
+ break;
+ case 'i':
+ strcat(line, "<word or int> ");
+ break;
+ case 'n':
+ strcat(line, "<optional word or int> ");
+ break;
+ case 's':
+ strcat(line, "<string> ");
+ break;
+ case 't':
+ strcat(line, "<optional string> ");
+ break;
+ default:
+ break;
+ }
+ }
+ strcat(line, "\n");
+ write(serverSocket, line, strlen(line));
+}//- End of TellUser
+
+//- TellUser ------------------------------------------------
+void Mamer::TellUser(reasons reason, char *name, char *request) {
+ switch (reason) {
+ case NotFound:
+ XServerCom("qtell %s %s notes: Sorry %s is not found.\n", name, username, request);
+ break;
+ case GenericTell:
+ XServerCom("qtell %s %s notes: %s\n", name, username, request);
+ break;
+ case ChangedInfo:
+ XServerCom("qtell %s %s notes: Changed the info for %s.\n", name, username, request);
+ break;
+ case GameResultNotFound:
+ XServerCom("qtell %s %s notes: %s %s\n", name, username, "Can not set result to", request);
+ break;
+ case MultiCommand:
+ XServerCom("qtell %s %s notes: Ambiguous Command Matches:\\n %s\n", name, username, request);
+ break;
+ default:
+ break;
+ }
+}//- End of TellUser
+
+//- TellUser ------------------------------------------------
+void Mamer::TellUser(reasons reason, char *name, char *who, char *which, int new_value) {
+ switch (reason) {
+ case ChangedInfo:
+ XServerCom("qtell %s %s notes: Changed the %s stat for %s to %d.\n", name, username, which, who, new_value);
+ break;
+ case GameResultSet:
+ switch (new_value) {
+ case 1:
+ XServerCom("qtell %s %s notes: The game %s(w) vs. %s(b) has been set to 1-0\n", name, username, who, which);
+ break;
+ case 0:
+ XServerCom("qtell %s %s notes: The game %s(w) vs. %s(b) has been set to 0-1\n", name, username, who, which);
+ break;
+ default:
+ XServerCom("qtell %s %s notes: The game %s(w) vs. %s(b) has been set to 1/2-1/2\n", name, username, who, which);
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+}//- End of TellUser
+
+//- TellUser ------------------------------------------------
+void Mamer::TellUser(reasons reason, char *name, char *which, char *new_value) {
+ switch (reason) {
+ case CanNotChange:
+ XServerCom("qtell %s %s notes: Can not change the %s var to %s.\n", name, username, which, new_value);
+ break;
+ case ChangedInfo:
+ XServerCom("qtell %s %s notes: Changed %s to %s.\n", name, username, which, new_value);
+ break;
+ default:
+ break;
+ }
+}//- End of TellUser
+
+
+//- TellUser ------------------------------------------------
+void Mamer::TellUser(reasons reason, char *name, char *uname, int new_value) {
+ switch (reason) {
+ case ChangedManagerLevel:
+ XServerCom("qtell %s %s notes: %s's Manager Level has been changed to %d\n", name, username, uname,new_value);
+ break;
+ case ChangedCommandLevel:
+ XServerCom("qtell %s %s notes: The %s command's manager Level has been changed to %d\n",name,username,uname, new_value);
+ break;
+ case PlayerRemoved:
+ XServerCom("qtell %s %s notes: %s Has been removed from tourney #%i\n", name, username, uname, new_value);
+ break;
+ case NotFound:
+ XServerCom("qtell %s %s notes: %s Is not found in tourney #%i\n", name, username, uname, new_value);
+ break;
+ case ChangedAbuse:
+ XServerCom("qtell %s %s notes: %s's Chaos Points have been changed to %d\n",name, username, uname, new_value);
+ break;
+ case CanNotChange:
+ XServerCom("qtell %s %s notes: Can Not Change the %s stat to %d.\n", name, username, uname, new_value);
+ break;
+ case ChangedInfo:
+ XServerCom("qtell %s %s notes: Changed %s to %d.\n", name, username, uname, new_value);
+ break;
+ default:
+ break;
+ }
+}//- End of TellUser
+
+//- ParseParams ----------------------------------------------
+int Mamer::ParseParams(Command *comm, char *parameters) {
+ int i, parlen;
+ int paramLower;
+ char c;
+
+ for (i = 0; i < MAXNUMPARAMS; i++)
+ comm->params[i].type = TYPE_NULL; /* Set all parameters to NULL */
+ parlen = strlen(comm->parameterList);
+ parameters = eatWhite(parameters); /* remove and spaces before the command */
+ parameters = eatWord(parameters); /* remove the command itself */
+ for (i = 0; i < parlen; i++) {
+ c = comm->parameterList[i];
+ if (isupper(c)) {
+ paramLower = 0;
+ c = tolower(c);
+ } else {
+ paramLower = 1;
+ }
+ switch (c) {
+ case 'w':
+ case 'o': /* word or optional word */
+ parameters = eatWhite(parameters);
+ if (!*parameters)
+ return (c == 'o' ? COM_OK : COM_BADPARAMETERS);
+ comm->params[i].val.word = parameters;
+ comm->params[i].type = TYPE_WORD;
+ parameters = eatWord(parameters);
+ if (*parameters != '\0') {
+ *parameters = '\0';
+ parameters++;
+ }
+ if (paramLower)
+ stolower(comm->params[i].val.word);
+ break;
+
+ case 'd':
+ case 'p': /* optional or required integer */
+ parameters = eatWhite(parameters);
+ if (!*parameters)
+ return (c == 'p' ? COM_OK : COM_BADPARAMETERS);
+ if (sscanf(parameters, "%d", &comm->params[i].val.integer) != 1)
+ return COM_BADPARAMETERS;
+ comm->params[i].type = TYPE_INT;
+ parameters = eatWord(parameters);
+ if (*parameters != '\0') {
+ *parameters = '\0';
+ parameters++;
+ }
+ break;
+
+ case 'i':
+ case 'n': /* optional or required word or integer */
+ parameters = eatWhite(parameters);
+ if (!*parameters)
+ return (c == 'n' ? COM_OK : COM_BADPARAMETERS);
+ if (sscanf(parameters, "%d", &comm->params[i].val.integer) != 1) {
+ comm->params[i].val.word = parameters;
+ comm->params[i].type = TYPE_WORD;
+ } else {
+ comm->params[i].type = TYPE_INT;
+ }
+ parameters = eatWord(parameters);
+ if (*parameters != '\0') {
+ *parameters = '\0';
+ parameters++;
+ }
+ if (comm->params[i].type == TYPE_WORD)
+ if (paramLower)
+ stolower(comm->params[i].val.word);
+ break;
+
+ case 's':
+ case 't': /* optional or required string to end */
+ if (!*parameters)
+ return (c == 't' ? COM_OK : COM_BADPARAMETERS);
+ comm->params[i].val.string = parameters;
+ comm->params[i].type = TYPE_STRING;
+ while (*parameters)
+ parameters = nextWord(parameters);
+ if (paramLower)
+ stolower(comm->params[i].val.string);
+ break;
+ }
+ }
+ if (*parameters)
+ return COM_BADPARAMETERS;
+ else
+ return COM_OK;
+} //- End ParseParams ------------------
+
+//- isWhiteSpace -------------------------------------------
+int Mamer::isWhiteSpace (int c) {
+ if ((c < ' ') || (c == '\b') || (c == '\n') ||
+ (c == '\t') || (c == ' ')) { /* white */
+ return 1;
+ } else {
+ return 0;
+ }
+} //- End isWhiteSpace -------
+
+//- getWord ------------------------------------------------
+char *Mamer::getWord (char *str) {
+ int i;
+ static char word[MAX_WORD_SIZE];
+
+ i = 0;
+ while (*str && !isWhiteSpace(*str)) {
+ word[i] = *str;
+ str++;
+ i++;
+ if (i == MAX_WORD_SIZE) {
+ i = i - 1;
+ break;
+ }
+ }
+ word[i] = '\0';
+ return word;
+} //- End getWord -------------
+
+//- eatWord -------------------------------------------
+char *Mamer::eatWord (char *str) {
+ while (*str && !isWhiteSpace(*str))
+ str++;
+ return str;
+} //- eatWord ----
+
+//- eatWhite ------------------------------------------
+char *Mamer::eatWhite (char *str) {
+ while (*str && isWhiteSpace(*str))
+ str++;
+ return str;
+} //- eatWhite --------
+
+//- eatTailWhite -------------------------------------------
+char *Mamer::eatTailWhite (char *str) {
+ int len;
+ if (str == NULL)
+ return NULL;
+
+ len = strlen(str);
+ while (len > 0 && isWhiteSpace(str[len - 1]))
+ len--;
+ str[len] = '\0';
+ return (str);
+} //- End of eatTailWhite -----------
+
+//- nextWord -----------------------------------------------
+char *Mamer::nextWord(char *str) {
+ return eatWhite(eatWord(str));
+} //- End of nextWord
+
+char *Mamer::stolower(char *str) {
+ int i;
+
+ if (!str)
+ return NULL;
+ for (i = 0; str[i]; i++) {
+ if (isupper(str[i])) {
+ str[i] = tolower(str[i]);
+ }
+ }
+ return str;
+}
+
+//- GenerateTourneyNumber ----------------------------------------------
+int Mamer::GenerateTourneyNumber(void) {
+ Tourney *t = NULL;
+ int maxT = 0, used=0, i, count=0;
+ LinkListIter<Tourney> tourneyIter(tourneyList);
+
+ if(NULL != tourneyList.Head()) {
+ while((t = tourneyIter.Next()))
+ count++;
+
+ for(i=1; i<=count; i++) {
+ used = 0;
+ tourneyIter.Reset();
+ while((t = tourneyIter.Next())) {
+ if(i == t->number)
+ used = 1;
+ if(t->number > maxT)
+ maxT = t->number;
+ }
+ if(!used)
+ return i;
+ }
+ return(maxT + 1);
+ }
+
+ return(1);
+}
+
+
+// $Log: Mamer.cc,v $
+// Revision 1.19 2002/07/02 00:05:19 tridge
+// got rid of a bunch of RCS tags now that its in CVS
+//
+// Revision 1.18 2002/07/02 00:02:40 tridge
+// - fixed compile on g++ 2.96
+// - updated for lasker 'rmatch'
+//
+// Revision 1.17 1998/09/10 19:57:17 mlong
+// lots of little bug fixes and a few new features
+//
+// Revision 1.16 1998/08/04 21:02:13 mlong
+// changes to correct a few bugs including the this->* change that
+// correctly uses the function pointers now
+//
+// Revision 1.15 1998/06/18 18:41:30 mlong
+// prepairing for yet another move.
+//
+// Revision 1.14 1998/06/04 19:55:00 mlong
+// quick change to the load config file stuff to
+// allow for a commented out line
+//
+// Revision 1.13 1998/04/29 15:23:19 mlong
+// prepairing for the move to daimi
+// new sorting routine.
+//
+// Revision 1.12 1998/04/18 18:46:04 mlong
+// fixed delete bug &
+// added delete tourney function
+//
+// Revision 1.11 1998/04/17 00:14:37 mlong
+// fixes to the setres working with the Link delete method
+//
+// Revision 1.7 1997/10/22 19:47:38 mlong
+// fixed bug for parsing tells into user and command.
+//
+// Revision 1.6 1997/10/08 21:03:35 chess
+// preparing for move to oracle machine at eworks.
+//
+// Revision 1.5 1997/05/15 18:27:53 chess
+// added Player and TourneyPlayers support
+// added HandleGetPlayerInfo & HandleetGameInfo
+//
+// Revision 1.4 1997/04/13 03:14:35 chess
+// commands to do user stats manipulation added
+// also TellUser function added to make for easier reporting and bug checking
+// also added ParseParams that takes the commands parameter list definition
+// and parses out the input from the user to determine if the paramters
+// supplied are correct. If so it then sends those params to the
+// command.
+//
+// Revision 1.3 1997/03/21 15:31:04 moses
+// added the cleanup of commands
+// added the cleanup of tourneys
+// added the mamer shutdown command
+//
+// Revision 1.2 1996/10/01 20:14:43 moses
+// Changes to incorparte the new usage of the command list
+//
+// Revision 1.1 1996/09/30 20:52:48 moses
+// Initial revision
+//
--- /dev/null
+//--------------------------------------------------------------------------
+// Mamer.hh - Class header for the Mamer class
+//
+// Matthew E. Moses & Michael A. Long
+//
+// $Revision: 1.13 $
+// $Date: 2002/07/02 00:05:19 $
+//
+// $Log: Mamer.hh,v $
+// Revision 1.13 2002/07/02 00:05:19 tridge
+// got rid of a bunch of RCS tags now that its in CVS
+//
+// Revision 1.12 2002/07/02 00:02:40 tridge
+// - fixed compile on g++ 2.96
+// - updated for lasker 'rmatch'
+//
+// Revision 1.11 1998/09/10 19:58:41 mlong
+// lots of little bug fixes and a few new features.
+//
+// Revision 1.10 1998/06/18 18:41:52 mlong
+// prepairing for yet another move.
+//
+// Revision 1.9 1998/04/29 15:24:07 mlong
+// prepairing for the move to daimi
+// new sorting routine.
+//
+// Revision 1.8 1998/04/18 18:46:31 mlong
+// fixed delete bug and
+// added delete tourney function
+//
+// Revision 1.5 1997/05/15 18:29:12 chess
+// added pending and TourneyPlayers support
+// added HandleGetPlayerInfo & HandleGetGameInfo
+//
+// Revision 1.4 1997/04/13 03:21:32 chess
+// TellUser and ParseParams added
+//
+// Revision 1.3 1997/03/21 15:31:49 moses
+// added some defines to support the solaris sun compile
+//
+// Revision 1.2 1996/10/01 20:14:43 moses
+// Changes to support the new command list,
+// to correctly have the commands, I had to derive this class from the
+// CommandEntry class
+//
+// Revision 1.1 1996/09/30 20:52:48 moses
+// Initial revision
+//
+//--------------------------------------------------------------------------
+
+#ifndef _MAMER_
+#define _MAMER_
+
+#include <fstream.h>
+#include <iostream.h>
+
+extern "C" {
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <math.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <sys/signal.h>
+#include <sys/stat.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+
+#include <time.h>
+#include <unistd.h>
+#include <stdarg.h>
+}
+
+#ifdef SUN
+#define INADDR_NONE -1
+#endif
+
+#include "config.h"
+#include "link.hh"
+#include "linklist.hh"
+#include "User.hh"
+#include "Tourney.hh"
+#include "Command.hh"
+#include "CommandEntry.hh"
+#include "Player.hh"
+#include "Game.hh"
+#include "Storage.hh"
+#include "types.h"
+
+extern char *optarg;
+extern int optind;
+
+#define TRUE 1
+#define FALSE 0
+
+//#define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
+//#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
+
+class Mamer : public CommandEntry {
+ public:
+
+ Mamer();
+ ~Mamer();
+
+ int Initialize(int argc, char **argv);
+ char *s_and_r(char *, char *, char *);
+ int OpenServerConnection(void);
+ void ListenLoop(void);
+ void Shutdown(void);
+ int GivePlace(int, Tourney *);
+ void AnnounceTourneyEnd(Tourney *);
+ void savePlayerData(Tourney *);
+
+ void DumpConfiguration(void);
+
+ int XServerCom(char *, ...);
+ void TellUser(reasons, char *);
+ void TellUser(Command *, char *);
+ void TellUser(reasons, char *, char *);
+ void TellUser(reasons, char *, int);
+ void TellUser(reasons, char *, char *, int);
+ void TellUser(reasons, char *, char *, char *);
+ void TellUser(reasons, char *, char *, char *, int);
+
+#define MAX_WORD_SIZE 1024
+#define MAX_LINE_SIZE 1024
+
+ int UserIsLoaded(char *);
+ int ParseParams(Command *, char *);
+ int isWhiteSpace(int);
+ char *getWord(char *);
+ char *eatWord(char *);
+ char *eatWhite(char *);
+ char *eatTailWhite(char *);
+ char *nextWord(char *);
+ char *stolower(char *);
+
+ int GenerateTourneyNumber(void);
+
+ Tourney *FindTourney(int);
+ User *FindUser(char *);
+ Command *FindCommand(char *, char *);
+
+private:
+ void Usage(void);
+ void LoadConfigurationFile(void);
+ void BuildCommandList(void);
+ void CheckUser(char *);
+ void AdjustManagerList(int, char *);
+
+ int HandleQtell(char *);
+ int HandleTell(char *);
+ int HandleChannel(char *);
+ int HandleConnect(char *);
+ int HandleDisconnect(char *);
+ int HandleGame(char *);
+ int HandleGameInfo(char *);
+ int HandlePlayerInfo(char *);
+
+ void NextRound();
+
+ Player *FindPending(char *);
+
+public:
+ char configFilename[MAXPATHLEN];
+
+ char hostname[256];
+ int portNumber;
+ int channelNumber;
+ char username[80];
+ char password[80];
+
+ int serverSocket;
+
+ int debugLevel;
+
+ char logFilename[MAXPATHLEN];
+ char dataFilePath[MAXPATHLEN];
+ char homeFilePath[MAXPATHLEN];
+ char userFilePath[MAXPATHLEN];
+ char helpFilePath[MAXPATHLEN];
+
+ short loggedInFlag;
+
+ long countOfTourneysSinceRestart;
+
+ TourneyParameters tourneyParams;
+
+ LinkList<Tourney> tourneyList;
+ LinkList<Player> pendingList;
+ LinkList<User> userList;
+ LinkList<Command> commandList;
+ LinkList<Storage> storageList;
+};
+
+#endif
--- /dev/null
+//--------------------------------------------------------------------------
+// Player.cc - Source file for the Player class
+//
+// Matthew E. Moses && Michael A. Long
+//
+// $Revision: 1.4 $
+// $Date: 1998/09/10 19:57:17 $
+//
+// $Author: mlong $
+// $Locker: $
+//
+// $Log: Player.cc,v $
+// Revision 1.4 1998/09/10 19:57:17 mlong
+// lots of little bug fixes and a few new features
+//
+// Revision 1.3 1998/02/12 18:44:04 mlong
+// ..\7f
+//
+// Revision 1.2 1997/10/08 21:03:35 chess
+// preparing for move to oracle machine at eworks.
+//
+// Revision 1.1 1997/05/16 03:22:36 chess
+// Initial revision
+//
+// Revision 1.1 1997/05/14 17:00:30 chess
+// Initial revision
+//
+//
+//--------------------------------------------------------------------------
+
+// static char RCSid[] = "$Id: Player.cc,v 1.4 1998/09/10 19:57:17 mlong Exp $";
+
+#include "Player.hh"
+
+//- Constructor -----------------------------------------------------------
+Player::Player(char *n, int wt) {
+ strcpy(name, n);
+ value = wt;
+}
+
+//- Constructor -----------------------------------------------------------
+Player::Player(char *n, float wt) {
+ strcpy(name, n);
+ floatValue = wt;
+}
+
+//- Constructor -----------------------------------------------------------
+Player::Player(char *n, double wt) {
+ strcpy(name, n);
+ floatValue = wt;
+}
+
+//- Constructor -----------------------------------------------------------
+Player::Player(char *n, float f, int i) {
+ strcpy(name, n);
+ floatValue = f;
+ value = i;
+}
+
+//- Constructor -----------------------------------------------------------
+Player::Player(char *n, float f, int i, int r) {
+ strcpy(name, n);
+ floatValue = f;
+ value = i;
+ rating = r;
+}
+
+//- DeConstructor ---------------------------------------------------------
+Player::~Player() {
+}
+
+//- IsPlayer -----------------------------------------------------------------
+int Player::IsPlayer(char *user) {
+ if(0 == strcasecmp(user, name))
+ return(1);
+ else
+ return(0);
+} //- End of IsPlayer
--- /dev/null
+//--------------------------------------------------------------------------
+// Player.hh - Class header for the Player class
+//
+// Matthew E. Moses & Michael A. Long
+//
+// $Revision: 1.4 $
+// $Date: 2002/07/02 00:02:40 $
+//
+// $Author: tridge $
+// $Locker: $
+//
+// $Log: Player.hh,v $
+// Revision 1.4 2002/07/02 00:02:40 tridge
+// - fixed compile on g++ 2.96
+// - updated for lasker 'rmatch'
+//
+// Revision 1.3 1998/02/12 18:44:25 mlong
+// *** empty log message ***
+//
+// Revision 1.2 1997/11/11 16:48:06 chess
+// *** empty log message ***
+//
+// Revision 1.2 1997/10/23 19:56:12 chess
+// *** empty log message ***
+//
+// Revision 1.1 1997/05/16 03:22:36 chess
+// Initial revision
+//
+//
+//
+//--------------------------------------------------------------------------
+
+#ifndef _Player_
+#define _Player_
+
+#include <fstream.h>
+#include <iostream.h>
+
+extern "C" {
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <sys/stat.h>
+
+#include <time.h>
+#include <unistd.h>
+}
+
+#include "config.h"
+#include "User.hh"
+#include "link.hh"
+#include "linklist.hh"
+
+class Player : public Link {
+public:
+
+ Player(char *, int);
+ Player(char *, float);
+ Player(char *, double);
+ Player(char *, float, int);
+ Player(char *, float, int, int);
+ ~Player();
+
+int IsPlayer(char *);
+
+private:
+
+public:
+
+ char name[NAMELEN];
+ int value;
+ double floatValue;
+ int rating;
+
+private:
+
+};
+
+
+#endif
+
+
+
+
+
+
--- /dev/null
+//--------------------------------------------------------------------------
+// Storage.cc - Source file for the Storage class
+//
+// Matthew E. Moses && Michael A. Long
+//
+// $Revision: 1.1 $
+// $Date: 1998/09/10 19:57:17 $
+//
+// $Author: mlong $
+// $Locker: $
+//
+// $Log: Storage.cc,v $
+// Revision 1.1 1998/09/10 19:57:17 mlong
+// Initial revision
+//
+//
+//--------------------------------------------------------------------------
+
+// static char RCSid[] = "$Id: Storage.cc,v 1.1 1998/09/10 19:57:17 mlong Exp $";
+
+#include "Storage.hh"
+
+//- Constructor -----------------------------------------------------------
+Storage::Storage(char *n, int wt) {
+ strcpy(name, n);
+ value = wt;
+}
+
+//- Constructor -----------------------------------------------------------
+Storage::Storage(char *n, float wt) {
+ strcpy(name, n);
+ floatValue = wt;
+}
+
+//- Constructor -----------------------------------------------------------
+Storage::Storage(char *n, double wt) {
+ strcpy(name, n);
+ floatValue = wt;
+}
+
+//- Constructor -----------------------------------------------------------
+Storage::Storage(char *n, float f, int i) {
+ strcpy(name, n);
+ floatValue = f;
+ value = i;
+}
+
+//- Constructor -----------------------------------------------------------
+Storage::Storage(char *n, float f, int i, int r) {
+ strcpy(name, n);
+ floatValue = f;
+ value = i;
+ rating = r;
+}
+
+//- DeConstructor ---------------------------------------------------------
+Storage::~Storage() {
+}
--- /dev/null
+//--------------------------------------------------------------------------
+// Storage.hh - Class header for the Storage class
+//
+// Matthew E. Moses & Michael A. Long
+//
+// $Revision: 1.1 $
+// $Date: 1998/09/10 19:58:41 $
+//
+// $Author: mlong $
+// $Locker: $
+//
+// $Log: Storage.hh,v $
+// Revision 1.1 1998/09/10 19:58:41 mlong
+// Initial revision
+//
+// Revision 1.3 1998/02/12 18:44:25 mlong
+// *** empty log message ***
+//
+// Revision 1.2 1997/11/11 16:48:06 chess
+// *** empty log message ***
+//
+// Revision 1.2 1997/10/23 19:56:12 chess
+// *** empty log message ***
+//
+// Revision 1.1 1997/05/16 03:22:36 chess
+// Initial revision
+//
+//
+//
+//--------------------------------------------------------------------------
+
+#ifndef _Storage_
+#define _Storage_
+
+#include <fstream.h>
+#include <iostream.h>
+
+extern "C" {
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <sys/stat.h>
+
+#include <time.h>
+#include <unistd.h>
+}
+
+#include "config.h"
+#include "User.hh"
+#include "link.hh"
+#include "linklist.hh"
+
+class Storage : public Link {
+public:
+
+ Storage(char *, int);
+ Storage(char *, float);
+ Storage(char *, double);
+ Storage(char *, float, int);
+ Storage(char *, float, int, int);
+ ~Storage();
+private:
+
+public:
+
+ char name[NAMELEN];
+ int value;
+ double floatValue;
+ int rating;
+
+private:
+
+};
+
+
+#endif
+
+
+
+
+
+
--- /dev/null
+//--------------------------------------------------------------------------
+// Tourney.cc - Source file for Tourney class
+//
+// Matthew E. Moses
+//
+// $Revision: 1.12 $
+// $Date: 2002/07/02 00:02:40 $
+//
+// $Author: tridge $
+// $Locker: $
+//
+// $Log: Tourney.cc,v $
+// Revision 1.12 2002/07/02 00:02:40 tridge
+// - fixed compile on g++ 2.96
+// - updated for lasker 'rmatch'
+//
+// Revision 1.11 1998/09/10 19:57:17 mlong
+// lots of little bug fixes and a few new features
+//
+// Revision 1.10 1998/04/29 15:23:19 mlong
+// prepairing for the move to daimi
+// new sorting routine.
+//
+// Revision 1.9 1998/04/18 20:05:14 mlong
+// fixed BYE bug
+//
+// Revision 1.8 1998/04/18 18:46:04 mlong
+// fixed delete bug &
+// added delete tourney function
+//
+// Revision 1.4 1997/10/08 21:03:35 chess
+// preparing for move to oracle machine at eworks.
+//
+// Revision 1.3 1997/05/15 18:27:53 chess
+// added pending and TourneyPlayers support
+// added HandleGetPlayerInfo & HandleGetGameInfo
+//
+// Revision 1.2 1996/10/01 20:14:43 moses
+// Added a new method IsTourney
+//
+// Revision 1.1 1996/09/30 20:52:48 moses
+// Initial revision
+//
+//--------------------------------------------------------------------------
+
+//static char RCSid[] = "$Id: Tourney.cc,v 1.12 2002/07/02 00:02:40 tridge Exp $";
+
+#include "Tourney.hh"
+#include "Mamer.hh"
+
+extern Mamer gMamer;
+
+//- Constructor ------------------------------------------------------------
+Tourney::Tourney() {
+} //- End of Tourney
+
+Tourney::Tourney(int n,User *u, TourneyParameters *tp) {
+ InitTourney(n, u, tp->time, tp->inc, tp->mode, tp->style, tp->rounds, tp->variant, tp->ratingLow, tp->ratingHigh);
+}
+
+Tourney::Tourney(int n, User *u, TourneyParameters *tp, int t, int i, char m, char s, int r) {
+ InitTourney(n, u, t, i, m, s, r, tp->variant, tp->ratingLow, tp->ratingHigh);
+}
+
+Tourney::Tourney(int n, User *u, TourneyParameters *tp, int t, int i, char m, char s, int r, char v) {
+ InitTourney(n, u, t, i, m, s, r, v, tp->ratingLow, tp->ratingHigh);
+}
+
+void Tourney::InitTourney(int n, User *u, int t, int i, char m, char s, int r, char v, int rl, int rh) {
+ number = n;
+ strncpy(manager, u->name, NAMELEN - 1);
+ managerLevel = u->GetManagerLevel();
+ averageRating = 0;
+ params.time = t;
+ params.inc = i;
+ params.mode = m;
+ params.style = s;
+ params.rounds = r;
+ params.variant = v;
+ params.wild = 10;
+ params.ratingLow = rl;
+ params.ratingHigh = rh;
+ params.currentRound = 0;
+ params.maxPlayers = DEFAULT_MAX_PLAYERS;
+
+ startDate = 0;
+ endDate = 0;
+ persist = 0;
+ lastCshouted = 0;
+
+ status = NEW;
+}
+
+//- Deconstructor ---------------------------------------------------------
+Tourney::~Tourney() {
+
+} //- End of ~Tourney
+
+//- IsTourney -------------------------------------------------------------
+int Tourney::IsTourney(int tourn) {
+ if(tourn == number)
+ return(1);
+ else
+ return(0);
+} //- End of IsTourney
+
+//- IsNotNew-------------------------------------------------------------
+short Tourney::IsNotNew(void) {
+ if(NEW != status)
+ return(TRUE);
+ return(FALSE);
+}
+
+//- IsNotClosed-------------------------------------------------------------
+short Tourney::IsNotClosed(void) {
+ if(CLOSED != status)
+ return(TRUE);
+ return(FALSE);
+}
+
+//- AddPlayer ----------------------------------------------------------
+int Tourney::AddPlayer(char *name, int rating, float score) {
+ TourneyPlayers *newPlayer = NULL, *tp = NULL;
+ Player *newSortPlayer = NULL;
+
+ if (status != OPEN) return 3; // If we are not open then we can't enter the tourney
+
+ tp = GetPlayer(name);
+
+ if(tp != NULL) return(2); // if we are already in the tourney we can't enter it again/
+
+ if(rating >= params.ratingLow && rating <= params.ratingHigh && status == OPEN) {
+
+ newPlayer = new TourneyPlayers(name, rating, score);
+ newSortPlayer = new Player(name, 0);
+
+ playerList.Append(newPlayer);
+ SortPlayers();
+ gMamer.XServerCom("%s %i %s %s%i%s %s%i %i %s%s", "tell", gMamer.channelNumber, name, "(", rating, ")",
+ "has joined tourney #", number, GetPlayerCount(), "players now.", "\n");
+ CalculateAverage();
+ if(GetPlayerCount() >= params.maxPlayers)
+ CloseAndStart();
+ return(1); // we entered the tourney
+ } else
+ return(0); // sucks to be us cause our rating doesn't fit the params
+}
+
+//- RemovePlayer ----------------------------------------------------------
+int Tourney::RemovePlayer(char *name) {
+ TourneyPlayers *tp = NULL, *p=NULL;
+ Player *opp=NULL;
+ int roundsRemaining=0;
+
+ tp = GetPlayer(name);
+ printf("forfeiting %s\n", tp->name);
+ if(tp == NULL) return -1; // Player not in THIS tourney
+
+ tp->activeFlag = 0;
+
+ roundsRemaining = GetRoundsRemaining();
+
+ // This code will go through a forfeited players list and give him a loss for current opponent
+ // with a quick modification it will give losses for all games played as well...
+ LinkListIter<Player> opponentIter(tp->opponentList); // List of opponents this player has had
+ opponentIter.Reset();
+ while((opp = opponentIter.Next())) {
+ if(strcmp("_BYE_", opp->name) != 0) { // If I am not _BYE_
+ p = GetPlayer(opp->name);
+ if(opp->floatValue == -1) { // floatValue stores the game result for this player
+ if(opp->value) { // if player leaving was white
+ SetGameResult(tp->name, opp->name, 0);
+ } else {
+ SetGameResult(opp->name, tp->name, 1);
+ }
+ roundsRemaining++;
+ }
+ }
+ }
+
+ LinkListIter<TourneyPlayers> playerIter(playerList);
+ playerIter.Reset();
+ while((p = playerIter.Next())) {
+ if(strcmp(p->name, "_BYE_") == 0) {
+ if(p->activeFlag != 0)
+ p->activeFlag = 0;
+ else
+ p->activeFlag = 1;
+ break;
+ }
+ }
+
+ SortPlayers();
+
+ return roundsRemaining;
+}
+
+//- GetPlayer ----------------------------------------------------------
+TourneyPlayers *Tourney::GetPlayer(char *name) {
+ LinkListIter<TourneyPlayers> playerIter(playerList);
+ TourneyPlayers *tp = NULL;
+
+ playerIter.Reset();
+ while((tp = playerIter.Next()))
+ if(!strcasecmp(tp->name, name))
+ return tp;
+
+ return NULL;
+}
+
+//- GetRound ----------------------------------------------------------
+int Tourney::GetRound() {
+ return params.currentRound;
+}//- end of GetRound --------------------------------------------------
+
+//- GetRoundsRemaining ------------------------------------------------
+int Tourney::GetRoundsRemaining() {
+ return (params.rounds - params.currentRound);
+}//- end of GetRoundsRemaining -----------------------------------------
+
+//- SortPlayers ----------------------------------
+void Tourney::SortPlayers() {
+ Player *temp=NULL, *s=NULL;
+ TourneyPlayers *tp = NULL;
+ int i=0, added=0;
+
+ LinkListIter<TourneyPlayers> playerIter(playerList);
+ LinkListIter<Player> sortIter(sortList);
+
+ sortIter.Reset();
+ while((s = sortIter.Next())) sortList.Delete(s);
+
+ i=0;
+ while((tp = playerIter.Next())) {
+ (tp->activeFlag) ? tp->sortValue = (tp->score + tp->rating/10000.0) : tp->sortValue = -1.0;
+ tp->ClearWhites();
+ tp->ClearBlacks();
+ if((status == OPEN) && (i < (GetPlayerCount()/2)))
+ (i % 2) ? tp->AddWhite() : tp->AddBlack();
+ i++;
+ }
+
+ playerIter.Reset();
+ while((tp = playerIter.Next())) {
+ added=0;
+ sortIter.Reset();
+ temp = new Player(tp->name, tp->sortValue);
+ while((s = sortIter.Next())) {
+ if(tp->sortValue > s->floatValue) {
+ sortList.Insert(s, temp);
+ added = 1;
+ break;
+ }
+ }
+ if(!added)
+ sortList.Append(temp);
+ }
+
+ i = 1;
+ sortIter.Reset();
+ while((s = sortIter.Next())) {
+ s->value = i;
+ if(gMamer.debugLevel >= 10) printf("%4d %-18s\n", s->value, s->name);
+ i++;
+ }
+}//- end of Sort Players ----------------------
+
+//- GetSortValueCount -------------------------------------------------------
+int Tourney::GetSortValueCount(double value) {
+ LinkListIter<TourneyPlayers> playerIter(playerList);
+ int count=0;
+ TourneyPlayers *tp=NULL;
+ Player *s=NULL;
+
+ while((tp = playerIter.Next())) {
+ if(tp->sortValue == value) {
+ s = GetSortPlayer(tp->name);
+ if(s->value != 0)
+ count++;
+ }
+ }
+
+ return count;
+}
+
+//- GetSortPlayer ----------
+Player *Tourney::GetSortPlayer(char *name) {
+ Player *p = NULL;
+ LinkListIter<Player> sortIter(sortList);
+
+ while((p = sortIter.Next())) {
+ if(strcasecmp(p->name, name) == 0) {
+ return p;
+ }
+ }
+
+ return p;
+}//- end of GetSortPlayer -----
+
+//- GetSortPlayer ------------------------------
+Player *Tourney::GetSortPlayer(int place) {
+ Player *p = NULL;
+ LinkListIter<Player> sortIter(sortList);
+
+ while((p = sortIter.Next())) {
+ if(p->value == place) {
+ return p;
+ }
+ }
+
+ return p;
+}//- end of GetSortPlayer -----
+
+//- CalculateAverage --------------------------------------------------
+void Tourney::CalculateAverage(void) {
+ int total=0, count=0;
+ TourneyPlayers *p;
+ LinkListIter<TourneyPlayers> playerIter(playerList);
+
+ while((p = playerIter.Next())) {
+ if(p->rating > 0) {
+ total += p->rating;
+ count++;
+ }
+ }
+ if(count)
+ averageRating = ((float)total/(float)count);
+ else
+ averageRating = 0;
+}//- end CalculateAverage
+
+//- GetAverageRating ----------------------------------------------------------
+float Tourney::GetAverageRating(void) {
+ return averageRating;
+}//end GetAverageRating
+
+//- GetVariant ----------------------------------------------------------
+int Tourney::GetVariant(void) {
+ float eTime;
+
+ switch(params.variant) {
+ case 'w':
+ return(0);
+ case 'r':
+ eTime = (float)params.time + (0.6666667 * (float)params.inc);
+ if(eTime < 3)
+ return(1);
+ else if(eTime < 15)
+ return(2);
+ else
+ return(3);
+ case 'b':
+ return(4);
+ case 's':
+ return(5);
+ default:
+ return(2);
+ }
+}
+
+//- Open ----------------------------------------------------------
+int Tourney::Open(void) {
+ if(status == NEW) {
+ status = OPEN;
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+//- GetPlayerCount ----------------------------------------------------------
+int Tourney::GetPlayerCount() {
+ int count=0;
+ TourneyPlayers *p;
+ LinkListIter<TourneyPlayers> playerIter(playerList);
+
+ while((p = playerIter.Next())) {
+ if(p->activeFlag != 0)
+ count++;
+ }
+
+ return count;
+}//- end GetPlayerCount ----------------------------------
+
+//- SetPersist -------------------------------------------------------------
+void Tourney::SetPersist(int i) {
+ persist = i;
+} //- end SetPersist
+
+//- GetPersist -------------------------------------------------------------
+int Tourney::GetPersist() {
+ return persist;
+} //- end GetPersist
+
+//- SetEndDate -------------------------------------------------------------
+void Tourney::SetEndDate() {
+ endDate = time(0);
+} //- end of SetEndDate ----------------------------------------------------
+
+//- CloseAndStart ----------------------------------------------------------
+void Tourney::CloseAndStart(void) {
+ status = CLOSED;
+ params.currentRound = 0;
+
+ startDate = time(0);
+
+ cout << "tourney started at: " << ctime(&startDate) << endl;
+
+ if(params.rounds == 0) {
+ switch(params.style) {
+ case 'r':
+ params.rounds = GetPlayerCount() - 1;
+ break;
+ case 's':
+ params.rounds = (int)ceil(log2(GetPlayerCount()));
+ break;
+ default:
+ params.rounds = DEFAULT_ROUNDS;
+ break;
+ }
+ }
+
+ // this is to stop a 4 player tourney from having 2 rounds
+ params.rounds = (params.rounds < MINIMUM_ROUNDS) ? MINIMUM_ROUNDS : params.rounds;
+
+ MakeAssignments();
+ TellThemWhoTheyPlay(); // tell them who they play
+}
+
+int Tourney::PopLastPairedPlayer() {
+ Storage *p=NULL, *lastPlayer=NULL;
+ LinkListIter<Storage> pairedIter(pairedPlayers);
+ int last=0;
+
+ while((p = pairedIter.Next())) {
+ lastPlayer = p;
+ last = p->value;
+ }
+
+ if(last) {
+ cout << "Popping: " << lastPlayer->name << " from the paired list " << endl;
+ pairedPlayers.Delete(lastPlayer);
+ } else
+ cout << "Popping: _NOBODY_" << " from the paired list " << endl;
+
+ return last;
+}
+
+void Tourney::ClearPairedPlayers() {
+ Storage *p=NULL;
+ LinkListIter<Storage> pairedIter(pairedPlayers);
+
+ while((p = pairedIter.Next())) pairedPlayers.Delete(p);
+}
+
+int Tourney::MakeAssignments(void) {
+ TourneyPlayers *tp = NULL, *opponent = NULL, *bye = NULL;
+ Storage *newPairedPlayer=NULL;
+ Player *p=NULL, *opp=NULL;
+ int everybodyPaired=0, byeFlag=1, playerCount=0, i=1;
+ LinkListIter<TourneyPlayers> playerIter(playerList);
+
+ params.currentRound++;
+ if(params.currentRound > params.rounds) {
+ cout << "Returning because current round is > rounds" << endl;
+ cerr << "Returning because current round is > rounds" << endl;
+ return 0;
+ }
+ // Initialize a few things...make sure nobody is paired,
+ playerIter.Reset();
+ while((tp = playerIter.Next())) {
+ UnPairPlayer(tp);
+ if(strcmp(tp->name, "_BYE_") == 0) { byeFlag = 0; } // unset the byeFlag
+ }
+ playerCount = GetPlayerCount();
+ if((byeFlag) && (playerCount % 2)){ // we need to add a bye
+ bye = new TourneyPlayers("_BYE_", 0, 0);
+ playerList.Append(bye); // add the bye to the tourney players list
+ SortPlayers();
+ playerCount++;
+ }
+
+ // Set up the PairingScores
+ playerIter.Reset();
+ while((tp = playerIter.Next())) { if(!tp->IsPaired()) SetPairingScores(tp); }
+
+ playerIter.Reset();
+ while((tp = playerIter.Next())) { UnPairPlayer(tp); tp->oppChoice=0; } // unpair all the players
+
+ i = 1;
+ ClearPairedPlayers();
+ while(everybodyPaired == 0) {
+ everybodyPaired = 0;
+ p = GetSortPlayer(i);
+ tp = GetPlayer(p->name);
+ opponent = (TourneyPlayers *)NULL;
+ // PrintPotentialLists();
+ if((tp->IsPaired() == FALSE) && tp->activeFlag) { // If I am not paired and I am active pair me
+ if((opponent = FindBestOpponent(tp))) {
+ newPairedPlayer = new Storage(tp->name, i);
+ pairedPlayers.Append(newPairedPlayer);
+ cerr << "Adding: " << tp->name << " " << i << " " << "to the paired list " << opponent->name << endl;
+ everybodyPaired = PairPlayers(tp, opponent); // Actually Pair me
+ i++; // go to the next player
+ } else { // If there is no opponent for me go back and repair up the tree
+ if(tp->oppChoice > playerCount) { // If I have tried all my opponents
+ tp->oppChoice = 0; // reset me so I can try again later
+ i = PopLastPairedPlayer(); // returns the last player paired & removes him from the paired list
+ cerr << "i=" << i << endl;
+ if(i <= 0) { // this would be really bad means we can't even find
+ cout << "Returning because we can't find pairings" << endl;
+ cerr << "Returning because we can't find pairings" << endl;
+ return 0; // an opponent for the first player. Tourney has to be over now
+ }
+ p = GetSortPlayer(i);
+ tp = GetPlayer(p->name);
+ opponent = GetPlayer(tp->oppName);
+ cout << "UnPairing: " << tp->name << " " << opponent->name << " choice: " << tp->oppChoice << endl;
+ tp->RemoveLastOpponent(); // removes the person we were planning on playing
+ opponent->RemoveLastOpponent();
+ UnPairPlayer(tp); // unpair us so we can be re-paired
+ UnPairPlayer(opponent);
+ tp->oppChoice++; // try his next possible opponent
+ } else {
+ tp->oppChoice++; // Try my next opponent
+ }
+ }
+ } else { // if I am already paired go to the next player and pair him
+ i++;
+ }
+ }
+
+ if(everybodyPaired > 0) {
+ playerIter.Reset();
+ while((tp = playerIter.Next())) UnPairPlayer(tp); // unpair all players so we can use that to tell
+ playerIter.Reset(); // if they have been assiged a color
+ while((tp = playerIter.Next())) {
+ if((!tp->IsPaired()) && (tp->activeFlag != 0)) {
+ opponent = GetPlayer(tp->oppName);
+ AssignColors(tp, opponent);
+ tp->NowPaired(TRUE); // mark BOTH players as having a color
+ opponent->NowPaired(TRUE); // this is important for when we hit this player later in the Iter
+ }
+ }
+ }
+
+ playerIter.Reset();
+ while((tp = playerIter.Next())) {
+ if(0 == strcmp(tp->name, "_BYE_")) { // If I am the bye
+ LinkListIter<Player> opponentIter(tp->opponentList);
+ while((opp = opponentIter.Next())) { // Got through my opponents and find the one I am playing now
+ if(0 == strcasecmp(opp->name, tp->oppName)) { // & Give him a win
+ if(opp->value)
+ SetGameResult(tp->name, tp->oppName, 0);
+ else
+ SetGameResult(tp->oppName, tp->name, 1);
+ gMamer.XServerCom("tell %s you get a BYE this round.%s", opp->name, "\n");
+ }
+ }
+ }
+ }
+ return 1;
+}
+
+//- PrintPotentialLists
+void Tourney::PrintPotentialLists() {
+ TourneyPlayers *tp=NULL;
+ Player *o=NULL;
+
+ LinkListIter<TourneyPlayers> playerIter(playerList);
+
+ while((tp = playerIter.Next())) {
+ printf("%-10s %i\n", tp->name, tp->oppChoice);
+ LinkListIter<Player> oppIter(tp->potentialOpponentList);
+ while((o = oppIter.Next())) {
+ printf("%d %-10s ", o->value, o->name);
+ }
+ printf("\n\n");
+ }
+}
+
+//- Start of FindBestOpponent
+TourneyPlayers *Tourney::FindBestOpponent(TourneyPlayers *tp) {
+ Player *tmp = NULL;
+
+ LinkListIter<Player> opponentIter(tp->potentialOpponentList);
+ while((tmp = opponentIter.Next())) {
+ if((tmp->value == tp->oppChoice) && (0 == GetPlayer(tmp->name)->IsPaired())) {
+ return GetPlayer(tmp->name);
+ }
+ }
+
+ return NULL;
+}
+
+//- Start of SetPairingSores -------------------------------
+void Tourney::SetPairingScores(TourneyPlayers *tp) {
+ double score;
+ TourneyPlayers *opponent = NULL;
+ Player *temp=NULL, *newOpp=NULL, *t=NULL, *me=NULL;
+ int offset=2, place=1, i=0, added=0;
+
+ tp->RemovePotentialOppList();
+
+ LinkListIter<TourneyPlayers> playerIter(playerList);
+
+ SortPlayers();
+
+ while((opponent = playerIter.Next())) {
+ if((strcmp(tp->name, opponent->name) != 0) &&
+ (tp->score == opponent->score)) {
+ offset++;
+ if(opponent->rating > tp->rating) {
+ place++;
+ }
+ }
+ }
+ offset = offset / 2;
+ if(place > offset) { offset *= -1; }
+
+ me = GetSortPlayer(tp->name);
+ playerIter.Reset();
+ while((opponent = playerIter.Next())) {
+ if(strcmp(tp->name, opponent->name) && (tp->activeFlag !=0)) { // If this isn't MY name & I am active
+ if((!tp->AlreadyPlayed(opponent->name)) && (!opponent->IsPaired()) && (opponent->activeFlag != 0)) {
+ // and I haven't played this person and this person is active. (not forfeited)
+ t = GetSortPlayer(opponent->name);
+ score = ((abs(t->value - (me->value + offset))) * 1000);
+ if(opponent->score >= tp->score) {
+ score = score + ((opponent->score - tp->score) * 10.0);
+ } else {
+ score = score + ((tp->score - opponent->score) * 10.0);
+ }
+ score += abs(opponent->ColorDue() - tp->ColorDue());
+ score += (abs(opponent->rating - tp->rating)) * 0.0001;
+
+ if(!strcmp(opponent->name, "_BYE_")) { score = 999999; }
+
+ added=0;
+ newOpp = new Player(opponent->name, score);
+ LinkListIter<Player> opponentIter(tp->potentialOpponentList);
+ opponentIter.Reset();
+ while((temp = opponentIter.Next())) {
+ if(score < temp->floatValue) {
+ tp->potentialOpponentList.Insert(temp, newOpp);
+ added = 1;
+ break;
+ }
+ }
+ if(!added)
+ tp->potentialOpponentList.Append(newOpp);
+ opponentIter.Reset();
+ i = 0;
+ while((temp = opponentIter.Next())) {
+ temp->value = i;
+ i++;
+ }
+ }
+ }
+ }
+}
+
+//- Start of PairPlayers ----------------------------------
+int Tourney::PairPlayers(TourneyPlayers *p1, TourneyPlayers *p2) {
+ TourneyPlayers *tp;
+ Player *temp = NULL;
+
+ LinkListIter<TourneyPlayers> playerIter(playerList);
+
+ temp = new Player(p2->name, -1.0, 0, p2->rating);
+ p1->opponentList.Append(temp);
+ p1->NowPaired(TRUE);
+ strcpy(p1->oppName, p2->name);
+
+ temp = new Player(p1->name, -1.0, 0, p1->rating);
+ p2->opponentList.Append(temp);
+ p2->NowPaired(TRUE);
+ strcpy(p2->oppName, p1->name);
+
+ playerIter.Reset();
+ while((tp = playerIter.Next())) {
+ if((!tp->IsPaired()) && (tp->activeFlag != 0))
+ return 0;
+ }
+
+ return 1;
+}
+
+//- Start of UnPairPlayer ----------------------------------
+void Tourney::UnPairPlayer(TourneyPlayers *p1) {
+ if(p1 != NULL)
+ p1->NowPaired(FALSE);
+}//- end of UnPairPlayer
+
+//- intcmp ----
+int Tourney::intcmp(int a, int b) {
+ if(a > b) {
+ return 1;
+ } else {
+ if (a == b) {
+ return 0;
+ } else {
+ return -1;
+ }
+ }
+}
+//- end intcmp ----
+
+//- AssignColors ----------------------------------------------------------
+void Tourney::AssignColors(TourneyPlayers *p1, TourneyPlayers *p2) {
+ int p1Color=0, rated = 1;
+ Game *g = NULL;
+ Player *opp1 = NULL, *opp2 = NULL;
+
+ if(params.mode != 'r') { rated = 0; }
+ if(intcmp(p1->ColorDue(), p2->ColorDue()) != 0) {
+ if(p1->ColorDue()) { p1Color = 1; }
+ } else {
+ if(p1->ColorDue()) { // Both are due white; need to find out how due.
+ switch (intcmp(p1->GetConsecutiveBlacks(), p2->GetConsecutiveBlacks())) {
+ case 1:
+ p1Color = 1;
+ break;
+ case -1: break;
+ case 0:
+ switch (intcmp(p1->GetTotalBlacks(), p2->GetTotalBlacks())) {
+ case 1:
+ p1Color = 1;
+ break;
+ case -1: break;
+ case 0:
+ if((p1->score * 10000 + p1->rating) >= (p2->score * 10000 + p2->rating))
+ p1Color = 1;
+ break;
+ }
+ break;
+ }
+ } else {
+ switch (intcmp(p1->GetConsecutiveWhites(), p2->GetConsecutiveWhites())) {
+ case 1: break;
+ case -1:
+ p1Color = 1;
+ break;
+ case 0:
+ switch (intcmp(p1->GetTotalWhites(), p2->GetTotalWhites())) {
+ case 1: break;
+ case -1:
+ p1Color = 1;
+ break;
+ case 0:
+ if((p1->score * 10000 + p1->rating) >= (p2->score * 10000 + p2->rating))
+ p1Color = 1;
+ break;
+ }
+ break;
+ }
+ }
+ }
+ LinkListIter<Player> opponentIter1(p1->opponentList);
+ LinkListIter<Player> opponentIter2(p2->opponentList);
+ while((opp1 = opponentIter1.Next())) {
+ if(!strcasecmp(opp1->name, p2->name)) { break; }
+ }
+ while((opp2 = opponentIter2.Next())) {
+ if(!strcasecmp(opp2->name, p1->name)) { break; }
+ }
+ if(p1Color) {
+ p1->AddWhite(); p2->AddBlack();
+ opp1->value = 1;
+ g = new Game(p1->name, p2->name, params.time, params.inc, rated, 'r');
+ } else {
+ p1->AddBlack(); p2->AddWhite();
+ opp2->value = 1;
+ g = new Game(p2->name, p1->name, params.time, params.inc, rated, 'r');
+ }
+ gameList.Append(g);
+}
+
+//- GetStatus --------------------------------------------------------
+int Tourney::GetStatus(void) {
+ return status;
+}
+
+//- EndTourney -----------------------
+void Tourney::EndTourney(void) {
+ status = DONE;
+}//- End EndTourney
+
+//- Announce ----------------------------------------------------------
+void Tourney::Announce(void) {
+ char temp[128];
+ char *announce;
+ long now=0;
+
+ announce = new char[MAX_LINE_SIZE];
+ memset(announce, '\0', MAX_LINE_SIZE);
+ sprintf(announce, "*****Tourney Announcement***** %80s Trny #%d %d %d %c ",
+ "", number, params.time, params.inc, params.mode);
+ if(params.style == 's') { strcat(announce, " SWISS"); } else { strcat(announce, " RR"); }
+ switch(params.variant) {
+ case 'w':
+ strcat(announce, " Wild ");
+ strcat(announce, GetWild(params.wild));
+ break;
+ case 'b':
+ strcat(announce, " Bug"); break;
+ case 's':
+ strcat(announce, " Suicide"); break;
+ default:
+ break;
+ }
+ memset(temp, '\0', 128);
+ sprintf(temp, " %i-%i %i plr(s). tell %s join %d. Avg: %5.1f",
+ params.ratingLow, params.ratingHigh, GetPlayerCount(), gMamer.username, number, averageRating);
+ strcat(announce, temp);
+
+ printf("%s + cha 49\n", announce);
+ fflush(stdout);
+
+ gMamer.XServerCom("%s %i %s%s", "tell", gMamer.channelNumber, announce, "\n");
+
+ now = time(0);
+ if((now - lastCshouted) > (SEC_BETWEEN_CSHOUTS)) {
+ gMamer.XServerCom("%s %s%s", "cshout", announce, "\n");
+ lastCshouted = now;
+ }
+
+ delete(announce);
+}
+
+//- SetVariable ---------------------------------------------------------------
+void Tourney::SetVariable(int why, int newValue) {
+
+ switch (why) {
+ case 0:
+ if((newValue >= 0) && (newValue <= MAX_TIME))
+ params.time = newValue;
+ break;
+ case 1:
+ if((newValue >= 0) && (newValue <= MAX_INCREMENT))
+ params.inc = newValue;
+ break;
+ case 2:
+ params.rounds = newValue;
+ params.rounds = MIN(params.rounds, MAX_ROUNDS);
+ params.rounds = MIN((params.maxPlayers - 1), params.rounds);
+ break;
+ case 6:
+ if(((newValue >= 0) && (newValue <= 5)) ||
+ ((newValue >= 8) || (newValue <= 10)))
+ params.wild = newValue;
+ break;
+ case 7:
+ params.ratingLow = newValue;
+ params.ratingLow = MAX(0, params.ratingLow);
+ if(params.ratingLow >= (params.ratingHigh - 200))
+ params.ratingLow = params.ratingHigh - 200;
+ break;
+ case 8:
+ params.ratingHigh = newValue;
+ if(params.ratingHigh <= (params.ratingLow + 200))
+ params.ratingHigh = params.ratingLow + 200;
+ break;
+ case 9:
+ params.maxPlayers = newValue;
+ params.maxPlayers = MAX(params.maxPlayers, MINIMUM_PLAYERS);
+ params.maxPlayers = MAX(params.maxPlayers, (params.rounds + 1));
+ break;
+ default:
+ break;
+ }
+}//- End SetVariable
+
+//- SetVariable ---------------------------------------------------------------
+void Tourney::SetVariable(int why, char *newValue) {
+
+ switch (why) {
+ case 3:
+ if((newValue[0] == 's') || (newValue[0] == 'r'))
+ params.style = newValue[0];
+ break;
+ case 4:
+ if((newValue[0] == 'r') || (newValue[0] == 'w') || (newValue[0] == 'b') || (newValue[0] == 's'))
+ params.variant = newValue[0];
+ break;
+ case 5:
+ if((newValue[0] == 'r') || (newValue[0] == 'u'))
+ params.mode = newValue[0];
+ break;
+ default:
+ break;
+ }
+}//- End SetVariable
+
+//- Begin GetWild - take a int return a string
+char *Tourney::GetWild(int w) {
+ switch (w) {
+ case 0:
+ return "0";
+ case 1:
+ return "1";
+ case 2:
+ return "2";
+ case 3:
+ return "3";
+ case 4:
+ return "4";
+ case 5:
+ return "5";
+ case 8:
+ return "8";
+ case 9:
+ return "8a";
+ case 10:
+ return "fr";
+ default:
+ return "";
+ }
+}//- end GetWild
+
+//- TellThemWhoTheyPlay ------------------------------------------
+void Tourney::TellThemWhoTheyPlay() {
+ Game *g = NULL;
+ LinkListIter<Game> gameIter(gameList); // List of games in this tourney
+ char *Variant=new char[MAX_LINE_SIZE];
+
+ memset(Variant, '\0', MAX_LINE_SIZE);
+
+ if(params.variant == 'w')
+ sprintf(Variant, "wild %2s", GetWild(params.wild));
+ else if(params.variant == 's')
+ sprintf(Variant, "suicide");
+ else if(params.variant == 'b')
+ sprintf(Variant, "bug");
+
+ while((g = gameIter.Next())) {
+ /* note that we rely on rmatch and on the ; separated commands from lasker */
+ gMamer.XServerCom("rmatch %s %s %i %i %c %s white ; rmatch %s %s %i %i %c %s black\n",
+ g->whiteName, g->blackName, g->time, g->inc, params.mode, Variant,
+ g->blackName, g->whiteName, g->time, g->inc, params.mode, Variant);
+ }
+ delete(Variant);
+}//- end TellThemWhoTheyPlay --------------------------------------
+
+//- SetGameResult --------------------------------------------
+int Tourney::SetGameResult(char *white, char *black, int result) {
+ Player *opp1 = NULL, *opp2 = NULL;
+ TourneyPlayers *tp1 = NULL, *tp2 = NULL;
+ Game *g = NULL;
+ int found=0;
+
+ tp1 = GetPlayer(white);
+ tp2 = GetPlayer(black);
+
+ if((NULL == tp1) || (NULL == tp2)) { return 0; }
+
+ LinkListIter<Player> opponentIter1(tp1->opponentList); // List of opponents this player has had
+ while((opp1 = opponentIter1.Next())) {
+ if(!strcasecmp(opp1->name, black)) { break; }
+ }
+ LinkListIter<Player> opponentIter2(tp2->opponentList);
+ while((opp2 = opponentIter2.Next())) {
+ if(!strcasecmp(opp2->name, white)) { break; }
+ }
+ if((NULL == opp1) || (NULL == opp2)) { return -1; }
+
+ switch (result) { // set the result
+ case 1:
+ opp1->floatValue = 1.0;
+ opp2->floatValue = 0.0;
+ break;
+ case 0:
+ opp1->floatValue = 0.0;
+ opp2->floatValue = 1.0;
+ break;
+ case 2:
+ opp1->floatValue = 0.5;
+ opp2->floatValue = 0.5;
+ break;
+ default:
+ return 0;
+ }
+ tp1->CalculateScore();
+ tp2->CalculateScore();
+
+ LinkListIter<Game> gameIter(gameList); // List of games in this tourney
+ while((g = gameIter.Next())) {
+ if(!(strcasecmp(g->whiteName, white)) && !(strcasecmp(g->blackName, black))) {
+ gameList.Delete(g);
+ found=1;
+ break;
+ }
+ }
+ if(found) {
+ gameIter.Reset();
+ if((g = gameIter.Next())) {
+ return 1;
+ } else {
+ return 2;
+ }
+ } else {
+ return 1;
+ }
+} //- End SetGameResult --------------------------------------
+
+//- GetStartDate ---------------------------------------------
+long Tourney::GetStartDate() {
+ return startDate;
+} //- end of GetStartDate ------------------------------------
+
+//- GetEndDate ---------------------------------------------
+long Tourney::GetEndDate() {
+ return endDate;
+} //- end of GetEndDate ------------------------------------
--- /dev/null
+//--------------------------------------------------------------------------
+// Tourney.hh - Class header for the Tourney class
+//
+// Matthew E. Moses & Michael A. Long
+//
+// $Revision: 1.12 $
+// $Date: 2002/07/02 00:02:40 $
+//
+// $Author: tridge $
+// $Locker: $
+//
+//--------------------------------------------------------------------------
+
+#ifndef _TOURNEY_
+#define _TOURNEY_
+
+#define log2(x) (log(x)/log(2))
+
+#include <fstream.h>
+#include <iostream.h>
+
+extern "C" {
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <sys/stat.h>
+
+#include <time.h>
+#include <unistd.h>
+#include <math.h>
+}
+
+#include "config.h"
+#include "link.hh"
+#include "linklist.hh"
+#include "User.hh"
+#include "TourneyParameters.hh"
+#include "TourneyPlayers.hh"
+#include "Game.hh"
+#include "Storage.hh"
+
+class Tourney : public Link {
+ public:
+ Tourney();
+ Tourney(int, User *, TourneyParameters *);
+ Tourney(int, User *, TourneyParameters *, int, int, char, char, int);
+ Tourney(int, User *, TourneyParameters *, int, int, char, char, int, char);
+ ~Tourney();
+
+ void InitTourney(int, User *, int, int, char, char, int, char, int, int);
+
+ int intcmp(int, int);
+
+ void TellThemWhoTheyPlay(void);
+
+ int IsTourney(int);
+ short IsNotNew(void);
+ short IsNotClosed(void);
+ int Open(void);
+ void CloseAndStart(void);
+ int GetStatus(void);
+ void EndTourney();
+
+ void Announce(void);
+
+ int AddPlayer(char *, int, float);
+ int RemovePlayer(char *);
+ void SetVariable(int, int);
+ void SetVariable(int, char *);
+ char *GetWild(int);
+ void CalculateAverage();
+
+ void SortPlayers();
+ int GetSortValueCount(double);
+ Player *GetSortPlayer(char *);
+ Player *GetSortPlayer(int);
+
+ TourneyPlayers *GetPlayer(char *);
+ int GetPlayerCount();
+ int GetVariant();
+ int GetRound();
+ int GetRoundsRemaining();
+ float GetAverageRating();
+
+ int MakeAssignments();
+ void SetOffsets();
+ void SetPairingScores(TourneyPlayers *);
+ TourneyPlayers *FindBestOpponent(TourneyPlayers *);
+ int PairPlayers(TourneyPlayers *, TourneyPlayers *);
+ void UnPairPlayer(TourneyPlayers *);
+ void AssignColors(TourneyPlayers *, TourneyPlayers *);
+ int SetGameResult(char *, char *, int);
+
+ long GetStartDate();
+ long GetEndDate();
+ void SetEndDate();
+ void SetPersist(int);
+ int GetPersist();
+
+ int PopLastPairedPlayer();
+ void ClearPairedPlayers();
+
+ void PrintPotentialLists();
+
+ public:
+ int number;
+ long lastCshouted;
+
+ LinkList<TourneyPlayers> playerList;
+ LinkList<Game> gameList;
+ LinkList<Player> sortList;
+ LinkList<Storage> pairedPlayers;
+
+ TourneyParameters params;
+
+ char manager[NAMELEN];
+ int managerLevel;
+
+ private:
+ int persist;
+ time_t startDate;
+ time_t endDate;
+
+ int status;
+
+ float averageRating;
+
+ int currentRound;
+};
+
+#endif
+
+//---------------------------------------------------------
+// $Log: Tourney.hh,v $
+// Revision 1.12 2002/07/02 00:02:40 tridge
+// - fixed compile on g++ 2.96
+// - updated for lasker 'rmatch'
+//
+// Revision 1.11 1998/09/10 19:58:41 mlong
+// lots of little bug fixes and a few new features.
+//
+// Revision 1.10 1998/04/29 15:24:07 mlong
+// prepairing for the move to daimi
+// new sorting routine.
+//
+// Revision 1.9 1998/04/18 18:46:31 mlong
+// fixed delete bug and
+// added delete tourney function
+//
+// Revision 1.8 1998/02/12 18:44:25 mlong
+// *** empty log message ***
+//
+// Revision 1.7 1997/10/28 21:03:48 mlong
+// *** empty log message ***
+//
+// Revision 1.6 1997/10/23 19:56:44 mlong
+// *** empty log message ***
+//
+// Revision 1.5 1997/10/23 19:37:22 chess
+// lots of new stuff
+//
+// Revision 1.4 1997/05/15 18:29:12 chess
+// added pending and TourneyPlayers support
+// added HandleGetPlayerInfo & HandleGetGameInfo
+//
+// Revision 1.3 1997/05/02 23:55:18 chess
+// added TourneyParameters class include
+//
+// Revision 1.2 1996/10/01 20:14:43 moses
+// added methods
+//
+// Revision 1.1 1996/09/30 20:52:48 moses
+// Initial revision
+//
+//--------------------------------------------------------------------------
--- /dev/null
+//--------------------------------------------------------------------------
+// TourneyParameters.cc - Source file for the TourneyParameters class
+//
+// Matthew E. Moses & Michael A. Long
+//
+// $Revision: 1.2 $
+// $Date: 1998/09/10 19:57:17 $
+//
+// $Author: mlong $
+// $Locker: $
+//
+// $Log: TourneyParameters.cc,v $
+// Revision 1.2 1998/09/10 19:57:17 mlong
+// lots of little bug fixes and a few new features
+//
+// Revision 1.1 1997/05/02 23:52:06 chess
+// Initial revision
+//
+//
+//--------------------------------------------------------------------------
+
+// static char RCSid[] = "$Id: TourneyParameters.cc,v 1.2 1998/09/10 19:57:17 mlong Exp $";
+
+#include "TourneyParameters.hh"
+
+//- Constructor -----------------------------------------------------------
+TourneyParameters::TourneyParameters() {
+}
+
+//- DeConstructor ---------------------------------------------------------
+TourneyParameters::~TourneyParameters() {
+}
+
--- /dev/null
+//--------------------------------------------------------------------------
+// TourneyParameters.hh - Class header for the TourneyParameters class
+//
+// Matthew E. Moses & Michael A. Long
+//
+// $Revision: 1.3 $
+// $Date: 1998/09/10 19:58:41 $
+//
+// $Author: mlong $
+// $Locker: $
+//
+// $Log: TourneyParameters.hh,v $
+// Revision 1.3 1998/09/10 19:58:41 mlong
+// lots of little bug fixes and a few new features.
+//
+// Revision 1.2 1998/02/12 18:44:25 mlong
+// *** empty log message ***
+//
+// Revision 1.2 1997/10/23 19:56:12 chess
+// *** empty log message ***
+//
+// Revision 1.1 1997/05/02 23:52:06 chess
+// Initial revision
+//
+//
+//--------------------------------------------------------------------------
+
+#ifndef _TOURNEYPARAMETERS_
+#define _TOURNEYPARAMETERS_
+
+class TourneyParameters {
+ public:
+ TourneyParameters();
+ ~TourneyParameters();
+
+ private:
+
+ public:
+
+ int time;
+ int inc;
+ char variant;
+ int wild;
+ char mode;
+ char style;
+ int ratingHigh;
+ int ratingLow;
+ int rounds;
+ int currentRound;
+ int maxPlayers;
+
+ private:
+
+};
+
+#endif
+
--- /dev/null
+//--------------------------------------------------------------------------
+// TourneyPlayers.cc - Source file for the TourneyPlayers class
+//
+// Matthew E. Moses && Michael A. Long
+//
+// $Revision: 1.7 $
+// $Date: 1998/09/10 19:57:17 $
+//
+// $Author: mlong $
+// $Locker: $
+//
+// $Log: TourneyPlayers.cc,v $
+// Revision 1.7 1998/09/10 19:57:17 mlong
+// lots of little bug fixes and a few new features
+//
+// Revision 1.6 1998/04/29 15:23:19 mlong
+// prepairing for the move to daimi
+// new sorting routine.
+//
+//
+// Revision 1.2 1997/10/08 21:03:35 chess
+// preparing for move to oracle machine at eworks.
+//
+// Revision 1.1 1997/05/14 16:59:13 chess
+// Initial revision
+//
+//
+//--------------------------------------------------------------------------
+
+// static char RCSid[] = "$Id: TourneyPlayers.cc,v 1.7 1998/09/10 19:57:17 mlong Exp $";
+
+#include "TourneyPlayers.hh"
+
+//- Constructor -----------------------------------------------------------
+TourneyPlayers::TourneyPlayers(char *n, int r, float s) {
+ perform=0;
+ upset=0;
+
+ totalWhites = 0;
+ totalBlacks = 0;
+ consecutiveBlacks = 0;
+ consecutiveWhites = 0;
+
+ activeFlag = 1;
+ sortValue = r/10000.0;
+
+ dueColor = 0;
+ paired = 0;
+
+ memset(oppName, '\0', NAMELEN);
+
+ memset(name, '\0', NAMELEN);
+ strcpy(name, n);
+
+ rating = r;
+ score = s;
+
+ oppChoice=0;
+ location=ONLINE;
+}
+
+//- Constructor -----------------------------------------------------------
+TourneyPlayers::TourneyPlayers() {
+ perform=0;
+ upset=0;
+
+ totalWhites = 0;
+ totalBlacks = 0;
+ consecutiveBlacks = 0;
+ consecutiveWhites = 0;
+
+ activeFlag = 1;
+ sortValue = 0.0;
+
+ dueColor = 0;
+ paired = 0;
+
+ memset(oppName, '\0', NAMELEN);
+
+ memset(name, '\0', NAMELEN);
+ rating = 0;
+ score = 0;
+
+ oppChoice=0;
+ location=ONLINE;
+}
+
+//- DeConstructor ---------------------------------------------------------
+TourneyPlayers::~TourneyPlayers() {
+}
+
+//- AlreadyPlayed --------------------------------------------------------
+int TourneyPlayers::AlreadyPlayed(char *oppName) {
+ Player *temp;
+
+ LinkListIter<Player> opponentIter(opponentList);
+
+ while((temp = opponentIter.Next())) {
+ if(!strcmp(oppName, temp->name)) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+//- Start of RemovePotentialOppList
+int TourneyPlayers::RemovePotentialOppList() {
+ Player *temp;
+
+ LinkListIter<Player> opponentIter(potentialOpponentList);
+
+ while((temp = opponentIter.Next())) {
+ potentialOpponentList.Delete(temp);
+ }
+ return 1;
+}//- end of RemovePotentialOppList
+
+//- Start of RemoveFromOppList -------------------------------------------------
+void TourneyPlayers::RemoveFromOppList(char *name) {
+ Player *p=NULL;
+
+ LinkListIter<Player> opponentIter(opponentList);
+
+ while((p = opponentIter.Next())) {
+ if(strcasecmp(p->name, name) == 0) {
+ opponentList.Delete(p);
+ break;
+ }
+ }
+}//- end RemoveFromOppList -----------------------------------------------------
+
+//- Start of RemoveLastOpponent -------------------------------------------------
+void TourneyPlayers::RemoveLastOpponent() {
+ Player *p=NULL, *last=NULL;
+ LinkListIter<Player> opponentIter(opponentList);
+
+ opponentIter.Reset();
+ while((p = opponentIter.Next()))
+ last = p;
+
+ cout << name << " " << last->name << endl;
+ opponentList.Delete(last);
+}//- end RemoveLastOpponent -----------------------------------------------------
+
+//- Start GetOpponentPlayer --------------------------------------------------------
+Player *TourneyPlayers::GetOpponentPlayer(char *oppName) {
+ Player *temp=NULL;
+ LinkListIter<Player> opponentIter(opponentList);
+
+ while((temp = opponentIter.Next())) {
+ if(!strcmp(oppName, temp->name)) {
+ return temp;
+ }
+ }
+
+ return NULL;
+}//- end of GetOpponentPlayer
+
+//- IsPaired ---------------------------------
+int TourneyPlayers::IsPaired(void) {
+ return paired;
+}//- end IsPaired
+
+//- ColorDue ---------------------------------
+int TourneyPlayers::ColorDue(void) {
+ return dueColor;
+}//- end colorDue
+
+//- NowPaired ---------------------------------
+void TourneyPlayers::NowPaired(int value) {
+ paired = value;
+}//- end NowPaired
+
+//-ChangeColorDue ---------------------------------
+void TourneyPlayers::ChangeColorDue(int value) {
+ dueColor = value;
+}//- end ToggleColorDue
+
+//- AddWhite ---------------------------------
+void TourneyPlayers::AddWhite(void) {
+ consecutiveWhites++;
+ ChangeColorDue(0);
+ ClearBlacks();
+}//- end AddWhite
+
+//- AddBlack ---------------------------------
+void TourneyPlayers::AddBlack(void) {
+ consecutiveBlacks++;
+ ChangeColorDue(1);
+ ClearWhites();
+}//- end AddBlack
+
+//- ClearWhites ---------------------------------
+void TourneyPlayers::ClearWhites(void) {
+ consecutiveWhites = 0;
+}//- end ClearWhites
+
+//- ClearBlacks ---------------------------------
+void TourneyPlayers::ClearBlacks(void) {
+ consecutiveBlacks = 0;
+}//- end ClearBlacks
+
+//- GetTotalWhites ---------------------------------
+int TourneyPlayers::GetTotalWhites(void) {
+ return totalWhites;
+}//- end GetTotalWhites
+
+//- GetTotalBlacks ---------------------------------
+int TourneyPlayers::GetTotalBlacks(void) {
+ return totalBlacks;
+}//- end GetTotalBlacks
+
+//- GetConsecutiveWhites ---------------------------------
+int TourneyPlayers::GetConsecutiveWhites(void) {
+ return consecutiveWhites;
+}//- end GetConsecutiveWhites
+
+//- GetConsecutiveBlacks ---------------------------------
+int TourneyPlayers::GetConsecutiveBlacks(void) {
+ return consecutiveBlacks;
+}//- end GetConsecutiveBlacks
+
+//- CalculateScore --------------------------------------
+void TourneyPlayers::CalculateScore(void) {
+ score = 0.0;
+ Player *opp;
+ LinkListIter<Player> opponentIter(opponentList);
+
+ while((opp = opponentIter.Next())) {
+ if(opp->floatValue > 0.0) {
+ score += opp->floatValue;
+ }
+ }
+ CalculatePerform();
+}//- End of CalculateScore -------------------
+
+//- CalculatePerform --------------------------------------
+void TourneyPlayers::CalculatePerform(void) {
+ int total=0, counter=0, upsetpoints=0, rtng=0;
+ Player *opp;
+ LinkListIter<Player> opponentIter(opponentList);
+
+ while((opp = opponentIter.Next())) {
+ if(!strcmp(opp->name, "_BYE_")) continue;
+ rtng = opp->rating;
+ if(opp->rating <= 0) rtng = 1675;
+ if(opp->floatValue == 0.5) {
+ total += rtng;
+ if(rtng > rating)
+ upsetpoints += (rtng - rating)/2;
+ } else if(opp->floatValue == 1.0) {
+ total += (rtng + 400);
+ if(rtng > rating)
+ upsetpoints += (rtng - rating);
+ } else if(opp->floatValue == 0.0) {
+ total += (rtng - 400);
+ }
+ counter++;
+ }
+
+ if(counter > 0)
+ perform = total/counter;
+ else
+ perform = 0;
+ upset = upsetpoints;
+}//- End of CalculatePerform -------------------
+
+
+
--- /dev/null
+//--------------------------------------------------------------------------
+// TourneyPlayers.hh - Class header for the TourneyPlayers class
+//
+// Matthew E. Moses & Michael A. Long
+//
+// $Revision: 1.6 $
+// $Date: 1998/09/10 19:58:41 $
+//
+// $Author: mlong $
+// $Locker: $
+//
+// $Log: TourneyPlayers.hh,v $
+// Revision 1.6 1998/09/10 19:58:41 mlong
+// lots of little bug fixes and a few new features.
+//
+// Revision 1.5 1998/04/29 15:24:07 mlong
+// prepairing for the move to daimi
+// new sorting routine.
+//
+// Revision 1.4 1998/02/12 18:44:25 mlong
+// *** empty log message ***
+//
+// Revision 1.3 1997/10/28 21:03:48 mlong
+// *** empty log message ***
+//
+// Revision 1.2 1997/10/23 19:56:12 chess
+// *** empty log message ***
+//
+// Revision 1.1 1997/05/14 16:59:13 chess
+// Initial revision
+//
+//
+//--------------------------------------------------------------------------
+
+#ifndef _TOURNEYPLAYERS_
+#define _TOURNEYPLAYERS_
+
+#include <fstream.h>
+#include <iostream.h>
+
+extern "C" {
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <sys/stat.h>
+
+#include <time.h>
+#include <unistd.h>
+}
+
+#include "config.h"
+#include "User.hh"
+#include "link.hh"
+#include "linklist.hh"
+#include "Player.hh"
+#include "types.h"
+
+class TourneyPlayers : public Link {
+public:
+ TourneyPlayers(char *, int, float);
+ TourneyPlayers();
+ ~TourneyPlayers();
+
+ void AddWhite();
+ void AddBlack();
+ void ClearWhites();
+ void ClearBlacks();
+
+ int GetConsecutiveWhites();
+ int GetConsecutiveBlacks();
+ int GetTotalWhites();
+ int GetTotalBlacks();
+ int ColorDue();
+
+ int IsPaired();
+ void NowPaired(int);
+
+ int AlreadyPlayed(char *);
+ void CalculateScore();
+
+ int RemovePotentialOppList();
+ Player *GetOpponentPlayer(char *);
+ void RemoveFromOppList(char *);
+ void RemoveLastOpponent();
+
+private:
+ void ChangeColorDue(int);
+
+ void CalculatePerform();
+
+public:
+
+ char name[NAMELEN];
+ int rating;
+ float score;
+ int perform;
+ int upset;
+ int activeFlag;
+ double sortValue;
+ int oppChoice;
+ int location;
+
+ char oppName[NAMELEN];
+
+ LinkList<Player> opponentList;
+ LinkList<Player> potentialOpponentList;
+
+private:
+
+ int totalWhites;
+ int totalBlacks;
+ int consecutiveWhites;
+ int consecutiveBlacks;
+ int dueColor;
+ int paired;
+
+};
+
+
+#endif
--- /dev/null
+//--------------------------------------------------------------------------
+// User.cc - Source file for User class
+//
+// Matthew E. Moses
+//
+// $Revision: 1.10 $
+// $Date: 1998/09/10 19:57:17 $
+//
+// $Author: mlong $
+// $Locker: $
+//
+// $Log: User.cc,v $
+// Revision 1.10 1998/09/10 19:57:17 mlong
+// lots of little bug fixes and a few new features
+//
+// Revision 1.9 1998/04/29 15:23:19 mlong
+// prepairing for the move to daimi
+// new sorting routine.
+//
+//
+// Revision 1.7 1997/05/15 18:27:53 chess
+// added pending and TourneyPlayers support
+// added HandleGetPlayerInfo & HandleGetGameInfo
+//
+// Revision 1.6 1997/04/13 03:14:35 chess
+// setstatistic and addabuse added for data manipulation
+//
+// Revision 1.4 1997/03/27 13:45:58 chess
+// added functions to return user's statistics
+//
+// Revision 1.3 1997/03/21 15:29:53 moses
+// changed the initial clearing of the name variable
+//
+// Revision 1.2 1996/10/01 20:14:43 moses
+// added a new Method IsUser
+// added a new Method GetManagerLevel
+//
+// Revision 1.1 1996/09/30 20:52:48 moses
+// Initial revision
+//
+//--------------------------------------------------------------------------
+
+// static char RCSid[] = "$Id: User.cc,v 1.10 1998/09/10 19:57:17 mlong Exp $";
+
+#include "User.hh"
+
+//- Constructors ------------------------------------------------------------
+User::User() {
+ memset(name, '\0', NAMELEN);
+ abuse = 0;
+ playedTourneys = wins = losses = draws = 0;
+ firsts = seconds = thirds = 0;
+ rating = placePoints = 0.0;
+
+ managerLevel = 0;
+ managedTourneys = 0;
+ last = 0;
+ tourneyLocation = 0;
+
+ inTourney = 0;
+
+ managerLevel = 0;
+ managedTourneys = 0;
+ last = 0;
+
+} //- End of User
+
+User::User(char *path, char *inName) {
+ abuse = 0;
+ playedTourneys = wins = losses = draws = 0;
+ firsts = seconds = thirds = 0;
+ rating = placePoints = 0.0;
+ char *lowername;
+ int i=0, length=strlen(inName);
+
+ lowername = new char[NAMELEN];
+ memset(name, '\0', NAMELEN);
+ memset(lowername, '\0', NAMELEN);
+ for(i = 0; i < length; i++) lowername[i] = tolower(inName[i]);
+
+ strncpy(name, lowername, MIN(length, NAMELEN));
+
+ // printf("User:%s::%s::%s\n", inName, name, path);
+
+ delete(lowername);
+
+ managerLevel = 0;
+ managedTourneys = 0;
+ last = 0;
+ tourneyLocation = 0;
+
+ inTourney = 0;
+
+ // printf("User:%s::%s::%s\n", inName, name, path);
+
+ if(0 == LoadPlayer(path, name))
+ SavePlayer(path);
+} //- End of User
+
+//- Deconstructor ----------------------------------------------------------
+User::~User() {
+
+} //- End of ~User
+
+//- IsUser -----------------------------------------------------------------
+int User::IsUser(char *user) {
+ // printf("IsUser: %18s :: %s\n", user, name);
+
+ if(0 == strcasecmp(user, name))
+ return(1);
+ else
+ return(0);
+} //- End of IsUser
+
+//- LoadPlayer -------------------------------------------------------------
+void User::LoadPlayer(char *filePath) {
+ char filename[MAXPATHLEN];
+ fstream theFile;
+
+ CreateDirectory(filePath, name);
+ sprintf(filename, "%s/%c/%s", filePath, name[0], name);
+ theFile.open(filename, ios::in);
+
+ theFile >> name >> abuse >> playedTourneys >> wins >> losses >> draws
+ >> firsts >> seconds >> thirds >> rating >> placePoints
+ >> managerLevel >> managedTourneys >> last >> tourneyLocation;
+
+ CalculateRating();
+ theFile.close();
+} //- End of LoadPlayer
+
+//- LoadPlayer -------------------------------------------------------------
+short User::LoadPlayer(char *filePath, char *user) {
+ struct stat statBuffer;
+ char filename[MAXPATHLEN];
+ fstream theFile;
+ char *lowername;
+ int i=0, length=strlen(user);
+
+ // printf("LoadPlayer: %18s :: %s :: %i\n", user, filePath, length);
+
+ lowername = new char[NAMELEN];
+ memset(lowername, '\0', NAMELEN);
+ for(i = 0; i < length; i++) lowername[i] = tolower(user[i]);
+
+ user = lowername;
+ sprintf(filename, "%s/%c/%s", filePath, user[0], user);
+
+ i = stat(filename, &statBuffer);
+
+ // printf("%i filename: %s :: User: %18s :: %s\n", i, filename, name, user);
+
+ if(0 == i) {
+ theFile.open(filename, ios::in);
+
+ theFile >> name >> abuse >> playedTourneys >> wins >> losses >> draws
+ >> firsts >> seconds >> thirds >> rating >> placePoints
+ >> managerLevel >> managedTourneys >> last >> tourneyLocation;
+
+ theFile.close();
+
+ // printf("%i filename: %s :: User: %18s :: %s\n", i, filename, name, user);
+
+ return(1);
+ }
+
+ delete(lowername);
+
+ return(0);
+} //- End of LoadPlayer
+
+//- SavePlayer -----------------------------------------------------------
+void User::SavePlayer(char *filePath) {
+ char filename[MAXPATHLEN];
+ fstream theFile;
+
+ CreateDirectory(filePath, name);
+ sprintf(filename, "%s/%c/%s", filePath, name[0], name);
+
+ CalculateRating();
+
+ theFile.open(filename, ios::out);
+
+ printf("Saving=%s Abuse=%i\n", name, abuse);
+
+ theFile << name << " " << abuse << " " << playedTourneys << " "
+ << wins << " " << losses << " " << draws << " " << firsts << " "
+ << seconds << " " << thirds << " " << rating << " "
+ << placePoints << " " << managerLevel << " "
+ << managedTourneys << " " << last << " " << tourneyLocation
+ << endl;
+ theFile.close();
+} //- End of SavePlayer
+
+//- GetRating --------------------------------------------------------------
+float User::GetRating(void) {
+ return(rating);
+} //- End of GetRating
+
+int User::GetAbuse(void) {
+ return(abuse);
+}
+
+long User::GetWins(void) {
+ return(wins);
+}
+
+long User::GetLosses(void) {
+ return(losses);
+}
+
+long User::GetDraws(void) {
+ return(draws);
+}
+
+long User::GetFirsts(void) {
+ return(firsts);
+}
+
+long User::GetSeconds(void) {
+ return(seconds);
+}
+
+long User::GetThirds(void) {
+ return(thirds);
+}
+
+float User::GetPlacePoints(void) {
+ return(placePoints);
+}
+
+long User::GetPlayedTourneys(void) {
+ return(playedTourneys);
+}
+
+long User::GetManagedTourneys(void) {
+ return(managedTourneys);
+}
+
+long User::GetLast(void) {
+ return(last);
+}
+
+void User::SetLast(long n) {
+ last = n;
+}
+
+//- AddAbuse ---------------------------------------------------------------
+void User::AddAbuse(int num) {
+ abuse += num;
+ if(abuse < 0)
+ abuse = 0;
+} //- End of AddAbuse
+
+//- ResetAbuse -------------------------------------------------------------
+void User::ResetAbuse(void) {
+ abuse = ABUSE_RESET_VALUE;
+} //- End of ResetAbuse
+
+//- Start AddStat -----------------------------------------
+void User::AddStat(double i) {
+ if(i == 0.0) {
+ AddLoss();
+ } else if(i == 0.5) {
+ AddDraw();
+ } else if(i == 1.0) {
+ AddWin();
+ }
+}//- End AddStat -----------------------------------------
+
+//- Start AddStat -----------------------------------------
+void User::AddStat(int i) {
+ switch(i) {
+ case 1:
+ AddFirst();
+ break;
+ case 2:
+ AddSecond();
+ break;
+ case 3:
+ AddThird();
+ break;
+ default:
+ break;
+ }
+}//- End AddStat -----------------------------------------
+
+//- AddWin -----------------------------------------------------------------
+void User::AddWin(void) {
+ wins++;
+} //- End of AddWin
+
+//- AddLoss -----------------------------------------------------------------
+void User::AddLoss(void) {
+ losses++;
+} //- End of AddLoss
+
+//- AddDraw -----------------------------------------------------------------
+void User::AddDraw(void) {
+ draws++;
+} //- End of AddDraw
+
+//- AddFirst -----------------------------------------------------------------
+void User::AddFirst(void) {
+ firsts++;
+} //- End of AddFirst
+
+//- AddSecond -----------------------------------------------------------------
+void User::AddSecond(void) {
+ seconds++;
+} //- End of AddSecond
+
+//- AddThird -----------------------------------------------------------------
+void User::AddThird(void) {
+ thirds++;
+} //- End of AddThird
+
+//- AddPlayedTourney -------------------------------------------------------
+void User::AddPlayedTourney(void) {
+ playedTourneys++;
+} //- End of playedTourney
+
+//- SetStatistic ---------------------------------------------------------------
+int User::SetStatistic(int why, int newValue) {
+
+ switch (why) {
+ case 1:
+ playedTourneys = newValue;
+ break;
+ case 2:
+ wins = newValue;
+ break;
+ case 3:
+ losses = newValue;
+ break;
+ case 4:
+ draws = newValue;
+ break;
+ case 5:
+ firsts = newValue;
+ break;
+ case 6:
+ seconds = newValue;
+ break;
+ case 7:
+ thirds = newValue;
+ break;
+ case 8:
+ abuse = newValue;
+ break;
+ case 9:
+ rating = (float)newValue/100.0;
+ break;
+ case 10:
+ managedTourneys = newValue;
+ break;
+ default:
+ return 0;
+ break;
+ }
+
+ CalculateRating();
+ return 1;
+} //- End of SetStatistic
+
+//- CalculateRating ---------------------------------------------------------
+void User::CalculateRating(void) {
+ int games = (wins + losses + draws);
+
+ if((rating == 0.0) && ((wins + draws) > 0)) {
+ if(games != 0)
+ rating = (wins +(0.5 * draws)) / (games * 0.5);
+ }
+} //- End of CalculateRating
+
+//- CalculateRating ---------------------------------------------------------
+void User::CalculateRating(float tourn_expect, float pre_expect) {
+ if((tourn_expect + pre_expect) > 0)
+ rating = (wins + (draws * 0.5)) / (pre_expect + tourn_expect);
+} //-End of CalculateRating
+
+//- AddManagedTourney -------------------------------------------------------
+void User::AddManagedTourney(void) {
+ managedTourneys++;
+} //- End of AddManagedTourney
+
+//- ChangeManagerLevel ------------------------------------------------------
+void User::ChangeManagerLevel(int newLevel) {
+ managerLevel = newLevel;
+} //- End of ChangeManagerLevel
+
+//- CreateDirectory ---------------------------------------------------------
+void User::CreateDirectory(char *path, char *user) {
+ struct stat statBuffer;
+ char filename[MAXPATHLEN];
+
+ sprintf(filename, "%s/%c", path, user[0]);
+ if(-1 == stat(filename, &statBuffer)) {
+ switch(errno) {
+ case ENOENT:
+ if(-1 == mkdir(filename, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IXOTH)) {
+ switch(errno) {
+ case EACCES:
+ break;
+ case ENOENT:
+ break;
+ case ENOTDIR:
+ break;
+ }
+ }
+ break;
+ }
+ }
+} //- End of CreateDirectory
+
+//- GetMangerLevel ----------------------------------------------------------
+int User::GetManagerLevel(void) {
+ return(managerLevel);
+} //- End of GetManagerLevel
--- /dev/null
+//--------------------------------------------------------------------------
+// User.hh - Class header for the User class
+//
+// Matthew E. Moses
+//
+// $Revision: 1.8 $
+// $Date: 1998/09/10 19:58:41 $
+//
+// $Author: mlong $
+// $Locker: $
+//
+// $Log: User.hh,v $
+// Revision 1.8 1998/09/10 19:58:41 mlong
+// lots of little bug fixes and a few new features.
+//
+// Revision 1.7 1998/02/12 18:44:25 mlong
+// *** empty log message ***
+//
+// Revision 1.6 1997/04/13 03:21:32 chess
+// AddAbuse and SetStatistic added
+//
+// Revision 1.5 1997/04/07 22:22:12 chess
+// *** empty log message ***
+//
+// Revision 1.4 1997/03/27 13:45:28 chess
+// added functions to return user's statistics
+//
+// Revision 1.3 1997/03/21 15:29:53 moses
+// *** empty log message ***
+//
+// Revision 1.2 1996/10/01 20:14:43 moses
+// added methods
+//
+// Revision 1.1 1996/09/30 20:52:48 moses
+// Initial revision
+//
+//
+//--------------------------------------------------------------------------
+
+#ifndef _USER_
+#define _USER_
+
+#include <fstream.h>
+#include <iostream.h>
+
+extern "C" {
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <sys/stat.h>
+
+#include <time.h>
+#include <unistd.h>
+}
+
+#include "config.h"
+#include "link.hh"
+
+#ifndef NAMELEN
+#define NAMELEN 19
+#endif
+
+class User : public Link {
+public:
+
+ User();
+ User(char *, char *);
+ ~User();
+
+ int IsUser(char *);
+
+ void LoadPlayer(char *);
+ short LoadPlayer(char *, char *);
+
+ void SavePlayer(char *);
+
+ float GetRating(void);
+ int GetManagerLevel(void);
+
+ int GetAbuse(void);
+ long GetWins(void);
+ long GetLosses(void);
+ long GetDraws(void);
+ long GetFirsts(void);
+ long GetSeconds(void);
+ long GetThirds(void);
+ float GetPlacePoints(void);
+ long GetPlayedTourneys(void);
+ long GetManagedTourneys(void);
+ long GetLast(void);
+ void SetLast(long);
+
+ void AddAbuse(int);
+ void ResetAbuse(void);
+
+ void AddManagedTourney();
+ void ChangeManagerLevel(int);
+
+ void AddPlayedTourney();
+
+ int SetStatistic(int, int);
+
+ void AddStat(double);
+ void AddStat(int);
+ void CalculateRating(float, float);
+
+ private:
+ void CalculateRating(void);
+
+ void AddWin(void);
+ void AddLoss(void);
+ void AddDraw(void);
+
+ void AddFirst(void);
+ void AddSecond(void);
+ void AddThird(void);
+
+ void CreateDirectory(char *, char *);
+
+ public:
+
+ int inTourney;
+ char name[NAMELEN];
+
+ private:
+
+ int abuse;
+
+ long playedTourneys;
+
+ long wins;
+ long losses;
+ long draws;
+
+ long firsts;
+ long seconds;
+ long thirds;
+
+ float rating;
+ float placePoints;
+
+ int managerLevel;
+
+ long managedTourneys;
+
+ long last;
+ int tourneyLocation;
+};
+
+#endif
+
+
+
+
+
--- /dev/null
+/cleaner.pl/1.1/Mon Jul 1 23:55:37 2002//
+/hindex.pl/1.1/Mon Jul 1 23:55:37 2002//
+/rank.pl/1.1/Mon Jul 1 23:55:37 2002//
+D
--- /dev/null
+lasker/bots/mamer/bin
--- /dev/null
+#!/usr/local/bin/perl
+
+@dirList = ("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
+ "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z");
+
+foreach $i (@dirList) {
+ opendir(THISDIR, "/Users/mlong/mamer/players/$i");
+ @tempdir = sort(readdir(THISDIR));
+ close(THISDIR);
+
+ foreach $file (@tempdir) {
+## print ("FILE = :$file:\n");
+ if($file !~ /\.$/) {
+ if($file =~ /\s*/) {
+ print("unlink :$file :\n");
+ unlink("/Users/mlong/mamer/players/$i/$file");
+ }
+ }
+ }
+}
--- /dev/null
+#!/usr/local/bin/perl
+
+$dirpath = "/home/mlong/mamer/help/";
+
+opendir(FILELIST, "$dirpath");
+@allfiles = readdir(FILELIST);
+closedir(FILELIST);
+
+open(OUT, ">$dirpath/index");
+$i = 0;
+$j = 0;
+$offset = $#allfiles/4;
+@allfiles = sort @allfiles;
+foreach $a (@allfiles) {
+ if($allfiles[$i] !~ /\./) {
+ $temp[$j] = $allfiles[$i];
+ $j++;
+ }
+ $i++;
+}
+@allfiles = @temp;
+$i = 0;
+#print OUT "$#allfiles files listed\n";
+while ($i <= ($#allfiles/4)) {
+ printf OUT
+ (" %-18s %-18s %-18s %-18s\n",
+ $allfiles[$i], $allfiles[$i+($offset*1)],
+ $allfiles[$i+($offset*2)], $allfiles[$i+($offset*3)]);
+ $i++;
+}
+#print OUT "\n";
+close(OUT);
--- /dev/null
+#!/usr/local/bin/perl
+
+$PLAYER_DATA_PATH = "/home/mlong/mamer/players";
+$OUTFILE = "/home/mlong/mamer/data/rank.new";
+
+# you should not have to change this its just where it belongs
+@dirList = ("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
+ "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "_");
+
+&main();
+
+sub main {
+ foreach $a (@dirList) {
+ if(-d "$PLAYER_DATA_PATH/$a") {
+# printf("$PLAYER_DATA_PATH/$a\n");
+ opendir(THISDIR, "$PLAYER_DATA_PATH/$a");
+ @tempdir = sort(readdir(THISDIR));
+ close(THISDIR);
+
+ foreach $file (@tempdir) {
+ if(!(-d "$PLAYER_DATA_PATH/$a/$file")) {
+# printf ("Converting %s %s\n", $file, $PLAYER_DATA_PATH);
+ open(IN, "$PLAYER_DATA_PATH/$a/$file") || die "Can't open $file\n";
+ while($line = <IN>) {
+ chop($line);
+ ($n, $abuse, $tourneys, $w, $l, $d, $fsts, $scds, $thds, $rating,
+ $placePoints, $managerLevel, $managedTourneys, $last, $tourneyLocation) = split(/ /, $line);
+ if($tourneys > 4) {
+ $rank{$n} = "$rating $n $tourneys";
+ }
+ }
+ close(IN);
+ }
+ }
+ }
+ }
+ $i = 0;
+ $last = 0;
+ foreach $a (reverse (sort (values %rank))) {
+ ($b, $c, $d) = split(/ /, $a);
+ if($b != $last) {
+ $i++;
+ $last = $b;
+ }
+ open(OUT, ">>$OUTFILE") || die "Can't open $OUTFILE\n";
+ printf OUT ("%-18s %d %4.2f\n", $c, $d, $b);
+ close(OUT);
+ }
+}
+
--- /dev/null
+//--------------------------------------------------------------------------
+// command_list.h - List of all the commands for mamer and their respective
+// parameter lists.
+//
+// Matthew E. Moses & Michael A. Long
+//
+// $Revision: 1.2 $
+// $Date: 1997/10/08 21:03:08 $
+//
+// $Author: chess $
+// $Locker: $
+//
+// $Log: command_list.h,v $
+// Revision 1.2 1997/10/08 21:03:08 chess
+// no log message
+//
+// Revision 1.1 1997/04/08 23:12:33 chess
+// Initial revision
+//
+//
+//--------------------------------------------------------------------------
+
+#ifndef _COMLIST_
+#define _COMLIST_
+
+/*
+ Parameter string format
+ w - a word
+ o - an optional word
+ d - integer
+ p - optional integer
+ i - word or integer
+ n - optional word or integer
+ s - string to end
+ t - optional string to end
+
+ If the parameter option is given in lower case then the parameter is
+ converted to lower case before being passsed to the function. If it is
+ in upper case, then the parameter is passed as typed.
+ */
+
+
+/***********************
+ * Command List *
+ ***********************/
+t_cmds commands[] = {
+ {"abort", "d", AbortTourney, MANAGER },
+ {"addabuse", "w", AddAbuse, MANAGER },
+ {"announce", "d", AnnounceTourney, MANAGER },
+ {"best", "", ListBest, USER },
+ {"close", "d", CloseTourney, MANAGER },
+ {"finger", "o", FingerUser, USER },
+ {"forfeit", "wd", ForfeitUser, MANAGER },
+ {"games", "d", ListGamesInTourney, USER },
+ {"grid", "d", ListGridForTourney, USER },
+ {"help", "o", Help, USER },
+ {"info", "p", ListTourneyInfo, USER },
+ {"join", "d", JoinTourney, USER },
+ {"last", "", LastFinishedTourneys, USER },
+ {"load", "o", LoadSavedTourney, MANAGER },
+ {"loadedusers", "", LoadedUsers, MANAGER },
+ {"manage", "d", ManageTourney, MANAGER },
+ {"managers", "", ListManagers, USER },
+ {"messman", "", MessageManagers, SUPERMANAGER },
+ {"newmgr", "w", AddManagerToList, SUPERMANAGER },
+ {"open", "d", OpenTourney, MANAGER },
+ {"pairings", "d", PairingsInTourney, USER },
+ {"players", "d", ListPlayersInTourney, USER },
+ {"pose", "wT", PoseAsMamer, PRESIDENT },
+ {"quit", "", Shutdown, SUPERMANAGER },
+ {"rank", "o", RankUser, USER },
+ {"reopen", "d", ReopenTourney, MANAGER },
+ {"resetabuse", "w", ResetAbuse, SUPERMANAGER },
+ {"results", "d", ResultsFromTourney, USER },
+ {"rmmgr", "w", DeleteManagerFromList, SUPERMANAGER },
+ {"set", "wn", SetVariable, MANAGER },
+ {"setlevel", "wd", SetManagerLevel, SUPERMANAGER },
+ {"setres", "dwwd", SetResult, MANAGER },
+ {"setscore", "dwd", SetScore, MANAGER },
+ {"standings", "d", ListStandingsTourney, USER },
+ {"start", "d", StartTourney, MANAGER },
+ {"subabuse", "d", SubtractAbuse, SUPERMANAGER },
+ {"tourneys", "", ListTourneys, USER },
+ {"unmanage", "d", UnmanageTourney, MANAGER },
+ {"uncensor", "w", UncensorUser, SUPERMANAGER },
+ {"version", "", ShowVersion, USER },
+ {"who", "d", ListPlayerInTourney, USER },
+ {"withdraw", "d", WithdrawFromTourney, USER },
+ {"worst", "", ListWorst, USER },
+ { NULL, NULL }
+};
+
+
+/************************
+ * Command Aliases *
+ ************************/
+t_cmds aliases[] = {
+ {"abor", do_abort },
+ {"adda", do_addabuse },
+ {"ann", do_announce },
+ {"cl", do_close },
+ {"fi", do_finger },
+ {"for", do_forfeit },
+ {"ga", do_games },
+ {"gr", do_grid },
+ {"he", do_help },
+ {"inf", do_set },
+ {"mm", do_messman },
+ {"op", do_open },
+ {"pair", do_games },
+ {"pl", do_players },
+ {"po", do_pose },
+ {"qui", do_quit },
+ {"reopen", do_reopen },
+ {"reseta", do_resetabuse },
+ {"resu", do_results },
+ {"rm", do_rmmgr },
+ {"setl", do_setlevel },
+ {"setr", do_setres },
+ {"sets", do_setscore },
+ {"stand", do_standings },
+ {"suba", do_subabuse },
+ {"unm", do_unmanage },
+ {"unc", do_uncensor },
+ {"ver", do_version },
+ {"wo", do_worst },
+ {NULL, NULL }
+};
+
+
+#endif
--- /dev/null
+ //--------------------------------------------------------------------------
+// config.h - default configuration parameters if the config file doesn't
+// exist, or the value isn't in the config file. Can be
+// overridden during the build by using the DEFINES flags.
+//
+// Matthew E. Moses & Michael A. Long
+//
+// $Revision: 1.5 $
+// $Date: 1998/09/10 19:58:20 $
+//
+// $Author: mlong $
+// $Locker: $
+//
+// $Log: config.h,v $
+// Revision 1.5 1998/09/10 19:58:20 mlong
+// *** empty log message ***
+//
+// Revision 1.4 1998/06/18 18:42:09 mlong
+// prepairing for yet another move.
+//
+// Revision 1.3 1998/04/18 19:00:07 mlong
+// y
+//
+// Revision 1.2 1997/10/08 21:03:08 chess
+// no log message
+//
+// Revision 1.1 1996/09/30 20:52:48 moses
+// Initial revision
+//
+//
+//--------------------------------------------------------------------------
+
+#ifndef _CONFIG_
+#define _CONFIG_
+
+#ifndef CONFIG_FILENAME
+#define CONFIG_FILENAME "./mamer.config"
+#endif
+
+#ifndef DEFAULT_PATH
+#define DEFAULT_PATH "/home/mlong/mamer"
+#endif
+
+#ifndef DEFAULT_HELP_FILE_PATH
+#define DEFAULT_HELP_FILE_PATH "help"
+#endif
+
+#ifndef DEFAULT_DATA_PATH
+#define DEFAULT_DATA_PATH "data"
+#endif
+
+#ifndef DEFAULT_LOG_FILE
+#define DEFAULT_LOG_FILE "logs/mamer"
+#endif
+
+#ifndef DEFAULT_USER_PATH
+#define DEFAULT_USER_PATH "players"
+#endif
+
+#ifndef DEFAULT_HOSTNAME
+#define DEFAULT_HOSTNAME "ics.onenet.net"
+#endif
+
+#ifndef DEFAULT_PORT
+#define DEFAULT_PORT 5000
+#endif
+
+#ifndef DEFAULT_CHANNEL
+#define DEFAULT_CHANNEL 49
+#endif
+
+#ifndef DEFAULT_USERNAME
+#define DEFAULT_USERNAME "mamertesti"
+#endif
+
+#ifndef DEFAULT_PASSWORD
+#define DEFAULT_PASSWORD "fkdi29s"
+#endif
+
+#ifndef ABUSE_INCREMENT_VALUE
+#define ABUSE_INCREMENT_VALUE 1
+#endif
+
+#ifndef ABUSE_RESET_VALUE
+#define ABUSE_RESET_VALUE 5
+#endif
+
+#ifndef FIRSTPLACEVALUE
+#define FIRSTPLACEVALUE 5
+#endif
+
+#ifndef MAX_ROUNDS
+#define MAX_ROUNDS 10
+#endif
+
+#ifndef MAX_INCREMENT
+#define MAX_INCREMENT 60
+#endif
+
+#ifndef MAX_TIME
+#define MAX_TIME 9000
+#endif
+
+#ifndef DEFAULT_MAX_PLAYERS
+#define DEFAULT_MAX_PLAYERS 16
+#endif
+
+#ifndef DEFAULT_TIME
+#define DEFAULT_TIME 4
+#endif
+
+#ifndef DEFAULT_INCREMENT
+#define DEFAULT_INCREMENT 0
+#endif
+
+#ifndef DEFAULT_ROUNDS
+#define DEFAULT_ROUNDS 0
+#endif
+
+#ifndef PENALTY_PER_ROUND
+#define PENALTY_PER_ROUND 10
+#endif
+
+#ifndef KEEP_TOURNEY_TIME
+#define KEEP_TOURNEY_TIME 7200
+#endif
+
+#ifndef SEC_BETWEEN_CSHOUTS
+#define SEC_BETWEEN_CSHOUTS 240
+#endif
+
+#ifndef MAX_CHAOS_POINTS
+#define MAX_CHAOS_POINTS 100
+#endif
+
+// MINIMUM_ROUNDS should always be less than MINIMUM_PLAYERS
+
+#ifndef MINIMUM_ROUNDS
+#define MINIMUM_ROUNDS 3
+#endif
+
+#ifndef MINIMUM_PLAYERS
+#define MINIMUM_PLAYERS 4
+#endif
+
+#endif
+
+
+
--- /dev/null
+/managers/1.1/Mon Jul 1 23:55:42 2002//
+D
--- /dev/null
+lasker/bots/mamer/data
--- /dev/null
+/about/1.1/Mon Jul 1 23:55:47 2002//
+/addchaos/1.1/Mon Jul 1 23:55:47 2002//
+/addtotourney/1.1/Mon Jul 1 23:55:47 2002//
+/announce/1.1/Mon Jul 1 23:55:47 2002//
+/chaos/1.1/Mon Jul 1 23:55:47 2002//
+/close/1.1/Mon Jul 1 23:55:47 2002//
+/create/1.1/Mon Jul 1 23:55:47 2002//
+/delete/1.1/Mon Jul 1 23:55:47 2002//
+/finger/1.1/Mon Jul 1 23:55:47 2002//
+/forfeit/1.1/Mon Jul 1 23:55:47 2002//
+/help/1.1/Mon Jul 1 23:55:47 2002//
+/index/1.1/Mon Jul 1 23:55:47 2002//
+/join/1.1/Mon Jul 1 23:55:47 2002//
+/keep/1.1/Mon Jul 1 23:55:47 2002//
+/listmanagers/1.1/Mon Jul 1 23:55:47 2002//
+/listplayers/1.1/Mon Jul 1 23:55:47 2002//
+/listtourneys/1.1/Mon Jul 1 23:55:47 2002//
+/listtourneyvars/1.1/Mon Jul 1 23:55:47 2002//
+/loadedusers/1.1/Mon Jul 1 23:55:47 2002//
+/manager_commands/1.1/Mon Jul 1 23:55:47 2002//
+/manager_help/1.1/Mon Jul 1 23:55:47 2002//
+/manager_level/1.1/Mon Jul 1 23:55:47 2002//
+/messman/1.1/Mon Jul 1 23:55:47 2002//
+/open/1.1/Mon Jul 1 23:55:47 2002//
+/performance/1.1/Mon Jul 1 23:55:47 2002//
+/rating/1.1/Mon Jul 1 23:55:47 2002//
+/setcommandlevel/1.1/Mon Jul 1 23:55:47 2002//
+/setmanagerlevel/1.1/Mon Jul 1 23:55:47 2002//
+/setres/1.1/Mon Jul 1 23:55:47 2002//
+/setstat/1.1/Mon Jul 1 23:55:47 2002//
+/settourneyvar/1.1/Mon Jul 1 23:55:47 2002//
+/showcommands/1.1/Mon Jul 1 23:55:47 2002//
+/showhelpfile/1.1/Mon Jul 1 23:55:47 2002//
+/shutdown/1.1/Mon Jul 1 23:55:47 2002//
+/swiss/1.1/Mon Jul 1 23:55:47 2002//
+/upset/1.1/Mon Jul 1 23:55:47 2002//
+/user_commands/1.1/Mon Jul 1 23:55:47 2002//
+/who/1.1/Mon Jul 1 23:55:47 2002//
+/withdraw/1.1/Mon Jul 1 23:55:47 2002//
+D
--- /dev/null
+lasker/bots/mamer/help
--- /dev/null
+ NOTE: This file dates back to 1996, and some of the information in it
+ is no longer accurate. However, it has been preserved because it
+ contains interesting historical information.
+
+ This program is an automated Tournament Direct for use with online
+ Chess servers mainly FICS. If it is used with anything other than
+ FICS at this time it will crash with out question. It is programmed
+ to respond to the parsing of FICS text only. Fred Baumgarten
+ originally wrote this code because there was a need and Chevier Joel
+ the creator of Tomato would not share the code. Fred gave me the code
+ in mid 1995 with the stipulation I not release it to anyone. I
+ have modified and (I hope) improved mame (now mamer).
+ Jean (current programmer of Tomato) and I are working very
+ closely on developing similar features and improving both tournament
+ directors. Our current project is to create a rating system that will
+ be used by both Mamer and Tomato.
+
+ Mamer stands for "manage me". Plus the -r- for the
+ differentiation between mame (Fred's) code and mamer (mlong's) code.
+ Fred's words follow: The intention to write this tournament director
+ program came out of the need to have such a program. Tomato - used at
+ FICS and written by darkside was not released to the public. Darkside
+ even did not want to accept a non disclosure agreement - so I decided
+ to write such a program myself. The program is written in C and will
+ support a bunch of new features soon. It is beta state since Version
+ 0.5 but there _are_ bugs.
+ Fred Baumgarten <dc6iq@insl1.etec.uni-karlsruhe.de>. Have fun !!!
+
+ Mamer is maintained and coded here on FICS by mlong. PLEASE! FOR BUGS
+ PERTAINING TO MAMER TALK TO mlong.
+
+[Last modified: September 12, 1998 -- toddmf]
--- /dev/null
+addchaos
+
+Alias: ac
+
+Usage: addchaos <handle> <points>
+
+Reserved for mamer managers (level of 25 or higher)
+
+Use this command to give <points> chaos points to <handle>. If you do not
+specify the number of points, 1 will be added. To take chaos points away, add
+a negative number of chaos points ("addchaos abc -10" removes 10 of abc's
+chaos points).
+
+See also: chaos
+
+[Last modified: August 29, 1998 -- toddmf]
--- /dev/null
+addtotourney
+
+Alias: att
+
+Usage: addtotourney <handle> <tourney number>
+
+Reserved for mamer managers (level of 50 or higher)
+
+This command forces <handle> to join the specified tourney number. Its main
+usage is to quickly create a test tourney, but it can also be used to get a
+player new to mamer in to a tourney that is about to start when he/she cannot
+figure out how to join. If you use this command in this fashion, please
+inform the player how to join future tourneys so that the player does not rely
+on managers to add him/her to the tourney.
+
+See also: join
+
+[Last modified: August 29, 1998 -- toddmf]
--- /dev/null
+announce
+
+Alias: ann
+
+Usage: announce <tourney number>
+
+Reserved for mamer managers (level 10 or higher)
+
+The announce command causes the specified tourney to be announced in channel
+49. The tourney announcement looks like this:
+
+mamer(TD)(49): *****Tourney Announcement*****
+\ Trny #5 3 0 r SWISS 0-9999 6 plr(s). tell mamer join 5. Avg: 1543.5
+
+This announcement is also cshouted when the tourney is opened, but "announce"
+will only cshout the announcement once every four minutes. Please do not spam
+channel 49 with tourney announcements; 1 or 2 per minute is sufficient.
+
+[Last modified: September 12, 1998 -- toddmf]
--- /dev/null
+chaos
+
+Chaos points are gained for disrupting a tourney and lost when you complete a
+tourney successfully. If you are forfeited or withdraw from a tourney in
+progress, you will gain 10 chaos points for every game you miss. Other
+tourney disruptions, including(but not limited to) profanity, playing
+non-tourney games, and misuse of the the tourney channel(telling channel 49
+"hi mamer" repeatedly, for example) will usually be rewarded with 10 to 20
+chaos points at the manager's discretion. If you are given chaos points by
+the manager, you will be sent a message explaining why you gained the points.
+If you feel you have been unfairly given chaos points, contact mamer's Chief
+Operating Officer(currently toddmf). If you complete a tourney without
+withdrawing or being forfeited, you will lose one chaos point per round
+played. If you reach 100 chaos points, mamer will censor you, preventing you
+from playing in mamer tournaments. You can check how many chaos points you
+have by using mamer's "finger" command(type "mam finger").
+
+See also: finger, forfeit, withdraw
+
+[Last modified: September 1, 1998 -- toddmf]
--- /dev/null
+close
+
+Alias: cl
+
+Usage: close <tourney number>
+
+Reserved for mamer managers (level 10 or higher)
+
+This command closes the specified tourney and starts it, preventing more
+players from joining. If the amount of players who have joined reaches the
+"Max Players" set in the tourney's variables, the tourney will close and start
+automatically.
+
+See also: listtourneyvars, settourneyvar
+
+[Last modified: August 29, 1998 -- toddmf]
--- /dev/null
+create
+
+Usage: create
+
+Alias: cr
+
+Reserved for mamer managers (level of 10 or higher)
+
+This command creates a new tourney and assigns it a tourney number.
+
+[Last modified: July 31, 1998 -- toddmf]
+
--- /dev/null
+delete
+
+Alias: del
+
+Usage: delete <tourney number>
+
+Use the "delete" command to delete the specified tourney. The most common
+usage of this is to delete a tourney in which there are not enough players to
+close and start. Mamer deletes tourneys that are not "kept" two hours after
+their completion. Please do not delete the tourneys before then, as many
+users view the standings of recent tourneys.
+
+See also: close, keep
+
+[Last modified: August 29, 1998 -- toddmf]
--- /dev/null
+finger
+
+Alias: fi
+
+Usage: finger <optional handle>
+
+Use the "finger" command to find out a player's mamer statistics. If you do
+not specify the handle, you will see your own statistics. Here is a sample
+"finger":
+
+:toddmf's Stats:
+:
+:Name Tnys W L D 1st 2nd 3rd Chaos Rating
+:----------------- ----- ---- ---- --- --- --- --- ----- ------
+:toddmf 751 1894 767 133 355 219 0 0 1.41
+:
+:Manager Level: 75
+
+"Name" is the handle of the player you are fingering.
+"Tnys" is the number of tourneys he/she has played in.
+"W" is the number of games he/she has won in tourneys.
+"L" is the number of games he/she has lost in tourneys.
+"D" is the number of games he/she has drawn in tourneys.
+"1st" is the number times he/she has finished in or tied for first place.
+"2nd" is the number times he/she has finished in or tied for second place.
+"3rd" is the number times he/she has finished in or tied for first place.
+"Chaos" is the number of Chaos Points he/she has.
+"Rating" is the player's mamer rating.
+"Manager Level" is only displayed for mamer managers.
+
+
+NOTE: "3rd"s have been recorded for a much shorter time than "1st"s and
+ "2nd"s. Thus, many players have finished in 3rd more than the amount
+ of times indicated.
+
+See also: chaos, manager_level, mamer_rating
+
+[Last modified: August 29, 1998 -- toddmf]
--- /dev/null
+forfeit
+
+Alias: fo
+
+Usage: forfeit <handle> <tourney number>
+
+Reserved for mamer managers (level 10 or higher)
+
+The "forfeit" command forfeits the specified handle from the specified
+tourney. If a player is forfeited from an open tourney, he is removed from the
+tourney with no penalty. If the tourney is in progress when the player is
+forfeited, the player will gain chaos points equal to 10 times the number of
+rounds he/she missed. Please remove these chaos points if you feel they are
+unwarranted. If the tourney is in progress and it is a round robin, the
+results of the player's games are all set to 0-0. If the tourney is in
+progress and it is a swiss, the player's results for completed games stand,
+but he/she loses all uncompleted games by forfeit.
+
+See also: chaos, swiss
+
+[Last modified: September 1, 1998 -- toddmf]
--- /dev/null
+help
+
+Alias: h
+
+Usage: help
+
+This command displays a list of all of mamer's commands, their aliases, the
+minimum manager level needed to use them, and a short summary of the command's
+function. If you are not a mamer manager, you can use the commands marked as
+level 0 commands.
+
+NOTE: The "help" command is equivalent to the "showcommands" command.
+
+See also: manager_level, showcommands, usage
+
+[Last modified: August 29, 1998 -- toddmf]
--- /dev/null
+ about forfeit manager_commands settourneyvar
+ addchaos help manager_help showcommands
+ addtotourney index manager_level showhelpfile
+ announce join messman shutdown
+ chaos keep open swiss
+ close listmanagers performance upset
+ create listplayers rating user_commands
+ delete listtourneys setmanagerlevel who
+ finger listtourneyvars setres withdraw
+ forfeit loadedusers setstat
--- /dev/null
+join
+
+Alias: j
+
+Usage: join <tourney number>
+
+Use this command to join the specified tourney. You can only join an open
+tourney. To find a list of open tourneys, use the "listtourneys" command and
+look for tourneys with a status of "open".
+
+See also: listtourneys
+
+[Last modified: August 29, 1998 -- toddmf]
--- /dev/null
+keep
+
+Alias: k
+
+Usage: keep <tourney number> <boolean>
+
+This command is used to edit the "keep" status of a tourney. If the keep
+status is true, mamer will not automatically delete the tourney. If it is
+false, mamer will automatically delete the tourney two hours after its
+completion. "keep # 1" or "keep # y"(y is short for yes) will set the keep
+status to true. Using anything else but 1 or y will set it to false. This
+command is most commonly used to save a scheduled tourney or a tourney with
+bugs so that it can be examined later.
+
+See also: delete
+
+[Last modified: August 29, 1998 -- toddmf]
--- /dev/null
+listmanagers
+
+Alias: lm
+
+Usage: listmanagers
+
+This command displays a list of all the managers, their manager level, the
+total number of tourneys they have managed, and the date of the last tourney
+they managed. Managers marked with a "+" before their handle are currently
+online.
+
+See also: manager_level
+
+[Last modified: August 29, 1998 -- toddmf]
--- /dev/null
+listplayers
+
+Alias: lp
+
+Usage: listplayers <tourney number>
+
+This command lists all the players in the specified tourney and other
+information about the players in the tourney.
+
+: Name Rating Score Perfrm Upset Results
+: ----------------- ------ ----- ------ ------ -------
+: 1 +ghettoCHECKMATE [1651] 3.0 [2242] [ 573] +07b +02b +04w
+: 2 +TheOnlyOne [1914] 2.0 [1764] [ 0] +03b -01w +05w
+: 3 +westham [1725] 2.0 [1843] [ 47] -02w +04b +06w
+: 4 +frankenschach [1772] 1.0 [1497] [ 0] +05w -03w -01b
+: 5 +Arbakov [1516] 1.0 [1443] [ 0] -04b +06w -02b
+: 6 +Ostap [forf] 0.0 [1251] [ 0] -01w
+:
+: Average Rating 1736.3
+
+The number in the leftmost column is the player's current ranking in the
+tourney.
+
+"Name" is the player's handle. A "+" to the left indicates that the player is
+ currently logged in. A "-" indicates that he is not.
+"Rating" is the player's FICS rating before the tourney started in the
+ category of games played in the tourney. "forf" means the player is no
+ longer in the tourney.
+"Score" is the number of tourney points the player has. 1.0 is awarded for
+ each win, 0.5 for each draw, and 0.0 for each loss.
+"Perfrm" is the player's performance rating for the tourney.
+"Upset is the number of upset points the player has.
+"Results" is a grid of the tourney results. "+" represents a win, "="
+ represents a draw, and "-" represents a loss. The number following is
+ the ranking of the opponent in the tourney(see the leftmost column).
+ The letter following that is the color played. "b" is black; "w" is
+ white.
+"Average Rating" is the average rating of all the players in the tourney.
+ The ratings used are ratings when the players join the tourney.
+
+NOTE: This command is the same as the "who" command.
+
+See also: performance, upset, who
+
+[Last modified: August 29, 1998 -- toddmf]
--- /dev/null
+listtourneys
+
+Alias: lt
+
+Usage: listtourneys
+
+This command lists all tourneys in mamer's memory. This includes all tourneys
+currently open, all tourneys in progress, recent tourneys that have ended,
+and tourneys that have been marked for saving. Here is a sample tourney list:
+
+:mamer Notes:
+: No. Rds Sty Time Inc Md Vrnt Rtng Rnge Status Started at Ended at
+: --- --- --- ---- --- -- ---- --------- ------ ---------- --------
+: 1 3 r 3 0 r r 0-9999 done 00:23 08/30/98 00:58 08/30/98
+: 2 3 s 3 0 r r 0-9999 closed 01:00 08/30/98 n/a
+: 3 0 s 0 1 u s 0-9999 open n/a n/a
+
+
+"No." indicates the tourney number.
+"Rds", "Sty", "Time", "Inc", "Md", "Vrnt", and "Rtng Rnge" are
+ variables that determine who may join a tourney and the type of games
+ played in the tourney. See "mam help listtourneyvars" for more detailed
+ information about these variables.
+"Status" indicates the current status of the tourney: open, closed, or done.
+"Started at" indicates the time(using server time) and date the tourney
+ started. n/a indicates that the tourney has not yet started.
+"Ended at" indicates the time(using server time) and date the tourney ended.
+ n/a indicates that the tourney has not yet ended.
+
+See also: listtourneyvars
+
+[Last modified: August 29, 1998 -- toddmf]
--- /dev/null
+listtourneyvars
+
+Alias: vars <tourney number>
+
+Usage: listtourneyvars
+
+This command lists thr variables for the specified tourney number. Here is a
+sample variable listing:
+
+: (T)ime: 4
+: (I)ncrement: 0
+: (R)ounds: 0
+: Max (P)layers: 16
+: (M)ode: r (r)ated or (u)nrated
+: (S)tyle: s (s)wiss or (r)oundrobin
+: (V)ariant: w (w)ild, (r)egular, (b)ug, or (s)uicide
+: (W)ild Type: 10 (0), (1), (2), (3), (4), (5), (8), (9)8a, (10)fr
+: Rating (L)ow: 0
+: Rating (H)igh: 9999
+:
+: Manager: toddmf
+
+The letters in () refer to the variable shortcut to be used when changing a
+value for a variable. Here is what the variables mean:
+
+ Time -- Same as always: minutes to start the game with
+ Increment -- Same as always: additional seconds per move
+ Rounds -- Number of rounds in the tourney. If this is 0, mamer will
+ choose an optimal number of rounds.
+ Max Players -- The tourney will automatically close and start when this
+ many players have joined.
+ Mode -- Will the tourney games be rated or unrated?
+ Style -- Round Robin(everyone plays everyone) or Swiss System(system
+ where, generally speaking, players play opponents with the
+ same score in the tourney each round).
+ Variant -- What type of game is being played? Regular is used for
+ blitz, standard, and lightning.
+ Wild Type -- This only appears when Variant is set to Wild. This is the
+ type of wild that will be played.
+ Rating Low -- Players with a rating lower than this cannot join.
+ Rating High -- Players with a rating higher than this cannot join.
+ Manager -- The handle of this tourney's manager.
+
+See also: settourneyvar, swiss
+
+[Last modified: September 1, 1998 -- toddmf]
--- /dev/null
+loadedusers
+
+Alias: lu
+
+Usage: loadedusers
+
+Reserved for mamer managers (level 25 or higher)
+
+This command lists all players who have sent mamer a tell since it has been
+logged in. This can be used to find out if a player who is having trouble
+using mamer has even reached the point of sending a tell to it.
+
+[Last modified: August 29, 1998 -- toddmf]
--- /dev/null
+manager_commands
+
+addchaos | ac | 25 | Adds (or subs) chaos points.
+announce | ann | 10 | Announce the tournament to the working
+\ channel.
+addtotourney | att | 50 | Add a user to a tourney.
+create | cr | 10 | Creates a new tournament.
+close | cl | 10 | Closes and starts a tournament.
+delete | del | 10 | Deletes a tournament.
+forfeit | fo | 10 | Remove a user from a tourney.
+keep | k | 25 | Keep a tourney in memory.
+listrank | rank | 100 | Displays player rank.
+loadedusers | lu | 25 | Displays the loaded users.
+messman | mm | 50 | Message all of the Managers.
+open | ot | 10 | Opens the tournament to players.
+setinfo | si | 100 | Set a user's finger info.
+setmanagerlevel | sml | 50 | Sets manager's level.
+setres | sr | 10 | Sets the result of a game.
+setstat | ss | 50 | Sets a specific finger stat.
+settourneyvar | stv | 10 | Sets a Tourney's Variables.
+shutdown | sd | 50 | Shuts down Mamer.
+
+[Last modified: September 1, 1998 -- toddmf]
--- /dev/null
+New mamer manager help file
+
+This file contains portions of server help files(written by Friar) and mamer
+help files(written by mlong) relevant to new mamer managers. toddmf merged
+these files, updated out of date information, added some new things, and
+removed some contradictions, hopefully resulting in a file useful for new mamer
+managers. With the release of mamer 2.0, much of this document has been
+rewritten by toddmf. Send questions, comments, suggestions, etc. to toddmf.
+
+Introduction and general server considerations
+----------------------------------------------
+
+ Congratulations on becoming a mamer manager! You have earned this position
+through your high level of maturity and interest in FICS chess(tournaments in
+particular). Less than 1% of FICS users have been given the honor of being a
+TM. That being said, being a TM is also a responsibility. It is essential that
+you continue to maintain a higher standard of maturity than most users for
+several reasons. The most obvious situations are problems in tourneys. Users
+often get angry or impatient for several reasons during a tourney. For example:
+User has just been given chaos points, user is angry because he was flagged in
+a drawn game, user strongly disagrees with mamer policy, etc. In these
+situations, it is necessary for you to stay calm, be competent, and keep
+channel 49 and/or the tourney under control without reacting too harshly.
+Another reason is that TMs are often mistaken for admins, especially by
+new/intermediate users. Please kindly help them if possible, but refer them to
+an admin if one really is necessary.
+
+Expectations
+------------
+
+ Apart from staying out of trouble on FICS, the only requirement that you must
+meet in order to remain a mamer manager is to meet a monthly quota for tourneys
+managed. Currently, it is 5 tourneys per month. This is only a minimum,
+though. Feel free to manage as many as you like. This is fun, remember? :)
+This quota does not apply to admins, several of whom only manage when there is
+a need for a tourney and no other TMs are online. The quota is in place in
+order to keep the manager staff active. If you are unable to remain active as
+a manager temporarily, message the COO(currently toddmf) and explain why. If
+you plan on being inactive for a long period of time(at least 3 months, or
+longer than summer break for students), it is probably best if you step down as
+TM(if you've done well as a TM you would probably be able to return as TM when
+you return to FICS).
+
+Mamer's user commands
+---------------------
+
+ Before you get to the the details of manager commands and how to manage a
+tourney, you should first make sure you are well equipped to deal with users'
+questions about how to use mamer. If you are unfamiliar with any of these
+commands, you should try them.
+
+ Command Abbrev Level Basic info
+ ---------------------------------------------------------------------
+ finger | fi | 0 | Displays the stats for a user.
+ help | h | 0 | List commands and descripts.
+ join | j | 0 | Request to enter a tourney.
+ listmanagers | lm | 0 | Displays the Managers list.
+ listtourneys | lt | 0 | Displays the tournament list.
+ listtourneyvars | vars | 0 | Displays the tournament variables.
+ listtourneygames | games | 0 | Displays the tournament games.
+ listplayers | lp | 0 | Displays the players in the tourney.
+ showcommands | sc | 0 | List commands and descripts.
+ showhelpfile | shf | 0 | Shows a help file.
+ who | who | 0 | Displays the tournament games.
+ withdraw | with | 0 | Remove yourself from a tourney.
+
+User commands notes:
+ The "finger" command shows your statistics by default. You can see other
+ players' stats by "mam finger name".
+
+ "help" is the same as "showcommands". To see help files, use "showhelpfile".
+
+ The old commands "grid" and "standings" are now all neatly packaged in the
+ "who" command. The players are listed in rank order.
+
+ The "upset points" in the "who" listing are temporary points(they are deleted
+ when the tourney is deleted). They are calculated like this: If you beat a
+ higher rated player, you get the difference in rating in upset points. If you
+ draw a higher rated player, you get half the difference in rating points,
+ rounded down. For example, a 2000 who beats a 2101 gets 101 upset points. If
+ he had drawn, the 2000 would have gained 50 upset points. Ratings from when
+ the players join the tourney are used.
+
+ The "Perfrm" (performance rating) in the "who" listing is a measure of what
+ the player's USCF(and several other similar systems) rating would be if this
+ was the only tourney he played in. Again, the ratings from when the players
+ join the tourney are used. Here is the formula:
+
+ Perf. Rating = Avg. opp. rating + 400 * ((wins-losses)/rounds)
+
+ Most commands now require you to specify the tourney number! Remember this
+ when giving help.
+
+ Players very often ask about how to find out who is in a tourney, how to see
+ the standings, how to see a grid, how to see which games are in progress, and
+ how to see tourney variables. It is useful to have an alias for telling 49
+ something along the lines of "Please use the commands 'mam games #',
+ 'mam vars #', and 'mam who #' for information about the tourney."
+
+Introduction to managing tourneys
+---------------------------------
+
+ The first thing you should do after becoming a manager is to join channel
+48. You can ask for the advice of more experienced TMs in the channel if you
+run in to any problems while managing. Channel 48 is also used to discuss
+other mamer issues, and it is just as often used for friendly chat among TMs.
+Here is a tutorial on how to manage a typical tourney.
+
+The first thing you need to know is that you will be sending a lot of tells to
+mamer while managing. To save yourself some typing, you should either use the
+server alias "mam"(short for xtell mamer) or create an even shorter alias like
+m. In this tutorial, I will use "mam".
+
+ Step 1: Create a tourney
+ ------------------------
+
+ To create a new tourney, type "mam create". You should get the following
+ response:
+
+ mamer(TD) tells you: Created tourney number: 6
+
+ Contact the COO if mamer tells you that "you do not have permission". If you
+ did create the tourney successfully, all you need to remember is the tourney
+ number. In this tutorial, we'll continue managing tourney number 6.
+
+ Step 2: Select the tournament variable settings
+ -----------------------------------------------
+
+ Assuming you are now the manager for tourney 6, type "mam vars 6".
+ You get back a listing of the current tournament variable settings:
+
+:
+: (T)ime: 4
+: (I)ncrement: 0
+: (R)ounds: 0
+: Max (P)layers: 16
+: (M)ode: r (r)ated or (u)nrated
+: (S)tyle: s (s)wiss or (r)oundrobin
+: (V)ariant: w (w)ild, (r)egular, (b)ug, or (s)uicide
+: (W)ild Type: 10 (0), (1), (2), (3), (4), (5), (8), (9)8a, (10)fr
+: Rating (L)ow: 0
+: Rating (H)igh: 9999
+:
+: Manager: toddmf
+
+ The letters in () refer to the variable shortcut to be used when changing a
+ value for a variable. Here is what the variables mean:
+
+ Time -- Same as always: minutes to start the game with
+ Increment -- Same as always: additional seconds per move
+ Rounds -- Number of rounds in the tourney. If you leave this at 0,
+ mamer will choose an optimal number of rounds.
+ Max Players -- The tourney will automatically close and start when this
+ many players have joined.
+ Mode -- Will the tourney games be rated or unrated?
+ Style -- Round Robin(everyone plays everyone) or Swiss System(system
+ where, generally speaking, players play opponents with the
+ same score in the tourney each round).
+ Variant -- What type of game is being played? Regular is used for
+ blitz, standard, and lightning.
+ Wild Type -- This only appears when Variant is set to Wild. Use this to
+ set which wild type will be played.
+ Rating Low -- Players with a rating lower than this cannot join.
+ Rating High -- Players with a rating higher than this cannot join.
+
+ You can change these variables before the tourney starts by using "mam stv #
+ var value". For example, "mam stv 6 t 1" would change the time variable to 1.
+ Once the tourney has opened, you can only change the Max Players and Style
+ variants, and once it has closed and started, you cannot change any variables!
+
+ Step 3: Beginning the tournament
+ --------------------------------
+
+ After you have set the variables, you need to open the tournament so that
+ players may join. To do so, type "mam open #" ("mam open 6" in our case).
+
+ At this point, mamer will announce the tourney in channel 49 and with a
+ cshout. You can duplicate the announcements by using the "mam announce #"
+ command to announce tourney number #. At the moment, there is no limit on how
+ often you can announce. I hope not to hear many complaints about mamer making
+ too many cshouts, so please use announce reasonably(somewhere around once per
+ 30-60 seconds is reasonable).
+
+ When you have enough players, you can close and start the tournament. To do
+ so, "mam close #". If you are unable to find enough players(a minimum of 4 is
+ needed for mamer to run a tourney) in a reasonable amount of time, you should
+ delete the tourney by using "mam delete #" where # is the tourney number.
+
+ Step 4: Running the tournament itself
+ -------------------------------------
+
+ If nobody leaves the tournament, there should be no problems. Mamer should
+ take care of itself. If someone leaves the tourney or logs off of FICS, you
+ may have some work to do. After managing several tourneys, you will have a
+ good sense of how long to wait for someone to return before taking action.
+ The commands you're going to need are "forfeit" and "setres". "mam forfeit
+ handle #" forfeits a player from tourney number #. Use the forfeit command if
+ a player has left, you don't expect him back, and there is at least another
+ round left in the tourney. "mam setres # white black 1/=/0" sets the result
+ of white vs black in tourney # to a win for white/draw/win for black. Use
+ this if you are late in the tourney so that the player doesn't have to forfeit
+ his previous points. Also use setres if you simply want to keep the tourney
+ moving but expect the player to be back(this is useful for tourneys at very
+ fast time controls).
+
+ Step 5: The tournament ends
+ ---------------------------
+
+ Mamer will usually end the tournament automatically and post the final
+ results. If it does not, type "mam games #" to see any uncompleted games.
+ Check if those players are logged in(a fast way to do this is "in handle"),
+ and use forfeit/setres accordingly.
+
+ If there are any problems with the data of the tourney then "message mlong"
+ the correct values and let the players know that the results will be
+ corrected. Points in the tourneys are not recorded; what is important is
+ wins, losses, and placement in the final tourney standings.
+
+ If you have just managed a scheduled tourney(see "help motd" for a list of
+ them), please message the COO the names of the winner(s) and anyone else who
+ may have managed the tourney, so that he can create a news item each week.
+ Also, please "mam keep # 1" to set tourney #'s keep variable to 1. This
+ allows people to view the scheduled tourney's standings days after the
+ tourney.
+
+Chaos points
+------------
+
+ As a TM, you will soon have the power to penalize tourney abuse by giving
+someone chaos points. This is done by typing "mam addchaos handle #", where #
+is the number of chaos points(use a negative number to remove chaos points).
+When someone has 100 chaos points, mamer will censor him, thus preventing him
+from playing in tourneys. Firstly, let's talk about when you should not give
+someone chaos points. If you forfeit someone or they withdraw before the
+tourney ends, mamer will automatically give that person 10 chaos points per
+round missed. Chaos points should be given out for non tourney games,
+profanity, and other distractions(such as telling 49 "hi mamer" repeatedly
+after being warned about overuse of it). Use good judgement. If a player is
+playing a non tourney game that will end in 30 seconds, maybe you should not
+act. However, if he is in a standard game and ignores your request to end it
+and start the tourney, chaos points are warranted. You should probably give
+somewhere between 10 and 20 chaos points per disruption. If you find yourself
+wanting to give out less than 10, you should consider giving a warning instead.
+If you find yourself wanting to give more than 20, you should probably contact
+an admin about the abuse. In any case, whenever you add chaos points, please
+send them a message explaining how many points were given, why you did so,
+and note that decisions can be appealed to the COO. If you don't send a
+message, the player may never knew he did anything wrong, repeat his actions,
+and soon find himself censored by mamer. By sending a message, the player has
+a better chance of not repeating his actions, and it also necessitates having a
+good reason for adding the points.
+
+Manager commands
+----------------
+
+ Here is a summary of all the manager commands.
+
+: addchaos | ac | 25 | Adds (or subs) chaos points.
+: announce | ann | 10 | Announce the tournament to the working
+ channel.
+: addtotourney | att | 25 | Add a user to a tourney.
+: create | cr | 10 | Creates a new tournament.
+: close | cl | 10 | Closes and starts a tournament.
+: delete | del | 10 | Deletes a tournament.
+: forfeit | fo | 10 | Remove a user from a tourney.
+: keep | k | 25 | Keep a tourney in memory.
+: loadedusers | lu | 25 | Displays the loaded users.
+: messman | mm | 50 | Message all of the Managers.
+: open | ot | 10 | Opens the tournament to players.
+: setinfo | si | 100 | Set a user's finger info.
+: setmanagerlevel | sml | 50 | Sets manager's level.
+: setres | sr | 10 | Sets the result of a game.
+: setstat | ss | 50 | Sets a specific finger stat.
+: settourneyvar | stv | 10 | Sets a Tourney's Variables.
+: shutdown | sd | 50 | Shuts down Mamer.
+
+All of the level 10 and 25 commands have been covered except for
+"addtotourney" and "loadedusers". "addtotourney player #" forces player to join
+tourney number #. This is useful for players who want to play in a tourney
+that is about to close but can't figure out how to join the first time. If you
+need to use this, please try to tell the person how to join future tournaments
+so that he doesn't rely on the manager to use addtotourney. It is also useful
+to create test tournaments, but aside from mlong testing code, there is rarely
+a need for that. "loadedusers" is simply a list of players in mamer's
+"memory"; players who have told mamer something recently. The only practical
+application for most managers that I can think of is trying to check if a new
+mamer player having trouble is even getting as far as telling mamer something.
+A note on "delete": Tourneys that aren't "kept"(using keep) are automatically
+deleted after two hours. Please don't delete them before this unless you
+either want to abort a tourney in progress or open or the tourney list is
+getting very cluttered with many fast(ie 1 0, 0 1 suicide) tourneys. Keeping
+tourney standings available for some time after the tourney ends was a feature
+requested by many users, so please don't negate it by deleting the tourneys
+prematurely.
+
+
+
+Historical information about mamer
+----------------------------------
+
+ Users sometimes ask about this information. You may also find it
+interesting. The following is a cleaned up and up-to-date version of mamer
+1.x's "mam help about".
+
+ "Mamer is an automated tournament director for use on FICS only.
+ Fred Baumgarten originally wrote this code because there was a need and
+ Chevrier Joel, the creator of Tomato(another TD program), would not
+ share the code. Fred gave me(mlong) the code in mid 1995 with the
+ stipulation I not release it to anyone. I have modified and (I hope)
+ improved mame (now mamer).
+
+ Mamer stands for "manage me". Plus the -r- for the
+ differentiation between mame (Fred's) code and mamer (mlong's) code.
+
+ Fred's words follow: The intention to write this tournament director
+ program came out of the need to have such a program. Tomato - used at
+ FICS and written by darkside was not released to the public. Darkside
+ even did not want to accept a non disclosure agreement - so I decided
+ to write such a program myself. (Tomato was sold to ICC shortly after
+ and has been used there ever since - toddmf).
+ The program is written in C and will support a bunch of new features soon.
+ It is beta state since Version 0.5 but there _are_ bugs.
+ Fred Baumgarten <dc6iq@insl1.etec.uni-karlsruhe.de>. Have fun !!!
+
+ Mamer is maintained and coded here on FICS by mlong. PLEASE! FOR BUGS
+ PERTAINING TO MAMER TALK TO mlong."
+
+ mlong has always maintained the mamer code. He also was in control of
+mamer's day to day operations at first. GBPacker soon took over this position,
+and fpawn followed. toddmf currently holds this position.
+
+ Mamer's largest(in terms of number of players) tourneys occurred shortly
+after games in the 1997 Deep Blue-Kasparov rematch. Some of these tourneys
+drew 50-60+ players(if anyone knows the exact numbers, please tell me). The
+longest tourney(in terms of number of rounds) was probably a 15 round, 16
+player 1 0 RR tourney held in early 1998(again, please tell me if this is not
+accurate).
+
+See also: every other help file
+
+[Last modified: September 1, 1998 -- toddmf]
--- /dev/null
+manager_level
+
+Here is a list of all of mamer's manager levels and their functions. For a
+list of all mamer managers and their levels, use mamer's "listmanagers"
+command.
+
+Level 0 : All non-managers are level 0.
+
+Level 5 : Mamer managers who cannot use mamer's manager commands. This level
+ is reserved for the rare case when a manager's manager ablities are
+ suspended.
+
+Level 10 : This is an introductory manager level. Enough manager commands to
+ be able to run a tourney are available, and nothing more.
+
+Level 25 : This is the standard manager level. The ability to add and remove
+ chaos points, keep tourneys in mamer's list for longer than two
+ hours, and other minor perks are now available.
+
+Level 50 : Managers at this level are co-mamer Vice Presidents. Additional
+ abilites include the ability to shut down mamer and add players to
+ a tourney manually. Level 50 managers can also modify the manager
+ level of managers below level 50, send a message to all mamer
+ managers, and modify some parts of mamer's player database, but
+ these commands are usually used by only the mamer COO. Additional
+ responsibilities include keeping up to date with mamer activities,
+ consulting with the mamer COO when decisions need to be made, and
+ assisting less experienced managers.
+
+Level 75 : The manager at this level is mamer's Chief Operating Officer. The
+ COO handles day to day operations of mamer. These include new
+ manager applications, chaos point appeals, periodic review of the
+ manager staff, keeping the manager staff updated, and basically all
+ non-programming mamer issues.
+
+Level 100: This level is reserved for mamer's programmer(mlong).
+
+See also: listmanagers
+
+[Last modified: September 12, 1998 -- toddmf]
--- /dev/null
+messman
+
+Alias: mm
+
+Usage: messman <string>
+
+Reserved for mamer managers (level 50 or higher)
+
+This command sends a message containing <string> to all of mamer's managers.
+This is useful for updating managers on mamer news.
+
+[Last updated: August 29, 1998 -- toddmf]
--- /dev/null
+open
+
+Alias: ot
+
+Usage: open <tourney number>
+
+Reserved for mamer managers (level 10 or higher)
+
+This causes the specified tourney to be opened, allowing players to join the
+tourney. Mamer cshouts and tells channel 49 the tourney announcement when the
+tourney is opened. Once a tourney is open, the only variables that can be
+changed are "Max Players" and "Style".
+
+See also: announce, listtourneyvars, settourneyvar
+
+[Last modified: August 29, 1998 -- toddmf]
--- /dev/null
+performance
+
+mamer's "who"(also known as "listplayers") command lists performance ratings
+for the players in the tourney. A performance rating is what the player's
+USCF(several other organizations use the same formula) rating would be if this
+tourney was the player's first tourney. Here is the formula.
+
+ Perf. Rating = Avg. opp. rating + 400 * ((wins-losses)/rounds)
+
+Your performance rating is for the current tourney only.
+
+See also: listplayers, who
+
+[Last modified: September 1, 1998 -- toddmf]
--- /dev/null
+mamer_rating
+
+mamer rating formula
+--------------------
+
+ Pre_tourney stats:
+ pre_wins
+ pre_draws
+ pre_losses
+ pre_rating - this is what we have to initialize
+
+
+ From the tourney just completed:
+ tourn_wins, tourn_draws, tourn_losses
+
+ Post tourney stats: stuff that is saved.
+ post_wins, post_draws, post_losses, post_rating
+
+
+ Calculations:
+ tourn_expect = sigma(over all rounds) {1/[1+10^(delta/400)]}
+ delta = player_FICS_rating - opponent_FICS_rating
+
+ pre_expect = (pre_wins + 0.5*pre_draws)/pre_rating
+
+ post_wins = pre_wins + tourn_wins
+ post_draws = pre_draws + tourn_draws
+ post_losses = pre_losses + tourn_losses
+
+ post_rating = (post_wins + 0.5*post_draws)/(pre_expect + tourn_expect)
+
+
+ Comments:
+----------------
+Ratings will tend to be near 1.0, and a typical range is 0.5 to 1.5.
+Ratings are initialized based on your win percentage.
+
+ Questions, comments, suggestions?? contact mlong.
+
+[Last modified: August 19, 1998 -- fpawn & mlong]
--- /dev/null
+setcommandlevel
+
+Alias: setcl
+
+Usage: setcommandlevel <command> <level>
+
+This command sets the minimum manager level required to use <command> to
+<level>. You can only modify the permissions of commands that require a
+level lower than yours to use. The most common use for this is to disable
+a buggy command.
+
+See also: manager_level, showcommands
+
+[Last modified: September 12, 1998 -- toddmf]
--- /dev/null
+setmanagerlevel
+
+Alias: sml
+
+Usage: setmanagerlevel <handle> <manager level>
+
+Reserved for mamer managers (level 50 or higher)
+
+This command sets <handle>'s manager level. You may only modify the
+levels of managers with a manager level lower than yours, and you can only
+set manager levels to levels lower than yours. Use the "listmanagers"
+command for a list of all the mamer managers and their manager levels(and
+other useful manager information).
+
+See also: listmanagers
+
+[Last modified: September 12, 1998 -- toddmf]
+
--- /dev/null
+
+
+Alias: sr
+
+Usage: setres <tourney number> <white's handle> <black's handle> <result>
+
+Reserved for mamer managers (level 10 or higher)
+
+The setres command is used to set the result of a game that is unable to be
+completed by the players. Normally, the result is set against the person who
+is unable to complete the game unless he has no mating material. The <result>
+is "1" for a white win, "=" for a draw, and "0" for a black win.
+
+[Last modified: September 3, 1998 -- toddmf]
+
--- /dev/null
+setstat
+
+Alias: ss
+
+Usage: setstat <handle> <stat to set> <integer value>
+
+Reserved for mamer managers (level 50 or higher)
+
+This command is used to set <handle>'s tourney finger statistics in the event
+that something goes wrong in a tourney. Statistics that can be modified are:
+
+t - Modifies the "Tnys" (tourneys played) statistic.
+w - Modifies the "W" (wins) statistic.
+l - Modifies the "L" (losses) statistic.
+d - Modifies the "D" (draws) statistic.
+1 - Modifies the "1st" (first places) statistic.
+2 - Modifies the "2nd" (second places) statistic.
+3 - Modifies the "3rd" (third places) statistic.
+
+See also: finger
+
+[Last modified: September 3, 1998 -- toddmf]
+
--- /dev/null
+settourneyvar
+
+Alias: stv
+
+Usage: settourneyvar <tourney number> <variable> <value>
+
+Reserved for mamer managers (level 10 or higher)
+
+This command sets the the value of a tourney variable. To see a list of the
+variables and their function, read "mam help listtourneyvars".
+
+See also: listtourneyvars
+
+[Last modified: August 29, 1998 -- toddmf]
--- /dev/null
+showcommands
+
+Alias: sc
+
+Usage: showcommands
+
+This command displays a list of all of mamer's commands, their aliases, the
+minimum manager level needed to use them, and a short summary of the command's
+function. If you are not a mamer manager, you can use the commands marked as
+level 0 commands.
+
+NOTE: The "showcommands" command is equivalent to the "help" command.
+
+See also: help, manager_level, usage
+
+[Last modified: August 29, 1998 -- toddmf]
--- /dev/null
+showhelpfile
+
+Alias: shf
+
+Usage: showhelpfile <optional name of help file>
+
+The showhelpfile command displays the requested help file. If you do not
+specify a file, the "index" file(a listing of all help files) will be
+displayed.
+
+[Last modified: September 1, 1998 -- toddmf]
--- /dev/null
+shutdown
+
+Alias: sd
+
+Usage: shutdown
+
+Reserved for mamer managers (level 50 or higher)
+
+This command causes mamer to shut down and log off.
+
+[Last modified: September 1, 1998 -- toddmf]
--- /dev/null
+swiss
+
+The swiss system is a fairly complicated pairing system(books have been
+written on it). Here is a short summary. For the first round, the players
+are ranked by rating. The top player of the top half plays the top player of
+the bottom half, the #2 player from the top half plays the #2 player from the
+bottom half, and so on. Colors alternate for the top players. A sample first
+round pairing for an 8 player tourney would be 1-5, 6-2, 3-7, 8-4. After each
+round, the players are sorted again. This time, they are sorted by score in
+the tourney(1.0 for each win, 0.5 for each draw, 0.0 for each loss). The
+swiss algorithm mentioned above is then applied to each group. As the tourney
+goes on, the number of groups(and thus the number of groups with an odd number
+of players) grows. There are many techniques used to pair players that are at
+least very close in score while avoiding having two players play each other
+more than once and giving very lopsided color distribution(for example, having
+4 whites and one black in a 5 round tourney) which are beyond the scope of
+this short summary. To sum up, you play people who are doing close to as well
+(or poorly) as you in the tourney, you play close to an equal number of
+games with white as with black, and you don't play the same player twice.
+Mamer does its best to make good swiss pairings, but occasionally it will
+produce some odd pairings.
+
+[Last modified: September 1, 1998 -- toddmf]
--- /dev/null
+upset
+
+mamer's "who"(also known as "listplayers") command lists upset points for each
+player in the tourney. Upset points are gained for beating or drawing higher
+rated players. If you beat a higher rated player, you gain the difference in
+ratings in upset points. If you draw a higher rated player, you gain half the
+difference(rounded down) in upset points. For example, a 1600 who beats a
+2001 would gain 401 upset points. If the game had ended in a draw, the 1600
+would have gained 200 upset points. Upset points do not carry from tourney to
+tourney.
+
+See also: listplayers, who
+
+[Last modified: September 1, 1998 -- toddmf]
--- /dev/null
+user_commands
+
+finger | fi | 0 | Displays the stats for a user.
+help | h | 0 | List commands and descripts.
+join | j | 0 | Request to enter a tourney.
+listmanagers | lm | 0 | Displays the Managers list.
+listtourneys | lt | 0 | Displays the tournament list.
+listtourneyvars | vars | 0 | Displays the tournament variables.
+listtourneygames | games | 0 | Displays the tournament games.
+listplayers | lp | 0 | Displays the players in the tourney.
+showcommands | sc | 0 | List commands and descripts.
+showhelpfile | shf | 0 | Shows a help file.
+who | who | 0 | Displays the tournament games.
+withdraw | with | 0 | Remove yourself from a tourney.
+
+[Last modified: September 1, 1998 -- toddmf]
--- /dev/null
+who
+
+Usage: who <tourney number>
+
+This command lists all the players in the specified tourney and other
+information about the players in the tourney.
+
+: Name Rating Score Perfrm Upset Results
+: ----------------- ------ ----- ------ ------ -------
+: 1 +ghettoCHECKMATE [1651] 3.0 [2242] [ 573] +07b +02b +04w
+: 2 +TheOnlyOne [1914] 2.0 [1764] [ 0] +03b -01w +05w
+: 3 +westham [1725] 2.0 [1843] [ 47] -02w +04b +06w
+: 4 +frankenschach [1772] 1.0 [1497] [ 0] +05w -03w -01b
+: 5 +Arbakov [1516] 1.0 [1443] [ 0] -04b +06w -02b
+: 6 +Ostap [forf] 0.0 [1251] [ 0] -01w
+:
+: Average Rating 1736.3
+
+The number in the leftmost column is the player's current ranking in the
+tourney.
+
+"Name" is the player's handle. A "+" to the left indicates that the player is
+ currently logged in. A "-" indicates that he is not.
+"Rating" is the player's FICS rating before the tourney started in the
+ category of games played in the tourney. "forf" means the player is no
+ longer in the tourney.
+"Score" is the number of tourney points the player has. 1.0 is awarded for
+ each win, 0.5 for each draw, and 0.0 for each loss.
+"Perfrm" is the player's performance rating for the tourney.
+"Upset is the number of upset points the player has.
+"Results" is a grid of the tourney results. "+" represents a win, "="
+ represents a draw, and "-" represents a loss. The number following is
+ the ranking of the opponent in the tourney(see the leftmost column).
+ The letter following that is the color played. "b" is black; "w" is
+ white.
+"Average Rating" is the average rating of all the players in the tourney.
+ The ratings used are ratings when the players join the tourney.
+
+NOTE: This is the same as the "listplayers" command.
+
+See also: listplayers, performance, upset
+
+[Last modified: August 29, 1998 -- toddmf]
--- /dev/null
+withdraw
+
+Alias: with
+
+Usage: withdraw <tourney number>
+
+Use this command to withdraw from(in other words, leave) a tourney. If the
+tourney has not started yet, you may withdraw without penalty. However, if
+you leave a tourney in progress, you will gain chaos points equal to 10 times
+the number of rounds you miss. If you were playing in a round robin tourney,
+the results of your games will all be set to 0-0. If you were playing in a
+swiss, the results of your completed games will stand, but you will lose
+remaining games by forfeit.
+
+See also: chaos, swiss
+
+[Last modified: September 1, 1998 -- toddmf]
--- /dev/null
+//--------------------------------------------------------------------------
+// link.cc - Source file for the link list classes
+//
+// Matthew E. Moses
+//
+// $Revision: 1.5 $
+// $Date: 1998/09/10 19:57:17 $
+//
+// $Author: mlong $
+// $Locker: $
+//
+// $Log: link.cc,v $
+// Revision 1.5 1998/09/10 19:57:17 mlong
+// lots of little bug fixes and a few new features
+//
+// Revision 1.4 1998/06/04 19:55:00 mlong
+// changed this?
+//
+// Revision 1.3 1998/04/18 18:46:04 mlong
+// fixed delete bug &
+// added delete tourney function
+//
+// Revision 1.2 1998/04/15 16:56:17 mlong
+// *** empty log message ***
+//
+// Revision 1.1 1998/03/16 18:09:27 moses
+// Initial revision
+//
+// Revision 1.2 1998/03/16 19:47:54 chess
+// cfi *.h
+//
+// Revision 1.1 1998/03/14 03:13:00 chess
+// Initial revision
+//
+// Revision 1.1 1996/09/30 20:52:48 moses
+// Initial revision
+//
+//
+//--------------------------------------------------------------------------
+
+// static char RCSid[] = "$Id: link.cc,v 1.5 1998/09/10 19:57:17 mlong Exp $";
+
+#include "link.hh"
+
+//----------------------------------------------------------------------------
+// Link class methods
+//
+
+// default constructor
+Link::Link(void) { next = 0; }
+
+// constructor
+Link::Link(Link *p) { next = p; }
+
+Link::~Link(void) {}
+
+
+//----------------------------------------------------------------------------
+// LinkListBase class methods
+//
+
+// default constructor
+LinkListBase::LinkListBase(void) { head = 0; }
+
+LinkListBase::~LinkListBase(void) {}
+
+void LinkListBase::Insert(Link *p)
+{
+ if(head)
+ p->next = head;
+
+ head = p;
+}
+
+void LinkListBase::Insert(Link *p, Link *q) {
+ Link *tmp = 0;
+
+ if(head)
+ if(head == p)
+ Insert(q);
+ else {
+ for(tmp = head; (tmp->next != 0); tmp = tmp->next) {
+ if(tmp->next == p) {
+ q->next = p;
+ tmp->next = q;
+ break;
+ }
+ }
+ if(tmp->next == 0)
+ Append(q);
+ }
+ else
+ head = q;
+}
+
+//--------------------------
+// Head
+//
+Link *LinkListBase::Head(void) { return(head); }
+
+void LinkListBase::Append(Link *p)
+{
+ if(head) {
+ Link *tmp = 0;
+
+ for(tmp = head; tmp->next != 0; tmp = tmp->next)
+ ;
+ tmp->next = p;
+ }
+ else
+ head = p;
+}
+
+void LinkListBase::Delete(void)
+{
+ Link *p = 0;
+
+ if(head) {
+ p = head->next;
+ delete head;
+ head = p;
+ }
+ else
+ head = 0;
+}
+
+void LinkListBase::Delete(Link *p)
+{
+ Link *tmp = 0;
+
+ if(head != p) {
+ for(tmp = head; (tmp != 0 && tmp->next != p); tmp = tmp->next)
+ ;
+
+ if(tmp->next == p) {
+ tmp->next = p->next;
+ delete p;
+ }
+ } else if(head == p) {
+ tmp = head->next;
+ delete head;
+ /*
+ head = 0;
+ */ /* This line will delete the entire list */
+ head = tmp; /* This one does not delete the entire list. */
+ } else {
+ head = 0;
+ }
+}
+
+
+//----------------------------------------------------------------------------
+// LinkListIterBase class methods
+//
+
+// constructor
+LinkListIterBase::LinkListIterBase(LinkListBase& list)
+{
+ currentList = &list;
+ currentItem = currentList->head;
+}
+
+void LinkListIterBase::Reset(void)
+{
+ currentItem = currentList->head;
+}
+
+Link *LinkListIterBase::Next(void)
+{
+ Link *ret = 0;
+
+ ret = currentItem;
+ if(0 != currentItem)
+ currentItem = currentItem->next;
+
+ return(ret);
+}
+
+
--- /dev/null
+//--------------------------------------------------------------------------
+// link.hh - Class header for the link and linklistbase classes
+//
+// Matthew E. Moses
+//
+// $Revision: 1.2 $
+// $Date: 1998/04/15 16:56:34 $
+//
+// $Author: mlong $
+// $Locker: $
+//
+// $Log: link.hh,v $
+// Revision 1.2 1998/04/15 16:56:34 mlong
+// *** empty log message ***
+//
+// Revision 1.2 1998/03/16 19:48:17 chess
+// *** empty log message ***
+//
+// Revision 1.1 1998/03/14 03:14:09 chess
+// Initial revision
+//
+// Revision 1.1 1996/09/30 20:52:48 moses
+// Initial revision
+//
+//
+//--------------------------------------------------------------------------
+
+#ifndef _link_
+#define _link_
+
+//--------------------------------------------
+// Base class for a link list element
+//
+
+class Link
+{
+public:
+ Link *next;
+
+ Link(void);
+ Link(Link *p);
+ ~Link(void);
+};
+
+//-----------------------------------------------
+// Base class for a Link List
+//
+
+class LinkListBase {
+public:
+
+ friend class LinkListIterBase;
+
+ LinkListBase(void);
+ ~LinkListBase(void);
+
+ void Insert(Link *p);
+ void Insert(Link *p, Link *q);
+ void Append(Link *p);
+ void Delete(void);
+ void Delete(Link *p);
+
+ Link *Head(void);
+
+private:
+ Link *head;
+};
+
+//-----------------------------------
+// Base class for a link list iterator
+//
+
+class LinkListIterBase
+{
+private:
+ Link *currentItem;
+ LinkListBase *currentList;
+
+public:
+ LinkListIterBase(LinkListBase& list);
+ void Reset(void);
+ Link *Next(void);
+};
+
+#endif
+
--- /dev/null
+//--------------------------------------------------------------------------
+// linklist.hh - Class header for the template linklist class
+//
+// Matthew E. Moses
+//
+// $Revision: 1.3 $
+// $Date: 1998/09/10 19:58:41 $
+//
+// $Author: mlong $
+// $Locker: $
+//
+// $Log: linklist.hh,v $
+// Revision 1.3 1998/09/10 19:58:41 mlong
+// lots of little bug fixes and a few new features.
+//
+// Revision 1.2 1998/04/15 16:56:34 mlong
+// *** empty log message ***
+//
+// Revision 1.2 1998/03/16 19:48:17 chess
+// *** empty log message ***
+//
+// Revision 1.1 1998/03/14 03:14:15 chess
+// Initial revision
+//
+// Revision 1.1 1996/09/30 20:52:48 moses
+// Initial revision
+//
+//
+//--------------------------------------------------------------------------
+
+#ifndef _linklist_
+#define _linklist_
+
+#include "link.hh"
+
+//----------------------------------------------------------------------------
+// Generic LinkList Class - derived from class LinkListBase
+//
+
+template <class T>
+class LinkList : public LinkListBase {
+public:
+ void Insert(T *p) { LinkListBase::Insert(p); }
+ void Insert(T *p, T *q) { LinkListBase::Insert(p, q); }
+ void Append(T *p) { LinkListBase::Append(p); }
+ void Delete(void) { LinkListBase::Delete(); }
+ void Delete(T *p) { LinkListBase::Delete(p); }
+ T *Head(void) { return((T *)LinkListBase::Head()); }
+};
+
+//----------------------------------------------------------------------------
+// Generic LinkListIterator Class - derived from class LinkListIterBase
+//
+
+template <class T>
+class LinkListIter : public LinkListIterBase {
+public:
+ LinkListIter(LinkList<T>& list) : LinkListIterBase(list) { }
+ inline void Reset(void) { LinkListIterBase::Reset(); }
+ inline T *Next(void) { return((T *) LinkListIterBase::Next()); }
+};
+
+#endif
+
--- /dev/null
+lasker/bots/mamer/logs
--- /dev/null
+//--------------------------------------------------------------------------
+// main.cc - main source file that starts Mamer
+//
+// Matthew E. Moses
+//
+// $Revision: 1.4 $
+// $Date: 1998/09/10 19:57:17 $
+//
+// $Author: mlong $
+// $Locker: $
+//
+// $Log: main.cc,v $
+// Revision 1.4 1998/09/10 19:57:17 mlong
+// lots of little bug fixes and a few new features
+//
+// Revision 1.3 1998/04/18 20:05:14 mlong
+// *** empty log message ***
+//
+// Revision 1.2 1998/04/18 18:46:04 mlong
+// fixed delete bug &
+// added delete tourney function
+//
+// Revision 1.1 1996/09/30 20:52:48 moses
+// Initial revision
+//
+//
+//--------------------------------------------------------------------------
+
+//static char RCSid[] = "$Id: main.cc,v 1.4 1998/09/10 19:57:17 mlong Exp $";
+
+#include "Mamer.hh"
+
+//- Globals ----------------------------------------------------------------
+Mamer gMamer;
+
+//- Prototypes -------------------------------------------------------------
+int main(int, char **);
+
+//- main -------------------------------------------------------------------
+int main(int argc, char **argv) {
+
+ if(gMamer.Initialize(argc, argv))
+ if(gMamer.OpenServerConnection()) {
+ gMamer.ListenLoop();
+ gMamer.Shutdown();
+ }
+ else
+ cerr << "ERROR: couldn't open server connection!" << endl;
+ else
+ cerr << "ERROR: couldn't initialize mamer!" << endl;
+
+ exit(0);
+} //- End of main
+
+//- HandleSignals ---------------------------------------------------------
+void HandleSignals(int theSignal) {
+ switch(theSignal) {
+ case SIGTERM:
+ case SIGKILL:
+ gMamer.Shutdown();
+ exit(0);
+ break;
+ case SIGUSR1:
+ gMamer.Shutdown();
+ exit(0);
+ case SIGUSR2:
+ gMamer.DumpConfiguration();
+ default:
+ break;
+ }
+} //- End of HandleSignals
--- /dev/null
+HOST freechess.org
+PORT 5000
+CHAN 49
+DBUG 5
+HOME /home/mlong/mamer
+DATA /home/mlong/mamer/data
+HELP /home/mlong/mamer/help
+UDB /home/mlong/mamer/players
+LOG /home/mlong/mamer/logs/mamer
+USER mamer
+PASS lmwi39s8
--- /dev/null
+/template.cc/1.1/Mon Jul 1 23:55:52 2002//
+/template.hh/1.1/Mon Jul 1 23:55:52 2002//
+D
--- /dev/null
+lasker/bots/mamer/template
--- /dev/null
+//--------------------------------------------------------------------------
+// .cc - Source file for the class
+//
+// Matthew E. Moses && Michael A. Long
+//
+// $Revision: 1.1 $
+// $Date: 2002/07/01 23:55:52 $
+//
+// $Author: tridge $
+// $Locker: $
+//
+// $Log: template.cc,v $
+// Revision 1.1 2002/07/01 23:55:52 tridge
+// import from mlong
+//
+//
+//--------------------------------------------------------------------------
+
+static char RCSid[] = "$Id: template.cc,v 1.1 2002/07/01 23:55:52 tridge Exp $";
--- /dev/null
+//--------------------------------------------------------------------------
+// .hh -
+//
+// Matthew E. Moses & Michael A. Long
+//
+// $Revision: 1.1 $
+// $Date: 2002/07/01 23:55:52 $
+//
+// $Author: tridge $
+// $Locker: $
+//
+// $Log: template.hh,v $
+// Revision 1.1 2002/07/01 23:55:52 tridge
+// import from mlong
+//
+//
+//--------------------------------------------------------------------------
+
+#ifndef __
+#define __
+
+#endif
--- /dev/null
+//--------------------------------------------------------------------------
+// types.h - Header file for types
+//
+// Matthew E. Moses & Michael A. Long
+//
+// $Revision: 1.11 $
+// $Date: 1998/09/10 19:58:20 $
+//
+// $Author: mlong $
+// $Locker: $
+//
+// $Log: types.h,v $
+// Revision 1.11 1998/09/10 19:58:20 mlong
+// *** empty log message ***
+//
+// Revision 1.10 1998/06/18 18:42:09 mlong
+// prepairing for yet another move.
+//
+// Revision 1.9 1998/06/04 19:56:02 mlong
+// *** empty log message ***
+//
+// Revision 1.8 1998/04/18 19:00:07 mlong
+// fixed delete bug and added delete tourney fuction
+//
+// Revision 1.7 1998/02/12 18:44:34 mlong
+// *** empty log message ***
+//
+// Revision 1.6 1997/11/06 20:51:29 chess
+// *** empty log message ***
+//
+// Revision 1.5 1997/10/08 21:03:08 chess
+// no log message
+//
+// Revision 1.4 1997/05/15 18:30:27 chess
+// *** empty log message ***
+//
+// Revision 1.3 1997/04/13 03:24:42 chess
+// added several enumerated types for params stuff and for TellUser outputs
+//
+// Revision 1.2 1997/04/07 22:22:26 chess
+// added enum ranks
+// and added enum reasons for why we are calling a centralized telluser function
+//
+// Revision 1.1 1996/10/01 20:17:34 moses
+// Initial revision
+//
+//
+//--------------------------------------------------------------------------
+
+#ifndef _TYPES_
+#define _TYPES_
+
+class Mamer;
+class User;
+class Tourney;
+class CommandEntry;
+class Player;
+class Storage;
+
+typedef enum {
+ USER=0,
+ DIRECTOR=10,
+ MANAGER=25,
+ VICE=50,
+ PRESIDENT=100
+} ranks;
+
+typedef enum {
+ BadCommand,
+ MultiCommand,
+ CanNotChange,
+ ChangedManagerLevel,
+ ChangedCommandLevel,
+ ChangedInfo,
+ ChangedAbuse,
+ GenericTell,
+ JoinedTourney,
+ WillKeepTourney,
+ NoPermissions,
+ NotEnoughPlayers,
+ NotFound,
+ NotKeepTourney,
+ NoPlayers,
+ PlayerRemoved,
+ TourneyDeleted,
+ TourneyNotFound,
+ TourneyNotNew,
+ TourneyNotOpen,
+ TourneyNotClosed,
+ TourneyDone,
+ TourneyClosed,
+ GameResultNotFound,
+ GameResultSet
+} reasons;
+
+#define COM_OK 0
+#define COM_FAILED 1
+#define COM_AMBIGUOUS 2
+#define COM_BADPARAMETERS 3
+#define COM_BADCOMMAND 4
+
+typedef enum {
+ ONLINE,
+ GONE,
+} locations;
+
+typedef enum {
+ TYPE_NONE=-1,
+ TYPE_UNTIMED,
+ TYPE_BLITZ,
+ TYPE_STAND,
+ TYPE_NONSTANDARD,
+ TYPE_WILD,
+ TYPE_LIGHT,
+ TYPE_BUGHOUSE,
+ TYPE_FR,
+ TYPE_SUICIDE
+} gametype;
+
+typedef enum {
+ NEW,
+ OPEN,
+ CLOSED,
+ DONE
+} status;
+
+
+typedef enum {
+ TYPE_NULL,
+ TYPE_WORD,
+ TYPE_STRING,
+ TYPE_INT
+} types;
+
+typedef struct u_parameter {
+ types type;
+ union {
+ char *word;
+ char *string;
+ int integer;
+ } val;
+} parameter;
+
+struct string_list {
+ char *string;
+ int number;
+};
+
+typedef struct string_list strings;
+
+#define MAXNUMPARAMS 10
+typedef parameter param_list[MAXNUMPARAMS];
+typedef int (Mamer::*USERFP) (User *, param_list);
+typedef int (Mamer::*TOURNFP) (User *, param_list, Tourney *);
+
+#endif
+
--- /dev/null
+D/admin////
+D/book////
+D/help////
+D/messages////
+D/stats////
+D/usage////
+D/boards////
+D/com_help////
--- /dev/null
+lasker/data
--- /dev/null
+/accounts/1.1/Thu Jun 6 11:41:21 2002//
+/addaccounts/1.1/Thu Jun 6 11:41:21 2002//
+/addcomment/1.1/Thu Jun 6 11:41:21 2002//
+/addplayer/1.1/Thu Jun 6 11:41:21 2002//
+/adjud_info/1.1/Thu Jun 6 11:41:21 2002//
+/adjudicate/1.1/Thu Jun 6 11:41:21 2002//
+/admin/1.1/Thu Jun 6 11:41:21 2002//
+/admin_hierarchy/1.1/Thu Jun 6 11:41:21 2002//
+/ahelp/1.1/Thu Jun 6 11:41:21 2002//
+/amotd/1.1/Thu Jun 6 11:41:21 2002//
+/anews/1.1/Thu Jun 6 11:41:21 2002//
+/announce/1.1/Thu Jun 6 11:41:21 2002//
+/annunreg/1.1/Thu Jun 6 11:41:21 2002//
+/areload/1.1/Thu Jun 13 04:19:13 2002//
+/asetadmin/1.1/Thu Jun 6 11:41:21 2002//
+/asetblitz/1.1/Thu Jun 6 11:41:21 2002//
+/asetemail/1.1/Thu Jun 6 11:41:21 2002//
+/asethandle/1.1/Thu Jun 6 11:41:21 2002//
+/asetmaxplayer/1.1/Thu Jun 6 11:41:21 2002//
+/asetpasswd/1.1/Thu Jun 6 11:41:21 2002//
+/asetrealname/1.1/Thu Jun 6 11:41:21 2002//
+/asetstd/1.1/Thu Jun 6 11:41:21 2002//
+/asetv/1.1/Thu Jun 6 11:41:21 2002//
+/asetwild/1.1/Thu Jun 6 11:41:21 2002//
+/ban/1.1/Thu Jun 6 11:41:21 2002//
+/buglist/1.1/Thu Jun 6 11:41:21 2002//
+/canewsf/1.1/Thu Jun 6 11:41:21 2002//
+/canewsi/1.1/Thu Jun 6 11:41:21 2002//
+/chkgame/1.1/Thu Jun 6 11:41:21 2002//
+/chkip/1.1/Thu Jun 6 11:41:21 2002//
+/chkpl/1.1/Thu Jun 6 11:41:21 2002//
+/chksc/1.1/Thu Jun 6 11:41:21 2002//
+/chkts/1.1/Thu Jun 6 11:41:21 2002//
+/cmuzzle/1.1/Thu Jun 6 11:41:21 2002//
+/createanews/1.1/Thu Jun 6 11:41:21 2002//
+/filter/1.1/Thu Jun 6 11:41:21 2002//
+/finger/1.1/Thu Jun 6 11:41:21 2002//
+/lists/1.1/Thu Jun 6 11:41:21 2002//
+/muzzle/1.1/Thu Jun 6 11:41:21 2002//
+/nuke/1.1/Thu Jun 6 11:41:21 2002//
+/pose/1.1/Thu Jun 6 11:41:21 2002//
+/projects/1.1/Thu Jun 6 11:41:21 2002//
+/quota/1.1/Thu Jun 6 11:41:21 2002//
+/raisedead/1.1/Thu Jun 6 11:41:21 2002//
+/register/1.1/Thu Jun 6 11:41:21 2002//
+/remplayer/1.1/Thu Jun 6 11:41:21 2002//
+/rerank/1.1/Thu Jun 6 11:41:21 2002//
+/server_com/1.1/Thu Jun 6 11:41:21 2002//
+/showcomment/1.1/Thu Jun 6 11:41:21 2002//
+/shutdown/1.1/Thu Jun 6 11:41:21 2002//
+/summon/1.1/Thu Jun 6 11:41:21 2002//
+/aconfig/1.2/Tue Jun 18 06:16:44 2002//
+/acheckhelp/1.1/Sun Jun 23 07:51:06 2002//
+/adump/1.1/Sun Jun 23 06:43:35 2002//
+/asetbughouse/1.1/Sun Jun 23 07:20:46 2002//
+/asetlight/1.1/Sun Jun 23 07:20:46 2002//
+/ftell/1.1/Sun Jun 23 07:20:47 2002//
+/hideinfo/1.1/Sun Jun 23 07:20:47 2002//
+/canewsd/1.1/Mon Jun 24 11:12:56 2002//
+/canewse/1.1/Sun Jun 23 22:40:37 2002//
+/canewsp/1.1/Sun Jun 23 22:40:37 2002//
+/canewst/1.1/Sun Jun 23 22:40:37 2002//
+/cnewsd/1.1/Mon Jun 24 11:12:56 2002//
+/cnewse/1.1/Sun Jun 23 22:40:37 2002//
+/cnewsf/1.2/Sat Jun 29 00:06:12 2002//
+/cnewsi/1.2/Sat Jun 29 00:06:12 2002//
+/cnewsp/1.1/Sun Jun 23 22:40:37 2002//
+/cnewst/1.1/Sun Jun 23 22:40:37 2002//
+D
--- /dev/null
+lasker/data/admin
--- /dev/null
+
+accounts
+
+These accounts were created in order to aid admins with their work. They
+shouldn't be used for any other purpose. Some of these accounts have admin
+status.
+
+ adjudicate - an account for adjudication requests
+ Bug - an account for bug reports
+ filter - an account to log filtered sites/reasons for filtering
+ Suggestion - an account for suggestions
+ vacation - an account for admin holiday notification
+ helpfiles - an account for help file updating requests
+
+If you need to use an account but don't know the password, ask an admin who
+does.
+
+[Last modified: December 25, 1995 -- Friar]
+
--- /dev/null
+
+ahelpcheck
+
+Usage: ahelpcheck
+RESTRICTED TO ADMINISTRATORS.
+
+ This prints a report on any commands that are missing help pages
+
--- /dev/null
+
+aconfig
+
+Usage: aconfig variable value
+RESTRICTED TO ADMINISTRATORS.
+
+ sets the server config variable 'variable' to 'value'
+
+ If used with no parameters then displays all current server
+ variables
+
+ If the value is set to '-' then the variable is deleted
+
+ Example:
+ aconfig SERVER_LOCATION Canberra, Australia
--- /dev/null
+addaccounts
+
+ This help file documents the rules for adding extra accounts for players.
+
+ The file is for the AFICS site, please feel free to modify the contents
+or admin names for your particular site.
+
+Types of account allowed:
+
+ playing account or | only 1 of these allowed per person
+ chatting account or | admins may have one of these in addition
+ playing/chatting account | to their normal account - see below.
+
+ - This is the default registered account.
+
+ blind account - for blindfold chess ONLY!
+
+ - may shout with it, but NOT to be used as
+ - an excuse to abuse/get round quota/get
+ - past censor lists etc.
+
+ - must use style 9 (although may set to
+ - another style to examine afterward)
+
+ team account - for team chess ONLY!
+ - see rules for blind accounts
+
+ - advise player not to let members other
+ - than from his/her site to use it as
+ - is responsible for their behaviour.
+ - this is not a hard fixed rule though.
+
+ computer account or | maximum 1 per player
+ 'cyborg' account | (more if automatic moving)
+
+ - non-automatic computers should NOT be
+ - used as a shouting mechanism (except for
+ - match pairings, greetings etc)
+
+ - A cyborg account is where the player is
+ - using a computer to analyse the moves,
+ - but a human is deciding which one to play.
+ - (can make a very strong player)
+
+ - Useful if computer specifications/house
+ - rules are placed in notes (eg no aborts)
+
+(any problems with the above three - remove immediately and comment the
+ player account)
+
+ admin account - may be used to play/chat
+
+ - advise to get a player account to save
+ - getting questions in the middle of a game
+
+ tester account - admins/programmers only.
+ - maximum of 2 per person (or more if only
+ - for a temporary period)
+
+ helper account - receives messages from players (eg bug)
+
+ - admins only, unless authorised by Sparky
+ - or sveshi (AFICS)
+ - do NOT put passwords in admin help files.
+
+1> Extra admins accounts.
+ Admins can have as many accounts as they wish as long as the above rules
+ are followed.
+
+2> Extra user accounts.
+
+ Must satisfy the following criterea:
+
+
+ 1> Is not currently being sanctioned (eg on abuser list)
+
+ 2> Comment file is clean or nearly clean (check the comments don't
+ assume because someone has more than one comment they have been
+ an abuser). Repeat offenders must be refused additional accounts.
+
+ 3> The player is not known to cause (much) trouble.
+
+ If in doubt please check with sveshi (AFICS) first.
+
+ Must put in comments list of the player applying for it the name and type
+ of account
+
+ Eg. addcomment FishFood DAV's blind account
+
+ Must add in the realname of the account, the handle of the player and what
+ type of account it is.
+
+ Finally add it to a list with +listname [name] if appropriate.
+
+ Do NOT revert an additional account to a player account without good reason
+ (eg old account was destroyed somehow). Check with sveshi (AFICS) if unsure..
+
+See ahelp: accounts, addplayer
+See help: addlist, sublist
+
+[Last modified 11/28/95 - DAV]
--- /dev/null
+
+addcomment
+
+Usage: addcomment user comment
+RESTRICTED TO ADMINISTRATORS.
+
+ Places "comment" in the user's comments. If a user has comments, the number
+of comments is indicated to admins using the "finger" command. The comments
+themselves are displayed by the "showcomments" command.
+
+ Please add comments when action is taken regarding the user's account, such
+as admin actions, changes in settings or even complaints from other users.
+Comments provide a ready source of documentation and reference for all admins
+to review as needed.
+
+See ahelp: finger showcomment
+See help:
+
+[Last modified: September 14, 1995 -- Friar]
+
--- /dev/null
+
+addplayer
+
+Usage: addplayer playername emailaddress realname
+RESTRICTED TO ADMINISTRATORS.
+
+ Adds a local player to the server with the handle of "playername". For
+example:
+
+ addplayer Hawk u940456@daimi.aau.dk Henrik Gram
+
+If there is no email address, use "none". Settings can be revised using
+asetemail, asethandle ans asetname.
+
+See ahelp: asetemail asethandle asetrealname raisedead remplayer
+See help: register
+
+[Last modified: September 14, 1995 -- Friar]
+
--- /dev/null
+
+adjud_info
+
+ Games should be adjudicated as a win for a player only if the game is an
+obvious (theoretical) win. For example, (a) K+R vs. K, or (b) up a queen in
+the middlegame. You may also grant a win due to time IF (1) the player
+requests a win on this basis and (2) the conditions (namely clocking settings)
+warrant it.
+
+ If the player seeks a draw, then the game should be dead equal in the
+endgame.
+
+ Abort adjudications are appropriate if the game has lasted only a few moves
+and neither player can speak of an advantage: i.e., 1. d4 d5, 2. c4 c6, 3. Nf3
+could be aborted. Games should *not* be aborted if one side has an advantage.
+For example, 1. d4 d5, 2. c4 e6, 3. c5 should *not* be adjudicated as an
+abort, especially if white wants the abort.
+
+ In rare cases, it might be necessary to adjudicate a game that is in
+progress. These occasions can occur when one opponent is a computer that
+either (a) fails to move, in which case an abort may be granted, or (b)
+continues play in a clearly drawn position, in which case a draw may be
+granted.
+
+ To list games for which adjudications have been requested, type "ahelp
+adjrequests".
+
+See ahelp: adjudicate
+See help: adjudication
+
+[Last modified: September 18, 1995 -- Friar]
+
--- /dev/null
+
+adjudicate
+
+Usage: adjudicate white_player black_player result
+RESTRICTED TO ADMINISTRATORS.
+
+ Adjudicates a game between white_player and black_player. The result is one
+of: abort, draw, white, black. "Abort" cancels the game (no win, loss or
+draw), "white" gives white_player the win, "black" gives black_player the win,
+and "draw" gives a draw. Both white_player and black_player will be notified
+by server messages concerning the adjudication.
+
+ In most cases, the game will be a stored (adjourned) game for which one
+opponent has made an adjudication request. To list games for which
+adjudications have been requested, type "ahelp adjrequests". However, there
+may be occasions when a game in progress needs to be adjudicated online --
+such as when a computer fails to move or cannot accept a draw in a clearly
+drawn position.
+
+ For guidelines about adjudications, see "adjud_info".
+
+See ahelp: adjud_info
+See help: adjourn adjudicate_request stored
+
+[Last modified: September 18, 1995 -- Friar]
+
--- /dev/null
+
+admin
+
+Usage: admin
+RESTRICTED TO ADMINISTRATORS.
+
+ This command toggles your admin symbol (*) on/off. This symbol appears in
+who listings.
+
+See ahelp:
+See help: who
+
+[Last modified: June 22, 1995 -- Friar]
+
--- /dev/null
+0 "Normal User"
+5 "Authorized Helper Person" (DAV says no, we can't do this. Hmmm!)
+10 "Administrator"
+15 "Help File Librarian/Administrator"
+20 "Master Administrator"
+50 "Master Help File Librarian/Administrator"
+60 "Assistant Super User"
+100 "Super User"
--- /dev/null
+
+adump
+
+Usage: adump
+RESTRICTED TO GODS
+
+This dumps the complete server internal state to a file called
+'globals.dat' in the main directory. Used for debugging.
--- /dev/null
+
+ahelp
+
+Usage: ahelp [topic]
+RESTRICTED TO ADMINISTRATORS.
+
+ If a topic is specified, this command prints help on the given administrator
+topic. If topic is omitted, this command lists help files that only admins
+may read.
+
+See ahelp: admin_commands
+See help: admins
+
+[Last modified: July 1, 1995 -- Friar]
+
--- /dev/null
+
+This is the admin motd. Type "help motd" to see the user motd.
+
+ Admin command helpfiles are shown by ahelp. Many don't have helpfiles yet.
+ "ahelp admin_commands" gives a list of all the admin commands.
+ Type "anews" for admin news. "anews all" to catch up if you forgot.
+__________________________________________________________________________
--- /dev/null
+
+anews
+
+Usage: anews [#, all]
+RESTRICTED TO ADMINISTRATORS.
+
+ This command is used to display anews (admin news) entries. The entries are
+numbered. "Anews #" displays that anews item. "Anews all" will display all
+items. Anews items are created by the "canewsi" command with further
+information archived by the "canewsf" command.
+
+See ahelp: canewsf canewsi cnewsf cnewsi
+See help: motd_help news
+
+[Last modified: September 14, 1995 -- Friar]
+
--- /dev/null
+
+announce
+
+Usage: announce message
+RESTRICTED TO ADMINISTRATORS.
+
+ Broadcasts your message to all logged on users. Announcements reach all
+users and cannot be censored in any way (such as by "set shout 0").
+
+See ahelp: annunreg
+See help: shout
+
+[Last modified: June 22, 1995 -- Friar]
+
--- /dev/null
+
+annunreg
+
+Usage: annunreg message
+RESTRICTED TO ADMINISTRATORS.
+
+ Broadcasts your message to all logged on unregistered users, and admins,
+too. Announcements reach all unregistered users and admins and cannot be
+censored in any way (such as by "set shout 0").
+
+See ahelp: announce
+See help: shout
+
+[Last modified: June 22, 1995 -- Friar]
+
--- /dev/null
+
+areload
+
+Usage: areload
+RESTRICTED TO GODS
+
+ This reloads the server code without disturbing any games that are
+ in progress or losing connections to users.
+
+ This makes it possible to add new commands or fix bugs on the fly.
+
--- /dev/null
+
+asetadmin
+
+Usage: asetadmin player AdminLevel
+RESTRICTED TO ADMINISTRATORS.
+
+ Sets the admin level of the player with the following restrictions.
+ 1. You can only set the admin level of players lower than yourself.
+ 2. You can only set the admin level to a level that is lower than
+ yourself.
+
+ Levels
+ ------
+ 0 - Normal user. Almost everyone is admin level 0.
+ 10 - Administrator. This level allows you to execute administrator
+ commands.
+ 20 - Master Administrator. Allows you to make and break
+ administrators.
+ 100 - God. You can do anything.
+
+See ahelp: admin-hierarchy
+See help:
+
+[Last modified: June 22, 1995 -- Friar]
+
--- /dev/null
+
+asetblitz
+
+Usage: asetblitz handle rating won lost drew RD
+RESTRICTED TO ADMINISTRATORS.
+
+ This command allows admins to set a user's statistics for Blitz games. The
+parameters are self-explanatory: rating, # of wins, # of losses, # of draws,
+and ratings deviation.
+
+See ahelp: asetstd asetwild
+See help: glicko ratings
+
+[Last modified: July 17, 1995 -- Friar]
+
--- /dev/null
+
+asetbughouse
+
+Usage: asetbughouse handle rating won lost drew RD
+RESTRICTED TO ADMINISTRATORS.
+
+ This command allows admins to set a user's statistics for bughouse games.
+The parameters are self-explanatory: rating, # of wins, # of losses, # of
+draws, and ratings deviation.
+
+See ahelp: asetblitz asetwild asetstd
--- /dev/null
+
+asetemail
+
+Usage: asetemail player [address]
+RESTRICTED TO ADMINISTRATORS.
+
+ Sets the email address of the player to the address given. If the address
+is omited, then the player's email address is cleared. The person's email
+address is revealed to them when they use the "finger" command, but no other
+users -- except admins -- will have another player's email address displayed.
+
+See ahelp: finger
+See help: finger
+
+[Last modified: June 22, 1995 -- Friar]
+
--- /dev/null
+
+asethandle
+
+Usage: asethandle oldname newname
+RESTRICTED TO ADMINISTRATORS.
+
+ This command changes the handle of the player from oldname to newname. The
+various player information, messages, logins, comments and games should be
+automatically transferred to the new account.
+
+See ahelp: asetpasswd
+See help:
+
+[Last modified: June 22, 1995 -- Friar]
+
--- /dev/null
+
+asetlight
+
+Usage: asetlight handle rating won lost drew RD
+RESTRICTED TO ADMINISTRATORS.
+
+ This command allows admins to set a user's statistics for lightning games.
+The parameters are self-explanatory: rating, # of wins, # of losses, # of
+draws, and ratings deviation.
+
+See ahelp: asetblitz asetwild asetstd
--- /dev/null
+
+asetmaxplayer
+
+Usage: asetmaxplayer [n]
+RESTRICTED TO ADMINISTRATORS.
+
+ With an argument, this command raises or lowers the level at which logons
+from non-admins will be filtered. If an argument is supplied, it is checked
+to make sure it is both within the limits of the operating system and at least
+minimally safe. Without an argument, the command displays detailed
+information about the current limits.
+
+ The greater of max_connections-50 and 200 is a threshhold for triggering
+guest login restrictions. When the number of non-admin users is above that
+value, unregistered logins are turned away with a nice message.
+
+See ahelp:
+See help: limits
+
+[Last modified: October 9, 1995 -- Friar]
+
--- /dev/null
+
+asetpasswd
+
+Usage: asetpasswd player {password,*}
+RESTRICTED TO ADMINISTRATORS.
+
+ This command sets the password of the player to the password given. If '*'
+is specified then the player's account is locked, and no password will work
+until a new one is set by asetpasswd..
+
+ If the player is connected, he is told of the new password and the name of
+the admin who changed it, or likewise of his account status. An email message
+is mailed to the player's email address as well.
+
+See ahelp:
+See help: password
+
+[Last modified: July 1, 1995 -- Friar]
+
--- /dev/null
+
+asetrealname
+
+Usage: asetrealname user newname
+RESTRICTED TO ADMINISTRATORS.
+
+ This command sets the user's real name (as displayed to admins on finger
+notes) to "newname".
+
+See ahelp: finger
+See help:
+
+[Last modified: June 22, 1995 -- Friar]
+
--- /dev/null
+
+asetstd
+
+Usage: asetstd handle rating won lost drew RD
+RESTRICTED TO ADMINISTRATORS.
+
+ This command allows admins to set a user's statistics for Standard games.
+The parameters are self-explanatory: rating, # of wins, # of losses, # of
+draws, and ratings deviation.
+
+See ahelp: asetblitz asetwild
+See help: glicko ratings
+
+[Last modified: July 17, 1995 -- Friar]
+
--- /dev/null
+
+asetv
+
+Usage: asetv user instruction
+RESTRICTED TO ADMINISTRATORS.
+
+ This command executes "set" instructions as if they had been made by the
+user indicated. For example, "asetv DAV shout 0" would set DAV's shout
+variable to 0.
+
+See ahelp: pose
+See help: set variables
+
+[Last modified: October 1, 1995 -- Friar]
+
--- /dev/null
+
+asetwild
+
+Usage: asetwild handle rating won lost drew RD
+RESTRICTED TO ADMINISTRATORS.
+
+ This command allows admins to set a user's statistics for Wild games. The
+parameters are self-explanatory: rating, # of wins, # of losses, # of draws,
+and ratings deviation.
+
+See ahelp: asetblitz asetstd
+See help: glicko ratings
+
+[Last modified: July 17, 1995 -- Friar]
+
--- /dev/null
+
+ban
+
+Usage: [+,-,=]ban handle
+RESTRICTED TO ADMINISTRATORS.
+
+ Adds to (+ban), removes from (-ban) or lists users on (=ban) the ban list.
+Users on the ban list cannot log onto the server. The user's account will
+still be active, however. As a result, autoregistration will screen out the
+user's email address and prevent additional accounts from being created from
+there, and the handle cannot be adopted by another user.
+
+ When you ban (or unban) a user, please leave a message in the player's
+comments file using the "addcom" command. You may also want to lock the
+account by "asetpasswd handle *".
+
+ Concerning when to ban a user, please refer to the admin guidelines that
+have been developed. See also help files on server conduct, such as abuser,
+etiquette and shout_abuse. It is also best to consult without admins abut the
+case in question. Documentation of user behavior is important.
+
+See ahelp: addcom asetpasswd filter
+See help: abuser etiquette lists shout_abuse showlists
+
+[Last modified: October 16, 1995 -- Friar]
+
--- /dev/null
+FICS bugs as of 7/22/95:
+
+The bugs followed by a (?) are not verified. They could be caused
+by some operator error or other anomoly. After verification by a
+few admins that they do not exist, they will be removed from the list.
+
+FIXED If you are observing a game and type moves it says that you are
+ not playing, observing, or examining a game.
+
+2. The ratings system needs to be verified for accuracy. Several
+ people have reported discrepencies. (E.g. According to the
+ formulas, RD can increase only due to the passage of time,
+ never because of playing a game. Yet sometimes people who
+ have just played play again and their RD increases. According
+ to Glickman, this must be a bug. (Courtesy fritzl))
+
+3. Draw by repetition being claim even though a position only came up
+ on time. (?)
+
+FIXED Some people stay logged into channels and notify lists even though
+ they are not logged in.
+
+FIXED Private games can be watched by repeated typing refresh.
+
+6. When challanged to a wild 5 game, after accepting, it becomes a
+ wild 0 game. Reported several times. (?)
+
+7. An ambiguity in the move list occurs when two rooks can capture on
+ the same square. (?)
+
+8. The width variable is not considered in who. Some reports even say
+ that it is not considered at all.
+
+9. History recognizes a stalemate as a win for the person who stalemated. (?)
+
+10. When you want to log in as an unregistered user, if you first choose
+ a handle which is already registered, the server tells you to hit
+ return and try again. But it doesn't let you try again! It
+ disconnects you instead.
+
+11. When loading a 2 12 rated game on move 19, an unrated untimed game
+ on move 1 comes up. (?)
+
+FIXED Even if kibitz is set to 0, you still hear kibitzes.
+
+13. The time and date that is sent with mailmoves is wrong. (?)
+
+FIXED When you offer an abort, your opponent is not told to type abort
+ to accept.
+
+15. Unregistered players can set stats and make notify lists and keep
+ a history, from login to login!
+
+16. Before the game the server reports "your new RD is x." However, after
+ the game, x does not correspond with your new RD.
+
+17. When someone makes the move "bc3" the server needs to check for Bishop
+ captures c3 or Pawn captures c3.
+
+FIXED Wins can be awarded on time even if there are no pieces left. (?)
+
+19. There are discrepencies in the 'assess' command's predictions. (?)
+
+FIXED Wild5 reverses the players ratings in the match challenge. (?)
+ (Has been report for other games too.)
+
+21. After mailing old moves, the server claims "No such game," but it
+ still mails the moves. (?)
+
+22. Someone sends a draw offer and then they move, which causes the
+ server to decline the draw. Then the person types decline
+ and it sends another draw offer. (?)
+
+23. When a player has two adjourned games, the 'accept' command tried to
+ load the other. The players are unable to play each other. (See
+ pdeck Jun 7) (?)
+
+24. A player cannot play 0 8 (or any other increment) because it parses as
+ untimed. (?)
+
+25. When a player is challenged to a normal match, and then a wild match by
+ a different person, if the normal game is accepted, the game becomes
+ a wild match with the person who challenged to the normal game. (?)
+
+26. If a player has been idle for example for 2:30 (2 hours 30 minutes),
+ when someone tells something to that person it says the player has
+ been idle for only 30 minutes (not 2:30).
+
+FIXED If you do 'sa' for say, it tries to simabort instead.
+
+28. With auto=1, drawn games are not sent. (?)
+
+[Last Modified: July 22, 1995 -- Marsalis]
+
+
--- /dev/null
+canewsd\r
+\r
+Usage: canewsd #\r
+RESTRICTED TO ADMINISTRATORS.\r
+\r
+This command removes the last line of an admin news item\r
+\r
+See ahelp: canewse canewsi canewsp canewst\r
+See help: anews\r
--- /dev/null
+canewse\r
+\r
+Usage: canewse # [n]\r
+RESTRICTED TO ADMINISTRATORS.\r
+\r
+ This command sets the expiration of the anews item to a number of days [n].\r
+The '#' is the number of the anews index. If the number of days is not\r
+specified, the anews item will be perpetual; otherwise, it will expire in\r
+the specified number of days and be removed from the anews index altogether.\r
+The expiration of anews items will force the anews index out of its running\r
+sequence.\r
+\r
+NOTICE: To expire an anews item immediately, use 'canewse # 0'.\r
+\r
+See ahelp: canewsf canewsi canewsp canewst\r
+See help: anews\r
+\r
+[Last modified: December 12, 1999 -- carlsbad]\r
--- /dev/null
+
+canewsf
+
+Usage: canewsf # message
+RESTRICTED TO ADMINISTRATORS.
+
+ This command allows you to add additional information about an anews item
+that had previously been created using 'canewsi'. The '#' is the number of
+the news index and 'message' is the additional text. You can also modify a
+previous anews item description and thus update the anews item easily.
+
+See ahelp: canewsi
+See help: anews
+
+[Last modified: September 14, 1995 -- Friar]
+
--- /dev/null
+
+canewsi
+
+Usage: canewsi message
+RESTRICTED TO ADMINISTRATORS.
+
+ This command adds a new item to the anews index. The message is limited to
+45 characters for formating purposes. In essence, the anews index works like
+a newspaper headline, giving admins enough information to know whether they
+should read the entire anews file for that item. A list of recent anews items
+is displayed by the 'anews' command.
+
+ After creating the anews item, the command reports the anews item number
+along with a reminder to create an anews file if necessary. This command
+replaced the 'createanews' command.
+
+See ahelp: canewsf
+See help: anews
+
+[Last modified: September 14, 1995 -- Friar]
+
--- /dev/null
+canewsp\r
+\r
+Usage: canewsp #\r
+RESTRICTED TO ADMINISTRATORS.\r
+\r
+ This command allows you to change the poster of an anews item. The 'Posted\r
+by <admin>' line at the end of the anews item will reflect the admin account\r
+which executed the command. The '#' is the number of the anews index.\r
+\r
+See ahelp: canewse canewsf canewsi canewst\r
+See help: anews\r
+\r
+[Last modified: December 12, 1999 -- carlsbad]\r
--- /dev/null
+canewst\r
+\r
+Usage: cnewst # message\r
+RESTRICTED TO ADMINISTRATORS.\r
+\r
+ This command allows you to change the title of an anews item that had\r
+previously been created using 'canewsi'. The '#' is the number of the anews\r
+index and 'message' is the new title. The message length limit in 'canewsi'\r
+also applies here.\r
+\r
+See ahelp: canewse canewsf canewsi canewsp\r
+See help: anews\r
+\r
+[Last modified: December 12, 1999 -- carlsbad]\r
--- /dev/null
+
+chkgame
+
+Usage: chkgame #
+RESTRICTED TO ADMINISTRATORS.
+
+ This command is a debugging tool primarlity, but might be useful for other
+occasions as well. The following information on a game is displayed:
+
+Current stored info for game # (garray[#]):
+Initial white time: # Initial white increment #
+Initial black time: # Initial black increment #
+Time of starting: DATE
+Game is: User1 (rating) vs. User2 (rating)
+White parray entry: # Black parray entry #
+Game is not bughouse or link to partner's game not found.
+ [versus bughouse links exist]
+Game is rated [or unrated]
+Game is not private [or is private]
+Games is of type blitz [or other type]
+## halfmove(s) have been made
+White's time # Black's time #
+The clock is [is not] ticking
+Game status: GAME_NEW [versus GAME_EXAMINE for instance]
+
+See ahelp:
+See help: games
+
+[Last modified: December 25, 1995 -- Friar]
+
--- /dev/null
+
+chkip
+
+Usage: chkip ip_address
+RESTRICTED TO ADMINISTRATORS.
+
+ This command returns the names and IPs of all users currently logged on from
+a given IP address. You can use the '*' wildcard in this command. For
+example:
+
+ chkip 129.1.*
+
+will give all users with IP's beginning with "129.1.1".
+
+See ahelp:
+See help:
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+
+chkpl
+
+Usage: chkpl handle
+RESTRICTED TO ADMINISTRATORS.
+
+ This command displays server information about a given user. Items
+displayed are:
+
+ number X in parray of size Y
+ name
+ login
+ fullName
+ emailAddress
+ socket
+ registered
+ last_tell
+ last_channel
+ logon_time
+ adminLevel
+ muzzled
+ cmuzzled
+ network_player
+ thisHost
+ lastHost
+ num_notify
+ num_comments
+
+See ahelp: chkip
+See help: finger
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+
+chksc
+
+Usage: chksc n
+RESTRICTED TO ADMINISTRATORS.
+
+ Shows which user is logged on to socket n.
+
+See ahelp:
+See help:
+
+[Last modified: October 11, 1995 -- Friar]
+
--- /dev/null
+
+chkts
+
+Usage: chkts
+RESTRICTED TO ADMINISTRATORS.
+
+ This command displays all current users who are using timeseal.
+
+See ahelp:
+See help: timeseal
+
+[Last modified: August 20, 1995 -- Friar]
+
--- /dev/null
+
+cmuzzle
+
+Usage: [=,-,=]cmuzzle
+RESTRICTED TO ADMINISTRATORS.
+
+ Adds to (+cmuzzle), removes from (-cmuzzle) or lists users on (=cmuzzle) the
+cmuzzle list. Users on the cmuzzle list cannot use "cshout". Other forms of
+communication are not affected.
+
+ When you cmuzzle (or uncmuzzle) a user, please leave a message in the
+player's comments file using the "addcom" command. Documentation of user
+behavior is important.
+
+ Concerning when to cmuzzle a user, please refer to the admin guidelines that
+have been developed. See also help files on server conduct, such as abuser,
+etiquette and shout_abuse.
+
+See ahelp: addcom muzzle
+See help: etiquette lists shout shout_abuse
+
+[Last modified: October 16, 1995 -- Friar]
+
--- /dev/null
+cnewsd\r
+\r
+Usage: cnewsd #\r
+RESTRICTED TO ADMINISTRATORS.\r
+\r
+This command removes the last line of a news item\r
+\r
+See ahelp: cnewse cnewsi cnewsp cnewst\r
+See help: news\r
--- /dev/null
+cnewse\r
+\r
+Usage: cnewse # [n]\r
+RESTRICTED TO ADMINISTRATORS.\r
+\r
+ This command sets the expiration of the news item to a number of days [n].\r
+The '#' is the number of the news index. If the number of days is not\r
+specified, the news item will be perpetual; otherwise, it will expire in the\r
+specified number of days and be removed from the news index altogether. The\r
+expiration of news items will force the news index out of its running sequence.\r
+\r
+NOTICE: To expire a news item immediately, use 'cnewse # 0'.\r
+\r
+See ahelp: cnewsf cnewsi cnewsp cnewst\r
+See help: news\r
+\r
+[Last modified: December 12, 1999 -- carlsbad]\r
--- /dev/null
+cnewsf\r
+\r
+Usage: cnewsf # message\r
+RESTRICTED TO ADMINISTRATORS.\r
+\r
+ This command allows you to add additional information about a news item\r
+that had previously been created using 'cnewsi'. The '#' is the number of the\r
+news index and 'message' is the additional text. You can also modify a\r
+previous news item description and thus update the news item easily.\r
+\r
+NOTICE: To remove the text in a news item, use 'cnews #'.\r
+\r
+See ahelp: cnewse cnewsi cnewsp cnewst\r
+See help: news\r
+\r
+[Last modified: December 12, 1999 -- carlsbad]\r
--- /dev/null
+cnewsi\r
+\r
+Usage: cnewsi message\r
+RESTRICTED TO ADMINISTRATORS.\r
+\r
+ This command adds a new item to the news index. The message is limited to\r
+45 characters for formating purposes. In essence, the news index works like a\r
+newspaper headline, giving the user enough information to know whether they\r
+should read the entire news file for that item. After creating the news item,\r
+the command reports the news item number along with a reminder to create a\r
+news file if necessary.\r
+\r
+See ahelp: cnewse cnewsf cnewsp cnewst\r
+See help: news\r
+\r
+[Last modified: December 12, 1999 -- carlsbad]\r
--- /dev/null
+cnewsp\r
+\r
+Usage: cnewsp #\r
+RESTRICTED TO ADMINISTRATORS.\r
+\r
+ This command allows you to change the poster of a news item. The 'Posted by\r
+<admin>' line at the end of the news item will reflect the admin account which\r
+executed the command. The '#' is the number of the news index.\r
+\r
+See ahelp: cnewse cnewsf cnewsi cnewst\r
+See help: news\r
+\r
+[Last modified: December 12, 1999 -- carlsbad]\r
--- /dev/null
+cnewst\r
+\r
+Usage: cnewst # message\r
+RESTRICTED TO ADMINISTRATORS.\r
+\r
+ This command allows you to change the title of a news item that had\r
+previously been created using 'cnewsi'. The '#' is the number of the news\r
+index and 'message' is the new title. The message length limit in 'cnewsi'\r
+also applies here.\r
+\r
+See ahelp: cnewse cnewsf cnewsi cnewsp\r
+See help: news\r
+\r
+[Last modified: December 12, 1999 -- carlsbad]\r
--- /dev/null
+
+createanews
+
+ This command has been superceded by the canewsi and canewsf commands.
+Please review those help files.
+
+See ahelp: anews canewsi canewsf
+See help: news
+
+[Last modified: September 14, 1995 -- Friar]
+
--- /dev/null
+
+filter
+
+Usage: [+,-,=]filter ip
+RESTRICTED TO ADMINISTRATORS.
+
+
+ This list bans unreg logins from a site where "ip" is a full or partial ip
+address. The number of levels in the "ip" affects how much filtering is made.
+An "ip" of 123.124.125.126 will ban a machine, 123.124.125 will ban the
+server, and 123.124 will probably ban the whole site. A special account has
+been established for documenting the need to filter logins: "filter".
+
+ When you filter a site, please leave a message in the filter account:
+"message filter <explanation>". To read the log of messages in this account,
+type "ahelp filtered".
+
+See ahelp: accounts lists
+See help:
+
+[Last modified: July 16, 1995 -- Friar]
+
--- /dev/null
+
+finger
+
+ Private, confidential information about a user is revealed to admins when
+they use the "finger" command. This information includes the player's real
+name, email address and whether the player has any comments attached to
+his/her account.
+
+See ahelp: showcomment
+See help: finger
+
+[Last modified: June 22, 1995 -- Friar]
+
--- /dev/null
+ftell
+
+Usage: ftell user
+
+ This command forwards all further conversation between an admin and a
+ user to all those listening in channel 0.
+ It is unset as soon as the user logs off or ftell is typed without a
+ parameter.
--- /dev/null
+
+hideinfo
+
+Usage: hideinfo
+RESTRICTED TO ADMINISTRATORS.
+
+This command enables/disables the displaying of private player
+information to administrators.
--- /dev/null
+
+lists
+
+RESTRICTED TO ADMINISTRATORS.
+
+ There are several lists restricted to admin use. They are:
+
+ abuser for users who have abused server etiquette
+ cmuzzle prevents user from using cshouts
+ computer identifies user as a computer
+ filter prevents unreg logons from certain sites
+ fm adds FM label to a user
+ gm adds GM label to a user
+ im adds IM label to a user
+ muzzle prevents user from using shouts
+ quota limits frequency of a user's shouts
+
+ To add a user to one of these lists, use "+list_name". To remove a user,
+use "-list_name". And "=list_name" lists users on that list. For most lists,
+comments are automatically added to the user's file, and you may want to add
+one of your own comments as well in order to record your action and reasons.
+
+ Some lists are private, for admin reading only. Some can be read by all
+users. The "showlists" help file gives the security level for the lists.
+
+See ahelp: cmuzzle filter muzzle quota
+See help: abuser etiquette showlists
+
+[Last modified: June 26, 1995 -- Friar]
+
--- /dev/null
+
+muzzle
+
+Usage: [=,-,=]muzzle
+RESTRICTED TO ADMINISTRATORS.
+
+ Adds to (+muzzle), removes from (-muzzle) or lists users on (=muzzle) the
+muzzle list. Users on the muzzle list cannot use "shout" or "it". They can,
+however, use "tell" (including tells to channels).
+
+ When you muzzle (or unmuzzle) a user, please leave a message in the player's
+comments file using the "addcom" command. Documentation of user behavior is
+important.
+
+ Concerning when to muzzle a user, please refer to the admin guidelines that
+have been developed. See also help files on server conduct, such as abuser,
+etiquette and shout_abuse.
+
+See ahelp: addcom cmuzzle
+See help: etiquette lists shout shout_abuse
+
+[Last modified: October 16, 1995 -- Friar]
+
--- /dev/null
+
+nuke
+
+Usage: nuke user
+RESTRICTED TO ADMINISTRATORS.
+
+ This command disconnects the user from the server. The user is informed
+that she/he has been nuked by the admin named and a comment is automatically
+placed in the user's files (if she/he is a registered user, of course). Do
+not nuke someone for fun!
+
+See ahelp:
+See help: etiquette shout_abuse
+
+[Last modified: July 1, 1995 -- Friar]
+
--- /dev/null
+
+pose
+
+Usage: pose user command
+RESTRICTED TO ADMINISTRATORS -- Super Users ONLY!!!
+
+ Executes 'command' as if it were typed by 'user'. This command goes beyond
+the "asetv" command because "asetv" relates only to variable settings while
+"pose" relates to ALL commands a user might execute.
+
+See ahelp: asetv
+See help:
+
+[Last modified: October 1, 1995 -- Friar]
+
--- /dev/null
+Projects for FICS:
+
+Big projects:
+
+1. Set up commands for examine mode; allow examiners to add or remove pieces
+ to or from a position. Also allow users to clear the board except for
+ kings.
+
+2. Network many servers together.
+
+
+Medium projects:
+
+3. Rank information in RAM. UpdateRank takes too long.
+
+
+Smaller projects:
+
+4. Channel names (like "admin channel") instead of channel numbers
+ ("channel 0"). If we do this, I think we could seriously consider
+ eliminating the "shout" and "it" commands.
+
+5. Draw offers and aborts for adjourned games.
+
+6. On line registration. I don't see any reason not to allow this now that
+ we also have autoreg by e-mail.
+
+7. Apparently some limits are not checked; MAX_CHANNEL, MAX_ALIAS, probably
+ some others as well. We should fix this.
+
+Well, these are my immediate thoughts; feel free to add your own, or to
+program these.
+
+[Last modified: November 16, 1995 -- hersco]
+
--- /dev/null
+
+quota
+
+Usage: quota [n]
+RESTRICTED TO ADMINISTRATORS.
+
+ The command sets the number of seconds (n) for the shout quota, which
+affects only those persons on the shout quota list. If no parameter (n) is
+given, the current setting is displayed.
+
+See ahelp: lists
+See help: it shout shout_abuse shout_quota
+
+[Last modified: June 23, 1995 -- Friar]
+
--- /dev/null
+
+raisedead
+
+Usage: raisedead oldname [newname]
+RESTRICTED TO ADMINISTRATORS
+
+ Restores an account that has been previously removed using "remplayer".
+The zombie files from which it came are removed. Under most circumstances,
+you restore the account to the same handle it had before (oldname). However,
+in some circumstances you may need to restore the account to a different
+handle, in which case you include "newname" as the new handle. After
+"raisedead", you may need to use the "asetpasswd" command to get the player
+started again as a registered user, especially if the account had been locked
+by setting the password to *.
+
+See ahelp: addplayer asethandle asetpasswd remplayer
+See help:
+
+[Last modified: July 1, 1995 -- Friar]
+
--- /dev/null
+
+register
+
+
+ *** Email registration is now automated! ***
+
+
+To get a registered account, send a message to this address:
+
+ chess@caissa.onenet.net
+
+... and use as the Subject: "Fics Registration"
+
+Include a line like the following as the text of your message (please make the
+appropriate substitutions as indicated by the <>'s markers):
+
+ fics_addplayer <handle> "<First M. Last>" <email-address> <human|computer>
+
+Here is an example which would register Sparky with the correct name and email
+information:
+
+ Ex: fics_addplayer Sparky "Chris L. Petroff" chris@onenet.net
+ or: fics_addplayer Sparky "Chris L. Petroff" chris@onenet.net human
+
+
+SPECIAL NOTES:
+
+(1) Quotation marks MUST be used around the name field.
+
+(2) If this is a human account, 'human' need not be specified. However,
+ 'computer' MUST be used if you are registering a computer on FICS (see
+ "computers" help file).
+
+(3) Do NOT include the <>'s markers in your text. They are used above only
+ to indicate where you need to place information.
+
+(4) Please tell us if you are an FM, IM or GM (master's titles for
+ international competition).
+
+
+See Also: computers
+
+[Last modified: June 23, 1995 -- Friar]
\ No newline at end of file
--- /dev/null
+
+remplayer
+
+Usage: remplayer name
+RESTRICTED TO ADMINISTRATORS.
+
+ Removes an account. A copy of its files are saved under .rem.* which can
+be found in the appropriate directory (useful in case of an accident).
+
+ The account's details, messages, games and logons are all saved as 'zombie'
+files. These zombie accounts are not listed in handles or totals. Although a
+handle may have been removed, it is not possible for another user to register
+with this handle -OR- to register for a new account using email registration.
+The autoregister program checks for regular as well as remplayered accounts.
+
+ Please do not use this command unless necessary, such as for multiple
+accounts or inappropriate handles. To stop a player from having access to an
+account, it may be preferable to use the "asetpasswd" command instead.
+
+See also: addplayer asetpasswd raisedead
+
+[Last modified: October 17, 1995 -- Friar]
+
--- /dev/null
+
+rerank
+
+Usage: rerank name
+RESTRICTED TO ADMINISTRATORS.
+
+ Use this command to reset a player's rank if there has been a calculation
+error.
+
+See ahelp:
+See help: best hbest hrank rank
+
+[Last modified: June 22, 1995 -- Friar]
+
--- /dev/null
+
+SERVER COMMANDS [taken from ONENET chess site]
+
+ The following text is displayed when you telnet to ics.onenet.net and log in
+through the admin doorway.
+
+/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\
+| It's BACK!! ;-> Sveshi's Power-Admin command set: Commands now defined: |
+| |
+| 'ckemail' - search for anything you like in the address database. |
+| (will show matches for any part of email, realname) |
+| 'ckname' - search for A NAME (two words) in the address database. |
+| 'cklog' - search connect log for a player. |
+| 'host' - Tells you an alpha host name from the numeric. |
+| 'players' - gives last 24 autoregister attempts. |
+| 'uscf' - Searches for the USCF rating of a person (two words) |
+| 'fide' - Searches for the ELO rating of a person (two words) |
+| 'icswho' - Print name and email info for a player handle |
+| |
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Friar's notes
+-------------
+ The commands are typed at the server prompt. They may come in handy when
+trying to verify certain user information or dealing with problem situations,
+such as duplicate accounts or whether a user is a titled chess master.
+
+
+Usage Result
+______________________ _____________________________________________
+
+ckemail string Hits for 'string' in address database
+ckname name1 name2 Hits for 'name1 name2' in address database
+cklog user_handle Lists connect log for user_handle
+host ip_number Provides alpha name for IP address
+players Lists last 24 autoregister attempts
+uscf name1 name2 USCF rating for 'name1 name 2'
+fide name1 name2 FIDE rating for 'name1 name 2'
+icswho user_handle Real_name and email address for user_handle
+
+[Last update: September 24, 1995 -- Friar]
--- /dev/null
+
+showcomment
+
+Usage: showcomment user
+RESTRICTED TO ADMINISTRATORS.
+
+ This command will display all of the comments added to the user's account.
+
+See ahelp: addcomment
+See help:
+
+[Last modified: June 22, 1995 -- Friar]
+
--- /dev/null
+
+shutdown
+
+Usage: shutdown [now,cancel,time,die] [comment]
+RESTRICTED TO ADMINISTRATORS.
+
+ This command shuts down the server, but with different consequences. If the
+parameter is omitted or is 'now' then the server is immediately halted cleanly
+(including games being saved). If a time is given then a countdown commences
+and the server is halted when time is up; "time" is given in seconds (not
+minutes). If 'cancel' is given then the countdown is stopped. If the
+parameter is 'die', the server will be halted immediately without saving
+games; this version can be useful for debugging purposes, but users will need
+to be warned in advance because the consequences differ from a normal,
+announced shutdown.
+
+ You can add an optional comment to this command. If there is a comment, it
+will be displayed to users each time the countdown is updated. Having a
+comment is a useful way to explain the reason for the shutdown and cut down on
+the number of questions admins will have to answer about the shutdown.
+
+ Using "announce" may be useful during a coutdown so that users can be
+informed of special information, such as how long the shutdown will last.
+
+See ahelp: announce
+See help:
+
+[Last modified: December 25, 1995 -- Friar]
+
--- /dev/null
+
+summon
+
+Usage: summon player
+RESTRICTED TO ADMINISTRATORS.
+
+ This command gives a beep and a message to the player indicating that you
+want to talk with him/her. The command is useful for waking someone up, for
+example a sleepy admin or an ignorant player.
+
+See ahelp:
+See help:
+
+[Last modified: June 22, 1995 -- Friar]
+
--- /dev/null
+D/wild////
--- /dev/null
+lasker/data/boards
--- /dev/null
+lasker/data/boards/wild
--- /dev/null
+/changes.txt/1.1/Thu Jun 6 12:09:14 2002//
+/eco000.idx/1.1/Thu Jun 6 12:09:14 2002//
+/eco999.idx/1.2/Thu Jun 6 12:09:14 2002//
+/fen.doc/1.1/Thu Jun 6 12:09:14 2002//
+/long001.idx/1.1/Thu Jun 6 12:09:14 2002//
+/long999.idx/1.2/Thu Jun 6 12:09:14 2002//
+/nic000.idx/1.1/Thu Jun 6 12:09:14 2002//
+/nic999.idx/1.2/Thu Jun 6 12:09:14 2002//
+/opening.doc/1.1/Thu Jun 6 12:09:14 2002//
+D
--- /dev/null
+lasker/data/book
--- /dev/null
+
+To long001.idx:
+
+Changed:
+
+ KGA: bishop's gambit, Chigorin's attack/Gifford variation
+ KGA: bishop's gambit, Chigorin's attack (Gifford variation)
+
+ Santasiere's folly
+ Santasiere's Folly
+
+ Nimzo-Indian: 4.e3 c5, 5.Ne2 (Rubinstein)
+ Nimzo-Indian: 4.e3 c5, 5.Ne2 (Rubinstein, anti-H\"ubner system)
+
+ Ruy Lopez: closed (8...Na5)
+ Ruy Lopez: closed (9...Na5)
+
+ All occurences of "defence" to "defense"
+ All occurences of "manoevre" to "maneuver"
+ All occurences of "centre" to "center"
+
+Added:
+
+ Queen's pawn: London system
+ d2d4 g8f6 c1f4
--- /dev/null
+1rbq1rk1/1pp1ppbp/p1np1np1/8/2PPP3/2N1BP2/PP1QN1PP/R3KB1R w KQ -
+E84
+2kr1b1r/ppp3pp/2n2q2/3npp2/6b1/P2PPN2/1PQNBPPP/R1B1K2R b KQ -
+B99*
+2kr1b1r/ppp3pp/2n5/3qpp2/6b1/3PPN2/PP2BPPP/R1BQ1RK1 w - -
+B65*
+2kr1b1r/pppq1ppp/2n5/3np3/6b1/P1NPPN2/1P1B1PPP/R2QKB1R b KQ -
+B67*
+2kr1b1r/pppq2pp/2n2n2/4pp2/1P6/P1NPPb2/3BBPPP/R2QK2R w KQ -
+B69*
+2kr1b1r/pppq2pp/2n5/3npp2/6b1/2NPPN2/PP2BPPP/R1BQ1RK1 w - -
+B64*
+2kr1b1r/pppq2pp/2n5/3npp2/6b1/P1NPPN2/1P1BBPPP/R2QK2R b KQ -
+B68*
+2kr3r/pppq2p1/1bn1bp2/3np2p/Q7/2NP1NP1/PP1BPPBP/R1R3K1 w - -
+B79*
+2kr3r/pppq2pp/2n1bp2/2bnp3/8/2NP1NP1/PP1BPPBP/R2Q1RK1 w - -
+B78*
+2r1kb1r/ppq2ppp/2n1pn2/2pp4/3P2b1/2P1PN2/PP1NBPPP/R1BQ1RK1 w k -
+D64*
+2r1kb1r/ppq2ppp/2n1pn2/3p4/3p2b1/P1P1PN2/1P1NBPPP/R1BQ1RK1 w k -
+D65*
+2rqk2r/pp3ppp/2n1pn2/2bp4/3N2b1/2P1P3/PP1NBPPP/R1BQ1RK1 b k -
+D67*
+2rqk2r/pp3ppp/2nbpn2/2pp4/3P2b1/2P1PN2/PP1NBPPP/R1BQ1RK1 w k -
+D66*
+2rqkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w k -
+D63*
+2rqkbnr/pp3ppp/2n1p3/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQ1RK1 w k -
+D54*
+3q1rk1/pp3ppp/2r1p3/2b5/4Q3/2P5/PP3PPP/R1B2RK1 b - -
+D69*
+3q1rk1/pp3ppp/2r1pn2/2bp4/4P3/2P5/PP1NQPPP/R1B2RK1 b - -
+D68*
+r1b1k2r/1pqnbppp/p2ppn2/6B1/3NPP2/2N2Q2/PPP3PP/2KR1B1R w kq -
+B99
+r1b1kb1r/1pq2ppp/p1nppn2/8/3NPP2/2N5/PPP1B1PP/R1BQ1RK1 w kq -
+B85
+r1b1kb1r/pp2pppp/1qn2n2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+D96*
+r1b1kb1r/pp3ppp/1qn1pn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+D95*
+r1b1kb1r/pp3ppp/2n2n2/2qpp1B1/8/5NP1/PPP1PPBP/RN1Q1RK1 b kq -
+D98*
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+D97*
+r1b1kbnr/1pq1pppp/p1n5/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R w KQkq -
+E36*
+r1b1kbnr/1pq1pppp/p7/2ppN3/3P4/4P3/PPP2PPP/RNBQK2R w KQkq -
+E37*
+r1b1kbnr/1pqp1ppp/p1n1p3/8/3NP3/2N1B3/PPP1BPPP/R2QK2R b KQkq -
+B49
+r1b1kbnr/pp2pppp/1qn5/1Bp5/2p5/2N1PN2/PP1P1PPP/R1BQK2R b KQkq -
+E23*
+r1b1kbnr/pp2pppp/1qn5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+E22*
+r1b1kbnr/pp2pppp/1qn5/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+D81*
+r1b1kbnr/ppq1pppp/2n5/1B1p4/3P4/5N2/PPP2PPP/RNBQK2R b KQkq -
+E35*
+r1b1kbnr/ppq1pppp/2n5/1Bp5/2p5/4PN2/PP1P1PPP/RNBQ1RK1 b kq -
+E39*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+E38*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R b KQkq -
+E34*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/8/2N1PN2/PPPP1PPP/R1BQK2R b KQkq -
+E33*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+E32*
+r1b1kbnr/ppqp1ppp/2n1p3/8/3NP3/2N1B3/PPP2PPP/R2QKB1R b KQkq -
+B48
+r1b1kbnr/ppqp1ppp/2n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+B47
+r1b2rk1/1p2qppp/2n1pn2/pBbp4/5B2/2P1PN2/PP3PPP/RN1Q1RK1 w - -
+D19*
+r1b2rk1/2q1bppp/p1np1n2/1pp1p3/3PP3/2P2N1P/PPBN1PP1/R1BQR1K1 w - -
+C98
+r1b2rk1/2q1bppp/p2p1n2/np2p3/3PP3/5N1P/PPBN1PP1/R1BQR1K1 b - -
+C99
+r1b2rk1/2q1bppp/p2p1n2/npp1p3/3PP3/2P2N1P/PPB2PP1/RNBQR1K1 w - -
+C97
+r1b2rk1/pp1nqppp/2p5/4p3/2BP4/2R1PN2/PP3PPP/3Q1RK1 w - -
+D68
+r1b2rk1/pp2ppbp/2q2np1/2pp4/8/1P2P3/PBPPBPPP/RN1Q1RK1 w - -
+E19*
+r1b2rk1/pp3ppp/2p5/4q3/2B5/2R1P3/PP3PPP/3Q1RK1 w - -
+D69
+r1b2rk1/ppq1ppbp/2n2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 w - -
+A98*
+r1b2rk1/ppqnppbp/5np1/2pp4/3P4/2P1PN2/PP1NBPPP/R1BQ1RK1 w - -
+E09*
+r1bq1rk1/1p1n1pbp/2pp1np1/p3p3/2PPP3/2N2N2/PP3PPP/R1BQRBK1 w - -
+E96
+r1bq1rk1/1p1nbppp/p1p1pn2/3P2B1/3P4/2N1PN2/PPQ2PPP/2R1KB1R b K -
+D65
+r1bq1rk1/1p1nppbp/2n3p1/p7/2Pp4/P2P1NP1/1P1N1PBP/R1BQR1K1 b - -
+A64*
+r1bq1rk1/1p2bppp/2n2n2/p3p1B1/2Pp4/P2P1NP1/1P3PBP/RN1Q1RK1 b - -
+A75*
+r1bq1rk1/1p3ppp/p1n1pn2/1BbP4/8/2N1PN2/PP3PPP/R1BQ1RK1 b - -
+E57*
+r1bq1rk1/1pp1ppbp/p1np1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+E63
+r1bq1rk1/2p1bpp1/p1np1n1p/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+C93
+r1bq1rk1/2p1bppp/p1n2n2/1p1pp3/4P3/1BP2N2/PP1P1PPP/RNBQR1K1 w - -
+C89
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/3PP3/1BP2N2/PP3PPP/RNBQR1K1 b - -
+C91
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 b - -
+C92
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/1BP2N2/PP1P1PPP/RNBQR1K1 w - -
+C90
+r1bq1rk1/2p1bppp/p2p1n2/np2p3/4P3/2P2N1P/PPBP1PP1/RNBQR1K1 b - -
+C96
+r1bq1rk1/5ppp/p1p1pn2/2bp4/2P5/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+E59*
+r1bq1rk1/5ppp/p1pbpn2/2pp4/2PP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+E58*
+r1bq1rk1/p3ppbp/1pn2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 w - -
+A99*
+r1bq1rk1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N2NPP/PP3PB1/R1BQ1RK1 b - -
+E69
+r1bq1rk1/pp1n1pbp/3p1np1/2pP4/8/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+A63
+r1bq1rk1/pp1n1ppp/4pn2/2p5/1bBP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+E55
+r1bq1rk1/pp1nb1pp/2n2p2/4p3/2Pp4/3P1NP1/PPN2PBP/R1BQR1K1 b - -
+A79*
+r1bq1rk1/pp1nbppp/2n5/4p3/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 w - -
+A77*
+r1bq1rk1/pp1nbppp/2n5/4p3/2Pp4/N2P1NP1/PP3PBP/R1BQR1K1 b - -
+A78*
+r1bq1rk1/pp1nbppp/2p1p3/3n2B1/2BP4/2N1PN2/PP3PPP/2RQK2R w K -
+D67
+r1bq1rk1/pp1nbppp/2p1pn2/3p2B1/2PP4/2N1PN2/PPQ2PPP/2R1KB1R b K -
+D64
+r1bq1rk1/pp1nbppp/2p1pn2/3p2B1/2PP4/2NBPN2/PP3PPP/2RQK2R b K -
+D66
+r1bq1rk1/pp1nbppp/2p1pn2/3p4/2PP4/5NP1/PPQNPPBP/R1B2RK1 b - -
+E09
+r1bq1rk1/pp1nbppp/4pn2/2Pp2B1/2P5/2N1PN2/PPQ2PPP/R3KB1R b KQ -
+D62
+r1bq1rk1/pp1p1ppp/2n1pn2/2p5/2PP4/P1PBP3/5PPP/R1BQK1NR w KQ -
+E29
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+A39
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/2NP1NP1/PPP2PBP/R1BQ1RK1 b - -
+E97*
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 w - -
+E94*
+r1bq1rk1/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 w - -
+A73*
+r1bq1rk1/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 b - -
+A76*
+r1bq1rk1/pp2bppp/2n2n2/4p3/2Pp4/P2P1NP1/1P3PBP/RNBQ1RK1 b - -
+A74*
+r1bq1rk1/pp2bppp/2nppn2/6B1/3NPP2/2N5/PPPQ2PP/2KR1B1R b - -
+B64
+r1bq1rk1/pp2bppp/3ppn2/6B1/3QPP2/2N5/PPP3PP/2KR1B1R b - -
+B65
+r1bq1rk1/pp2ppbp/2n2np1/2p5/2Pp4/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+E66*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w - -
+A39*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 w - -
+E65*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/3P1P2/2P1PN2/PP2B1PP/RNBQ1RK1 b - -
+A95*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5P2/2NP1NP1/PPP1P1BP/R1BQ1RK1 b - -
+A89*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5P2/2PP1NP1/PP2P1BP/RNBQ1RK1 b - -
+A88*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 b - -
+A97*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/1P2PN2/PBPPBPPP/RN1Q1RK1 w - -
+E18*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/P1NP1NP1/1PP1PPBP/R1BQ1RK1 b - -
+E63*
+r1bq1rk1/pp2ppbp/2n2np1/8/2Pp4/3P1NP1/PP1N1PBP/R1BQ1RK1 b - -
+A63*
+r1bq1rk1/pp2ppbp/2n3p1/8/2BPP3/4B3/P3NPPP/R2Q1RK1 b - -
+D88
+r1bq1rk1/pp2ppbp/2np1np1/2pP4/2P5/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+E66
+r1bq1rk1/pp2ppbp/2np1np1/8/2BNP3/2N1BP2/PPPQ2PP/R3K2R b KQ -
+B77
+r1bq1rk1/pp2ppbp/2np1np1/8/2PNPP2/2N1B3/PP2B1PP/R2QK2R b KQ -
+E79
+r1bq1rk1/pp2ppbp/2np1np1/8/4P3/1NN1B3/PPP1BPPP/R2Q1RK1 b - -
+B74
+r1bq1rk1/pp3pb1/2n2npp/2ppp3/4P3/2PP1NP1/PP1N1PBP/R1BQ1RK1 w - -
+E69*
+r1bq1rk1/pp3pbp/2n2np1/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+E68*
+r1bq1rk1/pp3ppp/2n1pn2/1Bbp4/2P5/4PN2/PP1N1PPP/R1BQ1RK1 b - -
+E55*
+r1bq1rk1/pp3ppp/2n1pn2/1Bbp4/2P5/4PN2/PP3PPP/RNBQ1RK1 w - -
+E54*
+r1bq1rk1/pp3ppp/2n1pn2/2p5/2BP4/P1P1PN2/5PPP/R1BQ1RK1 b - -
+E59
+r1bq1rk1/pp3ppp/2n1pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+E56
+r1bq1rk1/pp3ppp/2n1pn2/2pp4/2PP4/P1PBPN2/5PPP/R1BQ1RK1 b - -
+E58
+r1bq1rk1/pp3ppp/2n1pn2/8/1bBp4/P1N1PN2/1P3PPP/R1BQ1RK1 w - -
+E57
+r1bq1rk1/pp3ppp/2nbpn2/1Bpp4/2PP4/2N1PN2/PP3PPP/R1BQ1RK1 b - -
+E56*
+r1bq1rk1/ppp1b1pp/2n5/3npp2/8/P1NPPN2/1PQ2PPP/R1B1KB1R b KQ -
+B85*
+r1bq1rk1/ppp1npbp/3p1np1/3Pp3/2P1P3/2N5/PP2BPPP/R1BQNRK1 b - -
+E98
+r1bq1rk1/ppp1p1bp/2np1np1/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+A89
+r1bq1rk1/ppp1ppbp/2np1np1/8/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+E83
+r1bq1rk1/ppp2pbp/2np1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+E97
+r1bq1rk1/pppn1pbp/3p1np1/3Pp3/2P1P3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+E93
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQR1K1 b - -
+E95
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2NP1/PP3PBP/R1BQ1RK1 b - -
+E68
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/2RQKB1R b K -
+D63
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQ -
+D60
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PPQ2PPP/R3KB1R b KQ -
+D61
+r1bq1rk1/pppnbppp/4pn2/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+E07
+r1bq1rk1/pppnbppp/4pn2/3p4/2PP4/5NP1/PPQ1PPBP/RNB2RK1 b - -
+E08
+r1bq1rk1/pppnn1bp/3p2p1/3Ppp2/2P1P3/2N2P2/PP2B1PP/R1BQNRK1 w - -
+E99
+r1bq1rk1/pppnppbp/3p1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+E67
+r1bqk1nr/5ppp/p1pbp3/2pp4/2P5/2N1PN2/PP1P1PPP/R1BQ1RK1 b kq -
+E29*
+r1bqk1nr/5ppp/p1pbp3/2pp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 w kq -
+E49*
+r1bqk1nr/p4ppp/2p5/2bpp3/8/6P1/PPP1PPBP/RNBQK2R w KQkq -
+D86*
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+A37
+r1bqk1nr/pp1pppbp/2n3p1/8/2PNP3/4B3/PP3PPP/RN1QKB1R b KQkq -
+B38
+r1bqk1nr/pp1pppbp/2n3p1/8/2PNP3/8/PP3PPP/RNBQKB1R w KQkq -
+B37
+r1bqk1nr/pp2b1pp/2n5/2pppp2/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+E77*
+r1bqk1nr/pp2bppp/2n5/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E73*
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NP2P1/PPP2PBP/R1BQK1NR b KQkq -
+A26*
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NP2P1/PPP2PBP/R1BQK1NR w KQkq -
+B25
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NPB1P1/PPP2PBP/R2QK1NR b KQkq -
+B26
+r1bqk1nr/pp3ppp/2nbp3/1Bpp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 b kq -
+E48*
+r1bqk1nr/pp3ppp/2nbp3/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+E47*
+r1bqk1nr/pp4pp/2n5/4pp2/1bPp4/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+A67*
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR b KQkq -
+B25*
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR w KQkq -
+A26
+r1bqk1nr/pppp1ppp/2n5/1Bb1p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C64
+r1bqk1nr/pppp1ppp/2n5/2b1N3/4P3/8/PPPP1PPP/RNBQKB1R b KQkq -
+C27*
+r1bqk1nr/pppp1ppp/2n5/2b1p3/1PB1P3/5N2/P1PP1PPP/RNBQK2R b KQkq -
+C51
+r1bqk1nr/pppp1ppp/2n5/2b1p3/2B1P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+C53
+r1bqk1nr/pppp1ppp/2n5/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+C28*
+r1bqk1nr/pppp1ppp/2n5/b3p3/2B1P3/2P2N2/P2P1PPP/RNBQK2R w KQkq -
+C52
+r1bqk2r/1pp1bppp/p1np1n2/4p3/B3P3/5N2/PPPP1PPP/RNBQR1K1 w kq -
+C87
+r1bqk2r/1pp1bppp/p1p2n2/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+C85
+r1bqk2r/1pppbppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+C84
+r1bqk2r/1pppbppp/p1n2n2/4p3/B3P3/5N2/PPPPQPPP/RNB2RK1 b kq -
+C86
+r1bqk2r/2ppbppp/p1n2n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQR1K1 b kq -
+C88
+r1bqk2r/p3nppp/2p5/2bpp3/2P5/6P1/PP2PPBP/RNBQ1RK1 b kq -
+D87*
+r1bqk2r/pp1nnppp/3b4/3p4/3Pp3/2N1P3/PP1N1PPP/R1BQKB1R w KQkq -
+C06*
+r1bqk2r/pp1p1ppp/2n1pn2/2P5/1bP5/1QN5/PP2PPPP/R1B1KBNR w KQkq -
+E23
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+A38*
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+A38
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+A37*
+r1bqk2r/pp1pppbp/2n2np1/8/2BNP3/2N1B3/PPP2PPP/R2QK2R b KQkq -
+B35
+r1bqk2r/pp1pppbp/2n3p1/8/2PNP1n1/2N1B3/PP3PPP/R2QKB1R w KQkq -
+B39
+r1bqk2r/pp2b1pp/2n2n2/2pppp2/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 w kq -
+E78*
+r1bqk2r/pp2b1pp/2n2n2/4pp2/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 b kq -
+A69*
+r1bqk2r/pp2bppp/2n2n2/2p1p3/3pP3/3P1NP1/PPPN1PBP/R1BQ1RK1 b kq -
+E93*
+r1bqk2r/pp2bppp/2n2n2/2pp4/3P4/2N2NP1/PP2PPBP/R1BQK2R w KQkq -
+D34
+r1bqk2r/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 b kq -
+E92*
+r1bqk2r/pp2bppp/2n2n2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+E91*
+r1bqk2r/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+A72*
+r1bqk2r/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+A71*
+r1bqk2r/pp2ppbp/2n2np1/2pp4/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+E64*
+r1bqk2r/pp2ppbp/2n2np1/2pp4/8/3P1NP1/PPPNPPBP/R1BQ1RK1 b kq -
+E67*
+r1bqk2r/pp2ppbp/2n2np1/3p4/2PP4/2N2N2/PP2BPPP/R1BQK2R b KQkq -
+D34*
+r1bqk2r/pp2ppbp/2n2np1/8/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+A62*
+r1bqk2r/pp2ppbp/2np1np1/8/3NP3/2N1B3/PPP1BPPP/R2Q1RK1 b kq -
+B73
+r1bqk2r/pp3ppp/2n1pn2/2bp4/8/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+D47*
+r1bqk2r/pp3ppp/2nbpn2/1Bpp4/2PP4/4PN2/PP3PPP/RNBQ1RK1 b kq -
+E53*
+r1bqk2r/pp3ppp/2nbpn2/1Bpp4/3P4/1P2PN2/P1P2PPP/RNBQ1RK1 b kq -
+E52*
+r1bqk2r/pp3ppp/2nbpn2/2pp4/3P4/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+D46*
+r1bqk2r/pp3ppp/2nbpn2/3p4/1P6/P1P1PN2/3N1PPP/R1BQKB1R b KQkq -
+D48*
+r1bqk2r/pp3ppp/2nbpn2/3p4/2PN4/2N1P3/PP3PPP/R1BQKB1R w KQkq -
+D42*
+r1bqk2r/pp3ppp/3b1n2/3P4/1n2p3/P3PN2/3N1PPP/R1BQKB1R w KQkq -
+D49*
+r1bqk2r/ppp1bppp/1nn5/4p3/4P3/2NP1N2/PP3PPP/R1BQKB1R w KQkq -
+B59*
+r1bqk2r/ppp1bppp/2n5/3np3/8/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+B58*
+r1bqk2r/ppp1bppp/2n5/3np3/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+B83*
+r1bqk2r/ppp1bppp/2n5/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+B92*
+r1bqk2r/ppp1bppp/2n5/3np3/8/P2PPN2/1P3PPP/RNBQKB1R b KQkq -
+B84*
+r1bqk2r/ppp2ppp/1bn5/3np3/1P6/P2PPN2/5PPP/RNBQKB1R b KQkq -
+B87*
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+B57*
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/2NPPN2/PP3PPP/R1BQKB1R b KQkq -
+B88*
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+B86*
+r1bqk2r/pppp1ppp/2n1pn2/8/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+E33
+r1bqk2r/pppp1ppp/2n2n2/1B2p3/1b2P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+C49*
+r1bqk2r/pppp1ppp/2n2n2/1B2p3/1b2P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+C49
+r1bqk2r/pppp1ppp/2n2n2/2b5/2BPP3/5N2/PP3PPP/RNBQK2R b KQkq -
+C54
+r1bqk2r/pppp1ppp/2n2n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+C48*
+r1bqkb1r/1p2pppp/2n2n2/p1Pp4/5B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+D17*
+r1bqkb1r/1p2pppp/2n2n2/p1Pp4/8/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+D16*
+r1bqkb1r/1p3ppp/2n1pn2/p1Pp4/5B2/2P2N2/PP2PPPP/RN1QKB1R w KQkq -
+D18*
+r1bqkb1r/1p3ppp/p1nppn2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R w KQkq -
+B66
+r1bqkb1r/1pp2ppp/p1np1n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+C79
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+C78
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C77
+r1bqkb1r/1ppp1ppp/p1n5/4p3/B3n3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+C80
+r1bqkb1r/3n1ppp/p1p1pn2/1p6/3P4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+D48
+r1bqkb1r/3n1ppp/p3pn2/1N2P3/3p4/3B1N2/PP3PPP/R1BQK2R b KQkq -
+D49
+r1bqkb1r/p4pp1/2p2n1p/n3p1N1/8/8/PPPPBPPP/RNBQK2R w KQkq -
+C59
+r1bqkb1r/pp1n1ppp/2n1p3/3pP3/3P4/3B4/PP1NNPPP/R1BQK2R b KQkq -
+C06
+r1bqkb1r/pp1n1ppp/2p1pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R b KQkq -
+D52
+r1bqkb1r/pp1n1ppp/2p1pn2/3p4/2PP4/2NBPN2/PP3PPP/R1BQK2R b KQkq -
+D46
+r1bqkb1r/pp1n1ppp/2p1pn2/8/2BP4/2N1PN2/PP3PPP/R1BQK2R b KQkq -
+D47
+r1bqkb1r/pp1p1ppp/2n1pn2/8/2PN4/2N5/PP2PPPP/R1BQKB1R w KQkq -
+A33
+r1bqkb1r/pp1ppp1p/2n2np1/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+A29*
+r1bqkb1r/pp1ppppp/2n2n2/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+A28*
+r1bqkb1r/pp1ppppp/2n2n2/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+A27*
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+E42*
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/8/1P2PN2/P1PP1PPP/RNBQK2R w KQkq -
+E44*
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/8/BP2PN2/P1PP1PPP/RN1QK2R b KQkq -
+E45*
+r1bqkb1r/pp2pp1p/2n2np1/2pp4/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E62*
+r1bqkb1r/pp2pp1p/2n2np1/3p4/2PP4/2N5/PP3PPP/R1BQKBNR w KQkq -
+D33*
+r1bqkb1r/pp2pppp/2n2n2/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R b KQkq -
+D38*
+r1bqkb1r/pp2pppp/2n2n2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+E21*
+r1bqkb1r/pp2pppp/2n2n2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+D24*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/2PP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+D40*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/2P1PN2/PP3PPP/RNBQKB1R b KQkq -
+D43*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+D15*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+D37*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+D90*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/4P3/3P1N2/PPP2PPP/RNBQKB1R w KQkq -
+A54*
+r1bqkb1r/pp2pppp/2n2n2/3p4/2Pp4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+D41*
+r1bqkb1r/pp2pppp/2n2n2/8/2Pp4/3P1NP1/PP3P1P/RNBQKB1R b KQkq -
+A61*
+r1bqkb1r/pp2pppp/2n5/2pn4/8/2N1PN2/PP1P1PPP/R1BQKB1R b KQkq -
+A33*
+r1bqkb1r/pp2pppp/2np1n2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R b KQkq -
+B60
+r1bqkb1r/pp2pppp/2np1n2/8/2BNP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+B57
+r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+B58
+r1bqkb1r/pp3ppp/2n1p3/2pn4/3P4/2NBPN2/PP3PPP/R1BQK2R b KQkq -
+D42
+r1bqkb1r/pp3ppp/2n1pn2/1Bpp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 b kq -
+E51*
+r1bqkb1r/pp3ppp/2n1pn2/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+E50*
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/2P1PN2/PP3PPP/RNBQKB1R w KQkq -
+D45*
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+D94*
+r1bqkb1r/pp3ppp/2n2n2/2ppp3/4P3/3P1N2/PPPN1PPP/R1BQKB1R w KQkq -
+A55*
+r1bqkb1r/pp3ppp/2n2n2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E90*
+r1bqkb1r/pp3ppp/2n2n2/4p3/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+A70*
+r1bqkb1r/pp3ppp/2np1n2/4p3/4P3/1NN5/PPP1BPPP/R1BQK2R b KQkq -
+B59
+r1bqkb1r/pp3ppp/2nppn2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R w KQkq -
+B62
+r1bqkb1r/pp3ppp/2nppn2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R b KQkq -
+B63
+r1bqkb1r/pp3ppp/2nppn2/8/2BNP3/2N1B3/PPP2PPP/R2QK2R b KQkq -
+B89
+r1bqkb1r/pp3ppp/2nppn2/8/2BNP3/2N5/PPP2PPP/R1BQK2R w KQkq -
+B88
+r1bqkb1r/pp4pp/2n2n2/4pp2/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+A68*
+r1bqkb1r/ppp2p1p/2n3p1/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+B91*
+r1bqkb1r/ppp2p1p/2n5/3np1p1/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+B81*
+r1bqkb1r/ppp2pp1/5nn1/3p3p/8/2P3BP/PP1NPPP1/R2QKBNR b KQkq -
+B19*
+r1bqkb1r/ppp2ppp/2n1pn2/3p4/3PP3/5N2/PPPN1PPP/R1BQKB1R w KQkq -
+C04
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+C47*
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+B07*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N1P3/PP1P1PPP/R1BQKBNR w KQkq -
+B45*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N1P3/PPQP1PPP/R1B1KBNR b KQkq -
+B47*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3P1N2/PP2PPPP/RNBQKB1R w KQkq -
+B56*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3P1NP1/PP2PP1P/RNBQKB1R b KQkq -
+B70*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3PPN2/PP3PPP/RNBQKB1R b KQkq -
+B80*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P1N1P3/1P1P1PPP/R1BQKBNR b KQkq -
+B46*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R b KQkq -
+B90*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P3P3/1P1P1PPP/RNBQKBNR w KQkq -
+B43*
+r1bqkb1r/ppp2ppp/2np1n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+C66
+r1bqkb1r/ppp2ppp/5n2/n2Pp1N1/2B5/8/PPPP1PPP/RNBQK2R w KQkq -
+C58
+r1bqkb1r/ppp3pp/2n5/3npp2/8/3P1NP1/PP2PP1P/RNBQKB1R w KQkq -
+B71*
+r1bqkb1r/ppp3pp/2n5/3npp2/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+B82*
+r1bqkb1r/ppp3pp/2n5/3npp2/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+B93*
+r1bqkb1r/pppn1ppp/3p1n2/4p3/2PPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+A55
+r1bqkb1r/pppn1ppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR w KQkq -
+D51
+r1bqkb1r/pppn1ppp/4pn2/8/2QP4/6P1/PP2PPBP/RNB1K1NR b KQkq -
+E03
+r1bqkb1r/pppn1ppp/5n2/3p4/2PP4/2N5/PP3PPP/R1BQKBNR b KQkq -
+C09*
+r1bqkb1r/pppn1ppp/5n2/3pp3/3P4/2N1PN2/PPP2PPP/R1BQKB1R b KQkq -
+C04*
+r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+C48
+r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C65
+r1bqkb1r/pppp1ppp/2n2n2/4p1B1/3P4/2P5/PP2PPPP/RN1QKBNR b KQkq -
+B11*
+r1bqkb1r/pppp1ppp/2n2n2/4p1N1/2B1P3/8/PPPP1PPP/RNBQK2R b KQkq -
+C57
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+C28
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C55
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+A28
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N2NP1/PP1PPP1P/R1BQKB1R b KQkq -
+A29
+r1bqkb1r/pppp1ppp/2n2n2/4p3/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+C47
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+C46*
+r1bqkb1r/pppp1ppp/2n5/1B2p3/4n3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+C67
+r1bqkb1r/pppp1ppp/2n5/8/2Bpn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+C56
+r1bqkbnr/1p1p1ppp/p1n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+B46
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+C74
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+C72
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C71
+r1bqkbnr/1pp2ppp/p1p5/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+C69
+r1bqkbnr/1ppp1ppp/p1B5/4p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+C68
+r1bqkbnr/1ppp1ppp/p1n5/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+C70
+r1bqkbnr/2p2ppp/p1p5/3p4/2PPp3/4P3/PP2NPPP/RNBQK2R b KQkq -
+C19*
+r1bqkbnr/2p2ppp/p1p5/3p4/2PPp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+C18*
+r1bqkbnr/2p2ppp/p1pp4/4p3/3PP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+C73
+r1bqkbnr/4p1pp/p1p2p2/3p4/2Pp4/4PN2/PP3PPP/RNBQK2R w KQkq -
+E25*
+r1bqkbnr/4pppp/p1p5/2pp4/8/4PN2/PPPP1PPP/RNBQ1RK1 b kq -
+E27*
+r1bqkbnr/4pppp/p1p5/2pp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+E24*
+r1bqkbnr/5ppp/p1p1p3/2pp4/2P5/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+E26*
+r1bqkbnr/5ppp/p1p1p3/2pp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+E28*
+r1bqkbnr/pp1npppp/2p5/8/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+B17
+r1bqkbnr/pp1p1ppp/2n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+B45
+r1bqkbnr/pp1p1ppp/2n1p3/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+B44
+r1bqkbnr/pp1p1ppp/2n5/2p1p3/2P5/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+A19*
+r1bqkbnr/pp1p1ppp/2n5/2p1p3/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+A18*
+r1bqkbnr/pp1ppp1p/2n3p1/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+B31
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+A36*
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/2P2N2/PP1P1PPP/RNBQKB1R b KQkq -
+A23*
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/5NP1/PPPP1P1P/RNBQKB1R b KQkq -
+A24*
+r1bqkbnr/pp1ppp1p/2n3p1/8/2PNP3/8/PP3PPP/RNBQKB1R b KQkq -
+B36
+r1bqkbnr/pp1ppp1p/2n3p1/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+B34
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+A36
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+A35*
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+A35
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+A34*
+r1bqkbnr/pp1ppppp/2n5/2p5/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+B32
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+B24
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+A25*
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+A22*
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+B30
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+A21*
+r1bqkbnr/pp1ppppp/2n5/2p5/8/4PN2/PPPP1PPP/RNBQKB1R b KQkq -
+A17*
+r1bqkbnr/pp1ppppp/2n5/2p5/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+A16*
+r1bqkbnr/pp1ppppp/2n5/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+B33
+r1bqkbnr/pp2pppp/2n5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R b KQkq -
+E20*
+r1bqkbnr/pp2pppp/2n5/2pp4/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+D32*
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+D31*
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+D35*
+r1bqkbnr/pp2pppp/2n5/2pp4/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+A85*
+r1bqkbnr/pp2pppp/2n5/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+E61*
+r1bqkbnr/pp2pppp/2n5/3p4/3N4/6P1/PPP1PP1P/RNBQKB1R b KQkq -
+D85*
+r1bqkbnr/pp3p1p/2n3p1/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E72*
+r1bqkbnr/pp3pp1/2n4p/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E71*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+E41*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/1P2PN2/P1PP1PPP/RNBQK2R b KQkq -
+E43*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 b kq -
+E46*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+E40*
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+D33
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+B14*
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/5N2/PPPN1PPP/R1BQKB1R w KQkq -
+C09
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/3P2P1/PPP1PPBP/RNBQK1NR w KQkq -
+A42*
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/5NP1/PPPPPPBP/RNBQK2R w KQkq -
+E70*
+r1bqkbnr/pp3ppp/2n5/4p3/2Pp4/3P1N2/PP3PPP/RNBQKB1R w KQkq -
+A65*
+r1bqkbnr/pp3ppp/2n5/4p3/2Pp4/B2P1N2/4PPPP/RN1QKB1R w KQkq -
+A59*
+r1bqkbnr/pp4pp/2n2p2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 b kq -
+E81*
+r1bqkbnr/pp4pp/2n2p2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E80*
+r1bqkbnr/pp4pp/2n5/2pppp2/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E76*
+r1bqkbnr/pp4pp/2n5/4pp2/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+A66*
+r1bqkbnr/ppp1pppp/2n5/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+D07
+r1bqkbnr/ppp2ppp/2n5/1B1p4/2PPp3/4P3/PP3PPP/RNBQK1NR b KQkq -
+C17*
+r1bqkbnr/ppp2ppp/2n5/1B1p4/3Pp3/4P3/PPP2PPP/RNBQK1NR w KQkq -
+C16*
+r1bqkbnr/ppp2ppp/2n5/1B1pp3/3P4/4P3/PPP2PPP/RNBQK1NR b KQkq -
+C15*
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+B15*
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+C10*
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+C11*
+r1bqkbnr/ppp2ppp/2n5/4P3/2Pp4/5NP1/PP2PP1P/RNBQKB1R b KQkq -
+D09
+r1bqkbnr/ppp2ppp/2np4/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C62
+r1bqkbnr/ppp2ppp/8/3p4/8/2P2P2/PP2PP1P/RNBQKB1R b KQkq -
+B16*
+r1bqkbnr/ppp2ppp/8/3pn3/5B2/2P5/PP2PPPP/RN1QKBNR b KQkq -
+B18*
+r1bqkbnr/ppp2ppp/8/3pn3/8/2P5/PP1NPPPP/R1BQKBNR b KQkq -
+B17*
+r1bqkbnr/ppp3pp/2n5/3ppp2/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+B08*
+r1bqkbnr/pppn1ppp/8/3p4/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+C08*
+r1bqkbnr/pppn1ppp/8/3pp3/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+C07*
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+C03*
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+C05*
+r1bqkbnr/pppp1p1p/2n3p1/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+B24*
+r1bqkbnr/pppp1ppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+C60
+r1bqkbnr/pppp1ppp/2n5/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+C50
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+A27
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+A25
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+B23*
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+C46
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+C26*
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+C44
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+C25*
+r1bqkbnr/pppp1ppp/2n5/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+C45
+r1bqkbnr/pppp1ppp/2n5/8/3QP3/8/PPP2PPP/RNB1KBNR w KQkq -
+C22
+r1bqkbnr/pppp1ppp/8/1B2p3/3nP3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C61
+r1bqkbnr/pppp2pp/2n5/1B2pp2/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C63
+r1bqkbnr/pppp2pp/2n5/4pp2/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+C29*
+r1bqnrk1/pp2b1pp/2n2p2/2p1p3/3pPP2/3P2P1/PPPNN1BP/R1BQ1RK1 b - -
+E99*
+r1bqnrk1/pp2bppp/2n5/2p1p3/3pP3/3P1NP1/PPP1NPBP/R1BQ1RK1 w - -
+E98*
+r1bqr1k1/1p1n1pbp/p2p1np1/2pP4/P7/2N3P1/1P1NPPBP/R1BQ1RK1 w - -
+A64
+r1bqr1k1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+E95*
+r1bqr1k1/pp3pbp/n2p1np1/2pP4/4P3/2N5/PP1NBPPP/R1BQ1RK1 w - -
+A78
+r1bqr1k1/ppbn1pp1/2p2n1p/3pp3/1PP1P3/P1NP1N2/2Q1BPPP/R1B2RK1 b - -
+C98*
+r1bqr1k1/ppbn1pp1/5n1p/3pp3/NP2P3/P2P1N2/2Q1BPPP/R1B2RK1 w - -
+C99*
+r1bqr1k1/ppn2pbp/3p1np1/2pP4/4P3/2N2P2/PP1NB1PP/R1BQ1RK1 w - -
+A79
+r1bqrbk1/pp3ppp/2n2n2/2ppp3/P3P3/2PP1NP1/1P1N1PBP/R1BQ1RK1 b - -
+E96*
+r1r3k1/pp1bppbp/2np1np1/q7/3NP2P/1BN1BP2/PPPQ2P1/2KR3R b - -
+B79
+r2q1rk1/p3n1pp/3bbp2/3pp1B1/N7/6P1/PP2PPBP/R2Q1RK1 w - -
+D89*
+r2q1rk1/p3nppp/4b3/2bpp3/8/2N3P1/PP2PPBP/R1BQ1RK1 w - -
+D88*
+r2q1rk1/pp1bppbp/2np1np1/8/2BNP3/2N1BP2/PPPQ2PP/2KR3R b - -
+B78
+r2q1rk1/pp2ppbp/6p1/n7/3PP1b1/3BBP2/P3N1PP/R2Q1RK1 b - -
+D89
+r2q1rk1/ppp1bppp/1nn1b3/4p3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+B74*
+r2q1rk1/ppp1bppp/2n1b3/3np3/8/2NP1NP1/PP2PPBP/R1BQK2R w KQ -
+B73*
+r2qk1nr/pp2bppp/2n5/2p1p3/2Pp2b1/3PPNP1/PP3PBP/RNBQ1RK1 b kq -
+E75*
+r2qk1nr/pp2bppp/2n5/2ppp3/2P3b1/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+E74*
+r2qk1nr/ppp2pbp/2npb1p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR w KQkq -
+B26*
+r2qk2r/1p1bbppp/p1nppn2/6B1/3NPP2/2N5/PPPQ2PP/2KR1B1R w kq -
+B68
+r2qk2r/2p1bppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP3PPP/RNBQ1RK1 w kq -
+C83
+r2qk2r/3bbppp/p1nppB2/1p6/4PP2/2N2N2/PPPQ2PP/2KR1B1R b kq -
+B69
+r2qk2r/pp2b1pp/2n1b3/2pnpp2/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w kq -
+E79*
+r2qk2r/ppp1bppp/2n1b3/3np3/8/P1N1P3/1PQP1PPP/R1B1KBNR w KQkq -
+B49*
+r2qk2r/ppp2ppp/2n1b3/2bnp3/8/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+B35*
+r2qk2r/ppp2ppp/2n1b3/2bnp3/8/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+B89*
+r2qkb1r/1p1b1ppp/p1nppn2/6B1/3NP3/2N5/PPPQ1PPP/2KR1B1R w kq -
+B67
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1B3N2/PPP1QPPP/RNB2RK1 b kq -
+C81
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP3PPP/RNBQ1RK1 b kq -
+C82
+r2qkb1r/p4ppp/2p1pn2/3p4/3p4/4P2P/PPP1QPP1/RNB2RK1 w kq -
+D57*
+r2qkb1r/pp1bpppp/2np1n2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R b KQkq -
+B61
+r2qkb1r/pp2n1pp/2n1bp2/2p1p3/3PP3/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+E89*
+r2qkb1r/pp2n1pp/2n1bp2/2ppp3/4P3/2PP1NP1/PP3PBP/RNBQ1RK1 b kq -
+E86*
+r2qkb1r/pp2pppp/2n2n2/1BPp4/6b1/4PN2/PPP2PPP/RNBQK2R b KQkq -
+D39*
+r2qkb1r/pp2pppp/2n2n2/1Bpp3b/8/1P2PN1P/PBPP1PP1/RN1QK2R b KQkq -
+E13*
+r2qkb1r/pp2pppp/2n2n2/2Pp4/6b1/2P1PN2/PP3PPP/RNBQKB1R b KQkq -
+D44*
+r2qkb1r/pp2pppp/2n2n2/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+D92*
+r2qkb1r/pp2pppp/2n2n2/2pp4/3P2b1/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+D91*
+r2qkb1r/pp3ppp/2n1b3/2pnp1N1/8/2N3P1/PP1PPPBP/R1BQK2R b KQkq -
+B39*
+r2qkb1r/pp3ppp/2n1pn2/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+D93*
+r2qkb1r/pp3ppp/2n1pn2/2pp3b/3P4/1P2PN1P/P1P1BPP1/RNBQ1RK1 b kq -
+D58*
+r2qkb1r/pp3ppp/2n1pn2/2pp3b/3P4/4PN1P/PPP1BPP1/RNBQ1RK1 w kq -
+D56*
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+D52*
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQ1RK1 w kq -
+D55*
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 b kq -
+D60*
+r2qkb1r/pp3ppp/2n1pn2/3p3b/3N4/1P2P2P/P1P1BPP1/RNBQ1RK1 b kq -
+D59*
+r2qkb1r/ppp2ppp/2n1b3/3np3/8/2N1P3/PPQP1PPP/R1B1KBNR w KQkq -
+B48*
+r2qkb1r/ppp2ppp/2n1b3/3np3/8/3P1NP1/PP2PP1P/RNBQKB1R w KQkq -
+B72*
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+B60*
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NPPN2/PP3PPP/R1BQKB1R b KQkq -
+B62*
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+B94*
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/P2PPN2/1P3PPP/RNBQKB1R b KQkq -
+B95*
+r2qkb1r/ppp3pp/2n1bp2/3np3/8/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+B76*
+r2qkb1r/ppp3pp/2n1bp2/3np3/8/3P1NP1/PP2PPBP/RNBQK2R w KQkq -
+B75*
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/P2PPN2/1P2BPPP/RNBQK2R b KQkq -
+B98*
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/P2PPN2/1P3PPP/RNBQKB1R w KQkq -
+B96*
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/PQ1PPN2/1P3PPP/RNB1KB1R b KQkq -
+B97*
+r2qkbnr/1ppb1p1p/p1np2p1/4p3/B2PP3/2P2N2/PP3PPP/RNBQK2R w KQkq -
+C76
+r2qkbnr/1ppb1ppp/p1np4/4p3/B3P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+C75
+r2qkbnr/pp1nppp1/2p3bp/8/3P3P/5NN1/PPP2PP1/R1BQKB1R w KQkq -
+B19
+r2qkbnr/pp2pppp/2n5/1Bp4b/2Pp4/3PPN1P/PP3PP1/RNBQK2R b KQkq -
+E31*
+r2qkbnr/pp2pppp/2n5/1Bpp4/6b1/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+E30*
+r2qkbnr/pp2pppp/2n5/2pp1b2/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+D82*
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+D53*
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+D50*
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPPN1PPP/R1BQKB1R b KQkq -
+D51*
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+D80*
+r2qkbnr/pp3ppp/2n1p3/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQ1RK1 b kq -
+D83*
+r2qkbnr/pp3ppp/4p3/3p4/3Q4/6P1/PPb1PPBP/RNB2RK1 w kq -
+D84*
+r2qkbnr/pp4pp/2n1bp2/2p1p3/3pP3/2PP1NP1/PP3PBP/RNBQ1RK1 b kq -
+E88*
+r2qkbnr/pp4pp/2n1bp2/2p1p3/3pP3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+E87*
+r2qkbnr/pp4pp/2n1bp2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 b kq -
+E85*
+r2qkbnr/pp4pp/2n1bp2/2ppp3/8/1P1P1NP1/P1P1PPBP/RNBQ1RK1 b kq -
+E82*
+r2qkbnr/pp4pp/2n1bp2/2ppp3/8/2NP1NP1/PPP1PPBP/R1BQ1RK1 b kq -
+E83*
+r2qkbnr/ppp1pppp/2n5/3p4/3P2b1/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+D01*
+r2qkbnr/ppp2ppp/2n5/1B1pp3/3P2b1/4PN2/PPP2PPP/RNBQK2R b KQkq -
+C12*
+r2qkbnr/ppp2ppp/2n5/3p4/3Pp3/4P3/PPPNQPPP/RNB1K2R b KQkq -
+C14*
+r2qkbnr/ppp2ppp/2n5/3pP3/6b1/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+A83*
+r2qkbnr/ppp2ppp/2n5/3pp3/3P2b1/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+C13*
+r3k2r/pppq2pp/2n1bp2/2bnp3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w kq -
+B77*
+r3kb1r/pp1qn1pp/2n1bp2/2ppp3/8/P1NP1NP1/1PP1PPBP/1RBQ1RK1 b kq -
+E84*
+r3kb1r/pp3ppp/1qn1bn2/3pp1B1/8/6P1/PPPNPPBP/RN1Q1RK1 w kq -
+D99*
+r3kb1r/pppq1ppp/2n5/3np3/6b1/2NP1N2/PP1BPPPP/R2QKB1R w KQkq -
+B61*
+r3kb1r/pppq1ppp/2n5/3np3/6b1/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+B63*
+r3kb1r/pppq1ppp/2n5/3np3/6b1/P1NPPN2/1P3PPP/R1BQKB1R b KQkq -
+B66*
+r3kb1r/ppq2ppp/2n1pn2/2p5/2pP2b1/4PN2/PP1NBPPP/R1BQ1RK1 w kq -
+D62*
+r3kb1r/ppq2ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w kq -
+D61*
+r3kbnr/ppq1pppp/2n5/3p4/3P2b1/2P2N2/PP3PPP/RNBQKB1R w KQkq -
+D36*
+rn1q1rk1/1p3pbp/p2p1np1/2pP4/P3P1b1/2N2N2/1P2BPPP/R1BQ1RK1 w - -
+A75
+rn1q1rk1/p3ppbp/bp3np1/2pp4/3P1P2/2P1PN2/PP2B1PP/RNBQ1RK1 w - -
+A94*
+rn1q1rk1/pbppbppp/1p2p3/8/2PP4/2Q2NP1/PP2PPBP/R1B2RK1 b - -
+E19
+rn1q1rk1/pbppbppp/1p2pn2/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+E18
+rn1q1rk1/pp3ppp/2p1pn2/5b2/PbBP4/2N1PN2/1P2QPPP/R1B2RK1 b - -
+D19
+rn1q1rk1/ppp1ppbp/5np1/8/2QPP1b1/2N2N2/PP3PPP/R1B1KB1R w KQ -
+D98
+rn1q1rk1/pppnppbp/6p1/8/3PP1b1/1QN1BN2/PP3PPP/R3KB1R b KQ -
+D99
+rn1qk2r/p1pp1ppp/bp2pn2/8/1bPP4/2N1P3/PP2NPPP/R1BQKB1R w KQkq -
+E45
+rn1qk2r/pbpp1pp1/1p2pn1p/8/1bPP3B/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+E13
+rn1qk2r/pbpp1ppp/1p2pn2/8/1bPP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+E16
+rn1qk2r/pbppbppp/1p2pn2/8/2PP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+E17
+rn1qkb1r/1b3ppp/p3pn2/1pp5/3P4/1B2PN2/PP2QPPP/RNB2RK1 w kq -
+D29
+rn1qkb1r/4pppp/b2p1n2/2pP4/4P3/2N5/PP3PPP/R1BQKBNR b KQkq -
+A59
+rn1qkb1r/pp2pppp/2p2n2/3p1b2/2PP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+D12
+rn1qkb1r/pp2pppp/2p2n2/5b2/P1pP4/2N1PN2/1P3PPP/R1BQKB1R b KQkq -
+D18
+rn1qkb1r/pp2pppp/2p2n2/5b2/P1pP4/2N2N2/1P2PPPP/R1BQKB1R w KQkq -
+D17
+rn1qkb1r/pp2pppp/5n2/3p1b2/3P1B2/5N2/PP2PPPP/RN1QKB1R b KQkq -
+D14*
+rn1qkb1r/pp2pppp/5n2/3p1b2/3P1B2/5N2/PP2PPPP/RN1QKB1R w KQkq -
+D14
+rn1qkb1r/pp3ppp/4b3/2pnp3/8/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+B38*
+rn1qkb1r/ppp1pppp/3p4/3nP3/3P2b1/5N2/PPP2PPP/RNBQKB1R w KQkq -
+B05
+rn1qkb1r/ppp1pppp/5n2/3p4/3P2b1/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+D03*
+rn1qkbnr/pp1bpppp/3p4/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+B52
+rn1qkbnr/pp2pppp/2p5/3p4/4P1b1/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+B11
+rn1qkbnr/pp2pppp/2p5/5b2/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+B18
+rnb1k1nr/pp2ppbp/6p1/2qp4/8/4PN2/PPPN1PPP/R1BQKB1R w KQkq -
+E03*
+rnb1k1nr/pp2ppbp/6p1/q1Pp4/8/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+E02*
+rnb1k2r/pppnqppp/4p3/3pP3/3P4/2N5/PPP2PPP/R2QKBNR w KQkq -
+C14
+rnb1kb1r/1p3ppp/pq1ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+B97
+rnb1kb1r/ppp2ppp/5n2/3qp3/8/3P4/PP2PPPP/RNBQKBNR w KQkq -
+B53*
+rnb1kbnr/ppp2ppp/8/3qp3/8/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+C22*
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/1PN2NP1/P3PPBP/R1BQ1RK1 b - -
+A99
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+A97
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/2N2NP1/PPQ1PPBP/R1B2RK1 b - -
+A98
+rnb2rk1/pp2qppp/1b2pn2/3p4/1PP5/P3PN2/1B3PPP/RN1QKB1R b KQ -
+D29*
+rnb2rk1/pp2qppp/4pn2/2bp4/2P5/P3PN2/1P3PPP/RNBQKB1R w KQ -
+D28*
+rnb2rk1/ppB1ppbp/6p1/3q4/3P4/4P3/PP3PPP/R2QKBNR b KQ -
+D84
+rnb2rk1/ppp1qpp1/4p2p/3P4/3P4/2P1PN2/P4PPP/R2QKB1R b KQ -
+D57
+rnb2rk1/ppp1qppp/1b3n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R w KQ -
+C81*
+rnb2rk1/ppppqppp/5n2/b3p3/4P3/P1N2N2/1PPPBPPP/R1BQK2R w KQ -
+C86*
+rnb2rk1/ppq1ppbp/5np1/2pp4/3P4/4PN2/PPPNBPPP/R1BQ1RK1 w - -
+E08*
+rnbq1rk1/1p3pbp/p2p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+A74
+rnbq1rk1/2p1bppp/p2p1n2/1p2p3/3PP3/1BP2N1P/PP3PP1/RNBQR1K1 b - -
+C95
+rnbq1rk1/2p1bppp/p2p1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+C94
+rnbq1rk1/p1p1bpp1/1p2p2p/3n4/3P3B/2N1PN2/PP3PPP/R2QKB1R w KQ -
+D59
+rnbq1rk1/p1p1bpp1/1p2pn1p/3p4/2PP3B/2N1PN2/PP3PPP/R2QKB1R w KQ -
+D58
+rnbq1rk1/p1p1ppbp/1p1p1np1/8/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+E82
+rnbq1rk1/p1p2ppp/1p2pn2/3p4/1bPP4/2NBPN2/PP3PPP/R1BQK2R w KQ -
+E52
+rnbq1rk1/p3ppbp/1p3np1/2pp4/3P1P2/4PN2/PPP1B1PP/RNBQ1RK1 w - -
+A93*
+rnbq1rk1/pp1p1ppp/4pn2/2P5/1bP5/2N5/PPQ1PPPP/R1B1KBNR w KQ -
+E39
+rnbq1rk1/pp1pppbp/5np1/2p5/3P4/4PN2/PPP1BPPP/RNBQK2R w KQ -
+A14*
+rnbq1rk1/pp2b1pp/2p1pn2/3p1p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+A95
+rnbq1rk1/pp2b1pp/2p1pn2/3p1p2/2PP4/BP3NP1/P3PPBP/RN1Q1RK1 b - -
+A94
+rnbq1rk1/pp2p1bp/2pp1np1/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+A88
+rnbq1rk1/pp2ppbp/2p2np1/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+D78
+rnbq1rk1/pp2ppbp/3p1np1/2p3B1/2PPP3/2N5/PP2BPPP/R2QK1NR w KQ -
+E74
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+E65
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+E64
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PPPP2/2N2N2/PP2B1PP/R1BQK2R b KQ -
+E78
+rnbq1rk1/pp2ppbp/3p1np1/8/3NP3/2N1BP2/PPP3PP/R2QKB1R w KQ -
+B76
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/2P2NP1/PP2PPBP/RNBQ1RK1 b - -
+D78*
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/4PN2/PPPNBPPP/R1BQ1RK1 b - -
+E07*
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w - -
+D77*
+rnbq1rk1/pp2ppbp/5np1/2pp4/5P2/3PPN2/PPP1B1PP/RNBQ1RK1 b - -
+A96*
+rnbq1rk1/pp2ppbp/5np1/3p4/2PN4/6P1/PP2PPBP/RNBQ1RK1 b - -
+D75*
+rnbq1rk1/pp2ppbp/5np1/3p4/3N4/6P1/PPP1PPBP/RNBQ1RK1 w - -
+D74*
+rnbq1rk1/pp2ppbp/5np1/3p4/3P4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+D79*
+rnbq1rk1/pp2ppbp/5np1/3p4/3P4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+D79
+rnbq1rk1/pp2ppbp/5np1/3p4/8/1N4P1/PPP1PPBP/RNBQ1RK1 b - -
+D76*
+rnbq1rk1/pp2ppbp/6p1/2p5/2BPP3/2P5/P3NPPP/R1BQK2R w KQ -
+D87
+rnbq1rk1/pp2ppbp/6p1/2pn4/3P4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+D75
+rnbq1rk1/pp3pbp/2pp1np1/3Pp3/2P1P3/2N1BP2/PP4PP/R2QKBNR w KQ -
+E88
+rnbq1rk1/pp3pbp/2pp1np1/4p3/2PPP3/2N1BP2/PP2N1PP/R2QKB1R w KQ -
+E86
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+A73
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+A72
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4PP2/2N2N2/PP4PP/R1BQKB1R w KQ -
+A68
+rnbq1rk1/pp3pbp/3p1np1/2pP4/8/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+A62
+rnbq1rk1/pp3pbp/3p1np1/3pp3/2P1P3/2N1BP2/PP2N1PP/R2QKB1R w KQ -
+E89
+rnbq1rk1/pp3pbp/3ppnp1/2pP2B1/2P1P3/2N5/PP2BPPP/R2QK1NR w KQ -
+E75
+rnbq1rk1/pp3ppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P1BPPP/R2QK2R b KQ -
+C83*
+rnbq1rk1/pp3ppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R w KQ -
+C82*
+rnbq1rk1/pp3ppp/4pn2/2bp4/2P5/P3PN2/1P3PPP/RNBQKB1R b KQ -
+D27*
+rnbq1rk1/pp3ppp/4pn2/2p5/1bBP4/2N1PN2/PP3PPP/R1BQ1RK1 b - -
+E54
+rnbq1rk1/pp3ppp/4pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQK2R w KQ -
+E53
+rnbq1rk1/ppp1b1pp/3ppn2/5p2/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+A96
+rnbq1rk1/ppp1b1pp/4pn2/3p1p2/2PP4/1P3NP1/P3PPBP/RNBQ1RK1 b - -
+A93
+rnbq1rk1/ppp1bpp1/4pn1p/3p4/2PP3B/2N1PN2/PP3PPP/R2QKB1R b KQ -
+D56
+rnbq1rk1/ppp1bppp/4pn2/3p2B1/2PP4/2N1P3/PP3PPP/2RQKBNR b K -
+D54
+rnbq1rk1/ppp1bppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R b KQ -
+D55
+rnbq1rk1/ppp1ppbp/1n4p1/8/3P4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+D76
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2N2/PP2BPPP/R1BQK2R b KQ -
+E91
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2P2/PP4PP/R1BQKBNR w KQ -
+E81
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPPP2/2N5/PP2B1PP/R1BQK1NR b KQ -
+E77
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP1B2/2N1P3/PP3PPP/R2QKBNR w KQ -
+D83
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP1B2/2N1PN2/PP3PPP/R2QKB1R b KQ -
+D93
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/1QN1PN2/PP3PPP/R1B1KB1R b KQ -
+D95
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+D77
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/5NP1/PP2PPBP/RNBQK2R w KQ -
+D73
+rnbq1rk1/ppp1ppbp/5np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R b KQ -
+D97
+rnbq1rk1/ppp1ppbp/6p1/3n4/3P4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+D74
+rnbq1rk1/ppp2pbp/3p1np1/3Pp3/2P1P3/2N1BP2/PP4PP/R2QKBNR b KQ -
+E87
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+E85
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+E94
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+E92
+rnbq1rk1/ppp2ppp/4pn2/3p4/1bPP4/2N1PN2/PP3PPP/R1BQKB1R w KQ -
+E51
+rnbq1rk1/ppp2ppp/4pn2/3p4/1bPP4/2NBP3/PP3PPP/R1BQK1NR w KQ -
+E48
+rnbq1rk1/ppp2ppp/4pn2/3p4/2PP4/P1PBP3/5PPP/R1BQK1NR b KQ -
+E49
+rnbq1rk1/ppp2ppp/5n2/2bPN3/8/2N5/PPPP1PPP/R1BQKB1R b KQ -
+C56*
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQ -
+E46
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2N1PN2/PP3PPP/R1BQKB1R b KQ -
+E50
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2NBP3/PP3PPP/R1BQK1NR b KQ -
+E47
+rnbq1rk1/pppp1ppp/4pn2/8/2PP4/P1P1P3/5PPP/R1BQKBNR b KQ -
+E28
+rnbq1rk1/pppp1ppp/4pn2/8/2PP4/P1P5/4PPPP/R1BQKBNR w KQ -
+E27
+rnbq1rk1/pppp1ppp/5n2/4N3/1b2P3/2N5/PPPP1PPP/R1BQKB1R b KQ -
+C67*
+rnbq1rk1/pppp1ppp/5n2/4p3/1b2P3/2NP1N2/PPP2PPP/R1BQKB1R b KQ -
+C66*
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1P2N2/1PP1BPPP/R1BQK2R b KQ -
+C85*
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1P5/1PP2PPP/R1BQKBNR w KQ -
+C69*
+rnbq1rk1/pppp1ppp/5n2/b3N3/4P3/P1N5/1PPP1PPP/R1BQKB1R b KQ -
+C80*
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R w KQ -
+C78*
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPPBPPP/R1BQK2R b KQ -
+C84*
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1NP1N2/1PP2PPP/R1BQKB1R b KQ -
+C79*
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQ -
+C72*
+rnbq1rk1/ppppb1pp/4pn2/5p2/2PP4/5NP1/PP2PPBP/RNBQK2R w KQ -
+A92
+rnbqk1nr/pp2ppbp/6p1/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+E01*
+rnbqk1nr/pp2ppbp/6p1/2pp4/5P2/4PN2/PPPP2PP/RNBQKB1R w KQkq -
+A90*
+rnbqk1nr/pp2ppbp/6p1/2pp4/5P2/4PN2/PPPPB1PP/RNBQK2R b KQkq -
+A91*
+rnbqk1nr/pp2ppbp/6p1/3p4/3N4/6P1/PPP1PPBP/RNBQK2R b KQkq -
+D71*
+rnbqk1nr/pp3ppp/4p3/2ppP3/1b1P4/2N5/PPP2PPP/R1BQKBNR w KQkq -
+C17
+rnbqk1nr/pp3ppp/4p3/2ppP3/3P4/P1P5/2P2PPP/R1BQKBNR b KQkq -
+C18
+rnbqk1nr/ppp1ppbp/3p2p1/8/2PPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+A42
+rnbqk1nr/ppp2ppp/4p3/3p4/1b1PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+C15
+rnbqk1nr/ppp2ppp/4p3/3pP3/1b1P4/2N5/PPP2PPP/R1BQKBNR b KQkq -
+C16
+rnbqk1nr/pppp1pbp/8/6p1/2B1Pp2/5N2/PPPP2PP/RNBQK2R w KQkq -
+C38
+rnbqk1nr/pppp1ppp/8/2b1p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+C24*
+rnbqk1nr/pppp1ppp/8/2b1p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+C23*
+rnbqk1nr/ppppbppp/8/8/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+C35
+rnbqk2r/1p2bppp/p2ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+B98
+rnbqk2r/p1pp1ppp/1p2pn2/8/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQkq -
+E44
+rnbqk2r/p1pp1ppp/1p2pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+E43
+rnbqk2r/p1pp1ppp/5n2/1pb1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+C51*
+rnbqk2r/p2p1ppp/2p2n2/2b1p3/B3P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+C52*
+rnbqk2r/pp1p1ppp/2p2n2/2b1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+C53*
+rnbqk2r/pp1p1ppp/2p2n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQkq -
+C74*
+rnbqk2r/pp1p1ppp/2p2n2/b3p3/4P3/P1NP4/1PPB1PPP/R2QKBNR b KQkq -
+C75*
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQkq -
+E42
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+E41
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+E38
+rnbqk2r/pp1p1ppp/4pn2/2p5/2PP4/P1P1P3/5PPP/R1BQKBNR b KQkq -
+E26
+rnbqk2r/pp2npbp/6p1/3pp3/8/1N4P1/PPP1PPBP/RNBQK2R w KQkq -
+D72*
+rnbqk2r/pp2nppp/4p3/2ppP3/3P4/P1P5/2P2PPP/R1BQKBNR w KQkq -
+C19
+rnbqk2r/pp2ppbp/3p1np1/8/3NP3/2N1BP2/PPP3PP/R2QKB1R b KQkq -
+B75
+rnbqk2r/pp2ppbp/5np1/1Bpp4/8/1P2PN2/PBPP1PPP/RN1QK2R b KQkq -
+E16*
+rnbqk2r/pp2ppbp/5np1/2Pp4/8/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+E05*
+rnbqk2r/pp2ppbp/5np1/2Pp4/8/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+E04*
+rnbqk2r/pp2ppbp/5np1/2pp4/3P4/4PN2/PPP1BPPP/RNBQK2R w KQkq -
+E06*
+rnbqk2r/pp2ppbp/5np1/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 b kq -
+D73*
+rnbqk2r/pp2ppbp/5np1/2pp4/5P2/4PN2/PPPPB1PP/RNBQ1RK1 b kq -
+A92*
+rnbqk2r/pp2ppbp/5np1/2pp4/5P2/5NP1/PPPPP1BP/RNBQK2R w KQkq -
+A87*
+rnbqk2r/pp2ppbp/5np1/2pp4/8/1P2PN2/PBPPBPPP/RN1QK2R b KQkq -
+E17*
+rnbqk2r/pp3pbp/3p1np1/1BpP4/4PP2/2N5/PP4PP/R1BQK1NR b KQkq -
+A67
+rnbqk2r/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQK2R b KQkq -
+A71
+rnbqk2r/pp3pp1/3ppn1p/2pP4/1bP4B/2N5/PP2PPPP/R2QKBNR w KQkq -
+E31
+rnbqk2r/pp3ppp/2p2n2/b2pp3/4P3/P1NP2P1/1PPB1P1P/R2QKBNR b KQkq -
+C76*
+rnbqk2r/pp3ppp/4pn2/2pP4/3P4/P1P2P2/4P1PP/R1BQKBNR b KQkq -
+E25
+rnbqk2r/pp3ppp/5n2/2bpp3/2B5/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+C54*
+rnbqk2r/ppp1bppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR w KQkq -
+D53
+rnbqk2r/ppp1bppp/4pn2/3p2B1/3PP3/2N5/PPP2PPP/R2QKBNR w KQkq -
+C13
+rnbqk2r/ppp1bppp/4pn2/3p4/2P5/5NP1/PP1PPPBP/RNBQ1RK1 b kq -
+A14
+rnbqk2r/ppp1bppp/4pn2/3p4/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+E06
+rnbqk2r/ppp1bppp/4pn2/8/2pP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+E05
+rnbqk2r/ppp1ppbp/1n4p1/8/3PP3/6P1/PP2NPBP/RNBQK2R b KQkq -
+D72
+rnbqk2r/ppp1ppbp/3p1np1/8/2PP4/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+E62
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+E90
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N2P2/PP4PP/R1BQKBNR b KQkq -
+E80
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N3P1/PP3P1P/R1BQKBNR b KQkq -
+E72
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N4P/PP3PP1/R1BQKBNR b KQkq -
+E71
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N5/PP2BPPP/R1BQK1NR b KQkq -
+E73
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPPP2/2N5/PP4PP/R1BQKBNR b KQkq -
+E76
+rnbqk2r/ppp1ppbp/5np1/3p2B1/2PP4/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+D91
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP1B2/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+D92
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/1QN2N2/PP2PPPP/R1B1KB1R b KQkq -
+D96
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+D94
+rnbqk2r/ppp1ppbp/6p1/3n4/3P4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+D71
+rnbqk2r/ppp1ppbp/6p1/8/2BPP3/2P5/P4PPP/R1BQK1NR b KQkq -
+D86
+rnbqk2r/ppp2ppp/3b4/3np3/8/P3P3/1P1P1PPP/RNBQKBNR w KQkq -
+B42*
+rnbqk2r/ppp2ppp/4p3/3p4/2PPn3/P7/1PQ1PPPP/R1B1KBNR b KQkq -
+E37
+rnbqk2r/ppp2ppp/4pn2/3p2B1/1b1PP3/2N5/PPP2PPP/R2QKBNR w KQkq -
+C12
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+D38
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+E34
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/P1N5/1PQ1PPPP/R1B1KBNR b KQkq -
+E36
+rnbqk2r/ppp2ppp/4pn2/6B1/1bpP4/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+D39
+rnbqk2r/ppp2ppp/5n2/3p4/1b1P4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+E35
+rnbqk2r/ppp2ppp/5n2/3pp3/4P3/P1PP4/2P2PPP/R1BQKBNR w KQkq -
+C73*
+rnbqk2r/ppp3pp/5p2/3np3/1b2P3/3P1N2/PP3PPP/RNBQKB1R w KQkq -
+B55*
+rnbqk2r/pppp1ppp/4pn2/6B1/1bPP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+E30
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/1QN5/PP2PPPP/R1B1KBNR b KQkq -
+E22
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR b KQkq -
+E40
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+E21
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+E20
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N5/PPQ1PPPP/R1B1KBNR b KQkq -
+E32
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+E11
+rnbqk2r/pppp1ppp/4pn2/8/2PP4/P1P5/4PPPP/R1BQKBNR b KQkq -
+E24
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+C55*
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+C50*
+rnbqk2r/pppp1ppp/5n2/3Np3/1b2P3/8/PPPP1PPP/R1BQKBNR b KQkq -
+C61*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+C65*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+C60*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2NP4/PPP2PPP/R1BQKBNR b KQkq -
+C62*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+C63*
+rnbqk2r/pppp1ppp/5n2/4p3/1bB1P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+C64*
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+B31*
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/3P4/PP1BPPPP/RN1QKBNR b KQkq -
+B52*
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/3P4/PP2PPPP/RNBQKBNR w KQkq -
+B51*
+rnbqk2r/pppp1ppp/5n2/4p3/4P3/P1b5/1PPP1PPP/R1BQKBNR w KQkq -
+C68*
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R b KQkq -
+C77*
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N5/1PPP1PPP/R1BQKBNR w KQkq -
+C70*
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR b KQkq -
+C71*
+rnbqk2r/pppp1ppp/8/2b1p3/4P1n1/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+C57*
+rnbqk2r/pppp1ppp/8/2b5/N2pP1n1/5N2/PPP2PPP/R1BQKB1R b KQkq -
+C58*
+rnbqk2r/pppp2pp/5n2/2b1pP2/6P1/8/PPPP1PBP/RNBQK1NR b KQkq -
+C38*
+rnbqk2r/ppppb1pp/4pn2/5p2/2PP4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+A91
+rnbqk2r/ppppbppp/8/8/N3P1n1/2P2N1P/P4PP1/R1BQKB1R b KQkq -
+C59*
+rnbqk2r/ppppp1bp/5np1/5p2/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+A87
+rnbqk2r/ppppppbp/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+A08*
+rnbqk2r/ppppppbp/5np1/8/2PPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+E70
+rnbqkb1r/1p2pppp/p2p1n2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R b KQkq -
+B94
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N3P1/PPP2P1P/R1BQKB1R b KQkq -
+B91
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+B92
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+B90
+rnbqkb1r/1p2pppp/p2p1n2/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+B93
+rnbqkb1r/1p3ppp/p2ppn2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R w KQkq -
+B95
+rnbqkb1r/1p3ppp/p2ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R b KQkq -
+B96
+rnbqkb1r/1p3ppp/p2ppn2/8/3NP3/2N5/PPP1BPPP/R1BQK2R w KQkq -
+B84
+rnbqkb1r/1p3ppp/p3pn2/2p5/2BP4/4PN2/PP2QPPP/RNB2RK1 b kq -
+D28
+rnbqkb1r/1p3ppp/p3pn2/2p5/2BP4/4PN2/PP3PPP/RNBQ1RK1 w kq -
+D27
+rnbqkb1r/3ppppp/P4n2/2pP4/8/8/PP2PPPP/RNBQKBNR b KQkq -
+A58
+rnbqkb1r/5ppp/p2ppn2/1p6/3NP3/1BN5/PPP2PPP/R1BQK2R w KQkq -
+B87
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+E14
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+E12
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/5NP1/PP2PP1P/RNBQKB1R b KQkq -
+E15
+rnbqkb1r/p1pppppp/1p3n2/8/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+A47
+rnbqkb1r/p2ppppp/1p3n2/2p5/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+A12*
+rnbqkb1r/p2ppppp/5n2/1ppP4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+A57
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+A23
+rnbqkb1r/pp1p1ppp/4pn2/2p5/2P1P3/2N5/PP1P1PPP/R1BQKBNR w KQkq -
+A19
+rnbqkb1r/pp1p1ppp/4pn2/2pP4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+A60
+rnbqkb1r/pp1p1ppp/4pn2/8/2PN4/8/PP2PPPP/RNBQKB1R w KQkq -
+A32
+rnbqkb1r/pp1ppppp/5n2/2p5/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+A31
+rnbqkb1r/pp1ppppp/5n2/2p5/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+A56
+rnbqkb1r/pp1ppppp/5n2/2p5/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+A09*
+rnbqkb1r/pp1ppppp/5n2/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+B29
+rnbqkb1r/pp2pp1p/2p2p2/8/3P4/8/PPP2PPP/R1BQKBNR w KQkq -
+B16
+rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N1B3/PPP2PPP/R2QKB1R b KQkq -
+B72
+rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+B70
+rnbqkb1r/pp2pp1p/3p1np1/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+B71
+rnbqkb1r/pp2pp1p/5np1/2pP4/4p3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+D09*
+rnbqkb1r/pp2pp1p/5np1/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+E15*
+rnbqkb1r/pp2pppp/2p2n2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+D15
+rnbqkb1r/pp2pppp/2p2n2/8/P1pP4/2N2N2/1P2PPPP/R1BQKB1R b KQkq -
+D16
+rnbqkb1r/pp2pppp/3p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+B56
+rnbqkb1r/pp2pppp/5n2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R b KQkq -
+E11*
+rnbqkb1r/pp2pppp/5n2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+D23*
+rnbqkb1r/pp2pppp/5n2/2Pp4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+D21*
+rnbqkb1r/pp2pppp/5n2/2pp4/2P5/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+A31*
+rnbqkb1r/pp2pppp/5n2/2pp4/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+D11*
+rnbqkb1r/pp2pppp/5n2/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+D70*
+rnbqkb1r/pp2pppp/5n2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R b KQkq -
+E12*
+rnbqkb1r/pp2pppp/5n2/2pp4/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+E10*
+rnbqkb1r/pp2pppp/5n2/3p4/2PP4/2N5/PP3PPP/R1BQKBNR b KQkq -
+B14
+rnbqkb1r/pp2pppp/5n2/3p4/3P4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+D13*
+rnbqkb1r/pp2pppp/5n2/3p4/3P4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+D13
+rnbqkb1r/pp2pppp/8/2pn4/8/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+A32*
+rnbqkb1r/pp3p1p/3p1np1/2pP4/4P3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+A70
+rnbqkb1r/pp3p1p/3p1np1/2pP4/4PP2/2N5/PP4PP/R1BQKBNR b KQkq -
+A66
+rnbqkb1r/pp3p1p/3p1np1/2pP4/8/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+A61
+rnbqkb1r/pp3ppp/2p1pn2/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+D45
+rnbqkb1r/pp3ppp/2p1pn2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+D43
+rnbqkb1r/pp3ppp/2p1pn2/6B1/2pP4/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+D44
+rnbqkb1r/pp3ppp/2p2n2/3p2B1/3P4/2N5/PPQ1PPPP/R3KBNR b KQkq -
+D36
+rnbqkb1r/pp3ppp/3p1n2/1B2p3/3NP3/5P2/PPP3PP/RNBQK2R b KQkq -
+B55
+rnbqkb1r/pp3ppp/3p1n2/2pP4/4P3/2N5/PP3PPP/R1BQKBNR b KQkq -
+A65
+rnbqkb1r/pp3ppp/3ppn2/8/2BNP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+B86
+rnbqkb1r/pp3ppp/3ppn2/8/3NP1P1/2N5/PPP2P1P/R1BQKB1R b KQkq -
+B81
+rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+B83
+rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+B80
+rnbqkb1r/pp3ppp/3ppn2/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+B82
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+D26*
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+D25*
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/P7/1PP1PPPP/RNBQKBNR w KQkq -
+D22*
+rnbqkb1r/pp3ppp/4pn2/2pP4/3P4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+D41
+rnbqkb1r/pp3ppp/4pn2/2pp4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+D40
+rnbqkb1r/pp3ppp/4pn2/2pp4/3P1B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+D12*
+rnbqkb1r/pp3ppp/4pn2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+E14*
+rnbqkb1r/pp3ppp/8/2pnp3/8/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+B36*
+rnbqkb1r/pp3ppp/8/2pnp3/8/2N3P1/PP1PPPBP/R1BQK1NR b KQkq -
+B37*
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+B07
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PPP2/2N5/PPP3PP/R1BQKBNR b KQkq -
+B08
+rnbqkb1r/ppp1pp1p/5np1/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+D80
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP1B2/2N5/PP2PPPP/R2QKBNR b KQkq -
+D82
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/1QN5/PP2PPPP/R1B1KBNR b KQkq -
+D81
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+D90
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+D70
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/5P2/PP2P1PP/RNBQKBNR w KQkq -
+D70
+rnbqkb1r/ppp1pp1p/5np1/3p4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+A49*
+rnbqkb1r/ppp1pp1p/6p1/3n4/3P4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+D85
+rnbqkb1r/ppp1pppp/3p1n2/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+A53
+rnbqkb1r/ppp1pppp/3p1n2/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+B09
+rnbqkb1r/ppp1pppp/3p4/3nP3/3P4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+B04
+rnbqkb1r/ppp1pppp/5n2/3p2B1/3P4/2N5/PPP1PPPP/R2QKBNR b KQkq -
+D01
+rnbqkb1r/ppp1pppp/5n2/3p2B1/3P4/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+D03
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+D04
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+D02*
+rnbqkb1r/ppp1pppp/5n2/3p4/8/1P3N2/P1PPPPPP/RNBQKB1R b KQkq -
+A47*
+rnbqkb1r/ppp1pppp/5n2/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+A46*
+rnbqkb1r/ppp1pppp/5n2/3p4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+A48*
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+D24
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+D25
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+D23
+rnbqkb1r/ppp2ppp/3p1n2/4p3/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+A54
+rnbqkb1r/ppp2ppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+D50
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+D37
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+D35
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/6P1/PP2PPBP/RNBQK1NR b KQkq -
+E01
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+D05*
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+D05
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+D04*
+rnbqkb1r/ppp2ppp/4pn2/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+C11
+rnbqkb1r/ppp2ppp/4pn2/3p4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+C05
+rnbqkb1r/ppp2ppp/4pn2/8/2pP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+D26
+rnbqkb1r/ppp2ppp/4pn2/8/2pP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+E04
+rnbqkb1r/ppp2ppp/4pn2/8/Q1pP4/6P1/PP2PPBP/RNB1K1NR b KQkq -
+E02
+rnbqkb1r/ppp2ppp/5n2/3P4/4pP2/3P4/PPP3PP/RNBQKBNR w KQkq -
+C32
+rnbqkb1r/ppp2ppp/5n2/3p2B1/3Np3/3P4/PPP1PPPP/RN1QKB1R b KQkq -
+B05*
+rnbqkb1r/ppp2ppp/5n2/3p4/3Np3/3P4/PPP1PPPP/RNBQKB1R w KQkq -
+B04*
+rnbqkb1r/ppp2ppp/5n2/3pp3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+B32*
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+C43*
+rnbqkb1r/ppp2ppp/5n2/3pp3/4PP2/2N5/PPPP2PP/R1BQKBNR w KQkq -
+C29
+rnbqkb1r/ppp2ppp/8/3np3/8/2N1P3/PP1P1PPP/R1BQKBNR b KQkq -
+B44*
+rnbqkb1r/ppp2ppp/8/3np3/8/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+B34*
+rnbqkb1r/ppp2ppp/8/3np3/8/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+B33*
+rnbqkb1r/ppp2ppp/8/3np3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+C45*
+rnbqkb1r/ppp2ppp/8/3np3/8/3P4/PP2PPPP/RNBQKBNR w KQkq -
+B54*
+rnbqkb1r/ppp2ppp/8/3np3/8/P3P3/1P1P1PPP/RNBQKBNR b KQkq -
+B41*
+rnbqkb1r/pppp1p1p/5np1/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+A24
+rnbqkb1r/pppp1ppp/4pn2/8/2P1P3/2N5/PP1P1PPP/R1BQKBNR b KQkq -
+A18
+rnbqkb1r/pppp1ppp/4pn2/8/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+A17
+rnbqkb1r/pppp1ppp/4pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+E10
+rnbqkb1r/pppp1ppp/4pn2/8/2PP4/6P1/PP2PP1P/RNBQKBNR b KQkq -
+E00
+rnbqkb1r/pppp1ppp/5n2/4p3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+C24
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+B30*
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+A22
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/3P4/PP2PPPP/RNBQKBNR b KQkq -
+B50*
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/4P3/PP1P1PPP/RNBQKBNR b KQkq -
+B40*
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+B29*
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+B27*
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/P7/1P1PPPPP/RNBQKBNR b KQkq -
+B28*
+rnbqkb1r/pppp1ppp/5n2/4p3/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+A51
+rnbqkb1r/pppp1ppp/5n2/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+C43
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+C44*
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+C26
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+C41*
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+C42*
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+C42
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+C40*
+rnbqkb1r/pppp1ppp/8/4P3/2P3n1/8/PP2PPPP/RNBQKBNR w KQkq -
+A52
+rnbqkb1r/pppp1ppp/8/4p3/2B1n3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+C27
+rnbqkb1r/pppp2p1/5n2/4pP1p/6P1/8/PPPP1P1P/RNBQKBNR w KQkq -
+C39*
+rnbqkb1r/pppp2pp/4pn2/5p2/2PP4/6P1/PP2PPBP/RNBQK1NR b KQkq -
+A90
+rnbqkb1r/pppp2pp/5n2/4pP2/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+C36*
+rnbqkb1r/pppp2pp/5n2/4pP2/6P1/8/PPPP1P1P/RNBQKBNR b KQkq -
+C37*
+rnbqkb1r/pppp2pp/5n2/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+C34*
+rnbqkb1r/pppp2pp/5n2/4pP2/8/8/PPPPBPPP/RNBQK1NR b KQkq -
+C35*
+rnbqkb1r/ppppp1pp/5n2/5p2/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+A85
+rnbqkb1r/ppppp1pp/5n2/5p2/2PP4/6P1/PP2PP1P/RNBQKBNR b KQkq -
+A86
+rnbqkb1r/ppppp1pp/5n2/6B1/3Pp3/2N5/PPP2PPP/R2QKBNR b KQkq -
+A83
+rnbqkb1r/pppppp1p/5np1/8/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+E61
+rnbqkb1r/pppppp1p/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+E60
+rnbqkb1r/pppppp1p/5np1/8/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+A48
+rnbqkb1r/pppppp1p/5np1/8/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+A49
+rnbqkb1r/pppppp1p/5np1/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+A07*
+rnbqkb1r/pppppppp/5n2/8/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+A16
+rnbqkb1r/pppppppp/5n2/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+A15
+rnbqkb1r/pppppppp/5n2/8/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+A50
+rnbqkb1r/pppppppp/5n2/8/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+A46
+rnbqkb1r/pppppppp/5n2/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+A06*
+rnbqkb1r/pppppppp/5n2/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+A45
+rnbqkb1r/pppppppp/5n2/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+B02
+rnbqkb1r/pppppppp/5n2/8/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+A05*
+rnbqkb1r/pppppppp/5n2/8/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+A05
+rnbqkb1r/pppppppp/5n2/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+A04*
+rnbqkb1r/pppppppp/8/3nP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+B03
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+B43
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/3B4/PPP2PPP/RNBQK2R b KQkq -
+B42
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+B41
+rnbqkbnr/1p1ppppp/p7/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+B28
+rnbqkbnr/1pp1pppp/p7/8/2pP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+D22
+rnbqkbnr/p1pppppp/1p6/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+A01*
+rnbqkbnr/pp1p1ppp/2p5/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+B22*
+rnbqkbnr/pp1p1ppp/4p3/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+B40
+rnbqkbnr/pp1p1ppp/8/2pPp3/8/8/PPP1PPPP/RNBQKBNR w KQkq e6
+A44
+rnbqkbnr/pp1ppppp/2p5/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+A11
+rnbqkbnr/pp1ppppp/2p5/8/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+B12
+rnbqkbnr/pp1ppppp/2p5/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+B10
+rnbqkbnr/pp1ppppp/8/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+A34
+rnbqkbnr/pp1ppppp/8/2p5/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+A30*
+rnbqkbnr/pp1ppppp/8/2p5/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+A30
+rnbqkbnr/pp1ppppp/8/2p5/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+A43
+rnbqkbnr/pp1ppppp/8/2p5/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+B21
+rnbqkbnr/pp1ppppp/8/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+B23
+rnbqkbnr/pp1ppppp/8/2p5/4P3/2P5/PP1P1PPP/RNBQKBNR b KQkq -
+B22
+rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+B27
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+A20*
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+B20
+rnbqkbnr/pp1ppppp/8/2p5/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+B21
+rnbqkbnr/pp1ppppp/8/2p5/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+A11*
+rnbqkbnr/pp1ppppp/8/2p5/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+A13*
+rnbqkbnr/pp1ppppp/8/2p5/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+A15*
+rnbqkbnr/pp1ppppp/8/2p5/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+A10*
+rnbqkbnr/pp2p1pp/5p2/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+D70*
+rnbqkbnr/pp2pp1p/6p1/2pp4/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+A86*
+rnbqkbnr/pp2pp1p/6p1/2pp4/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+E00*
+rnbqkbnr/pp2pppp/2p5/3p4/2P5/1P3N2/P2PPPPP/RNBQKB1R b KQkq -
+A12
+rnbqkbnr/pp2pppp/2p5/3p4/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+D11
+rnbqkbnr/pp2pppp/2p5/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+D10
+rnbqkbnr/pp2pppp/2p5/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+B15
+rnbqkbnr/pp2pppp/3p4/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+B51
+rnbqkbnr/pp2pppp/3p4/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+B50
+rnbqkbnr/pp2pppp/3p4/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+B54
+rnbqkbnr/pp2pppp/3p4/8/3QP3/5N2/PPP2PPP/RNB1KB1R b KQkq -
+B53
+rnbqkbnr/pp2pppp/8/2Pp4/8/8/PPP1PPPP/RNBQKBNR b KQkq -
+D20*
+rnbqkbnr/pp2pppp/8/2p3N1/4p3/8/PPPP1PPP/RNBQKB1R b KQkq -
+A52*
+rnbqkbnr/pp2pppp/8/2p5/1PPp4/5N2/P2PPPPP/RNBQKB1R b KQkq -
+A57*
+rnbqkbnr/pp2pppp/8/2p5/2Pp4/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+A60*
+rnbqkbnr/pp2pppp/8/2pp4/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+A56*
+rnbqkbnr/pp2pppp/8/2pp4/3P4/2N5/PPP1PPPP/R1BQKBNR b KQkq -
+D07*
+rnbqkbnr/pp2pppp/8/2pp4/3P4/2P5/PP2PPPP/RNBQKBNR b KQkq -
+D10*
+rnbqkbnr/pp2pppp/8/2pp4/3P4/4P3/PPP2PPP/RNBQKBNR b KQkq -
+D30*
+rnbqkbnr/pp2pppp/8/2pp4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+D06*
+rnbqkbnr/pp2pppp/8/2pp4/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+D08*
+rnbqkbnr/pp2pppp/8/2pp4/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+A51*
+rnbqkbnr/pp2pppp/8/2pp4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+A84*
+rnbqkbnr/pp2pppp/8/2pp4/8/3P1N2/PPP1PPPP/RNBQKB1R b KQkq -
+A53*
+rnbqkbnr/pp2pppp/8/2pp4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+A50*
+rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+E60*
+rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPPBP/RNBQK2R b KQkq -
+A08
+rnbqkbnr/pp2pppp/8/3p4/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+B13
+rnbqkbnr/pp2pppp/8/8/2Pp4/p4N2/3PPPPP/RNBQKB1R w KQkq -
+A58*
+rnbqkbnr/pp3ppp/4p3/2pp4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+D32
+rnbqkbnr/pp3ppp/4p3/2pp4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+C07
+rnbqkbnr/pp3ppp/8/2pp4/3P4/8/PPPN1PPP/R1BQKBNR w KQkq -
+C08
+rnbqkbnr/ppp1pp1p/6p1/3p4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+A81*
+rnbqkbnr/ppp1pppp/3p4/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+A41
+rnbqkbnr/ppp1pppp/8/3p4/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+A09
+rnbqkbnr/ppp1pppp/8/3p4/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+A43*
+rnbqkbnr/ppp1pppp/8/3p4/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+D06
+rnbqkbnr/ppp1pppp/8/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+D02
+rnbqkbnr/ppp1pppp/8/3p4/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+D00*
+rnbqkbnr/ppp1pppp/8/3p4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+D00
+rnbqkbnr/ppp1pppp/8/3p4/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+B01
+rnbqkbnr/ppp1pppp/8/3p4/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+A80*
+rnbqkbnr/ppp1pppp/8/3p4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+A03
+rnbqkbnr/ppp1pppp/8/3p4/8/3P4/PPP1PPPP/RNBQKBNR b KQkq -
+A41*
+rnbqkbnr/ppp1pppp/8/3p4/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+A45*
+rnbqkbnr/ppp1pppp/8/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+A06
+rnbqkbnr/ppp1pppp/8/3p4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+A07
+rnbqkbnr/ppp1pppp/8/3p4/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+A40*
+rnbqkbnr/ppp1pppp/8/8/2PpP3/8/PP1P1PPP/RNBQKBNR b KQkq e3
+A44*
+rnbqkbnr/ppp1pppp/8/8/2pP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+D21
+rnbqkbnr/ppp1pppp/8/8/2pP4/8/PP2PPPP/RNBQKBNR w KQkq -
+D20
+rnbqkbnr/ppp2ppp/3p4/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+C41
+rnbqkbnr/ppp2ppp/4p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+D31
+rnbqkbnr/ppp2ppp/4p3/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+D30
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+C10
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/8/PPPN1PPP/R1BQKBNR b KQkq -
+C03
+rnbqkbnr/ppp2ppp/4p3/3pP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+C02
+rnbqkbnr/ppp2ppp/8/3Pp3/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+C21*
+rnbqkbnr/ppp2ppp/8/3p4/3Np3/8/PPPPPPPP/RNBQKB1R w KQkq -
+B03*
+rnbqkbnr/ppp2ppp/8/3p4/3P4/8/PP2PPPP/RNBQKBNR b KQkq -
+B13*
+rnbqkbnr/ppp2ppp/8/3p4/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+C01*
+rnbqkbnr/ppp2ppp/8/3p4/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+C01
+rnbqkbnr/ppp2ppp/8/3p4/3Pp3/4P3/PPP2PPP/RNBQKBNR w KQkq -
+C02*
+rnbqkbnr/ppp2ppp/8/3p4/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+C36
+rnbqkbnr/ppp2ppp/8/3pp3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+B21*
+rnbqkbnr/ppp2ppp/8/3pp3/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+D08
+rnbqkbnr/ppp2ppp/8/3pp3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+C31
+rnbqkbnr/ppp2ppp/8/3pp3/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+A82*
+rnbqkbnr/ppp2ppp/8/3pp3/8/2P5/PP1PPPPP/RNBQKBNR w KQkq -
+B12*
+rnbqkbnr/ppp2ppp/8/3pp3/8/3P1N2/PPP1PPPP/RNBQKB1R b KQkq -
+B09*
+rnbqkbnr/ppp3pp/3p4/4Pp2/3p4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+C32*
+rnbqkbnr/pppp1p1p/8/6p1/4Pp1P/5N2/PPPP2P1/RNBQKB1R b KQkq -
+C39
+rnbqkbnr/pppp1p1p/8/6p1/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+C37
+rnbqkbnr/pppp1ppp/4p3/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+A13
+rnbqkbnr/pppp1ppp/4p3/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+C00
+rnbqkbnr/pppp1ppp/8/4p3/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+C23
+rnbqkbnr/pppp1ppp/8/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+A21
+rnbqkbnr/pppp1ppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+B20*
+rnbqkbnr/pppp1ppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+A20
+rnbqkbnr/pppp1ppp/8/4p3/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+B01*
+rnbqkbnr/pppp1ppp/8/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+C25
+rnbqkbnr/pppp1ppp/8/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+C40
+rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+C20*
+rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+C20
+rnbqkbnr/pppp1ppp/8/4p3/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+C30
+rnbqkbnr/pppp1ppp/8/4p3/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+B10*
+rnbqkbnr/pppp1ppp/8/4p3/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+C00*
+rnbqkbnr/pppp1ppp/8/4p3/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+B02*
+rnbqkbnr/pppp1ppp/8/4p3/8/6P1/PPPPPP1P/RNBQKBNR b KQkq -
+B06*
+rnbqkbnr/pppp1ppp/8/4p3/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+B00*
+rnbqkbnr/pppp1ppp/8/8/3pP3/8/PPP2PPP/RNBQKBNR w KQkq -
+C21
+rnbqkbnr/pppp1ppp/8/8/4Pp2/5N2/PPPP2PP/RNBQKB1R b KQkq -
+C34
+rnbqkbnr/pppp1ppp/8/8/4Pp2/8/PPPP2PP/RNBQKBNR w KQkq -
+C33
+rnbqkbnr/pppp2pp/8/4pP2/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+C33*
+rnbqkbnr/pppp2pp/8/4pp2/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+B21*
+rnbqkbnr/pppp2pp/8/4pp2/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+C31*
+rnbqkbnr/pppp2pp/8/4pp2/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+C30*
+rnbqkbnr/ppppp1pp/8/5p2/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+A84
+rnbqkbnr/ppppp1pp/8/5p2/3P4/6P1/PPP1PP1P/RNBQKBNR b KQkq -
+A81
+rnbqkbnr/ppppp1pp/8/5p2/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+A03*
+rnbqkbnr/ppppp1pp/8/5p2/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+A80
+rnbqkbnr/ppppp1pp/8/5p2/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+A82
+rnbqkbnr/ppppp1pp/8/5p2/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+A02*
+rnbqkbnr/pppppp1p/6p1/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+B06
+rnbqkbnr/pppppppp/8/8/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+A10
+rnbqkbnr/pppppppp/8/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+A40
+rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+B00
+rnbqkbnr/pppppppp/8/8/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+A02
+rnbqkbnr/pppppppp/8/8/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+A01
+rnbqkbnr/pppppppp/8/8/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+A04
+rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR b KQkq -
+A00*
+rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+A00
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N1P/2P1BPP1/R1BQ1RK1 b - -
+C93*
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+C92*
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P2P1N2/2P1BPPP/RNBQ1RK1 b - -
+C94*
+rnbqr1k1/pp1p1ppp/1bp2n2/4p3/1P1PP3/P1N2N2/2P1BPPP/R1BQ1RK1 b - -
+C89*
+rnbqr1k1/pp1p1ppp/1bp2n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 b - -
+C90*
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+A76
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4P3/2N5/PP1NBPPP/R1BQ1RK1 b - -
+A77
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4PP2/2N2N2/PP2B1PP/R1BQK2R w KQ -
+A69
+rnbqr1k1/pp3pp1/1bp2n1p/3pp3/1P2P3/P2P1N2/2P1BPPP/RNBQ1RK1 w - -
+C95*
+rnbqr1k1/pp3ppp/1bp2n2/3pp3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+C91*
+rnbqr1k1/ppb2pp1/2p2n1p/3pp3/NPP1P3/P2P1N2/2Q1BPPP/R1B2RK1 b - -
+C97*
+rnbqr1k1/ppbp1pp1/2p2n1p/4p3/NP2P3/P2P1N2/2P1BPPP/R1BQ1RK1 w - -
+C96*
+rnbqr1k1/pppp1ppp/1b3n2/4p3/1P2P3/P1N2N2/2PPBPPP/R1BQK2R w KQ -
+C88*
+rnbqr1k1/pppp1ppp/5n2/b3p3/4P3/P1NP1N2/1PP1BPPP/R1BQK2R b KQ -
+C87*
--- /dev/null
+1rbq1rk1/1pp1ppbp/p1np1np1/8/2PPP3/2N1BP2/PP1QN1PP/R3KB1R w KQ -
+E84
+2kr1b1r/ppp3pp/2n2q2/3npp2/6b1/P2PPN2/1PQNBPPP/R1B1K2R b KQ -
+B99*
+2kr1b1r/ppp3pp/2n5/3qpp2/6b1/3PPN2/PP2BPPP/R1BQ1RK1 w - -
+B65*
+2kr1b1r/pppq1ppp/2n5/3np3/6b1/P1NPPN2/1P1B1PPP/R2QKB1R b KQ -
+B67*
+2kr1b1r/pppq2pp/2n2n2/4pp2/1P6/P1NPPb2/3BBPPP/R2QK2R w KQ -
+B69*
+2kr1b1r/pppq2pp/2n5/3npp2/6b1/2NPPN2/PP2BPPP/R1BQ1RK1 w - -
+B64*
+2kr1b1r/pppq2pp/2n5/3npp2/6b1/P1NPPN2/1P1BBPPP/R2QK2R b KQ -
+B68*
+2kr3r/pppq2p1/1bn1bp2/3np2p/Q7/2NP1NP1/PP1BPPBP/R1R3K1 w - -
+B79*
+2kr3r/pppq2pp/2n1bp2/2bnp3/8/2NP1NP1/PP1BPPBP/R2Q1RK1 w - -
+B78*
+2r1kb1r/ppq2ppp/2n1pn2/2pp4/3P2b1/2P1PN2/PP1NBPPP/R1BQ1RK1 w k -
+D64*
+2r1kb1r/ppq2ppp/2n1pn2/3p4/3p2b1/P1P1PN2/1P1NBPPP/R1BQ1RK1 w k -
+D65*
+2rqk2r/pp3ppp/2n1pn2/2bp4/3N2b1/2P1P3/PP1NBPPP/R1BQ1RK1 b k -
+D67*
+2rqk2r/pp3ppp/2nbpn2/2pp4/3P2b1/2P1PN2/PP1NBPPP/R1BQ1RK1 w k -
+D66*
+2rqkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w k -
+D63*
+2rqkbnr/pp3ppp/2n1p3/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQ1RK1 w k -
+D54*
+3q1rk1/pp3ppp/2r1p3/2b5/4Q3/2P5/PP3PPP/R1B2RK1 b - -
+D69*
+3q1rk1/pp3ppp/2r1pn2/2bp4/4P3/2P5/PP1NQPPP/R1B2RK1 b - -
+D68*
+r1b1k2r/1pqnbppp/p2ppn2/6B1/3NPP2/2N2Q2/PPP3PP/2KR1B1R w kq -
+B99
+r1b1kb1r/1pq2ppp/p1nppn2/8/3NPP2/2N5/PPP1B1PP/R1BQ1RK1 w kq -
+B85
+r1b1kb1r/pp2pppp/1qn2n2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+D96*
+r1b1kb1r/pp3ppp/1qn1pn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+D95*
+r1b1kb1r/pp3ppp/2n2n2/2qpp1B1/8/5NP1/PPP1PPBP/RN1Q1RK1 b kq -
+D98*
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+D97*
+r1b1kbnr/1pq1pppp/p1n5/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R w KQkq -
+E36*
+r1b1kbnr/1pq1pppp/p7/2ppN3/3P4/4P3/PPP2PPP/RNBQK2R w KQkq -
+E37*
+r1b1kbnr/1pqp1ppp/p1n1p3/8/3NP3/2N1B3/PPP1BPPP/R2QK2R b KQkq -
+B49
+r1b1kbnr/pp2pppp/1qn5/1Bp5/2p5/2N1PN2/PP1P1PPP/R1BQK2R b KQkq -
+E23*
+r1b1kbnr/pp2pppp/1qn5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+E22*
+r1b1kbnr/pp2pppp/1qn5/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+D81*
+r1b1kbnr/ppq1pppp/2n5/1B1p4/3P4/5N2/PPP2PPP/RNBQK2R b KQkq -
+E35*
+r1b1kbnr/ppq1pppp/2n5/1Bp5/2p5/4PN2/PP1P1PPP/RNBQ1RK1 b kq -
+E39*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+E38*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R b KQkq -
+E34*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/8/2N1PN2/PPPP1PPP/R1BQK2R b KQkq -
+E33*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+E32*
+r1b1kbnr/ppqp1ppp/2n1p3/8/3NP3/2N1B3/PPP2PPP/R2QKB1R b KQkq -
+B48
+r1b1kbnr/ppqp1ppp/2n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+B47
+r1b2rk1/1p2qppp/2n1pn2/pBbp4/5B2/2P1PN2/PP3PPP/RN1Q1RK1 w - -
+D19*
+r1b2rk1/2q1bppp/p1np1n2/1pp1p3/3PP3/2P2N1P/PPBN1PP1/R1BQR1K1 w - -
+C98
+r1b2rk1/2q1bppp/p2p1n2/np2p3/3PP3/5N1P/PPBN1PP1/R1BQR1K1 b - -
+C99
+r1b2rk1/2q1bppp/p2p1n2/npp1p3/3PP3/2P2N1P/PPB2PP1/RNBQR1K1 w - -
+C97
+r1b2rk1/pp1nqppp/2p5/4p3/2BP4/2R1PN2/PP3PPP/3Q1RK1 w - -
+D68
+r1b2rk1/pp2ppbp/2q2np1/2pp4/8/1P2P3/PBPPBPPP/RN1Q1RK1 w - -
+E19*
+r1b2rk1/pp3ppp/2p5/4q3/2B5/2R1P3/PP3PPP/3Q1RK1 w - -
+D69
+r1b2rk1/ppq1ppbp/2n2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 w - -
+A98*
+r1b2rk1/ppqnppbp/5np1/2pp4/3P4/2P1PN2/PP1NBPPP/R1BQ1RK1 w - -
+E09*
+r1bq1rk1/1p1n1pbp/2pp1np1/p3p3/2PPP3/2N2N2/PP3PPP/R1BQRBK1 w - -
+E96
+r1bq1rk1/1p1nbppp/p1p1pn2/3P2B1/3P4/2N1PN2/PPQ2PPP/2R1KB1R b K -
+D65
+r1bq1rk1/1p1nppbp/2n3p1/p7/2Pp4/P2P1NP1/1P1N1PBP/R1BQR1K1 b - -
+A64*
+r1bq1rk1/1p2bppp/2n2n2/p3p1B1/2Pp4/P2P1NP1/1P3PBP/RN1Q1RK1 b - -
+A75*
+r1bq1rk1/1p3ppp/p1n1pn2/1BbP4/8/2N1PN2/PP3PPP/R1BQ1RK1 b - -
+E57*
+r1bq1rk1/1pp1ppbp/p1np1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+E63
+r1bq1rk1/2p1bpp1/p1np1n1p/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+C93
+r1bq1rk1/2p1bppp/p1n2n2/1p1pp3/4P3/1BP2N2/PP1P1PPP/RNBQR1K1 w - -
+C89
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/3PP3/1BP2N2/PP3PPP/RNBQR1K1 b - -
+C91
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 b - -
+C92
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/1BP2N2/PP1P1PPP/RNBQR1K1 w - -
+C90
+r1bq1rk1/2p1bppp/p2p1n2/np2p3/4P3/2P2N1P/PPBP1PP1/RNBQR1K1 b - -
+C96
+r1bq1rk1/5ppp/p1p1pn2/2bp4/2P5/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+E59*
+r1bq1rk1/5ppp/p1pbpn2/2pp4/2PP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+E58*
+r1bq1rk1/p3ppbp/1pn2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 w - -
+A99*
+r1bq1rk1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N2NPP/PP3PB1/R1BQ1RK1 b - -
+E69
+r1bq1rk1/pp1n1pbp/3p1np1/2pP4/8/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+A63
+r1bq1rk1/pp1n1ppp/4pn2/2p5/1bBP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+E55
+r1bq1rk1/pp1nb1pp/2n2p2/4p3/2Pp4/3P1NP1/PPN2PBP/R1BQR1K1 b - -
+A79*
+r1bq1rk1/pp1nbppp/2n5/4p3/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 w - -
+A77*
+r1bq1rk1/pp1nbppp/2n5/4p3/2Pp4/N2P1NP1/PP3PBP/R1BQR1K1 b - -
+A78*
+r1bq1rk1/pp1nbppp/2p1p3/3n2B1/2BP4/2N1PN2/PP3PPP/2RQK2R w K -
+D67
+r1bq1rk1/pp1nbppp/2p1pn2/3p2B1/2PP4/2N1PN2/PPQ2PPP/2R1KB1R b K -
+D64
+r1bq1rk1/pp1nbppp/2p1pn2/3p2B1/2PP4/2NBPN2/PP3PPP/2RQK2R b K -
+D66
+r1bq1rk1/pp1nbppp/2p1pn2/3p4/2PP4/5NP1/PPQNPPBP/R1B2RK1 b - -
+E09
+r1bq1rk1/pp1nbppp/4pn2/2Pp2B1/2P5/2N1PN2/PPQ2PPP/R3KB1R b KQ -
+D62
+r1bq1rk1/pp1p1ppp/2n1pn2/2p5/2PP4/P1PBP3/5PPP/R1BQK1NR w KQ -
+E29
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+A39
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/2NP1NP1/PPP2PBP/R1BQ1RK1 b - -
+E97*
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 w - -
+E94*
+r1bq1rk1/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 w - -
+A73*
+r1bq1rk1/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 b - -
+A76*
+r1bq1rk1/pp2bppp/2n2n2/4p3/2Pp4/P2P1NP1/1P3PBP/RNBQ1RK1 b - -
+A74*
+r1bq1rk1/pp2bppp/2nppn2/6B1/3NPP2/2N5/PPPQ2PP/2KR1B1R b - -
+B64
+r1bq1rk1/pp2bppp/3ppn2/6B1/3QPP2/2N5/PPP3PP/2KR1B1R b - -
+B65
+r1bq1rk1/pp2ppbp/2n2np1/2p5/2Pp4/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+E66*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w - -
+A39*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 w - -
+E65*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/3P1P2/2P1PN2/PP2B1PP/RNBQ1RK1 b - -
+A95*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5P2/2NP1NP1/PPP1P1BP/R1BQ1RK1 b - -
+A89*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5P2/2PP1NP1/PP2P1BP/RNBQ1RK1 b - -
+A88*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 b - -
+A97*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/1P2PN2/PBPPBPPP/RN1Q1RK1 w - -
+E18*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/P1NP1NP1/1PP1PPBP/R1BQ1RK1 b - -
+E63*
+r1bq1rk1/pp2ppbp/2n2np1/8/2Pp4/3P1NP1/PP1N1PBP/R1BQ1RK1 b - -
+A63*
+r1bq1rk1/pp2ppbp/2n3p1/8/2BPP3/4B3/P3NPPP/R2Q1RK1 b - -
+D88
+r1bq1rk1/pp2ppbp/2np1np1/2pP4/2P5/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+E66
+r1bq1rk1/pp2ppbp/2np1np1/8/2BNP3/2N1BP2/PPPQ2PP/R3K2R b KQ -
+B77
+r1bq1rk1/pp2ppbp/2np1np1/8/2PNPP2/2N1B3/PP2B1PP/R2QK2R b KQ -
+E79
+r1bq1rk1/pp2ppbp/2np1np1/8/4P3/1NN1B3/PPP1BPPP/R2Q1RK1 b - -
+B74
+r1bq1rk1/pp3pb1/2n2npp/2ppp3/4P3/2PP1NP1/PP1N1PBP/R1BQ1RK1 w - -
+E69*
+r1bq1rk1/pp3pbp/2n2np1/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+E68*
+r1bq1rk1/pp3ppp/2n1pn2/1Bbp4/2P5/4PN2/PP1N1PPP/R1BQ1RK1 b - -
+E55*
+r1bq1rk1/pp3ppp/2n1pn2/1Bbp4/2P5/4PN2/PP3PPP/RNBQ1RK1 w - -
+E54*
+r1bq1rk1/pp3ppp/2n1pn2/2p5/2BP4/P1P1PN2/5PPP/R1BQ1RK1 b - -
+E59
+r1bq1rk1/pp3ppp/2n1pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+E56
+r1bq1rk1/pp3ppp/2n1pn2/2pp4/2PP4/P1PBPN2/5PPP/R1BQ1RK1 b - -
+E58
+r1bq1rk1/pp3ppp/2n1pn2/8/1bBp4/P1N1PN2/1P3PPP/R1BQ1RK1 w - -
+E57
+r1bq1rk1/pp3ppp/2nbpn2/1Bpp4/2PP4/2N1PN2/PP3PPP/R1BQ1RK1 b - -
+E56*
+r1bq1rk1/ppp1b1pp/2n5/3npp2/8/P1NPPN2/1PQ2PPP/R1B1KB1R b KQ -
+B85*
+r1bq1rk1/ppp1npbp/3p1np1/3Pp3/2P1P3/2N5/PP2BPPP/R1BQNRK1 b - -
+E98
+r1bq1rk1/ppp1p1bp/2np1np1/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+A89
+r1bq1rk1/ppp1ppbp/2np1np1/8/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+E83
+r1bq1rk1/ppp2pbp/2np1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+E97
+r1bq1rk1/pppn1pbp/3p1np1/3Pp3/2P1P3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+E93
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQR1K1 b - -
+E95
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2NP1/PP3PBP/R1BQ1RK1 b - -
+E68
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/2RQKB1R b K -
+D63
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQ -
+D60
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PPQ2PPP/R3KB1R b KQ -
+D61
+r1bq1rk1/pppnbppp/4pn2/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+E07
+r1bq1rk1/pppnbppp/4pn2/3p4/2PP4/5NP1/PPQ1PPBP/RNB2RK1 b - -
+E08
+r1bq1rk1/pppnn1bp/3p2p1/3Ppp2/2P1P3/2N2P2/PP2B1PP/R1BQNRK1 w - -
+E99
+r1bq1rk1/pppnppbp/3p1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+E67
+r1bqk1nr/5ppp/p1pbp3/2pp4/2P5/2N1PN2/PP1P1PPP/R1BQ1RK1 b kq -
+E29*
+r1bqk1nr/5ppp/p1pbp3/2pp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 w kq -
+E49*
+r1bqk1nr/p4ppp/2p5/2bpp3/8/6P1/PPP1PPBP/RNBQK2R w KQkq -
+D86*
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+A37
+r1bqk1nr/pp1pppbp/2n3p1/8/2PNP3/4B3/PP3PPP/RN1QKB1R b KQkq -
+B38
+r1bqk1nr/pp1pppbp/2n3p1/8/2PNP3/8/PP3PPP/RNBQKB1R w KQkq -
+B37
+r1bqk1nr/pp2b1pp/2n5/2pppp2/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+E77*
+r1bqk1nr/pp2bppp/2n5/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E73*
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NP2P1/PPP2PBP/R1BQK1NR b KQkq -
+A26*
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NP2P1/PPP2PBP/R1BQK1NR w KQkq -
+B25
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NPB1P1/PPP2PBP/R2QK1NR b KQkq -
+B26
+r1bqk1nr/pp3ppp/2nbp3/1Bpp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 b kq -
+E48*
+r1bqk1nr/pp3ppp/2nbp3/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+E47*
+r1bqk1nr/pp4pp/2n5/4pp2/1bPp4/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+A67*
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR b KQkq -
+B25*
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR w KQkq -
+A26
+r1bqk1nr/pppp1ppp/2n5/1Bb1p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C64
+r1bqk1nr/pppp1ppp/2n5/2b1N3/4P3/8/PPPP1PPP/RNBQKB1R b KQkq -
+C27*
+r1bqk1nr/pppp1ppp/2n5/2b1p3/1PB1P3/5N2/P1PP1PPP/RNBQK2R b KQkq -
+C51
+r1bqk1nr/pppp1ppp/2n5/2b1p3/2B1P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+C53
+r1bqk1nr/pppp1ppp/2n5/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+C28*
+r1bqk1nr/pppp1ppp/2n5/b3p3/2B1P3/2P2N2/P2P1PPP/RNBQK2R w KQkq -
+C52
+r1bqk2r/1pp1bppp/p1np1n2/4p3/B3P3/5N2/PPPP1PPP/RNBQR1K1 w kq -
+C87
+r1bqk2r/1pp1bppp/p1p2n2/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+C85
+r1bqk2r/1pppbppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+C84
+r1bqk2r/1pppbppp/p1n2n2/4p3/B3P3/5N2/PPPPQPPP/RNB2RK1 b kq -
+C86
+r1bqk2r/2ppbppp/p1n2n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQR1K1 b kq -
+C88
+r1bqk2r/p3nppp/2p5/2bpp3/2P5/6P1/PP2PPBP/RNBQ1RK1 b kq -
+D87*
+r1bqk2r/pp1nnppp/3b4/3p4/3Pp3/2N1P3/PP1N1PPP/R1BQKB1R w KQkq -
+C06*
+r1bqk2r/pp1p1ppp/2n1pn2/2P5/1bP5/1QN5/PP2PPPP/R1B1KBNR w KQkq -
+E23
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+A38*
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+A38
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+A37*
+r1bqk2r/pp1pppbp/2n2np1/8/2BNP3/2N1B3/PPP2PPP/R2QK2R b KQkq -
+B35
+r1bqk2r/pp1pppbp/2n3p1/8/2PNP1n1/2N1B3/PP3PPP/R2QKB1R w KQkq -
+B39
+r1bqk2r/pp2b1pp/2n2n2/2pppp2/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 w kq -
+E78*
+r1bqk2r/pp2b1pp/2n2n2/4pp2/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 b kq -
+A69*
+r1bqk2r/pp2bppp/2n2n2/2p1p3/3pP3/3P1NP1/PPPN1PBP/R1BQ1RK1 b kq -
+E93*
+r1bqk2r/pp2bppp/2n2n2/2pp4/3P4/2N2NP1/PP2PPBP/R1BQK2R w KQkq -
+D34
+r1bqk2r/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 b kq -
+E92*
+r1bqk2r/pp2bppp/2n2n2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+E91*
+r1bqk2r/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+A72*
+r1bqk2r/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+A71*
+r1bqk2r/pp2ppbp/2n2np1/2pp4/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+E64*
+r1bqk2r/pp2ppbp/2n2np1/2pp4/8/3P1NP1/PPPNPPBP/R1BQ1RK1 b kq -
+E67*
+r1bqk2r/pp2ppbp/2n2np1/3p4/2PP4/2N2N2/PP2BPPP/R1BQK2R b KQkq -
+D34*
+r1bqk2r/pp2ppbp/2n2np1/8/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+A62*
+r1bqk2r/pp2ppbp/2np1np1/8/3NP3/2N1B3/PPP1BPPP/R2Q1RK1 b kq -
+B73
+r1bqk2r/pp3ppp/2n1pn2/2bp4/8/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+D47*
+r1bqk2r/pp3ppp/2nbpn2/1Bpp4/2PP4/4PN2/PP3PPP/RNBQ1RK1 b kq -
+E53*
+r1bqk2r/pp3ppp/2nbpn2/1Bpp4/3P4/1P2PN2/P1P2PPP/RNBQ1RK1 b kq -
+E52*
+r1bqk2r/pp3ppp/2nbpn2/2pp4/3P4/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+D46*
+r1bqk2r/pp3ppp/2nbpn2/3p4/1P6/P1P1PN2/3N1PPP/R1BQKB1R b KQkq -
+D48*
+r1bqk2r/pp3ppp/2nbpn2/3p4/2PN4/2N1P3/PP3PPP/R1BQKB1R w KQkq -
+D42*
+r1bqk2r/pp3ppp/3b1n2/3P4/1n2p3/P3PN2/3N1PPP/R1BQKB1R w KQkq -
+D49*
+r1bqk2r/ppp1bppp/1nn5/4p3/4P3/2NP1N2/PP3PPP/R1BQKB1R w KQkq -
+B59*
+r1bqk2r/ppp1bppp/2n5/3np3/8/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+B58*
+r1bqk2r/ppp1bppp/2n5/3np3/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+B83*
+r1bqk2r/ppp1bppp/2n5/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+B92*
+r1bqk2r/ppp1bppp/2n5/3np3/8/P2PPN2/1P3PPP/RNBQKB1R b KQkq -
+B84*
+r1bqk2r/ppp2ppp/1bn5/3np3/1P6/P2PPN2/5PPP/RNBQKB1R b KQkq -
+B87*
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+B57*
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/2NPPN2/PP3PPP/R1BQKB1R b KQkq -
+B88*
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+B86*
+r1bqk2r/pppp1ppp/2n1pn2/8/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+E33
+r1bqk2r/pppp1ppp/2n2n2/1B2p3/1b2P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+C49*
+r1bqk2r/pppp1ppp/2n2n2/1B2p3/1b2P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+C49
+r1bqk2r/pppp1ppp/2n2n2/2b5/2BPP3/5N2/PP3PPP/RNBQK2R b KQkq -
+C54
+r1bqk2r/pppp1ppp/2n2n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+C48*
+r1bqkb1r/1p2pppp/2n2n2/p1Pp4/5B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+D17*
+r1bqkb1r/1p2pppp/2n2n2/p1Pp4/8/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+D16*
+r1bqkb1r/1p3ppp/2n1pn2/p1Pp4/5B2/2P2N2/PP2PPPP/RN1QKB1R w KQkq -
+D18*
+r1bqkb1r/1p3ppp/p1nppn2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R w KQkq -
+B66
+r1bqkb1r/1pp2ppp/p1np1n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+C79
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+C78
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C77
+r1bqkb1r/1ppp1ppp/p1n5/4p3/B3n3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+C80
+r1bqkb1r/3n1ppp/p1p1pn2/1p6/3P4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+D48
+r1bqkb1r/3n1ppp/p3pn2/1N2P3/3p4/3B1N2/PP3PPP/R1BQK2R b KQkq -
+D49
+r1bqkb1r/p4pp1/2p2n1p/n3p1N1/8/8/PPPPBPPP/RNBQK2R w KQkq -
+C59
+r1bqkb1r/pp1n1ppp/2n1p3/3pP3/3P4/3B4/PP1NNPPP/R1BQK2R b KQkq -
+C06
+r1bqkb1r/pp1n1ppp/2p1pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R b KQkq -
+D52
+r1bqkb1r/pp1n1ppp/2p1pn2/3p4/2PP4/2NBPN2/PP3PPP/R1BQK2R b KQkq -
+D46
+r1bqkb1r/pp1n1ppp/2p1pn2/8/2BP4/2N1PN2/PP3PPP/R1BQK2R b KQkq -
+D47
+r1bqkb1r/pp1p1ppp/2n1pn2/8/2PN4/2N5/PP2PPPP/R1BQKB1R w KQkq -
+A33
+r1bqkb1r/pp1ppp1p/2n2np1/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+A29*
+r1bqkb1r/pp1ppppp/2n2n2/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+A28*
+r1bqkb1r/pp1ppppp/2n2n2/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+A27*
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+E42*
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/8/1P2PN2/P1PP1PPP/RNBQK2R w KQkq -
+E44*
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/8/BP2PN2/P1PP1PPP/RN1QK2R b KQkq -
+E45*
+r1bqkb1r/pp2pp1p/2n2np1/2pp4/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E62*
+r1bqkb1r/pp2pp1p/2n2np1/3p4/2PP4/2N5/PP3PPP/R1BQKBNR w KQkq -
+D33*
+r1bqkb1r/pp2pppp/2n2n2/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R b KQkq -
+D38*
+r1bqkb1r/pp2pppp/2n2n2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+E21*
+r1bqkb1r/pp2pppp/2n2n2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+D24*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/2PP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+D40*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/2P1PN2/PP3PPP/RNBQKB1R b KQkq -
+D43*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+D15*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+D37*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+D90*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/4P3/3P1N2/PPP2PPP/RNBQKB1R w KQkq -
+A54*
+r1bqkb1r/pp2pppp/2n2n2/3p4/2Pp4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+D41*
+r1bqkb1r/pp2pppp/2n2n2/8/2Pp4/3P1NP1/PP3P1P/RNBQKB1R b KQkq -
+A61*
+r1bqkb1r/pp2pppp/2n5/2pn4/8/2N1PN2/PP1P1PPP/R1BQKB1R b KQkq -
+A33*
+r1bqkb1r/pp2pppp/2np1n2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R b KQkq -
+B60
+r1bqkb1r/pp2pppp/2np1n2/8/2BNP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+B57
+r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+B58
+r1bqkb1r/pp3ppp/2n1p3/2pn4/3P4/2NBPN2/PP3PPP/R1BQK2R b KQkq -
+D42
+r1bqkb1r/pp3ppp/2n1pn2/1Bpp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 b kq -
+E51*
+r1bqkb1r/pp3ppp/2n1pn2/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+E50*
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/2P1PN2/PP3PPP/RNBQKB1R w KQkq -
+D45*
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+D94*
+r1bqkb1r/pp3ppp/2n2n2/2ppp3/4P3/3P1N2/PPPN1PPP/R1BQKB1R w KQkq -
+A55*
+r1bqkb1r/pp3ppp/2n2n2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E90*
+r1bqkb1r/pp3ppp/2n2n2/4p3/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+A70*
+r1bqkb1r/pp3ppp/2np1n2/4p3/4P3/1NN5/PPP1BPPP/R1BQK2R b KQkq -
+B59
+r1bqkb1r/pp3ppp/2nppn2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R w KQkq -
+B62
+r1bqkb1r/pp3ppp/2nppn2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R b KQkq -
+B63
+r1bqkb1r/pp3ppp/2nppn2/8/2BNP3/2N1B3/PPP2PPP/R2QK2R b KQkq -
+B89
+r1bqkb1r/pp3ppp/2nppn2/8/2BNP3/2N5/PPP2PPP/R1BQK2R w KQkq -
+B88
+r1bqkb1r/pp4pp/2n2n2/4pp2/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+A68*
+r1bqkb1r/ppp2p1p/2n3p1/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+B91*
+r1bqkb1r/ppp2p1p/2n5/3np1p1/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+B81*
+r1bqkb1r/ppp2pp1/5nn1/3p3p/8/2P3BP/PP1NPPP1/R2QKBNR b KQkq -
+B19*
+r1bqkb1r/ppp2ppp/2n1pn2/3p4/3PP3/5N2/PPPN1PPP/R1BQKB1R w KQkq -
+C04
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+C47*
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+B07*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N1P3/PP1P1PPP/R1BQKBNR w KQkq -
+B45*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N1P3/PPQP1PPP/R1B1KBNR b KQkq -
+B47*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3P1N2/PP2PPPP/RNBQKB1R w KQkq -
+B56*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3P1NP1/PP2PP1P/RNBQKB1R b KQkq -
+B70*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3PPN2/PP3PPP/RNBQKB1R b KQkq -
+B80*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P1N1P3/1P1P1PPP/R1BQKBNR b KQkq -
+B46*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R b KQkq -
+B90*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P3P3/1P1P1PPP/RNBQKBNR w KQkq -
+B43*
+r1bqkb1r/ppp2ppp/2np1n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+C66
+r1bqkb1r/ppp2ppp/5n2/n2Pp1N1/2B5/8/PPPP1PPP/RNBQK2R w KQkq -
+C58
+r1bqkb1r/ppp3pp/2n5/3npp2/8/3P1NP1/PP2PP1P/RNBQKB1R w KQkq -
+B71*
+r1bqkb1r/ppp3pp/2n5/3npp2/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+B82*
+r1bqkb1r/ppp3pp/2n5/3npp2/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+B93*
+r1bqkb1r/pppn1ppp/3p1n2/4p3/2PPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+A55
+r1bqkb1r/pppn1ppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR w KQkq -
+D51
+r1bqkb1r/pppn1ppp/4pn2/8/2QP4/6P1/PP2PPBP/RNB1K1NR b KQkq -
+E03
+r1bqkb1r/pppn1ppp/5n2/3p4/2PP4/2N5/PP3PPP/R1BQKBNR b KQkq -
+C09*
+r1bqkb1r/pppn1ppp/5n2/3pp3/3P4/2N1PN2/PPP2PPP/R1BQKB1R b KQkq -
+C04*
+r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+C48
+r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C65
+r1bqkb1r/pppp1ppp/2n2n2/4p1B1/3P4/2P5/PP2PPPP/RN1QKBNR b KQkq -
+B11*
+r1bqkb1r/pppp1ppp/2n2n2/4p1N1/2B1P3/8/PPPP1PPP/RNBQK2R b KQkq -
+C57
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+C28
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C55
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+A28
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N2NP1/PP1PPP1P/R1BQKB1R b KQkq -
+A29
+r1bqkb1r/pppp1ppp/2n2n2/4p3/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+C47
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+C46*
+r1bqkb1r/pppp1ppp/2n5/1B2p3/4n3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+C67
+r1bqkb1r/pppp1ppp/2n5/8/2Bpn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+C56
+r1bqkbnr/1p1p1ppp/p1n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+B46
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+C74
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+C72
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C71
+r1bqkbnr/1pp2ppp/p1p5/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+C69
+r1bqkbnr/1ppp1ppp/p1B5/4p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+C68
+r1bqkbnr/1ppp1ppp/p1n5/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+C70
+r1bqkbnr/2p2ppp/p1p5/3p4/2PPp3/4P3/PP2NPPP/RNBQK2R b KQkq -
+C19*
+r1bqkbnr/2p2ppp/p1p5/3p4/2PPp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+C18*
+r1bqkbnr/2p2ppp/p1pp4/4p3/3PP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+C73
+r1bqkbnr/4p1pp/p1p2p2/3p4/2Pp4/4PN2/PP3PPP/RNBQK2R w KQkq -
+E25*
+r1bqkbnr/4pppp/p1p5/2pp4/8/4PN2/PPPP1PPP/RNBQ1RK1 b kq -
+E27*
+r1bqkbnr/4pppp/p1p5/2pp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+E24*
+r1bqkbnr/5ppp/p1p1p3/2pp4/2P5/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+E26*
+r1bqkbnr/5ppp/p1p1p3/2pp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+E28*
+r1bqkbnr/pp1npppp/2p5/8/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+B17
+r1bqkbnr/pp1p1ppp/2n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+B45
+r1bqkbnr/pp1p1ppp/2n1p3/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+B44
+r1bqkbnr/pp1p1ppp/2n5/2p1p3/2P5/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+A19*
+r1bqkbnr/pp1p1ppp/2n5/2p1p3/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+A18*
+r1bqkbnr/pp1ppp1p/2n3p1/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+B31
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+A36*
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/2P2N2/PP1P1PPP/RNBQKB1R b KQkq -
+A23*
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/5NP1/PPPP1P1P/RNBQKB1R b KQkq -
+A24*
+r1bqkbnr/pp1ppp1p/2n3p1/8/2PNP3/8/PP3PPP/RNBQKB1R b KQkq -
+B36
+r1bqkbnr/pp1ppp1p/2n3p1/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+B34
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+A36
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+A35*
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+A35
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+A34*
+r1bqkbnr/pp1ppppp/2n5/2p5/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+B32
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+B24
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+A25*
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+A22*
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+B30
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+A21*
+r1bqkbnr/pp1ppppp/2n5/2p5/8/4PN2/PPPP1PPP/RNBQKB1R b KQkq -
+A17*
+r1bqkbnr/pp1ppppp/2n5/2p5/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+A16*
+r1bqkbnr/pp1ppppp/2n5/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+B33
+r1bqkbnr/pp2pppp/2n5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R b KQkq -
+E20*
+r1bqkbnr/pp2pppp/2n5/2pp4/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+D32*
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+D31*
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+D35*
+r1bqkbnr/pp2pppp/2n5/2pp4/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+A85*
+r1bqkbnr/pp2pppp/2n5/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+E61*
+r1bqkbnr/pp2pppp/2n5/3p4/3N4/6P1/PPP1PP1P/RNBQKB1R b KQkq -
+D85*
+r1bqkbnr/pp3p1p/2n3p1/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E72*
+r1bqkbnr/pp3pp1/2n4p/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E71*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+E41*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/1P2PN2/P1PP1PPP/RNBQK2R b KQkq -
+E43*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 b kq -
+E46*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+E40*
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+D33
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+B14*
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/5N2/PPPN1PPP/R1BQKB1R w KQkq -
+C09
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/3P2P1/PPP1PPBP/RNBQK1NR w KQkq -
+A42*
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/5NP1/PPPPPPBP/RNBQK2R w KQkq -
+E70*
+r1bqkbnr/pp3ppp/2n5/4p3/2Pp4/3P1N2/PP3PPP/RNBQKB1R w KQkq -
+A65*
+r1bqkbnr/pp3ppp/2n5/4p3/2Pp4/B2P1N2/4PPPP/RN1QKB1R w KQkq -
+A59*
+r1bqkbnr/pp4pp/2n2p2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 b kq -
+E81*
+r1bqkbnr/pp4pp/2n2p2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E80*
+r1bqkbnr/pp4pp/2n5/2pppp2/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E76*
+r1bqkbnr/pp4pp/2n5/4pp2/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+A66*
+r1bqkbnr/ppp1pppp/2n5/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+D07
+r1bqkbnr/ppp2ppp/2n5/1B1p4/2PPp3/4P3/PP3PPP/RNBQK1NR b KQkq -
+C17*
+r1bqkbnr/ppp2ppp/2n5/1B1p4/3Pp3/4P3/PPP2PPP/RNBQK1NR w KQkq -
+C16*
+r1bqkbnr/ppp2ppp/2n5/1B1pp3/3P4/4P3/PPP2PPP/RNBQK1NR b KQkq -
+C15*
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+B15*
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+C10*
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+C11*
+r1bqkbnr/ppp2ppp/2n5/4P3/2Pp4/5NP1/PP2PP1P/RNBQKB1R b KQkq -
+D09
+r1bqkbnr/ppp2ppp/2np4/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C62
+r1bqkbnr/ppp2ppp/8/3p4/8/2P2P2/PP2PP1P/RNBQKB1R b KQkq -
+B16*
+r1bqkbnr/ppp2ppp/8/3pn3/5B2/2P5/PP2PPPP/RN1QKBNR b KQkq -
+B18*
+r1bqkbnr/ppp2ppp/8/3pn3/8/2P5/PP1NPPPP/R1BQKBNR b KQkq -
+B17*
+r1bqkbnr/ppp3pp/2n5/3ppp2/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+B08*
+r1bqkbnr/pppn1ppp/8/3p4/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+C08*
+r1bqkbnr/pppn1ppp/8/3pp3/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+C07*
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+C03*
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+C05*
+r1bqkbnr/pppp1p1p/2n3p1/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+B24*
+r1bqkbnr/pppp1ppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+C60
+r1bqkbnr/pppp1ppp/2n5/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+C50
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+A27
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+A25
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+B23*
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+C46
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+C26*
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+C44
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+C25*
+r1bqkbnr/pppp1ppp/2n5/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+C45
+r1bqkbnr/pppp1ppp/2n5/8/3QP3/8/PPP2PPP/RNB1KBNR w KQkq -
+C22
+r1bqkbnr/pppp1ppp/8/1B2p3/3nP3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C61
+r1bqkbnr/pppp2pp/2n5/1B2pp2/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C63
+r1bqkbnr/pppp2pp/2n5/4pp2/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+C29*
+r1bqnrk1/pp2b1pp/2n2p2/2p1p3/3pPP2/3P2P1/PPPNN1BP/R1BQ1RK1 b - -
+E99*
+r1bqnrk1/pp2bppp/2n5/2p1p3/3pP3/3P1NP1/PPP1NPBP/R1BQ1RK1 w - -
+E98*
+r1bqr1k1/1p1n1pbp/p2p1np1/2pP4/P7/2N3P1/1P1NPPBP/R1BQ1RK1 w - -
+A64
+r1bqr1k1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+E95*
+r1bqr1k1/pp3pbp/n2p1np1/2pP4/4P3/2N5/PP1NBPPP/R1BQ1RK1 w - -
+A78
+r1bqr1k1/ppbn1pp1/2p2n1p/3pp3/1PP1P3/P1NP1N2/2Q1BPPP/R1B2RK1 b - -
+C98*
+r1bqr1k1/ppbn1pp1/5n1p/3pp3/NP2P3/P2P1N2/2Q1BPPP/R1B2RK1 w - -
+C99*
+r1bqr1k1/ppn2pbp/3p1np1/2pP4/4P3/2N2P2/PP1NB1PP/R1BQ1RK1 w - -
+A79
+r1bqrbk1/pp3ppp/2n2n2/2ppp3/P3P3/2PP1NP1/1P1N1PBP/R1BQ1RK1 b - -
+E96*
+r1r3k1/pp1bppbp/2np1np1/q7/3NP2P/1BN1BP2/PPPQ2P1/2KR3R b - -
+B79
+r2q1rk1/p3n1pp/3bbp2/3pp1B1/N7/6P1/PP2PPBP/R2Q1RK1 w - -
+D89*
+r2q1rk1/p3nppp/4b3/2bpp3/8/2N3P1/PP2PPBP/R1BQ1RK1 w - -
+D88*
+r2q1rk1/pp1bppbp/2np1np1/8/2BNP3/2N1BP2/PPPQ2PP/2KR3R b - -
+B78
+r2q1rk1/pp2ppbp/6p1/n7/3PP1b1/3BBP2/P3N1PP/R2Q1RK1 b - -
+D89
+r2q1rk1/ppp1bppp/1nn1b3/4p3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+B74*
+r2q1rk1/ppp1bppp/2n1b3/3np3/8/2NP1NP1/PP2PPBP/R1BQK2R w KQ -
+B73*
+r2qk1nr/pp2bppp/2n5/2p1p3/2Pp2b1/3PPNP1/PP3PBP/RNBQ1RK1 b kq -
+E75*
+r2qk1nr/pp2bppp/2n5/2ppp3/2P3b1/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+E74*
+r2qk1nr/ppp2pbp/2npb1p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR w KQkq -
+B26*
+r2qk2r/1p1bbppp/p1nppn2/6B1/3NPP2/2N5/PPPQ2PP/2KR1B1R w kq -
+B68
+r2qk2r/2p1bppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP3PPP/RNBQ1RK1 w kq -
+C83
+r2qk2r/3bbppp/p1nppB2/1p6/4PP2/2N2N2/PPPQ2PP/2KR1B1R b kq -
+B69
+r2qk2r/pp2b1pp/2n1b3/2pnpp2/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w kq -
+E79*
+r2qk2r/ppp1bppp/2n1b3/3np3/8/P1N1P3/1PQP1PPP/R1B1KBNR w KQkq -
+B49*
+r2qk2r/ppp2ppp/2n1b3/2bnp3/8/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+B35*
+r2qk2r/ppp2ppp/2n1b3/2bnp3/8/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+B89*
+r2qkb1r/1p1b1ppp/p1nppn2/6B1/3NP3/2N5/PPPQ1PPP/2KR1B1R w kq -
+B67
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1B3N2/PPP1QPPP/RNB2RK1 b kq -
+C81
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP3PPP/RNBQ1RK1 b kq -
+C82
+r2qkb1r/p4ppp/2p1pn2/3p4/3p4/4P2P/PPP1QPP1/RNB2RK1 w kq -
+D57*
+r2qkb1r/pp1bpppp/2np1n2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R b KQkq -
+B61
+r2qkb1r/pp2n1pp/2n1bp2/2p1p3/3PP3/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+E89*
+r2qkb1r/pp2n1pp/2n1bp2/2ppp3/4P3/2PP1NP1/PP3PBP/RNBQ1RK1 b kq -
+E86*
+r2qkb1r/pp2pppp/2n2n2/1BPp4/6b1/4PN2/PPP2PPP/RNBQK2R b KQkq -
+D39*
+r2qkb1r/pp2pppp/2n2n2/1Bpp3b/8/1P2PN1P/PBPP1PP1/RN1QK2R b KQkq -
+E13*
+r2qkb1r/pp2pppp/2n2n2/2Pp4/6b1/2P1PN2/PP3PPP/RNBQKB1R b KQkq -
+D44*
+r2qkb1r/pp2pppp/2n2n2/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+D92*
+r2qkb1r/pp2pppp/2n2n2/2pp4/3P2b1/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+D91*
+r2qkb1r/pp3ppp/2n1b3/2pnp1N1/8/2N3P1/PP1PPPBP/R1BQK2R b KQkq -
+B39*
+r2qkb1r/pp3ppp/2n1pn2/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+D93*
+r2qkb1r/pp3ppp/2n1pn2/2pp3b/3P4/1P2PN1P/P1P1BPP1/RNBQ1RK1 b kq -
+D58*
+r2qkb1r/pp3ppp/2n1pn2/2pp3b/3P4/4PN1P/PPP1BPP1/RNBQ1RK1 w kq -
+D56*
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+D52*
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQ1RK1 w kq -
+D55*
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 b kq -
+D60*
+r2qkb1r/pp3ppp/2n1pn2/3p3b/3N4/1P2P2P/P1P1BPP1/RNBQ1RK1 b kq -
+D59*
+r2qkb1r/ppp2ppp/2n1b3/3np3/8/2N1P3/PPQP1PPP/R1B1KBNR w KQkq -
+B48*
+r2qkb1r/ppp2ppp/2n1b3/3np3/8/3P1NP1/PP2PP1P/RNBQKB1R w KQkq -
+B72*
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+B60*
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NPPN2/PP3PPP/R1BQKB1R b KQkq -
+B62*
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+B94*
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/P2PPN2/1P3PPP/RNBQKB1R b KQkq -
+B95*
+r2qkb1r/ppp3pp/2n1bp2/3np3/8/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+B76*
+r2qkb1r/ppp3pp/2n1bp2/3np3/8/3P1NP1/PP2PPBP/RNBQK2R w KQkq -
+B75*
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/P2PPN2/1P2BPPP/RNBQK2R b KQkq -
+B98*
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/P2PPN2/1P3PPP/RNBQKB1R w KQkq -
+B96*
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/PQ1PPN2/1P3PPP/RNB1KB1R b KQkq -
+B97*
+r2qkbnr/1ppb1p1p/p1np2p1/4p3/B2PP3/2P2N2/PP3PPP/RNBQK2R w KQkq -
+C76
+r2qkbnr/1ppb1ppp/p1np4/4p3/B3P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+C75
+r2qkbnr/pp1nppp1/2p3bp/8/3P3P/5NN1/PPP2PP1/R1BQKB1R w KQkq -
+B19
+r2qkbnr/pp2pppp/2n5/1Bp4b/2Pp4/3PPN1P/PP3PP1/RNBQK2R b KQkq -
+E31*
+r2qkbnr/pp2pppp/2n5/1Bpp4/6b1/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+E30*
+r2qkbnr/pp2pppp/2n5/2pp1b2/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+D82*
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+D53*
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+D50*
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPPN1PPP/R1BQKB1R b KQkq -
+D51*
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+D80*
+r2qkbnr/pp3ppp/2n1p3/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQ1RK1 b kq -
+D83*
+r2qkbnr/pp3ppp/4p3/3p4/3Q4/6P1/PPb1PPBP/RNB2RK1 w kq -
+D84*
+r2qkbnr/pp4pp/2n1bp2/2p1p3/3pP3/2PP1NP1/PP3PBP/RNBQ1RK1 b kq -
+E88*
+r2qkbnr/pp4pp/2n1bp2/2p1p3/3pP3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+E87*
+r2qkbnr/pp4pp/2n1bp2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 b kq -
+E85*
+r2qkbnr/pp4pp/2n1bp2/2ppp3/8/1P1P1NP1/P1P1PPBP/RNBQ1RK1 b kq -
+E82*
+r2qkbnr/pp4pp/2n1bp2/2ppp3/8/2NP1NP1/PPP1PPBP/R1BQ1RK1 b kq -
+E83*
+r2qkbnr/ppp1pppp/2n5/3p4/3P2b1/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+D01*
+r2qkbnr/ppp2ppp/2n5/1B1pp3/3P2b1/4PN2/PPP2PPP/RNBQK2R b KQkq -
+C12*
+r2qkbnr/ppp2ppp/2n5/3p4/3Pp3/4P3/PPPNQPPP/RNB1K2R b KQkq -
+C14*
+r2qkbnr/ppp2ppp/2n5/3pP3/6b1/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+A83*
+r2qkbnr/ppp2ppp/2n5/3pp3/3P2b1/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+C13*
+r3k2r/pppq2pp/2n1bp2/2bnp3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w kq -
+B77*
+r3kb1r/pp1qn1pp/2n1bp2/2ppp3/8/P1NP1NP1/1PP1PPBP/1RBQ1RK1 b kq -
+E84*
+r3kb1r/pp3ppp/1qn1bn2/3pp1B1/8/6P1/PPPNPPBP/RN1Q1RK1 w kq -
+D99*
+r3kb1r/pppq1ppp/2n5/3np3/6b1/2NP1N2/PP1BPPPP/R2QKB1R w KQkq -
+B61*
+r3kb1r/pppq1ppp/2n5/3np3/6b1/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+B63*
+r3kb1r/pppq1ppp/2n5/3np3/6b1/P1NPPN2/1P3PPP/R1BQKB1R b KQkq -
+B66*
+r3kb1r/ppq2ppp/2n1pn2/2p5/2pP2b1/4PN2/PP1NBPPP/R1BQ1RK1 w kq -
+D62*
+r3kb1r/ppq2ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w kq -
+D61*
+r3kbnr/ppq1pppp/2n5/3p4/3P2b1/2P2N2/PP3PPP/RNBQKB1R w KQkq -
+D36*
+rn1q1rk1/1p3pbp/p2p1np1/2pP4/P3P1b1/2N2N2/1P2BPPP/R1BQ1RK1 w - -
+A75
+rn1q1rk1/p3ppbp/bp3np1/2pp4/3P1P2/2P1PN2/PP2B1PP/RNBQ1RK1 w - -
+A94*
+rn1q1rk1/pbppbppp/1p2p3/8/2PP4/2Q2NP1/PP2PPBP/R1B2RK1 b - -
+E19
+rn1q1rk1/pbppbppp/1p2pn2/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+E18
+rn1q1rk1/pp3ppp/2p1pn2/5b2/PbBP4/2N1PN2/1P2QPPP/R1B2RK1 b - -
+D19
+rn1q1rk1/ppp1ppbp/5np1/8/2QPP1b1/2N2N2/PP3PPP/R1B1KB1R w KQ -
+D98
+rn1q1rk1/pppnppbp/6p1/8/3PP1b1/1QN1BN2/PP3PPP/R3KB1R b KQ -
+D99
+rn1qk2r/p1pp1ppp/bp2pn2/8/1bPP4/2N1P3/PP2NPPP/R1BQKB1R w KQkq -
+E45
+rn1qk2r/pbpp1pp1/1p2pn1p/8/1bPP3B/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+E13
+rn1qk2r/pbpp1ppp/1p2pn2/8/1bPP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+E16
+rn1qk2r/pbppbppp/1p2pn2/8/2PP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+E17
+rn1qkb1r/1b3ppp/p3pn2/1pp5/3P4/1B2PN2/PP2QPPP/RNB2RK1 w kq -
+D29
+rn1qkb1r/4pppp/b2p1n2/2pP4/4P3/2N5/PP3PPP/R1BQKBNR b KQkq -
+A59
+rn1qkb1r/pp2pppp/2p2n2/3p1b2/2PP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+D12
+rn1qkb1r/pp2pppp/2p2n2/5b2/P1pP4/2N1PN2/1P3PPP/R1BQKB1R b KQkq -
+D18
+rn1qkb1r/pp2pppp/2p2n2/5b2/P1pP4/2N2N2/1P2PPPP/R1BQKB1R w KQkq -
+D17
+rn1qkb1r/pp2pppp/5n2/3p1b2/3P1B2/5N2/PP2PPPP/RN1QKB1R b KQkq -
+D14*
+rn1qkb1r/pp2pppp/5n2/3p1b2/3P1B2/5N2/PP2PPPP/RN1QKB1R w KQkq -
+D14
+rn1qkb1r/pp3ppp/4b3/2pnp3/8/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+B38*
+rn1qkb1r/ppp1pppp/3p4/3nP3/3P2b1/5N2/PPP2PPP/RNBQKB1R w KQkq -
+B05
+rn1qkb1r/ppp1pppp/5n2/3p4/3P2b1/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+D03*
+rn1qkbnr/pp1bpppp/3p4/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+B52
+rn1qkbnr/pp2pppp/2p5/3p4/4P1b1/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+B11
+rn1qkbnr/pp2pppp/2p5/5b2/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+B18
+rnb1k1nr/pp2ppbp/6p1/2qp4/8/4PN2/PPPN1PPP/R1BQKB1R w KQkq -
+E03*
+rnb1k1nr/pp2ppbp/6p1/q1Pp4/8/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+E02*
+rnb1k2r/pppnqppp/4p3/3pP3/3P4/2N5/PPP2PPP/R2QKBNR w KQkq -
+C14
+rnb1kb1r/1p3ppp/pq1ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+B97
+rnb1kb1r/ppp2ppp/5n2/3qp3/8/3P4/PP2PPPP/RNBQKBNR w KQkq -
+B53*
+rnb1kbnr/ppp2ppp/8/3qp3/8/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+C22*
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/1PN2NP1/P3PPBP/R1BQ1RK1 b - -
+A99
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+A97
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/2N2NP1/PPQ1PPBP/R1B2RK1 b - -
+A98
+rnb2rk1/pp2qppp/1b2pn2/3p4/1PP5/P3PN2/1B3PPP/RN1QKB1R b KQ -
+D29*
+rnb2rk1/pp2qppp/4pn2/2bp4/2P5/P3PN2/1P3PPP/RNBQKB1R w KQ -
+D28*
+rnb2rk1/ppB1ppbp/6p1/3q4/3P4/4P3/PP3PPP/R2QKBNR b KQ -
+D84
+rnb2rk1/ppp1qpp1/4p2p/3P4/3P4/2P1PN2/P4PPP/R2QKB1R b KQ -
+D57
+rnb2rk1/ppp1qppp/1b3n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R w KQ -
+C81*
+rnb2rk1/ppppqppp/5n2/b3p3/4P3/P1N2N2/1PPPBPPP/R1BQK2R w KQ -
+C86*
+rnb2rk1/ppq1ppbp/5np1/2pp4/3P4/4PN2/PPPNBPPP/R1BQ1RK1 w - -
+E08*
+rnbq1rk1/1p3pbp/p2p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+A74
+rnbq1rk1/2p1bppp/p2p1n2/1p2p3/3PP3/1BP2N1P/PP3PP1/RNBQR1K1 b - -
+C95
+rnbq1rk1/2p1bppp/p2p1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+C94
+rnbq1rk1/p1p1bpp1/1p2p2p/3n4/3P3B/2N1PN2/PP3PPP/R2QKB1R w KQ -
+D59
+rnbq1rk1/p1p1bpp1/1p2pn1p/3p4/2PP3B/2N1PN2/PP3PPP/R2QKB1R w KQ -
+D58
+rnbq1rk1/p1p1ppbp/1p1p1np1/8/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+E82
+rnbq1rk1/p1p2ppp/1p2pn2/3p4/1bPP4/2NBPN2/PP3PPP/R1BQK2R w KQ -
+E52
+rnbq1rk1/p3ppbp/1p3np1/2pp4/3P1P2/4PN2/PPP1B1PP/RNBQ1RK1 w - -
+A93*
+rnbq1rk1/pp1p1ppp/4pn2/2P5/1bP5/2N5/PPQ1PPPP/R1B1KBNR w KQ -
+E39
+rnbq1rk1/pp1pppbp/5np1/2p5/3P4/4PN2/PPP1BPPP/RNBQK2R w KQ -
+A14*
+rnbq1rk1/pp2b1pp/2p1pn2/3p1p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+A95
+rnbq1rk1/pp2b1pp/2p1pn2/3p1p2/2PP4/BP3NP1/P3PPBP/RN1Q1RK1 b - -
+A94
+rnbq1rk1/pp2p1bp/2pp1np1/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+A88
+rnbq1rk1/pp2ppbp/2p2np1/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+D78
+rnbq1rk1/pp2ppbp/3p1np1/2p3B1/2PPP3/2N5/PP2BPPP/R2QK1NR w KQ -
+E74
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+E65
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+E64
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PPPP2/2N2N2/PP2B1PP/R1BQK2R b KQ -
+E78
+rnbq1rk1/pp2ppbp/3p1np1/8/3NP3/2N1BP2/PPP3PP/R2QKB1R w KQ -
+B76
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/2P2NP1/PP2PPBP/RNBQ1RK1 b - -
+D78*
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/4PN2/PPPNBPPP/R1BQ1RK1 b - -
+E07*
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w - -
+D77*
+rnbq1rk1/pp2ppbp/5np1/2pp4/5P2/3PPN2/PPP1B1PP/RNBQ1RK1 b - -
+A96*
+rnbq1rk1/pp2ppbp/5np1/3p4/2PN4/6P1/PP2PPBP/RNBQ1RK1 b - -
+D75*
+rnbq1rk1/pp2ppbp/5np1/3p4/3N4/6P1/PPP1PPBP/RNBQ1RK1 w - -
+D74*
+rnbq1rk1/pp2ppbp/5np1/3p4/3P4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+D79*
+rnbq1rk1/pp2ppbp/5np1/3p4/3P4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+D79
+rnbq1rk1/pp2ppbp/5np1/3p4/8/1N4P1/PPP1PPBP/RNBQ1RK1 b - -
+D76*
+rnbq1rk1/pp2ppbp/6p1/2p5/2BPP3/2P5/P3NPPP/R1BQK2R w KQ -
+D87
+rnbq1rk1/pp2ppbp/6p1/2pn4/3P4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+D75
+rnbq1rk1/pp3pbp/2pp1np1/3Pp3/2P1P3/2N1BP2/PP4PP/R2QKBNR w KQ -
+E88
+rnbq1rk1/pp3pbp/2pp1np1/4p3/2PPP3/2N1BP2/PP2N1PP/R2QKB1R w KQ -
+E86
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+A73
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+A72
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4PP2/2N2N2/PP4PP/R1BQKB1R w KQ -
+A68
+rnbq1rk1/pp3pbp/3p1np1/2pP4/8/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+A62
+rnbq1rk1/pp3pbp/3p1np1/3pp3/2P1P3/2N1BP2/PP2N1PP/R2QKB1R w KQ -
+E89
+rnbq1rk1/pp3pbp/3ppnp1/2pP2B1/2P1P3/2N5/PP2BPPP/R2QK1NR w KQ -
+E75
+rnbq1rk1/pp3ppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P1BPPP/R2QK2R b KQ -
+C83*
+rnbq1rk1/pp3ppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R w KQ -
+C82*
+rnbq1rk1/pp3ppp/4pn2/2bp4/2P5/P3PN2/1P3PPP/RNBQKB1R b KQ -
+D27*
+rnbq1rk1/pp3ppp/4pn2/2p5/1bBP4/2N1PN2/PP3PPP/R1BQ1RK1 b - -
+E54
+rnbq1rk1/pp3ppp/4pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQK2R w KQ -
+E53
+rnbq1rk1/ppp1b1pp/3ppn2/5p2/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+A96
+rnbq1rk1/ppp1b1pp/4pn2/3p1p2/2PP4/1P3NP1/P3PPBP/RNBQ1RK1 b - -
+A93
+rnbq1rk1/ppp1bpp1/4pn1p/3p4/2PP3B/2N1PN2/PP3PPP/R2QKB1R b KQ -
+D56
+rnbq1rk1/ppp1bppp/4pn2/3p2B1/2PP4/2N1P3/PP3PPP/2RQKBNR b K -
+D54
+rnbq1rk1/ppp1bppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R b KQ -
+D55
+rnbq1rk1/ppp1ppbp/1n4p1/8/3P4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+D76
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2N2/PP2BPPP/R1BQK2R b KQ -
+E91
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2P2/PP4PP/R1BQKBNR w KQ -
+E81
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPPP2/2N5/PP2B1PP/R1BQK1NR b KQ -
+E77
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP1B2/2N1P3/PP3PPP/R2QKBNR w KQ -
+D83
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP1B2/2N1PN2/PP3PPP/R2QKB1R b KQ -
+D93
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/1QN1PN2/PP3PPP/R1B1KB1R b KQ -
+D95
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+D77
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/5NP1/PP2PPBP/RNBQK2R w KQ -
+D73
+rnbq1rk1/ppp1ppbp/5np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R b KQ -
+D97
+rnbq1rk1/ppp1ppbp/6p1/3n4/3P4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+D74
+rnbq1rk1/ppp2pbp/3p1np1/3Pp3/2P1P3/2N1BP2/PP4PP/R2QKBNR b KQ -
+E87
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+E85
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+E94
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+E92
+rnbq1rk1/ppp2ppp/4pn2/3p4/1bPP4/2N1PN2/PP3PPP/R1BQKB1R w KQ -
+E51
+rnbq1rk1/ppp2ppp/4pn2/3p4/1bPP4/2NBP3/PP3PPP/R1BQK1NR w KQ -
+E48
+rnbq1rk1/ppp2ppp/4pn2/3p4/2PP4/P1PBP3/5PPP/R1BQK1NR b KQ -
+E49
+rnbq1rk1/ppp2ppp/5n2/2bPN3/8/2N5/PPPP1PPP/R1BQKB1R b KQ -
+C56*
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQ -
+E46
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2N1PN2/PP3PPP/R1BQKB1R b KQ -
+E50
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2NBP3/PP3PPP/R1BQK1NR b KQ -
+E47
+rnbq1rk1/pppp1ppp/4pn2/8/2PP4/P1P1P3/5PPP/R1BQKBNR b KQ -
+E28
+rnbq1rk1/pppp1ppp/4pn2/8/2PP4/P1P5/4PPPP/R1BQKBNR w KQ -
+E27
+rnbq1rk1/pppp1ppp/5n2/4N3/1b2P3/2N5/PPPP1PPP/R1BQKB1R b KQ -
+C67*
+rnbq1rk1/pppp1ppp/5n2/4p3/1b2P3/2NP1N2/PPP2PPP/R1BQKB1R b KQ -
+C66*
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1P2N2/1PP1BPPP/R1BQK2R b KQ -
+C85*
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1P5/1PP2PPP/R1BQKBNR w KQ -
+C69*
+rnbq1rk1/pppp1ppp/5n2/b3N3/4P3/P1N5/1PPP1PPP/R1BQKB1R b KQ -
+C80*
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R w KQ -
+C78*
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPPBPPP/R1BQK2R b KQ -
+C84*
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1NP1N2/1PP2PPP/R1BQKB1R b KQ -
+C79*
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQ -
+C72*
+rnbq1rk1/ppppb1pp/4pn2/5p2/2PP4/5NP1/PP2PPBP/RNBQK2R w KQ -
+A92
+rnbqk1nr/pp2ppbp/6p1/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+E01*
+rnbqk1nr/pp2ppbp/6p1/2pp4/5P2/4PN2/PPPP2PP/RNBQKB1R w KQkq -
+A90*
+rnbqk1nr/pp2ppbp/6p1/2pp4/5P2/4PN2/PPPPB1PP/RNBQK2R b KQkq -
+A91*
+rnbqk1nr/pp2ppbp/6p1/3p4/3N4/6P1/PPP1PPBP/RNBQK2R b KQkq -
+D71*
+rnbqk1nr/pp3ppp/4p3/2ppP3/1b1P4/2N5/PPP2PPP/R1BQKBNR w KQkq -
+C17
+rnbqk1nr/pp3ppp/4p3/2ppP3/3P4/P1P5/2P2PPP/R1BQKBNR b KQkq -
+C18
+rnbqk1nr/ppp1ppbp/3p2p1/8/2PPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+A42
+rnbqk1nr/ppp2ppp/4p3/3p4/1b1PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+C15
+rnbqk1nr/ppp2ppp/4p3/3pP3/1b1P4/2N5/PPP2PPP/R1BQKBNR b KQkq -
+C16
+rnbqk1nr/pppp1pbp/8/6p1/2B1Pp2/5N2/PPPP2PP/RNBQK2R w KQkq -
+C38
+rnbqk1nr/pppp1ppp/8/2b1p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+C24*
+rnbqk1nr/pppp1ppp/8/2b1p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+C23*
+rnbqk1nr/ppppbppp/8/8/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+C35
+rnbqk2r/1p2bppp/p2ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+B98
+rnbqk2r/p1pp1ppp/1p2pn2/8/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQkq -
+E44
+rnbqk2r/p1pp1ppp/1p2pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+E43
+rnbqk2r/p1pp1ppp/5n2/1pb1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+C51*
+rnbqk2r/p2p1ppp/2p2n2/2b1p3/B3P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+C52*
+rnbqk2r/pp1p1ppp/2p2n2/2b1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+C53*
+rnbqk2r/pp1p1ppp/2p2n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQkq -
+C74*
+rnbqk2r/pp1p1ppp/2p2n2/b3p3/4P3/P1NP4/1PPB1PPP/R2QKBNR b KQkq -
+C75*
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQkq -
+E42
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+E41
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+E38
+rnbqk2r/pp1p1ppp/4pn2/2p5/2PP4/P1P1P3/5PPP/R1BQKBNR b KQkq -
+E26
+rnbqk2r/pp2npbp/6p1/3pp3/8/1N4P1/PPP1PPBP/RNBQK2R w KQkq -
+D72*
+rnbqk2r/pp2nppp/4p3/2ppP3/3P4/P1P5/2P2PPP/R1BQKBNR w KQkq -
+C19
+rnbqk2r/pp2ppbp/3p1np1/8/3NP3/2N1BP2/PPP3PP/R2QKB1R b KQkq -
+B75
+rnbqk2r/pp2ppbp/5np1/1Bpp4/8/1P2PN2/PBPP1PPP/RN1QK2R b KQkq -
+E16*
+rnbqk2r/pp2ppbp/5np1/2Pp4/8/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+E05*
+rnbqk2r/pp2ppbp/5np1/2Pp4/8/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+E04*
+rnbqk2r/pp2ppbp/5np1/2pp4/3P4/4PN2/PPP1BPPP/RNBQK2R w KQkq -
+E06*
+rnbqk2r/pp2ppbp/5np1/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 b kq -
+D73*
+rnbqk2r/pp2ppbp/5np1/2pp4/5P2/4PN2/PPPPB1PP/RNBQ1RK1 b kq -
+A92*
+rnbqk2r/pp2ppbp/5np1/2pp4/5P2/5NP1/PPPPP1BP/RNBQK2R w KQkq -
+A87*
+rnbqk2r/pp2ppbp/5np1/2pp4/8/1P2PN2/PBPPBPPP/RN1QK2R b KQkq -
+E17*
+rnbqk2r/pp3pbp/3p1np1/1BpP4/4PP2/2N5/PP4PP/R1BQK1NR b KQkq -
+A67
+rnbqk2r/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQK2R b KQkq -
+A71
+rnbqk2r/pp3pp1/3ppn1p/2pP4/1bP4B/2N5/PP2PPPP/R2QKBNR w KQkq -
+E31
+rnbqk2r/pp3ppp/2p2n2/b2pp3/4P3/P1NP2P1/1PPB1P1P/R2QKBNR b KQkq -
+C76*
+rnbqk2r/pp3ppp/4pn2/2pP4/3P4/P1P2P2/4P1PP/R1BQKBNR b KQkq -
+E25
+rnbqk2r/pp3ppp/5n2/2bpp3/2B5/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+C54*
+rnbqk2r/ppp1bppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR w KQkq -
+D53
+rnbqk2r/ppp1bppp/4pn2/3p2B1/3PP3/2N5/PPP2PPP/R2QKBNR w KQkq -
+C13
+rnbqk2r/ppp1bppp/4pn2/3p4/2P5/5NP1/PP1PPPBP/RNBQ1RK1 b kq -
+A14
+rnbqk2r/ppp1bppp/4pn2/3p4/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+E06
+rnbqk2r/ppp1bppp/4pn2/8/2pP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+E05
+rnbqk2r/ppp1ppbp/1n4p1/8/3PP3/6P1/PP2NPBP/RNBQK2R b KQkq -
+D72
+rnbqk2r/ppp1ppbp/3p1np1/8/2PP4/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+E62
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+E90
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N2P2/PP4PP/R1BQKBNR b KQkq -
+E80
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N3P1/PP3P1P/R1BQKBNR b KQkq -
+E72
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N4P/PP3PP1/R1BQKBNR b KQkq -
+E71
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N5/PP2BPPP/R1BQK1NR b KQkq -
+E73
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPPP2/2N5/PP4PP/R1BQKBNR b KQkq -
+E76
+rnbqk2r/ppp1ppbp/5np1/3p2B1/2PP4/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+D91
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP1B2/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+D92
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/1QN2N2/PP2PPPP/R1B1KB1R b KQkq -
+D96
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+D94
+rnbqk2r/ppp1ppbp/6p1/3n4/3P4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+D71
+rnbqk2r/ppp1ppbp/6p1/8/2BPP3/2P5/P4PPP/R1BQK1NR b KQkq -
+D86
+rnbqk2r/ppp2ppp/3b4/3np3/8/P3P3/1P1P1PPP/RNBQKBNR w KQkq -
+B42*
+rnbqk2r/ppp2ppp/4p3/3p4/2PPn3/P7/1PQ1PPPP/R1B1KBNR b KQkq -
+E37
+rnbqk2r/ppp2ppp/4pn2/3p2B1/1b1PP3/2N5/PPP2PPP/R2QKBNR w KQkq -
+C12
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+D38
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+E34
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/P1N5/1PQ1PPPP/R1B1KBNR b KQkq -
+E36
+rnbqk2r/ppp2ppp/4pn2/6B1/1bpP4/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+D39
+rnbqk2r/ppp2ppp/5n2/3p4/1b1P4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+E35
+rnbqk2r/ppp2ppp/5n2/3pp3/4P3/P1PP4/2P2PPP/R1BQKBNR w KQkq -
+C73*
+rnbqk2r/ppp3pp/5p2/3np3/1b2P3/3P1N2/PP3PPP/RNBQKB1R w KQkq -
+B55*
+rnbqk2r/pppp1ppp/4pn2/6B1/1bPP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+E30
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/1QN5/PP2PPPP/R1B1KBNR b KQkq -
+E22
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR b KQkq -
+E40
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+E21
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+E20
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N5/PPQ1PPPP/R1B1KBNR b KQkq -
+E32
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+E11
+rnbqk2r/pppp1ppp/4pn2/8/2PP4/P1P5/4PPPP/R1BQKBNR b KQkq -
+E24
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+C55*
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+C50*
+rnbqk2r/pppp1ppp/5n2/3Np3/1b2P3/8/PPPP1PPP/R1BQKBNR b KQkq -
+C61*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+C65*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+C60*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2NP4/PPP2PPP/R1BQKBNR b KQkq -
+C62*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+C63*
+rnbqk2r/pppp1ppp/5n2/4p3/1bB1P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+C64*
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+B31*
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/3P4/PP1BPPPP/RN1QKBNR b KQkq -
+B52*
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/3P4/PP2PPPP/RNBQKBNR w KQkq -
+B51*
+rnbqk2r/pppp1ppp/5n2/4p3/4P3/P1b5/1PPP1PPP/R1BQKBNR w KQkq -
+C68*
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R b KQkq -
+C77*
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N5/1PPP1PPP/R1BQKBNR w KQkq -
+C70*
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR b KQkq -
+C71*
+rnbqk2r/pppp1ppp/8/2b1p3/4P1n1/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+C57*
+rnbqk2r/pppp1ppp/8/2b5/N2pP1n1/5N2/PPP2PPP/R1BQKB1R b KQkq -
+C58*
+rnbqk2r/pppp2pp/5n2/2b1pP2/6P1/8/PPPP1PBP/RNBQK1NR b KQkq -
+C38*
+rnbqk2r/ppppb1pp/4pn2/5p2/2PP4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+A91
+rnbqk2r/ppppbppp/8/8/N3P1n1/2P2N1P/P4PP1/R1BQKB1R b KQkq -
+C59*
+rnbqk2r/ppppp1bp/5np1/5p2/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+A87
+rnbqk2r/ppppppbp/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+A08*
+rnbqk2r/ppppppbp/5np1/8/2PPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+E70
+rnbqkb1r/1p2pppp/p2p1n2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R b KQkq -
+B94
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N3P1/PPP2P1P/R1BQKB1R b KQkq -
+B91
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+B92
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+B90
+rnbqkb1r/1p2pppp/p2p1n2/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+B93
+rnbqkb1r/1p3ppp/p2ppn2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R w KQkq -
+B95
+rnbqkb1r/1p3ppp/p2ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R b KQkq -
+B96
+rnbqkb1r/1p3ppp/p2ppn2/8/3NP3/2N5/PPP1BPPP/R1BQK2R w KQkq -
+B84
+rnbqkb1r/1p3ppp/p3pn2/2p5/2BP4/4PN2/PP2QPPP/RNB2RK1 b kq -
+D28
+rnbqkb1r/1p3ppp/p3pn2/2p5/2BP4/4PN2/PP3PPP/RNBQ1RK1 w kq -
+D27
+rnbqkb1r/3ppppp/P4n2/2pP4/8/8/PP2PPPP/RNBQKBNR b KQkq -
+A58
+rnbqkb1r/5ppp/p2ppn2/1p6/3NP3/1BN5/PPP2PPP/R1BQK2R w KQkq -
+B87
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+E14
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+E12
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/5NP1/PP2PP1P/RNBQKB1R b KQkq -
+E15
+rnbqkb1r/p1pppppp/1p3n2/8/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+A47
+rnbqkb1r/p2ppppp/1p3n2/2p5/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+A12*
+rnbqkb1r/p2ppppp/5n2/1ppP4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+A57
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+A23
+rnbqkb1r/pp1p1ppp/4pn2/2p5/2P1P3/2N5/PP1P1PPP/R1BQKBNR w KQkq -
+A19
+rnbqkb1r/pp1p1ppp/4pn2/2pP4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+A60
+rnbqkb1r/pp1p1ppp/4pn2/8/2PN4/8/PP2PPPP/RNBQKB1R w KQkq -
+A32
+rnbqkb1r/pp1ppppp/5n2/2p5/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+A31
+rnbqkb1r/pp1ppppp/5n2/2p5/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+A56
+rnbqkb1r/pp1ppppp/5n2/2p5/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+A09*
+rnbqkb1r/pp1ppppp/5n2/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+B29
+rnbqkb1r/pp2pp1p/2p2p2/8/3P4/8/PPP2PPP/R1BQKBNR w KQkq -
+B16
+rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N1B3/PPP2PPP/R2QKB1R b KQkq -
+B72
+rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+B70
+rnbqkb1r/pp2pp1p/3p1np1/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+B71
+rnbqkb1r/pp2pp1p/5np1/2pP4/4p3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+D09*
+rnbqkb1r/pp2pp1p/5np1/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+E15*
+rnbqkb1r/pp2pppp/2p2n2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+D15
+rnbqkb1r/pp2pppp/2p2n2/8/P1pP4/2N2N2/1P2PPPP/R1BQKB1R b KQkq -
+D16
+rnbqkb1r/pp2pppp/3p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+B56
+rnbqkb1r/pp2pppp/5n2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R b KQkq -
+E11*
+rnbqkb1r/pp2pppp/5n2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+D23*
+rnbqkb1r/pp2pppp/5n2/2Pp4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+D21*
+rnbqkb1r/pp2pppp/5n2/2pp4/2P5/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+A31*
+rnbqkb1r/pp2pppp/5n2/2pp4/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+D11*
+rnbqkb1r/pp2pppp/5n2/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+D70*
+rnbqkb1r/pp2pppp/5n2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R b KQkq -
+E12*
+rnbqkb1r/pp2pppp/5n2/2pp4/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+E10*
+rnbqkb1r/pp2pppp/5n2/3p4/2PP4/2N5/PP3PPP/R1BQKBNR b KQkq -
+B14
+rnbqkb1r/pp2pppp/5n2/3p4/3P4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+D13*
+rnbqkb1r/pp2pppp/5n2/3p4/3P4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+D13
+rnbqkb1r/pp2pppp/8/2pn4/8/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+A32*
+rnbqkb1r/pp3p1p/3p1np1/2pP4/4P3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+A70
+rnbqkb1r/pp3p1p/3p1np1/2pP4/4PP2/2N5/PP4PP/R1BQKBNR b KQkq -
+A66
+rnbqkb1r/pp3p1p/3p1np1/2pP4/8/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+A61
+rnbqkb1r/pp3ppp/2p1pn2/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+D45
+rnbqkb1r/pp3ppp/2p1pn2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+D43
+rnbqkb1r/pp3ppp/2p1pn2/6B1/2pP4/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+D44
+rnbqkb1r/pp3ppp/2p2n2/3p2B1/3P4/2N5/PPQ1PPPP/R3KBNR b KQkq -
+D36
+rnbqkb1r/pp3ppp/3p1n2/1B2p3/3NP3/5P2/PPP3PP/RNBQK2R b KQkq -
+B55
+rnbqkb1r/pp3ppp/3p1n2/2pP4/4P3/2N5/PP3PPP/R1BQKBNR b KQkq -
+A65
+rnbqkb1r/pp3ppp/3ppn2/8/2BNP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+B86
+rnbqkb1r/pp3ppp/3ppn2/8/3NP1P1/2N5/PPP2P1P/R1BQKB1R b KQkq -
+B81
+rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+B83
+rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+B80
+rnbqkb1r/pp3ppp/3ppn2/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+B82
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+D26*
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+D25*
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/P7/1PP1PPPP/RNBQKBNR w KQkq -
+D22*
+rnbqkb1r/pp3ppp/4pn2/2pP4/3P4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+D41
+rnbqkb1r/pp3ppp/4pn2/2pp4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+D40
+rnbqkb1r/pp3ppp/4pn2/2pp4/3P1B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+D12*
+rnbqkb1r/pp3ppp/4pn2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+E14*
+rnbqkb1r/pp3ppp/8/2pnp3/8/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+B36*
+rnbqkb1r/pp3ppp/8/2pnp3/8/2N3P1/PP1PPPBP/R1BQK1NR b KQkq -
+B37*
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+B07
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PPP2/2N5/PPP3PP/R1BQKBNR b KQkq -
+B08
+rnbqkb1r/ppp1pp1p/5np1/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+D80
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP1B2/2N5/PP2PPPP/R2QKBNR b KQkq -
+D82
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/1QN5/PP2PPPP/R1B1KBNR b KQkq -
+D81
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+D90
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+D70
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/5P2/PP2P1PP/RNBQKBNR w KQkq -
+D70
+rnbqkb1r/ppp1pp1p/5np1/3p4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+A49*
+rnbqkb1r/ppp1pp1p/6p1/3n4/3P4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+D85
+rnbqkb1r/ppp1pppp/3p1n2/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+A53
+rnbqkb1r/ppp1pppp/3p1n2/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+B09
+rnbqkb1r/ppp1pppp/3p4/3nP3/3P4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+B04
+rnbqkb1r/ppp1pppp/5n2/3p2B1/3P4/2N5/PPP1PPPP/R2QKBNR b KQkq -
+D01
+rnbqkb1r/ppp1pppp/5n2/3p2B1/3P4/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+D03
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+D04
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+D02*
+rnbqkb1r/ppp1pppp/5n2/3p4/8/1P3N2/P1PPPPPP/RNBQKB1R b KQkq -
+A47*
+rnbqkb1r/ppp1pppp/5n2/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+A46*
+rnbqkb1r/ppp1pppp/5n2/3p4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+A48*
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+D24
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+D25
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+D23
+rnbqkb1r/ppp2ppp/3p1n2/4p3/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+A54
+rnbqkb1r/ppp2ppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+D50
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+D37
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+D35
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/6P1/PP2PPBP/RNBQK1NR b KQkq -
+E01
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+D05*
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+D05
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+D04*
+rnbqkb1r/ppp2ppp/4pn2/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+C11
+rnbqkb1r/ppp2ppp/4pn2/3p4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+C05
+rnbqkb1r/ppp2ppp/4pn2/8/2pP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+D26
+rnbqkb1r/ppp2ppp/4pn2/8/2pP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+E04
+rnbqkb1r/ppp2ppp/4pn2/8/Q1pP4/6P1/PP2PPBP/RNB1K1NR b KQkq -
+E02
+rnbqkb1r/ppp2ppp/5n2/3P4/4pP2/3P4/PPP3PP/RNBQKBNR w KQkq -
+C32
+rnbqkb1r/ppp2ppp/5n2/3p2B1/3Np3/3P4/PPP1PPPP/RN1QKB1R b KQkq -
+B05*
+rnbqkb1r/ppp2ppp/5n2/3p4/3Np3/3P4/PPP1PPPP/RNBQKB1R w KQkq -
+B04*
+rnbqkb1r/ppp2ppp/5n2/3pp3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+B32*
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+C43*
+rnbqkb1r/ppp2ppp/5n2/3pp3/4PP2/2N5/PPPP2PP/R1BQKBNR w KQkq -
+C29
+rnbqkb1r/ppp2ppp/8/3np3/8/2N1P3/PP1P1PPP/R1BQKBNR b KQkq -
+B44*
+rnbqkb1r/ppp2ppp/8/3np3/8/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+B34*
+rnbqkb1r/ppp2ppp/8/3np3/8/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+B33*
+rnbqkb1r/ppp2ppp/8/3np3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+C45*
+rnbqkb1r/ppp2ppp/8/3np3/8/3P4/PP2PPPP/RNBQKBNR w KQkq -
+B54*
+rnbqkb1r/ppp2ppp/8/3np3/8/P3P3/1P1P1PPP/RNBQKBNR b KQkq -
+B41*
+rnbqkb1r/pppp1p1p/5np1/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+A24
+rnbqkb1r/pppp1ppp/4pn2/8/2P1P3/2N5/PP1P1PPP/R1BQKBNR b KQkq -
+A18
+rnbqkb1r/pppp1ppp/4pn2/8/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+A17
+rnbqkb1r/pppp1ppp/4pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+E10
+rnbqkb1r/pppp1ppp/4pn2/8/2PP4/6P1/PP2PP1P/RNBQKBNR b KQkq -
+E00
+rnbqkb1r/pppp1ppp/5n2/4p3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+C24
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+B30*
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+A22
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/3P4/PP2PPPP/RNBQKBNR b KQkq -
+B50*
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/4P3/PP1P1PPP/RNBQKBNR b KQkq -
+B40*
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+B29*
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+B27*
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/P7/1P1PPPPP/RNBQKBNR b KQkq -
+B28*
+rnbqkb1r/pppp1ppp/5n2/4p3/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+A51
+rnbqkb1r/pppp1ppp/5n2/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+C43
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+C44*
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+C26
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+C41*
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+C42*
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+C42
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+C40*
+rnbqkb1r/pppp1ppp/8/4P3/2P3n1/8/PP2PPPP/RNBQKBNR w KQkq -
+A52
+rnbqkb1r/pppp1ppp/8/4p3/2B1n3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+C27
+rnbqkb1r/pppp2p1/5n2/4pP1p/6P1/8/PPPP1P1P/RNBQKBNR w KQkq -
+C39*
+rnbqkb1r/pppp2pp/4pn2/5p2/2PP4/6P1/PP2PPBP/RNBQK1NR b KQkq -
+A90
+rnbqkb1r/pppp2pp/5n2/4pP2/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+C36*
+rnbqkb1r/pppp2pp/5n2/4pP2/6P1/8/PPPP1P1P/RNBQKBNR b KQkq -
+C37*
+rnbqkb1r/pppp2pp/5n2/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+C34*
+rnbqkb1r/pppp2pp/5n2/4pP2/8/8/PPPPBPPP/RNBQK1NR b KQkq -
+C35*
+rnbqkb1r/ppppp1pp/5n2/5p2/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+A85
+rnbqkb1r/ppppp1pp/5n2/5p2/2PP4/6P1/PP2PP1P/RNBQKBNR b KQkq -
+A86
+rnbqkb1r/ppppp1pp/5n2/6B1/3Pp3/2N5/PPP2PPP/R2QKBNR b KQkq -
+A83
+rnbqkb1r/pppppp1p/5np1/8/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+E61
+rnbqkb1r/pppppp1p/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+E60
+rnbqkb1r/pppppp1p/5np1/8/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+A48
+rnbqkb1r/pppppp1p/5np1/8/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+A49
+rnbqkb1r/pppppp1p/5np1/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+A07*
+rnbqkb1r/pppppppp/5n2/8/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+A16
+rnbqkb1r/pppppppp/5n2/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+A15
+rnbqkb1r/pppppppp/5n2/8/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+A50
+rnbqkb1r/pppppppp/5n2/8/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+A46
+rnbqkb1r/pppppppp/5n2/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+A06*
+rnbqkb1r/pppppppp/5n2/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+A45
+rnbqkb1r/pppppppp/5n2/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+B02
+rnbqkb1r/pppppppp/5n2/8/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+A05*
+rnbqkb1r/pppppppp/5n2/8/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+A05
+rnbqkb1r/pppppppp/5n2/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+A04*
+rnbqkb1r/pppppppp/8/3nP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+B03
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+B43
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/3B4/PPP2PPP/RNBQK2R b KQkq -
+B42
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+B41
+rnbqkbnr/1p1ppppp/p7/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+B28
+rnbqkbnr/1pp1pppp/p7/8/2pP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+D22
+rnbqkbnr/p1pppppp/1p6/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+A01*
+rnbqkbnr/pp1p1ppp/2p5/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+B22*
+rnbqkbnr/pp1p1ppp/4p3/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+B40
+rnbqkbnr/pp1p1ppp/8/2pPp3/8/8/PPP1PPPP/RNBQKBNR w KQkq e6
+A44
+rnbqkbnr/pp1ppppp/2p5/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+A11
+rnbqkbnr/pp1ppppp/2p5/8/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+B12
+rnbqkbnr/pp1ppppp/2p5/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+B10
+rnbqkbnr/pp1ppppp/8/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+A34
+rnbqkbnr/pp1ppppp/8/2p5/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+A30*
+rnbqkbnr/pp1ppppp/8/2p5/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+A30
+rnbqkbnr/pp1ppppp/8/2p5/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+A43
+rnbqkbnr/pp1ppppp/8/2p5/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+B21
+rnbqkbnr/pp1ppppp/8/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+B23
+rnbqkbnr/pp1ppppp/8/2p5/4P3/2P5/PP1P1PPP/RNBQKBNR b KQkq -
+B22
+rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+B27
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+A20*
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+B20
+rnbqkbnr/pp1ppppp/8/2p5/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+B21
+rnbqkbnr/pp1ppppp/8/2p5/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+A11*
+rnbqkbnr/pp1ppppp/8/2p5/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+A13*
+rnbqkbnr/pp1ppppp/8/2p5/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+A15*
+rnbqkbnr/pp1ppppp/8/2p5/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+A10*
+rnbqkbnr/pp2p1pp/5p2/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+D70*
+rnbqkbnr/pp2pp1p/6p1/2pp4/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+A86*
+rnbqkbnr/pp2pp1p/6p1/2pp4/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+E00*
+rnbqkbnr/pp2pppp/2p5/3p4/2P5/1P3N2/P2PPPPP/RNBQKB1R b KQkq -
+A12
+rnbqkbnr/pp2pppp/2p5/3p4/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+D11
+rnbqkbnr/pp2pppp/2p5/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+D10
+rnbqkbnr/pp2pppp/2p5/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+B15
+rnbqkbnr/pp2pppp/3p4/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+B51
+rnbqkbnr/pp2pppp/3p4/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+B50
+rnbqkbnr/pp2pppp/3p4/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+B54
+rnbqkbnr/pp2pppp/3p4/8/3QP3/5N2/PPP2PPP/RNB1KB1R b KQkq -
+B53
+rnbqkbnr/pp2pppp/8/2Pp4/8/8/PPP1PPPP/RNBQKBNR b KQkq -
+D20*
+rnbqkbnr/pp2pppp/8/2p3N1/4p3/8/PPPP1PPP/RNBQKB1R b KQkq -
+A52*
+rnbqkbnr/pp2pppp/8/2p5/1PPp4/5N2/P2PPPPP/RNBQKB1R b KQkq -
+A57*
+rnbqkbnr/pp2pppp/8/2p5/2Pp4/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+A60*
+rnbqkbnr/pp2pppp/8/2pp4/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+A56*
+rnbqkbnr/pp2pppp/8/2pp4/3P4/2N5/PPP1PPPP/R1BQKBNR b KQkq -
+D07*
+rnbqkbnr/pp2pppp/8/2pp4/3P4/2P5/PP2PPPP/RNBQKBNR b KQkq -
+D10*
+rnbqkbnr/pp2pppp/8/2pp4/3P4/4P3/PPP2PPP/RNBQKBNR b KQkq -
+D30*
+rnbqkbnr/pp2pppp/8/2pp4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+D06*
+rnbqkbnr/pp2pppp/8/2pp4/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+D08*
+rnbqkbnr/pp2pppp/8/2pp4/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+A51*
+rnbqkbnr/pp2pppp/8/2pp4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+A84*
+rnbqkbnr/pp2pppp/8/2pp4/8/3P1N2/PPP1PPPP/RNBQKB1R b KQkq -
+A53*
+rnbqkbnr/pp2pppp/8/2pp4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+A50*
+rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+E60*
+rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPPBP/RNBQK2R b KQkq -
+A08
+rnbqkbnr/pp2pppp/8/3p4/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+B13
+rnbqkbnr/pp2pppp/8/8/2Pp4/p4N2/3PPPPP/RNBQKB1R w KQkq -
+A58*
+rnbqkbnr/pp3ppp/4p3/2pp4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+D32
+rnbqkbnr/pp3ppp/4p3/2pp4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+C07
+rnbqkbnr/pp3ppp/8/2pp4/3P4/8/PPPN1PPP/R1BQKBNR w KQkq -
+C08
+rnbqkbnr/ppp1pp1p/6p1/3p4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+A81*
+rnbqkbnr/ppp1pppp/3p4/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+A41
+rnbqkbnr/ppp1pppp/8/3p4/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+A09
+rnbqkbnr/ppp1pppp/8/3p4/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+A43*
+rnbqkbnr/ppp1pppp/8/3p4/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+D06
+rnbqkbnr/ppp1pppp/8/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+D02
+rnbqkbnr/ppp1pppp/8/3p4/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+D00*
+rnbqkbnr/ppp1pppp/8/3p4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+D00
+rnbqkbnr/ppp1pppp/8/3p4/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+B01
+rnbqkbnr/ppp1pppp/8/3p4/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+A80*
+rnbqkbnr/ppp1pppp/8/3p4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+A03
+rnbqkbnr/ppp1pppp/8/3p4/8/3P4/PPP1PPPP/RNBQKBNR b KQkq -
+A41*
+rnbqkbnr/ppp1pppp/8/3p4/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+A45*
+rnbqkbnr/ppp1pppp/8/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+A06
+rnbqkbnr/ppp1pppp/8/3p4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+A07
+rnbqkbnr/ppp1pppp/8/3p4/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+A40*
+rnbqkbnr/ppp1pppp/8/8/2PpP3/8/PP1P1PPP/RNBQKBNR b KQkq e3
+A44*
+rnbqkbnr/ppp1pppp/8/8/2pP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+D21
+rnbqkbnr/ppp1pppp/8/8/2pP4/8/PP2PPPP/RNBQKBNR w KQkq -
+D20
+rnbqkbnr/ppp2ppp/3p4/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+C41
+rnbqkbnr/ppp2ppp/4p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+D31
+rnbqkbnr/ppp2ppp/4p3/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+D30
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+C10
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/8/PPPN1PPP/R1BQKBNR b KQkq -
+C03
+rnbqkbnr/ppp2ppp/4p3/3pP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+C02
+rnbqkbnr/ppp2ppp/8/3Pp3/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+C21*
+rnbqkbnr/ppp2ppp/8/3p4/3Np3/8/PPPPPPPP/RNBQKB1R w KQkq -
+B03*
+rnbqkbnr/ppp2ppp/8/3p4/3P4/8/PP2PPPP/RNBQKBNR b KQkq -
+B13*
+rnbqkbnr/ppp2ppp/8/3p4/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+C01*
+rnbqkbnr/ppp2ppp/8/3p4/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+C01
+rnbqkbnr/ppp2ppp/8/3p4/3Pp3/4P3/PPP2PPP/RNBQKBNR w KQkq -
+C02*
+rnbqkbnr/ppp2ppp/8/3p4/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+C36
+rnbqkbnr/ppp2ppp/8/3pp3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+B21*
+rnbqkbnr/ppp2ppp/8/3pp3/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+D08
+rnbqkbnr/ppp2ppp/8/3pp3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+C31
+rnbqkbnr/ppp2ppp/8/3pp3/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+A82*
+rnbqkbnr/ppp2ppp/8/3pp3/8/2P5/PP1PPPPP/RNBQKBNR w KQkq -
+B12*
+rnbqkbnr/ppp2ppp/8/3pp3/8/3P1N2/PPP1PPPP/RNBQKB1R b KQkq -
+B09*
+rnbqkbnr/ppp3pp/3p4/4Pp2/3p4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+C32*
+rnbqkbnr/pppp1p1p/8/6p1/4Pp1P/5N2/PPPP2P1/RNBQKB1R b KQkq -
+C39
+rnbqkbnr/pppp1p1p/8/6p1/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+C37
+rnbqkbnr/pppp1ppp/4p3/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+A13
+rnbqkbnr/pppp1ppp/4p3/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+C00
+rnbqkbnr/pppp1ppp/8/4p3/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+C23
+rnbqkbnr/pppp1ppp/8/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+A21
+rnbqkbnr/pppp1ppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+B20*
+rnbqkbnr/pppp1ppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+A20
+rnbqkbnr/pppp1ppp/8/4p3/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+B01*
+rnbqkbnr/pppp1ppp/8/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+C25
+rnbqkbnr/pppp1ppp/8/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+C40
+rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+C20*
+rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+C20
+rnbqkbnr/pppp1ppp/8/4p3/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+C30
+rnbqkbnr/pppp1ppp/8/4p3/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+B10*
+rnbqkbnr/pppp1ppp/8/4p3/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+C00*
+rnbqkbnr/pppp1ppp/8/4p3/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+B02*
+rnbqkbnr/pppp1ppp/8/4p3/8/6P1/PPPPPP1P/RNBQKBNR b KQkq -
+B06*
+rnbqkbnr/pppp1ppp/8/4p3/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+B00*
+rnbqkbnr/pppp1ppp/8/8/3pP3/8/PPP2PPP/RNBQKBNR w KQkq -
+C21
+rnbqkbnr/pppp1ppp/8/8/4Pp2/5N2/PPPP2PP/RNBQKB1R b KQkq -
+C34
+rnbqkbnr/pppp1ppp/8/8/4Pp2/8/PPPP2PP/RNBQKBNR w KQkq -
+C33
+rnbqkbnr/pppp2pp/8/4pP2/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+C33*
+rnbqkbnr/pppp2pp/8/4pp2/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+B21*
+rnbqkbnr/pppp2pp/8/4pp2/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+C31*
+rnbqkbnr/pppp2pp/8/4pp2/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+C30*
+rnbqkbnr/ppppp1pp/8/5p2/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+A84
+rnbqkbnr/ppppp1pp/8/5p2/3P4/6P1/PPP1PP1P/RNBQKBNR b KQkq -
+A81
+rnbqkbnr/ppppp1pp/8/5p2/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+A03*
+rnbqkbnr/ppppp1pp/8/5p2/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+A80
+rnbqkbnr/ppppp1pp/8/5p2/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+A82
+rnbqkbnr/ppppp1pp/8/5p2/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+A02*
+rnbqkbnr/pppppp1p/6p1/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+B06
+rnbqkbnr/pppppppp/8/8/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+A10
+rnbqkbnr/pppppppp/8/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+A40
+rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+B00
+rnbqkbnr/pppppppp/8/8/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+A02
+rnbqkbnr/pppppppp/8/8/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+A01
+rnbqkbnr/pppppppp/8/8/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+A04
+rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR b KQkq -
+A00*
+rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+A00
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N1P/2P1BPP1/R1BQ1RK1 b - -
+C93*
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+C92*
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P2P1N2/2P1BPPP/RNBQ1RK1 b - -
+C94*
+rnbqr1k1/pp1p1ppp/1bp2n2/4p3/1P1PP3/P1N2N2/2P1BPPP/R1BQ1RK1 b - -
+C89*
+rnbqr1k1/pp1p1ppp/1bp2n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 b - -
+C90*
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+A76
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4P3/2N5/PP1NBPPP/R1BQ1RK1 b - -
+A77
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4PP2/2N2N2/PP2B1PP/R1BQK2R w KQ -
+A69
+rnbqr1k1/pp3pp1/1bp2n1p/3pp3/1P2P3/P2P1N2/2P1BPPP/RNBQ1RK1 w - -
+C95*
+rnbqr1k1/pp3ppp/1bp2n2/3pp3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+C91*
+rnbqr1k1/ppb2pp1/2p2n1p/3pp3/NPP1P3/P2P1N2/2Q1BPPP/R1B2RK1 b - -
+C97*
+rnbqr1k1/ppbp1pp1/2p2n1p/4p3/NP2P3/P2P1N2/2P1BPPP/R1BQ1RK1 w - -
+C96*
+rnbqr1k1/pppp1ppp/1b3n2/4p3/1P2P3/P1N2N2/2PPBPPP/R1BQK2R w KQ -
+C88*
+rnbqr1k1/pppp1ppp/5n2/b3p3/4P3/P1NP1N2/1PP1BPPP/R1BQK2R b KQ -
+C87*
--- /dev/null
+
+Opening classification uses modified FEN notation, i.e. the halfmove and
+fullmove numbers are dropped since these are irrelvant for opening positions.
+
+---
+
+16.1.1: History
+
+FEN is based on a 19th century standard for position recording designed by the
+Scotsman David Forsyth, a newspaper journalist. The original Forsyth standard
+has been slightly extended for use with chess software by Steven Edwards with
+assistance from commentators on the Internet. This new standard, FEN, was
+first implemented in Edwards' SAN Kit.
+
+16.1.2: Uses for a position notation
+
+Having a standard position notation is particularly important for chess
+programmers as it allows them to share position databases. For example,
+there exist standard position notation databases with many of the classical
+benchmark tests for chessplaying programs, and by using a common position
+notation format many hours of tedious data entry can be saved. Additionally,
+a position notation can be useful for page layout programs and for confirming
+position status for e-mail competition.
+
+Many interesting chess problem sets represented using FEN can be found at the
+chess.uoknor.edu ftp site in the directory pub/chess/SAN_testsuites.
+
+
+16.1.3: Data fields
+
+FEN specifies the piece placement, the active color, the castling
+availability, the en passant target square, the halfmove clock, and the
+fullmove number. These can all fit on a single text line in an easily
+read format. The length of a FEN position description varies somewhat
+according to the position. In some cases, the description could be eighty
+or more characters in length and so may not fit conveniently on some
+displays. However, these positions aren't too common.
+
+A FEN description has six fields. Each field is composed only of non-blank
+printing ASCII characters. Adjacent fields are separated by a single ASCII
+space character.
+
+
+16.1.3.1: Piece placement data
+
+The first field represents the placement of the pieces on the board. The
+board contents are specified starting with the eighth rank and ending with
+the first rank. For each rank, the squares are specified from file a to
+file h. White pieces are identified by uppercase SAN piece letters
+("PNBRQK") and black pieces are identified by lowercase SAN piece letters
+("pnbrqk"). Empty squares are represented by the digits one through eight;
+the digit used represents the count of contiguous empty squares along a
+rank. A solidus character "/" is used to separate data of adjacent ranks.
+
+
+16.1.3.2: Active color
+
+The second field represents the active color. A lower case "w" is used if
+White is to move; a lower case "b" is used if Black is the active player.
+
+
+16.1.3.3: Castling availability
+
+The third field represents castling availability. This indicates potential
+future castling that may of may not be possible at the moment due to blocking
+pieces or enemy attacks. If there is no castling availability for either
+side, the single character symbol "-" is used. Otherwise, a combination of
+from one to four characters are present. If White has kingside castling
+availability, the uppercase letter "K" appears. If White has queenside
+castling availability, the uppercase letter "Q" appears. If Black has
+kingside castling availability, the lowercase letter "k" appears. If
+Black has queenside castling availability, then the lowercase letter "q"
+appears. Those letters which appear will be ordered first uppercase before
+lowercase and second kingside before queenside. There is no white space
+between the letters.
+
+
+16.1.3.4: En passant target square
+
+The fourth field is the en passant target square. If there is no en passant
+target square then the single character symbol "-" appears. If there is an
+en passant target square then is represented by a lowercase file character
+immediately followed by a rank digit. Obviously, the rank digit will be "3"
+following a white pawn double advance (Black is the active color) or else be
+the digit "6" after a black pawn double advance (White being the active
+color).
+
+An en passant target square is given if and only if the last move was a pawn
+advance of two squares. Therefore, an en passant target square field may have
+a square name even if there is no pawn of the opposing side that may
+immediately execute the en passant capture.
+
+
+16.1.3.5: Halfmove clock
+
+The fifth field is a nonnegative integer representing the halfmove clock.
+This number is the count of halfmoves (or ply) since the last pawn advance
+or capturing move. This value is used for the fifty move draw rule.
+
+
+16.1.3.6: Fullmove number
+
+The sixth and last field is a positive integer that gives the fullmove number.
+This will have the value "1" for the first move of a game for both White and
+Black. It is incremented by one immediately after each move by Black.
+
+
+16.1.4: Examples
+
+Here's the FEN for the starting position:
+
+rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
+
+And after the move 1. e4:
+
+rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1
+
+And then after 1. ... c5:
+
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 0 2
+
+And then after 2. Nf3:
+
+rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - 1 2
+
+For two kings on their home squares and a white pawn on e2 (White to move)
+with thirty eight full moves played with five halfmoves since the last pawn
+move or capture:
+
+4k3/8/8/8/8/8/4P3/4K3 w - - 5 39
--- /dev/null
+1q3rk1/pp3ppp/2r1pn2/2bp4/4P3/2P5/PP1NQPPP/R1B2RK1 w - -
+QGD: Orthodox defense, classical, 13.d1b1 (Mar\'oczy) *
+1r2kb1r/p1pq2pp/Q1n5/3npp2/6b1/P2PPN2/1P3PPP/RNB1KB1R b KQk -
+Sicilian: Najdorf, Poisoned pawn variation *
+1rb2rk1/pp3ppp/5q2/3P4/1n6/2P1Q3/PP3PPP/RN2KB1R w KQ -
+Scotch: Gottschall variation
+1rbq1rk1/1pp1ppbp/p1np1np1/8/2PPP3/2N1BP2/PP1QN1PP/R3KB1R w KQ -
+King's Indian: S\"amisch, Panno main line
+1rbq1rk1/ppp1ppbp/2np1np1/8/2PPP3/2N1BP2/PP2N1PP/R2QKB1R w KQ -
+King's Indian: S\"amisch, Ruban variation
+1rbqk1nr/pp1pppbp/2n3p1/2p5/4P3/2N3P1/PPPP1PBP/R1BQK1NR w KQk -
+English: closed, 5.Rb1 *
+1rbqk1nr/pp1pppbp/2n3p1/2p5/4P3/2N3PN/PPPP1PBP/R1BQK2R b KQk -
+English: closed, 5.Rb1 Taimanov variation *
+1rbqkb1r/p4ppp/2p2n2/nB2p1N1/8/5Q2/PPPP1PPP/RNB1K2R w KQk -
+two knights defense: Colman variation
+2bqkbnr/r4ppp/p1npp3/1p6/4P3/1BN2N2/PP2QPPP/R1B2RK1 w k -
+Sicilian: Smith-Morra gambit, Chicago defense
+2kr1b1r/ppp3pp/2n2q2/3npp2/6b1/P2PPN2/1PQNBPPP/R1B1K2R b KQ -
+Sicilian: Najdorf, 7...Be7 main line *
+2kr1b1r/ppp3pp/2n5/3qpp2/6b1/3PPN2/PP2BPPP/R1BQ1RK1 w - -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 defense, 9...Nxd4 *
+2kr1b1r/pppq1ppp/2n5/3np3/6b1/P1NPPN2/1P1B1PPP/R2QKB1R b KQ -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 defense, 8...Bd7 *
+2kr1b1r/pppq2pp/2n1bp2/3np3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+Sicilian: dragon, Yugoslav attack, Rauser variation *
+2kr1b1r/pppq2pp/2n2n2/2Pp1p2/3Pp3/2N1P3/PP1NQPPP/R1B2RK1 b - -
+French: classical, St\a hlberg variation *
+2kr1b1r/pppq2pp/2n2n2/4pp2/1P6/P1NPPb2/3BBPPP/R2QK2R w KQ -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 defense, 11.Bxf6 *
+2kr1b1r/pppq2pp/2n5/3Npp2/6b1/3PPN2/PP2BPPP/R1BQ1RK1 b - -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 defense, 9...Nxd4 *
+2kr1b1r/pppq2pp/2n5/3npp2/4P1b1/2NP1N2/PP2BPPP/R1BQ1RK1 b - -
+Sicilian: Richter-Rauzer, Rauzer attack, Geller variation *
+2kr1b1r/pppq2pp/2n5/3npp2/6b1/2NPPN2/PP2BPPP/R1BQ1RK1 w - -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 defense, 9.f4 *
+2kr1b1r/pppq2pp/2n5/3npp2/6b1/P1NPPN2/1P1BBPPP/R2QK2R b KQ -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 defense, 9...Be7 *
+2kr3r/pp2bppp/2nqbn2/3pp1B1/8/1NN3P1/PPP1PPBP/R2Q1RK1 w - -
+Gr\"unfeld: Russian, Keres variation *
+2kr3r/ppp2ppp/1bn1bPq1/6N1/2ppNPP1/8/PPP4P/R1BQR1K1 w - -
+two knights: Max Lange attack, Berger variation
+2kr3r/pppb1ppp/2n1q2n/1Bb1p3/8/2NP1N2/PPP2PPP/R1BQR1K1 w - -
+Center game: Kupreichik variation *
+2kr3r/pppq2p1/1bn1bp2/3np2p/Q7/2NP1NP1/PP1BPPBP/R1R3K1 w - -
+Sicilian: dragon, Yugoslav attack, 12.h4 *
+2kr3r/pppq2pp/2n1bp2/2bnp3/8/2NP1NP1/PP1BPPBP/R2Q1RK1 w - -
+Sicilian: dragon, Yugoslav attack, 10.O-O-O *
+2kr3r/pppqbppp/1nn1p3/4Pb2/2PP4/2N1BN2/PP2B1PP/R2Q1RK1 w - -
+Alekhine's defense: four pawns attack, Tartakower variation
+2kr3r/pppqbppp/2n1b3/3np3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+Sicilian: dragon, classical, Grigoriev variation *
+2kr3r/ppq1nppp/2nbp3/3p4/3P2b1/5N2/PPP1BPPP/R1BQRNK1 w - -
+QGD: exchange, chameleon variation *
+2krr3/pppq1ppp/1bn5/3n4/QPN1p1b1/P2PPN2/1B3PPP/R3KB1R w KQ -
+Sicilian: Najdorf, Ivkov variation *
+2r1kb1r/1pq2ppp/p1n1pn2/2pp4/3P2b1/P1P1PN2/1P1NBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Rubinstein attack, Gr\"unfeld variation *
+2r1kb1r/ppq2ppp/2n1pn2/2pp4/3P2b1/2P1PN2/PP1NBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Rubinstein attack (with Rc1) *
+2r1kb1r/ppq2ppp/2n1pn2/2pp4/3P2b1/P1P1PN2/1P1NBPPP/R1BQ1RK1 b k -
+QGD: Orthodox defense, Rubinstein attack, Karlsbad variation *
+2r1kb1r/ppq2ppp/2n1pn2/2ppN3/3P2b1/2P1P3/PP1NBPPP/R1BQ1RK1 b k -
+QGD: Orthodox defense, Rubinstein attack, Wolf variation *
+2r1kb1r/ppq2ppp/2n1pn2/3p4/3p2b1/P1P1PN2/1P1NBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Rubinstein attack, main line *
+2rq1rk1/pp2ppbp/2n2np1/2Pp4/3P2b1/2N1BN2/PP2BPPP/R2Q1RK1 b - -
+QGD: Tarrasch, Bogolyubov variation *
+2rq1rk1/pp2ppbp/2n2np1/3p4/2PP2b1/1PN1BN2/P3BPPP/R2Q1RK1 b - -
+QGD: Tarrasch, Stoltz variation *
+2rq1rk1/pp3ppp/2n1pn2/2bp4/3N4/2P1P3/PP1NQPPP/R1B2RK1 w - -
+QGD: Orthodox defense, Bd3 line, 11.O-O *
+2rq1rk1/pp3ppp/2n1pn2/2bp4/8/2P1PB1P/PP1N1PP1/R1BQ1RK1 w - -
+QGD: Petrosian variation *
+2rqk2r/pp3pp1/2n1pn2/2bp3p/3N2b1/2P1P3/PP1NBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Bd3 line, Janowski variation *
+2rqk2r/pp3ppp/2n1pn2/2bp4/1P4b1/2P1PN2/P2NBPPP/R1BQ1RK1 b k -
+QGD: Orthodox defense, Bd3 line, fianchetto variation *
+2rqk2r/pp3ppp/2n1pn2/2bp4/3N2b1/2P1P3/PP1NBPPP/R1BQ1RK1 b k -
+QGD: Orthodox defense, Bd3 line, Capablanca freeing maneuver *
+2rqk2r/pp3ppp/2n1pn2/2bp4/3N4/2P1P3/PP1NQPPP/R1B2RK1 b k -
+QGD: Orthodox defense, Bd3 line *
+2rqk2r/pp3ppp/2n1pn2/3p4/1b1P2b1/1P3N2/P1PNBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Capablanca variation *
+2rqk2r/pp3ppp/2nbpn2/2pp4/3P2b1/2P1PN2/PP1NBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Bd3 line *
+2rqk2r/pp3ppp/2nbpn2/3p4/3P2b1/1P3N2/P1PNBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Pillsbury attack *
+2rqk2r/pp3ppp/4pn2/2bpn3/3N4/2P1P3/PP1NQPPP/R1B2RK1 w k -
+QGD: Orthodox defense, Bd3 line, Alekhine variation *
+2rqkb1r/pp1bpppp/2n2n2/2pp4/Q2P4/2P1PN2/PP1N1PPP/R1B1KB1R w KQk -
+QGD: Rochlin variation *
+2rqkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/2P1PN2/PP1NBPPP/R1BQ1RK1 b k -
+QGD: Orthodox defense *
+2rqkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, 7.Rc1 *
+2rqkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/P3PN2/1PPNBPPP/R1BQ1RK1 b k -
+QGD: Orthodox defense, Swiss (Henneberger) variation *
+2rqkb1r/pp3ppp/2n1pn2/3p4/3p2b1/P3PN2/1PPNBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Swiss, Karlsbad variation *
+2rqkb1r/pp3ppp/4pn2/3p4/3P4/1P2B2P/P1P1QPP1/RN3RK1 b k -
+QGD: Tartakower variation *
+2rqkbnr/pp3ppp/2n1p3/2p2b2/2pP4/4BNP1/PP2PPBP/RN1Q1RK1 b k -
+Gr\"unfeld: Gr\"unfeld gambit, Botvinnik variation *
+2rqkbnr/pp3ppp/2n1p3/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w k -
+Gr\"unfeld: Gr\"unfeld gambit, Capablanca variation *
+2rqkbnr/pp3ppp/2n1p3/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQ1RK1 w k -
+QGD: Anti-neo-orthodox variation *
+3q1rk1/pp3ppp/2r1p3/2b5/4Q3/2P5/PP3PPP/R1B2RK1 b - -
+QGD: Orthodox defense, classical, 13.de *
+3q1rk1/pp3ppp/2r1pn2/2bp4/4P3/2P5/PP1NQPPP/R1B2RK1 b - -
+QGD: Orthodox defense, classical variation *
+4rrk1/pppb2pp/2np1q2/2b2P2/4Q3/2N4B/PPPPNP1P/R1B1K2R w KQ -
+KGA: Muzio gambit, Paulsen variation *
+5rk1/5ppp/p1pbr3/1p1n3q/P2P2b1/1BPQB1P1/1P1N1P1P/R3R1K1 w - -
+Ruy Lopez: Marshall, main line, Spassky variation
+5rk1/ppq2ppp/2r1pn2/2bp4/4P3/2P5/PP1NQPPP/R1B2RK1 w - -
+QGD: Orthodox defense, classical, 13.d1c2 (Vidmar) *
+N1bk1b1r/p2pq2p/1pnn2p1/3Qpp2/8/1B6/PPPP1PPP/R1B1K1NR w KQ -
+Vienna: `Frankenstein-Dracula' variation
+N1bk3r/pp1p1ppp/2n2n2/8/1b6/P4B1q/1PPN1P1P/R1BQK2R b KQ -
+Scotch: Berger variation
+r1b1k1nr/ppp2ppp/1bn5/3p4/4P2q/2NN4/PPPP1PPP/R1BQKB1R w KQkq -
+Vienna: Adams' gambit *
+r1b1k1nr/ppp2ppp/2n5/q3P3/1b6/2N2N2/PPPB1PPP/R2QKB1R b KQkq -
+Scandinavian: Anderssen counter-attack orthodox attack
+r1b1k1nr/pppp1ppp/1b6/8/3qPP2/1PNN2P1/P2PQ2P/n1BK1B1R b kq -
+Vienna: `Frankenstein-Dracula' variation *
+r1b1k1nr/pppp1ppp/1b6/nP2N1q1/2B1P3/8/P1PP1PPP/RNBQK2R w KQkq -
+Evans gambit declined, Hirschbach variation
+r1b1k1nr/pppp1ppp/1bn5/8/4P2q/3N4/PPPPBPPP/RNBQK2R b KQkq -
+Vienna game *
+r1b1k1nr/pppp1ppp/2n2q2/1Nb5/4P3/4B3/PPP2PPP/RN1QKB1R b KQkq -
+Scotch: Blumenfeld attack
+r1b1k1nr/pppp1ppp/2n5/1N6/1b2P2q/8/PPPB1PPP/RN1QKB1R b KQkq -
+Scotch game
+r1b1k1nr/ppppqppp/1bn5/4p1B1/2BPP3/2P2N2/PP3PPP/RN1QK2R b KQkq -
+Giuoco Piano: Mestel variation
+r1b1k1nr/ppppqppp/1bn5/4p3/2BPP3/2P2N2/PP3PPP/RNBQK2R w KQkq -
+Giuoco Piano: center-holding variation
+r1b1k1nr/ppppqppp/2n5/1Bb1p3/4P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Ruy Lopez: classical defense, Boden variation
+r1b1k1nr/ppppqppp/2n5/2b1p3/2B1P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Giuoco Piano: close variation
+r1b1k1nr/pppq1ppp/1b6/n3N3/2B1P3/BQP5/P4PPP/RN3RK1 b kq -
+Evans gambit: Levenfish variation
+r1b1k2r/1pp1qppp/pbnp1n2/4p3/P1BPP3/2P2N1P/1P3PP1/RNBQR1K1 b kq -
+Giuoco Piano: Tarrasch variation
+r1b1k2r/1pp2ppp/p1n5/2bpq3/3NP3/2P1K3/PPN3PP/R1BQ1B1R b kq -
+two knights defense: Fegatello attack, Leonhardt variation *
+r1b1k2r/1pq1bppp/p1nppn2/8/P2NPP2/2N5/1PP1B1PP/R1BQ1R1K b kq -
+Sicilian: Scheveningen, classical, Mar\'oczy system
+r1b1k2r/1pqnbppp/p2ppn2/6B1/3NPP2/2N2Q2/PPP3PP/2KR1B1R w kq -
+Sicilian: Najdorf, 7...Be7 main line
+r1b1k2r/2q1bppp/p2p1n2/npp1p3/P2PP3/2P2N2/1PB2PPP/RNBQR1K1 b kq -
+Ruy Lopez: closed, Balla variation
+r1b1k2r/p1q2pp1/2pb1n1p/n3N3/3Pp3/8/PPPBBPPP/RN1QK2R b KQkq -
+two knights defense: Knorre variation
+r1b1k2r/pp1n1ppp/2p1pn2/q2p2B1/1bPP4/2N1P3/PPQN1PPP/R3KB1R b KQkq -
+QGD: Cambridge Springs defense, Bogolyubov variation
+r1b1k2r/pp3ppp/1qn1p3/2bp4/6n1/5NP1/PPPNPPBP/R1BQ1RK1 w kq -
+Gr\"unfeld: Pachman variation *
+r1b1k2r/pp3ppp/3b1q2/3P4/1P2n3/4PN2/5PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: Meran, Stahlberg variation *
+r1b1k2r/ppp1qppp/5n2/4p1B1/2BnP3/2N5/PPP3PP/R2Q1RK1 b kq -
+Giuoco piano: Holzhausen attack
+r1b1k2r/ppp2ppp/2N5/1B1pP3/4n2q/8/PPP2bPP/RNBQ1K1R w kq -
+Two knights defense, Keidanz variation
+r1b1k2r/ppp3p1/2np1q1p/2b1pP2/2B5/2NP1N2/PPP2PPP/R2QK2R b KQkq -
+KGD: classical, Svenonius variation *
+r1b1k2r/pppp1ppp/1bn5/8/4n2q/2NN4/PPPPBPPP/R1BQK2R w KQkq -
+Vienna: Alekhine variation *
+r1b1k2r/pppp1ppp/2n2q2/2b5/3NP3/4K3/PPP1N1PP/R1BQ1B1R b kq -
+two knights defense: Fegatello attack, Polerio defense *
+r1b1k2r/ppppnp1p/2n4b/4q3/2B2p2/2NP1Q2/PPPB2PP/4RRK1 b kq -
+KGA: Muzio gambit, Paulsen variation
+r1b1k2r/ppppnppp/2n2q2/1Bb5/3NP3/2P1B3/PP3PPP/RN1QK2R b KQkq -
+Scotch: Paulsen attack
+r1b1k2r/ppppnppp/2n2q2/2b5/3NP3/2P1B3/PP1Q1PPP/RN2KB1R b KQkq -
+Scotch: Blackburne attack
+r1b1k2r/ppppnppp/2n2q2/2b5/4P3/2P1B3/PPN2PPP/RN1QKB1R b KQkq -
+Scotch: Meitner variation
+r1b1k2r/ppppnppp/2n3q1/b3P3/2B5/1QN2N2/P4PPP/R1BR2K1 b kq -
+Evans gambit: compromised defense, Potter variation
+r1b1k2r/ppppnppp/2n3q1/b3P3/2B5/BQN2N2/P4PPP/R4RK1 b kq -
+Evans gambit: compromised defense, Paulsen variation
+r1b1kb1r/1pp3pp/p1n2n2/5pq1/2BPp3/2N1PP2/PP1N2PP/R1BQ1RK1 b kq -
+French: Steinitz, Brodsky-Jones variation *
+r1b1kb1r/1pq2ppp/p1nppn2/8/3NPP2/2N1B3/PPP1B1PP/R2Q1RK1 b kq -
+Sicilian: Scheveningen, classical
+r1b1kb1r/1pq2ppp/p1nppn2/8/3NPP2/2N5/PPP1B1PP/R1BQ1RK1 w kq -
+Sicilian: Scheveningen, classical variation with ...Qc7 and ...Nc6
+r1b1kb1r/2p1nppp/p1p5/3P4/3Pp3/4P3/PPQ1NP1q/RNB1K1R1 w Qkq -
+French: Winawer, advance, poisoned pawn, Konstantinopolsky variation *
+r1b1kb1r/p1q2pp1/2p2n1p/n3N3/4p3/8/PPPPBPPP/RNBQK2R w KQkq -
+two knights defense: G\"oring variation
+r1b1kb1r/p1q2ppp/2p2n2/n3p1N1/8/3B1Q2/PPPP1PPP/RNB1K2R b KQkq -
+two knights defense: Paoli variation
+r1b1kb1r/pp1n1ppp/2p1p3/q2n2B1/3P4/2N1PN2/PP3PPP/R2QKB1R w KQkq -
+QGD: Cambridge Springs defense, Yugoslav variation
+r1b1kb1r/pp1n1ppp/2p1pB2/q2p4/2PP4/2N1PN2/PP3PPP/R2QKB1R b KQkq -
+QGD: Cambridge Springs defense, Capablanca variation
+r1b1kb1r/pp1n1ppp/2p1pn2/q2P2B1/3P4/2N1PN2/PP3PPP/R2QKB1R b KQkq -
+QGD: Cambridge Springs defense, 7.cd
+r1b1kb1r/pp1n1ppp/2p1pn2/q2p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQkq -
+QGD: Cambridge Springs defense
+r1b1kb1r/pp1n1ppp/2p1pn2/q2p4/2PP4/2N2N2/PP1BPPPP/2RQKB1R b Kkq -
+QGD: Rochlin variation
+r1b1kb1r/pp1n1ppp/2p1pn2/q5B1/2pP4/2N1P3/PP1N1PPP/R2QKB1R w KQkq -
+QGD: Cambridge Springs defense, Rubinstein variation
+r1b1kb1r/pp1p1ppp/1qn1pn2/8/2PN4/2N3P1/PP2PP1P/R1BQKB1R w KQkq -
+English: symmetrical, Geller variation
+r1b1kb1r/pp1p1ppp/4pn2/1Bp5/3nPq2/2N2N2/PPPP1PPP/R1BQR1K1 w kq -
+English: four knights, Stean variation *
+r1b1kb1r/pp2pppp/1qn2n2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: Russian variation *
+r1b1kb1r/pp2pppp/1qn2n2/3p2B1/2PP4/2N5/PP3PPP/R2QKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik, Reifir (Spielmann) variation
+r1b1kb1r/pp2pppp/1qnp1n2/8/2BNP3/2N5/PPP2PPP/R1BQK2R w KQkq -
+Sicilian: Sozin, Benk\"o variation
+r1b1kb1r/pp2pppp/2n2n2/q1pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: Flohr variation *
+r1b1kb1r/pp2pppp/2n2n2/q2p2B1/2PP4/2N5/PP3PPP/R2QKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik, Czerniak variation
+r1b1kb1r/pp3ppp/1qn1pn2/2pp4/3P4/4PNP1/PPP2PBP/RNBQ1RK1 b kq -
+Gr\"unfeld: Botvinnik variation *
+r1b1kb1r/pp3ppp/1qn1pn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Gr\"unfeld with e3 & Qb3 *
+r1b1kb1r/pp3ppp/2n2n2/2qpp1B1/8/5NP1/PPP1PPBP/RN1Q1RK1 b kq -
+Gr\"unfeld: Russian, Smyslov variation *
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/1P3NP1/P1P1PPBP/RNBQ1RK1 b kq -
+Gr\"unfeld: Russian, Levenfish variation *
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/2N2NP1/PPP1PPBP/R1BQ1RK1 b kq -
+Gr\"unfeld: Russian, Byrne (Simagin) variation *
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/2P2NP1/PP2PPBP/RNBQ1RK1 b kq -
+Gr\"unfeld: Russian, Szabo (Boleslavsky) variation *
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Gr\"unfeld: Russian variation with e4 *
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/N4NP1/PPP1PPBP/R1BQ1RK1 b kq -
+Gr\"unfeld: Russian, Prins variation *
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/P4NP1/1PP1PPBP/RNBQ1RK1 b kq -
+Gr\"unfeld: Russian, Alekhine (Hungarian) variation *
+r1b1kb1r/pp3ppp/2n5/2pqp3/8/3P1NP1/PP2PP1P/R1BQKB1R b KQkq -
+Sicilian: accelerated fianchetto, Gurgenidze variation *
+r1b1kb1r/ppppq1pp/2n2n2/3Q4/8/5N2/PPP1PPPP/RNB1KB1R w KQkq -
+Queen's pawn: Englund gambit
+r1b1kb1r/ppppq1pp/2n2n2/4N1B1/3Pp3/8/PPP2PPP/RN1QKB1R w KQkq -
+Vienna gambit: Kaufmann variation *
+r1b1kb1r/ppppqppp/5n2/1B2N3/3nPP2/2N5/PPPP2PP/R1BQK2R b KQkq -
+Four knights: Rubinstein counter-gambit, Bogolyubov variation
+r1b1kb1r/ppq1pppp/2n2n2/1Bpp4/8/2NPPN2/PPP2PPP/R1BQK2R b KQkq -
+Nimzo-Indian: classical, Milner-Barry (Zurich) variation *
+r1b1kb1r/ppq2ppp/2n1pn2/2pp4/3P4/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: Stoltz variation *
+r1b1kb1r/ppqp1ppp/2B1pn2/2p5/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+English: four knights, Romanishin variation *
+r1b1kbnr/1p2pppp/p1q5/2pp4/1P6/4PN2/P1PP1PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: classical, Adorjan gambit *
+r1b1kbnr/1p2pppp/p1q5/2pp4/3P4/2N1PN2/PPP2PPP/R1BQK2R b KQkq -
+Nimzo-Indian: classical, Botvinnik variation *
+r1b1kbnr/1p2pppp/p1q5/2ppN3/3P4/4P3/PPP2PPP/RNBQK2R b KQkq -
+Nimzo-Indian: classical, Noa variation, main line *
+r1b1kbnr/1pp2ppp/p1pq4/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: exchange, Bronstein variation
+r1b1kbnr/1pq1pppp/p1n5/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R w KQkq -
+Nimzo-Indian: classical, Noa variation, 5.a3 *
+r1b1kbnr/1pq1pppp/p7/2ppN3/3P4/4P3/PPP2PPP/RNBQK2R w KQkq -
+Nimzo-Indian: classical, Noa variation, main line, 7.Qc2 *
+r1b1kbnr/1pq2ppp/p3p3/2ppN3/3PP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Nimzo-Indian: classical, San Remo variation *
+r1b1kbnr/1pqp1ppp/p1n1p3/8/3NP3/2N1B3/PPP1BPPP/R2QK2R b KQkq -
+Sicilian: Taimanov variation
+r1b1kbnr/2p2ppp/p1p5/3p2q1/2PPp3/4P3/PP2NPPP/RNBQK2R w KQkq -
+French: Winawer, advance, poisoned pawn variation *
+r1b1kbnr/p1p2ppp/2p5/3pN1q1/3Pp3/4P2P/PPP2PP1/RNBQ1K1R w kq -
+French: MacCutcheon, Duras variation *
+r1b1kbnr/p1pp1ppp/1pn5/8/3PPp1q/2N5/PPP1K1PP/R1BQ1BNR w kq -
+Vienna: Steinitz gambit, Fraser-Minckwitz variation
+r1b1kbnr/pp1qpppp/2np4/1B6/3QP3/5N2/PPP2PPP/RNB1K2R w KQkq -
+Sicilian: Chekhover, Zaitsev variation
+r1b1kbnr/pp2pppp/1qn5/1Bp5/2p5/2N1PN2/PP1P1PPP/R1BQK2R b KQkq -
+Nimzo-Indian: Spielmann, 4...c5, 5.dc Nc6 *
+r1b1kbnr/pp2pppp/1qn5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: Spielmann variation *
+r1b1kbnr/pp2pppp/1qn5/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Gr\"unfeld: Russian variation *
+r1b1kbnr/pp2pppp/2nq4/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: Mikenas attack *
+r1b1kbnr/pp3ppp/1qn1p3/2ppP3/3P4/2PB1N2/PP3PPP/RNBQK2R b KQkq -
+French: advance, Milner-Barry gambit
+r1b1kbnr/ppp1pppp/2n5/3q4/3P4/2N5/PPP2PPP/R1BQKBNR b KQkq -
+KP: Nimzovich defense, Marshall gambit
+r1b1kbnr/ppp1pppp/2n5/7q/8/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Novosibirsk opening *
+r1b1kbnr/ppp1qppp/2n5/4P3/2Pp4/5N2/PP1NPPPP/R1BQKB1R w KQkq -
+QGD: Albin counter-gambit, Balogh variation
+r1b1kbnr/ppp2ppp/2n5/1B1p2q1/2PPp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+French: Winawer, advance, Russian variation *
+r1b1kbnr/ppp2ppp/2n5/3p2q1/3Pp3/4P3/PPPN1PPP/RNBQKB1R w KQkq -
+French: Steinitz, Gledhill attack *
+r1b1kbnr/ppp2ppp/2n5/3p4/3PPp1q/2N5/PPP1K1PP/R1BQ1BNR w kq -
+Vienna: Steinitz gambit, Zukertort defense
+r1b1kbnr/ppp3pp/2n2q2/3pN3/3PpP2/8/PPP3PP/RNBQKB1R w KQkq -
+Vienna gambit: Heyde variation *
+r1b1kbnr/ppp3pp/2n5/5pq1/2BPp3/4P3/PP1N1PPP/RNBQK2R w KQkq -
+French: Steinitz, Bradford attack *
+r1b1kbnr/pppnq2p/8/4Npp1/3Q1P2/8/PPP3PP/RNB1KB1R w KQkq -
+KGD: Falkbeer, Charousek variation *
+r1b1kbnr/pppp1Npp/8/8/4q3/5n2/PPPPBP1P/RNBQKR2 w Qkq -
+Blackburne shilling gambit
+r1b1kbnr/pppp1p1p/2n5/4N3/2B1Pppq/8/PPPP2PP/RNBQ1K1R w kq -
+KGA: Herzfeld gambit
+r1b1kbnr/pppp1p1p/5q2/4n3/2B1PQ2/2N5/PPPP2PP/R1B2RK1 w kq -
+Vienna: Hamppe-Muzio, Dubois variation
+r1b1kbnr/pppp1ppp/2n2q2/4p3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: Goldman (Spielmann) variation *
+r1b1kbnr/pppp1ppp/2n5/1B2p1q1/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Vienna: Zhuravlev countergambit *
+r1b1kbnr/pppp1ppp/2n5/1N6/4P2q/8/PPP2PPP/RNBQKB1R b KQkq -
+Scotch: Horwitz attack
+r1b1kbnr/pppp1ppp/2n5/8/2B1Pp1q/8/PPPP2PP/RNBQ1KNR w kq -
+KGA: bishop's gambit, Boden defense
+r1b1kbnr/pppp1ppp/2n5/8/3NP2q/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Scotch: Steinitz variation
+r1b1kbnr/pppp1ppp/2n5/8/3NP2q/8/PPP2PPP/RNBQKB1R w KQkq -
+Scotch: Pulling counter-attack
+r1b1kbnr/pppp1ppp/2n5/8/4P2q/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Scotch: Fraser attack
+r1b1kbnr/pppp2pp/2n2q2/4N3/3Pp3/8/PPP2PPP/RNBQKB1R w KQkq -
+Vienna gambit: Paulsen attack *
+r1b1kbnr/pppp2pp/2n2q2/4N3/3PpP2/8/PPP3PP/RNBQKB1R b KQkq f3
+Vienna gambit: Bardeleben variation *
+r1b1kbnr/ppppq1pp/2n5/4Pp2/3p4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+KGD: Falkbeer, Rubinstein variation *
+r1b1kbnr/ppppqppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Vinogradov variation
+r1b1kbnr/ppq1pppp/2n5/1B1p4/3P4/5N2/PPP2PPP/RNBQK2R b KQkq -
+Nimzo-Indian: classical, Noa variation, 5.cd ed *
+r1b1kbnr/ppq1pppp/2n5/1Bp5/2p5/4PN2/PP1P1PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: classical, Pir\'c variation *
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+Nimzo-Indian: classical, 4...c5 *
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R b KQkq -
+Nimzo-Indian: classical, Noa variation *
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/8/2N1PN2/PPPP1PPP/R1BQK2R b KQkq -
+Nimzo-Indian: classical, 4...Nc6 *
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: classical variation *
+r1b1kbnr/ppqp1ppp/2n1p3/8/3NP3/2N1B3/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: Taimanov variation
+r1b1kbnr/ppqp1ppp/2n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Taimanov (Bastrikov) variation
+r1b1kbnr/ppqppppp/2n5/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Flohr variation
+r1b2knr/pppp3p/2n2qP1/2b1p2Q/6P1/8/PPPP1PBP/RNB1K1NR w KQ -
+KGA: bishop's gambit, Fraser variation *
+r1b2rk1/1p2qp1p/2n1pn2/pBbpN1p1/5B2/2P1P3/PP3PPP/RN1Q1RK1 w - -
+QGD Slav: Dutch, S\"amisch variation *
+r1b2rk1/1p2qppp/2n1pn2/pBbp4/5B2/2P1PN2/PP3PPP/RN1Q1RK1 w - -
+QGD Slav: Dutch variation, main line *
+r1b2rk1/1pp1qppp/2n2n2/p1bPp3/8/2PP1N2/PP1NBPPP/R1BQ1RK1 b - -
+Philidor: Nimzovich, Sozin variation *
+r1b2rk1/1pq1bppp/p1nppn2/8/3NPP2/2N1B3/PPP1B1PP/R3QRK1 w - -
+Sicilian: Scheveningen, classical main line
+r1b2rk1/2q1bppp/p1np1n2/1pP1p3/4P3/2P2N1P/PPBN1PP1/R1BQR1K1 b - -
+Ruy Lopez: closed, Chigorin, Rauzer attack
+r1b2rk1/2q1bppp/p1np1n2/1pp1p3/3PP3/2P2N1P/PPBN1PP1/R1BQR1K1 w - -
+Ruy Lopez: closed, Chigorin, 12...Nc6
+r1b2rk1/2q1bppp/p1pp1n2/np2p3/3PP3/2P2N1P/PPB2PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Rossolimo defense
+r1b2rk1/2q1bppp/p2p1n2/np2p3/3PP3/5N1P/PPBN1PP1/R1BQR1K1 b - -
+Ruy Lopez: closed, Chigorin, 12...c5d4
+r1b2rk1/2q1bppp/p2p1n2/npp1p3/3PP3/2P2N1P/PPB2PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Chigorin defense
+r1b2rk1/5ppp/p1pb4/1p1n4/3P4/1BP3Pq/PP3P1P/RNBQR1K1 w - -
+Ruy Lopez: Marshall, main line, 14...Qh3
+r1b2rk1/p1q2ppp/2n2n2/3pp3/N7/1B1P4/PPPB1bPP/R2Q1KNR w - -
+Evans gambit: Fraser-Mortimer attack *
+r1b2rk1/p4ppp/1qB2n2/2bp4/3P4/2N5/PPP2PPP/R1BQK2R b KQ -
+Giuoco Piano: Bernstein variation *
+r1b2rk1/p4ppp/2n2n2/q1bpp1B1/8/1BNP4/PPP2PPP/R2QK1NR w KQ -
+Evans gambit: Fraser attack *
+r1b2rk1/pp1n1ppp/2p1pn2/q2p4/1bPP3B/2N1P3/PPQN1PPP/R3KB1R b KQ -
+QGD: Cambridge Springs defense, Argentine variation
+r1b2rk1/pp1nqppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P1BPPP/R2Q1RK1 w - -
+Ruy Lopez: open, Malkin variation *
+r1b2rk1/pp1nqppp/2n1p3/3pP3/2pP1P2/2N2N2/PPPQ2PP/2KR1B1R w - -
+French: classical, St\a hlberg variation
+r1b2rk1/pp1nqppp/2p1p3/3n4/2BP4/2N1PN2/PP3PPP/2RQ1RK1 b - -
+QGD: Orthodox defense, Bd3 line, 11.O-O
+r1b2rk1/pp1nqppp/2p1p3/3n4/2BP4/2N1PN2/PP3PPP/2RQK2R w K -
+QGD: Orthodox defense, Bd3 line
+r1b2rk1/pp1nqppp/2p1p3/3n4/2BPN3/4PN2/PP3PPP/2RQK2R b K -
+QGD: Orthodox defense, Bd3 line, Alekhine variation
+r1b2rk1/pp1nqppp/2p5/4p3/2BP4/2R1PN2/PP3PPP/1Q3RK1 b - -
+QGD: Orthodox defense, classical, 13.d1b1 (Mar\'oczy)
+r1b2rk1/pp1nqppp/2p5/4p3/2BP4/2R1PN2/PP3PPP/3Q1RK1 w - -
+QGD: Orthodox defense, classical variation
+r1b2rk1/pp1nqppp/2p5/4p3/2BP4/2R1PN2/PPQ2PPP/5RK1 b - -
+QGD: Orthodox defense, classical, 13.d1c2 (Vidmar)
+r1b2rk1/pp2nppp/2pq1n2/3pp1B1/1b2P2N/1BNP4/PPP2PPP/R2Q1RK1 w - -
+Four knights: symmetrical, Blake variation
+r1b2rk1/pp2ppbp/1qnp1np1/4P3/3N1P2/2N1B3/PPP1B1PP/R2Q1RK1 b - -
+Sicilian: dragon, classical, Zollner gambit
+r1b2rk1/pp2ppbp/2nq1np1/2pp4/3P4/2P1PN2/PP1NBPPP/R1BQ1RK1 w - -
+Catalan: closed, Botvinnik variation *
+r1b2rk1/pp2ppbp/2q2np1/2pp4/8/1P2P3/PBPPBPPP/RN1Q1RK1 w - -
+Queen's Indian: old main line, 9.Qxc3 *
+r1b2rk1/pp2qppp/1bn2n2/4p3/1P6/P1NPP3/R4PPP/2BQKBNR b K -
+Sicilian: Smith-Morra gambit, Chicago defense *
+r1b2rk1/pp2qppp/2n1pn2/2bp4/2P1P3/2NB1N2/PP2QPPP/R1B2RK1 b - -
+QGD: Semi-Tarrasch, Levenfish variation
+r1b2rk1/pp2qppp/2nb1n2/2p1p3/2BP4/2N1PN2/PP2QPPP/R1B2RK1 w - -
+QGD: Semi-Tarrasch, Levenfish variation *
+r1b2rk1/pp3ppp/2p5/4q3/2B5/2R1P3/PP3PPP/3Q1RK1 w - -
+QGD: Orthodox defense, classical, 13.de
+r1b2rk1/ppp1qppp/2n2n2/1B1pp3/1b2P3/3P1N2/PPP1NPPP/R1BQ1RK1 w - -
+Four knights: Alatortsev variation
+r1b2rk1/ppp1qppp/2np1n2/1B2p1B1/4P3/2PP1N2/P1P2PPP/R2Q1RK1 w - -
+Four knights: symmetrical, Metger unpin
+r1b2rk1/pppp2pp/2n5/2b1pq2/4N3/5Q2/PPPP1P1P/R1B1KBNR b KQ -
+Vienna: Hamppe-Muzio, Dubois variation *
+r1b2rk1/ppq1ppbp/2n2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 w - -
+Dutch: Ilyin-Genevsky variation with Qc2 *
+r1b2rk1/ppqnppbp/5np1/2pp4/3P4/2P1PN2/PP1NBPPP/R1BQ1RK1 w - -
+Catalan: closed, main line *
+r1b3nr/ppppkBpp/1b6/nP2N1qQ/4P3/8/P1PP1PPP/RNB1K2R b KQ -
+Evans gambit declined, V\'asquez variation
+r1b3r1/ppp2k1p/1b6/nP2B1q1/3PP3/8/P1PN1PPP/R2QK2R b KQ -
+Evans gambit declined, Pavlov variation
+r1bB1rk1/pp3ppp/8/4p3/3nn3/3P4/PPP1KbPP/R2Q1BNR w - -
+Scotch: Sea-cadet mate *
+r1bk1bnr/2p2ppp/p1p5/3P4/3Pp3/4P3/PPQ1NP1q/RNB1K1R1 w Q -
+French: Winawer, advance, poisoned pawn, Euwe-Gligori\'c variation *
+r1bk2nr/pppp1Qpp/1b6/nP2q3/2B1P3/8/PBPP1PPP/RN2K2R b KQ -
+Evans gambit declined, Hicken variation
+r1bk2nr/pppp1ppp/2n3q1/1N6/8/8/PPPNBPPP/R2Q1RK1 w - -
+Scotch: Rosenthal variation
+r1bk2nr/ppppq1pp/2n5/2b1PP1Q/8/8/PPPP2PP/RNBK1BNR b - -
+KGA: L\'opez-Gianutio counter-gambit, Hein variation *
+r1bnk2r/ppppnppp/5q2/1Bb5/3NP3/2P1B3/PP3PPP/RN1QK2R w KQkq -
+Scotch: Paulsen, Gunsberg defense
+r1bq1b1r/ppn3pp/2p1k3/3np3/2BPQ3/P1N5/1PP2PPP/R1B1K2R w KQ -
+two knights defense: Fegatello attack, Leonhardt variation
+r1bq1b1r/ppp1n1pp/4k3/3np3/2B5/2N2Q2/PPPP1PPP/R1B1K2R w KQ -
+two knights defense: Fegatello attack, Polerio defense
+r1bq1b1r/ppp2kp1/2n5/1B1p1PPp/3Qn3/5N2/PPP2P1P/RNB1K2R w KQ -
+KGA: Kieseritsky, Brentano defense, Kaplanek variation *
+r1bq1bnr/ppp1k1pp/2n5/3ppP1Q/3P4/2N5/PPP2PPP/R1B1KBNR b KQ -
+Vienna: Steinitz gambit, Zukertort defense *
+r1bq1bnr/ppp1k1pp/2n5/3ppP1Q/8/1PN5/P1PP1PPP/R1B1KBNR b KQ -
+Vienna: Steinitz gambit, Fraser-Minckwitz variation *
+r1bq1k1r/2p2ppp/p4n2/1pbPR1N1/3n4/1B6/PPPP1PPP/RNBQ2K1 w - -
+Ruy Lopez: Rabinovich variation
+r1bq1k1r/pp2nppp/2n5/4p3/2Pp4/3P1NP1/4PP1P/RN1QKB1R w KQ -
+Benk\"o gambit: Ne2 variation *
+r1bq1knr/pp3p1p/2n3p1/4p3/2Pp4/3P1NP1/4PP1P/RN1QKB1R w KQ -
+Benk\"o gambit *
+r1bq1knr/ppp3pp/2n5/2bp1P1Q/4p1P1/3P4/PPP2PBP/RNB1K1NR w KQ -
+KGA: bishop's gambit, Grimm attack *
+r1bq1knr/ppp3pp/2n5/2bppP1Q/6P1/8/PPPPNPBP/RNB1K2R b KQ -
+KGA: bishop's gambit, classical defense *
+r1bq1knr/ppp4p/2n3p1/2bppP1Q/6P1/8/PPPPNPBP/RNB1K2R w KQ -
+KGA: bishop's gambit, McDonnell attack *
+r1bq1knr/pppp3p/2n3p1/2b1pP1Q/6P1/8/PPPP1PBP/RNB1K1NR w KQ -
+KGA: bishop's gambit, McDonnell attack *
+r1bq1r1k/1pp1b1pp/2n5/p2npp2/8/P1NPPN2/1PQ1BPPP/R1B1K2R w KQ -
+Sicilian: Scheveningen, classical, Mar\'oczy system *
+r1bq1rk1/1p1n1pbp/2pp1np1/p3p3/2PPP3/2N2N2/PP3PPP/R1BQRBK1 w - -
+King's Indian: orthodox, 7...Nbd7, main line
+r1bq1rk1/1p1nbppp/p1p1pn2/3P2B1/3P4/2N1PN2/PPQ2PPP/2R1KB1R b K -
+QGD: Orthodox defense, Rubinstein attack, main line
+r1bq1rk1/1p1nbppp/p1p1pn2/3p2B1/2PP4/2N1PN2/PPQ2PPP/2R1KB1R w K -
+QGD: Orthodox defense, Rubinstein attack, Karlsbad variation
+r1bq1rk1/1p1nbppp/p1p1pn2/3p2B1/2PP4/P1N1PN2/1PQ2PPP/2R1KB1R b K -
+QGD: Orthodox defense, Rubinstein attack, Gr\"unfeld variation
+r1bq1rk1/1p1nppbp/2n3p1/p7/2Pp4/P2P1NP1/1P1N1PBP/R1BQR1K1 b - -
+Benoni: fianchetto, 11...Re8 *
+r1bq1rk1/1p2bppp/2n2n2/p3p1B1/2Pp4/P2P1NP1/1P3PBP/RN1Q1RK1 b - -
+Benoni: classical with ...a6 and 10...Bg4 *
+r1bq1rk1/1p2bppp/2n2n2/p3p3/2Pp4/P2P1NP1/1P3PBP/RNBQ1RK1 w - -
+Benoni: classical, 9...a6, 10.a4 *
+r1bq1rk1/1p2ppbp/2np1np1/p7/2BNP3/2N1BP2/PPPQ2PP/R3K2R w KQ -
+Sicilian: dragon, Yugoslav attack, Byrne variation
+r1bq1rk1/1p2ppbp/2np1np1/p7/4P3/1NN1B3/PPP1BPPP/R2Q1RK1 w - -
+Sicilian: dragon, classical, Alekhine variation
+r1bq1rk1/1p3ppp/2n1pn2/pBbp4/5B2/2P1PN2/PP3PPP/RN1QK2R w KQ -
+QGD Slav: Dutch variation *
+r1bq1rk1/1p3ppp/p1n1pn2/1BbP4/8/2N1PN2/PP3PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, main line with 8...dc and 9...cd *
+r1bq1rk1/1pp1ppbp/p1np1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, Panno variation
+r1bq1rk1/1pp1ppbp/p1np1np1/8/2PPP3/2N1BP2/PP2N1PP/R2QKB1R w KQ -
+King's Indian: S\"amisch, Panno formation
+r1bq1rk1/1pp2ppp/1bn5/p2PN3/1P1P4/P7/2P2PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, Berger variation *
+r1bq1rk1/1ppnbppp/p3pn2/3P2B1/3P4/2N1PN2/PP3PPP/2RQKB1R b K -
+QGD: Orthodox defense, Swiss, Karlsbad variation
+r1bq1rk1/1ppnbppp/p3pn2/3p2B1/2PP4/2N1PN2/PP3PPP/2RQKB1R w K -
+QGD: Orthodox defense, Swiss (Henneberger) variation
+r1bq1rk1/2p1bpp1/p1np1n1p/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Smyslov defense
+r1bq1rk1/2p1bppp/2np1n2/pp2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Keres (9...a5) variation
+r1bq1rk1/2p1bppp/p1n2n2/1p1P4/4p3/1BP2N2/PP1P1PPP/RNBQR1K1 w - -
+Ruy Lopez: Marshall, Herman Steiner variation
+r1bq1rk1/2p1bppp/p1n2n2/1p1pp3/4P3/1BP2N2/PP1P1PPP/RNBQR1K1 w - -
+Ruy Lopez: Marshall counter-attack
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/3PP3/1BP2N2/PP3PPP/RNBQR1K1 b - -
+Ruy Lopez: closed, 9.d4
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 b - -
+Ruy Lopez: closed, 9.h3
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/1BP2N2/PP1P1PPP/RNBQR1K1 w - -
+Ruy Lopez: closed (with ...d6)
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/1BPP1N2/PP3PPP/RNBQR1K1 b - -
+Ruy Lopez: closed, Pilnik variation
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/2P2N2/PPBP1PPP/RNBQR1K1 b - -
+Ruy Lopez: closed, Lutikov variation
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/PBP2N2/1P1P1PPP/RNBQR1K1 b - -
+Ruy Lopez: closed, Suetin variation
+r1bq1rk1/2p1bppp/p2p1n2/np2p3/4P3/2P2N1P/PPBP1PP1/RNBQR1K1 b - -
+Ruy Lopez: closed (9...Na5)
+r1bq1rk1/2pnbppp/p1np4/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Ragozin-Petrosian (`Keres') variation
+r1bq1rk1/2pnbppp/p2p1n2/1p2p3/3PP2N/1BP4P/PP3PP1/RNBQR1K1 b - -
+Ruy Lopez: closed, Breyer, Simagin variation
+r1bq1rk1/2pnbppp/p2p1n2/1p2p3/3PP3/1BP2N1P/PP3PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Breyer, Borisenko variation
+r1bq1rk1/2ppbppp/p1n2n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQR1K1 w - -
+Ruy Lopez: closed, 7...O-O
+r1bq1rk1/2ppbppp/p1n2n2/1p2p3/4P3/1B3N2/PPPPQPPP/RNB2RK1 w - -
+Ruy Lopez: Worrall attack, sharp line
+r1bq1rk1/2ppbppp/p1n2n2/1p2p3/4P3/1BP2N2/PP1P1PPP/RNBQR1K1 b - -
+Ruy Lopez: closed, 8.c3
+r1bq1rk1/2ppbppp/p1n2n2/1p2p3/P3P3/1B3N2/1PPP1PPP/RNBQR1K1 b - -
+Ruy Lopez: closed, anti-Marshall 8.a4
+r1bq1rk1/3nbppp/p2p4/npp1p3/3PP3/2P2N1P/PPB2PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Keres (...Nd7) defense
+r1bq1rk1/4bppp/p1np1n2/1pp1p3/3PP3/2P2N1P/PPB2PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Borisenko defense
+r1bq1rk1/4bppp/p1p5/1p1nR3/3P4/1BP5/PP3PPP/RNBQ2K1 b - -
+Ruy Lopez: Marshall, main line, 12.d2d4
+r1bq1rk1/4bppp/p1p5/1p1nR3/8/1BP5/PP1P1PPP/RNBQ2K1 w - -
+Ruy Lopez: Marshall counter-attack, 11...c6
+r1bq1rk1/4bppp/p2p1n2/npp1p3/4P3/2P2N1P/PPBP1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed (10...c5)
+r1bq1rk1/4bppp/ppnppn2/8/2P1P3/N1N5/PP2BPPP/R1BQ1RK1 w - -
+Sicilian, Sz\'en, hedgehog variation
+r1bq1rk1/5ppp/p1p1pn2/2bp4/2P5/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, main line *
+r1bq1rk1/5ppp/p1pbpn2/2pp4/2PP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, main line with 8...Bxc3 *
+r1bq1rk1/5ppp/p2b4/1p1p4/3P4/2P1R3/PP3PPP/RNBQ2K1 b - -
+Ruy Lopez: Marshall, Kevitz variation
+r1bq1rk1/p1p2ppp/2pp1n2/4p3/1b1PP3/2N2N2/PPP2PPP/R1BQ1RK1 b - -
+Four knights: Svenonius variation *
+r1bq1rk1/p1pnbppp/1p3n2/1B1p2B1/3P4/2N1PN2/PP3PPP/2RQK2R b K -
+QGD: Orthodox defense, Capablanca variation
+r1bq1rk1/p1pnbppp/1p3n2/3p2B1/3P4/2NBPN2/PP3PPP/2RQK2R b K -
+QGD: Orthodox defense, Pillsbury attack
+r1bq1rk1/p1ppbppp/8/2p1P3/3B4/2N5/PPP1QPPP/R3R1K1 w - -
+Ruy Lopez: Berlin defense, Rio de Janeiro variation
+r1bq1rk1/p2nbppp/1pp1pn2/3p4/P1PP4/5NP1/1PQ1PPBP/RNBR2K1 b - -
+Catalan: closed, Zagoryansky variation
+r1bq1rk1/p2nbppp/2p1pn2/1p4B1/2BP4/2N1PN2/PP3PPP/2RQK2R w K -
+QGD: Orthodox defense, Bd3 line, fianchetto variation
+r1bq1rk1/p2pppbp/1pn2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w - -
+English: symmetrical, main line with b3 *
+r1bq1rk1/p3bppp/2n2n2/1pp1p3/3pP3/3P1NP1/PPP1NPBP/R1BQ1RK1 w - -
+King's Indian: orthodox, Aronin-Taimanov, bayonet attack *
+r1bq1rk1/p3nppp/2p5/2bpp3/8/1P4P1/P1PQPPBP/RNB2RK1 b - -
+Gr\"unfeld: exchange, Larsen variation *
+r1bq1rk1/p3ppbp/1pn2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 w - -
+Dutch: Ilyin-Genevsky variation with b3 *
+r1bq1rk1/p4ppp/2n2n2/2bpp1B1/8/1BNP4/PPP2PPP/R2QK1NR b KQ -
+Evans gambit *
+r1bq1rk1/p4ppp/2n2n2/2bpp3/8/1BNP4/PPP2PPP/R1BQK1NR w KQ -
+Evans gambit: Morphy attack *
+r1bq1rk1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N2NPP/PP3PB1/R1BQ1RK1 b - -
+King's Indian: fianchetto, classical main line
+r1bq1rk1/pp1n1pbp/3p1np1/2pP4/8/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+Benoni: fianchetto, 9...Nbd7
+r1bq1rk1/pp1n1pp1/2p1pb1p/8/2BP4/2N1PN2/PP3PPP/2RQ1RK1 b - -
+QGD: Petrosian variation
+r1bq1rk1/pp1n1ppp/1bp2n2/4N3/1PBPp3/P1N1B3/2P2PPP/R2QK2R w KQ -
+Ruy Lopez: open, St. Petersburg variation *
+r1bq1rk1/pp1n1ppp/1bp5/3P4/1PN1p1n1/P1N1B3/2P2PPP/R2QKB1R w KQ -
+Ruy Lopez: open, Bernstein variation, Karpov gambit *
+r1bq1rk1/pp1n1ppp/4pn2/2p5/1bBP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, Gligori\'c system, Bronstein variation
+r1bq1rk1/pp1n1ppp/4pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, Gligori\'c system with 7...Nbd7
+r1bq1rk1/pp1n2pp/2n1pp2/2bpP3/5PQ1/P1N2N2/1PP3PP/R1B1KB1R w KQ -
+French: Steinitz, Brodsky-Jones variation
+r1bq1rk1/pp1nb1pp/2n2p2/4p3/2Pp4/N2P1NP1/PP3PBP/R1BQR1K1 w - -
+Benoni: classical, 11.f3 *
+r1bq1rk1/pp1nbppp/2n5/4p3/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 w - -
+Benoni: classical, 9...Re8, 10.Nd2 *
+r1bq1rk1/pp1nbppp/2n5/4p3/2Pp4/N2P1NP1/PP3PBP/R1BQR1K1 b - -
+Benoni: classical with ...Re8 and ...Na6 *
+r1bq1rk1/pp1nbppp/2p1p3/3n2B1/2BP3P/2N1PN2/PP3PP1/2RQK2R b K -
+QGD: Orthodox defense, Bd3 line, Janowski variation
+r1bq1rk1/pp1nbppp/2p1p3/3n2B1/2BP4/2N1PN2/PP3PPP/2RQK2R w K -
+QGD: Orthodox defense, Bd3 line, Capablanca freeing maneuver
+r1bq1rk1/pp1nbppp/2p1p3/3p2B1/2PPn3/2N1PN2/PPQ2PPP/2R1KB1R w K -
+QGD: Orthodox defense, Rubinstein attack, Wolf variation
+r1bq1rk1/pp1nbppp/2p1pn2/3p2B1/2PP4/2N1PN2/PP3PPP/2RQKB1R w K -
+QGD: Orthodox defense
+r1bq1rk1/pp1nbppp/2p1pn2/3p2B1/2PP4/2N1PN2/PPQ2PPP/2R1KB1R b K -
+QGD: Orthodox defense, Rubinstein attack (with Rc1)
+r1bq1rk1/pp1nbppp/2p1pn2/3p2B1/2PP4/2NBPN2/PP3PPP/2RQK2R b K -
+QGD: Orthodox defense, Bd3 line
+r1bq1rk1/pp1nbppp/2p1pn2/3p4/2PP4/1P3NP1/P1Q1PPBP/RNB2RK1 b - -
+Catalan: closed, Qc2 & b3
+r1bq1rk1/pp1nbppp/2p1pn2/3p4/2PP4/2NQ1NP1/PP2PPBP/R1B2RK1 b - -
+Catalan: closed, Botvinnik variation
+r1bq1rk1/pp1nbppp/2p1pn2/3p4/2PP4/5NP1/PPQNPPBP/R1B2RK1 b - -
+Catalan: closed, main line
+r1bq1rk1/pp1nbppp/2p4n/3pp1N1/2BPPP2/2P5/PP4PP/RNBQ1RK1 w - -
+Philidor: Hanham, Berger variation
+r1bq1rk1/pp1nbppp/2pp1n2/8/P1BpP3/2N2N2/1PP1QPPP/R1B2RK1 w - -
+Philidor: Nimzovich, Sozin variation
+r1bq1rk1/pp1nbppp/4pn2/2pP2B1/3P4/2N1PN2/PPQ2PPP/R3KB1R b KQ -
+QGD: Orthodox defense, 7.Qc2 c5, 8.cd (Rubinstein)
+r1bq1rk1/pp1p1ppp/2n1pn2/2p5/2PP4/P1PBP3/5PPP/R1BQK1NR w KQ -
+Nimzo-Indian: S\"amisch, main line
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/1P2PN2/PB1PBPPP/RN1QK2R b KQ -
+English: symmetrical, hedgehog system *
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/1PN2NP1/P2PPPBP/R1BQ1RK1 b - -
+English: symmetrical, main line with b3
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/2NP1NP1/PP2PPBP/R1BQ1RK1 b - -
+English: symmetrical, main line with d3
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+English: symmetrical, main line with d4
+r1bq1rk1/pp1pppbp/2n2np1/8/2PN4/2N1P3/PP2BPPP/R1BQK2R b KQ -
+English: Symmetrical, Keres defense *
+r1bq1rk1/pp2b1pp/2n2n2/2pp4/4pB2/1N2PP2/PPP1B1PP/RN1Q1RK1 b - -
+Alekhine's defense: four pawns attack, Korchnoi variation *
+r1bq1rk1/pp2bppp/2n1pn2/2pp4/4P3/3P1NP1/PPPN1PBP/R1BQR1K1 b - -
+R\'eti: King's Indian attack, French variation
+r1bq1rk1/pp2bppp/2n2n2/2pp2B1/3P4/2N2NP1/PP2PPBP/R2Q1RK1 b - -
+QGD: Tarrasch, Prague variation, 9.Bg5
+r1bq1rk1/pp2bppp/2n2n2/2pp4/3P4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+QGD: Tarrasch, Prague variation, Normal position
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/2NP1NP1/PPP2PBP/R1BQ1RK1 b - -
+King's Indian: orthodox, Aronin-Taimanov variation (Yugoslav attack / Mar del Plata variation) *
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/2PP1NP1/PP3PBP/RNBQ1RK1 b - -
+King's Indian: orthodox, Donner variation *
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 w - -
+King's Indian: orthodox variation *
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 b - -
+King's Indian: orthodox, 7...Nbd7 *
+r1bq1rk1/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 w - -
+Benoni: classical, 9.O-O *
+r1bq1rk1/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 b - -
+Benoni: classical, 9...Re8 *
+r1bq1rk1/pp2bppp/2np1n2/4p1B1/3NPP2/2N5/PPPQ2PP/2KR1B1R w - -
+Sicilian: Richter-Rauzer, Rauzer attack, Geller variation
+r1bq1rk1/pp2bppp/2nppn2/6B1/3NPP2/2N5/PPPQ2PP/2KR1B1R b - -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 defense, 9.f4
+r1bq1rk1/pp2bppp/2nppn2/8/3NPP2/1BN1B3/PPP3PP/R2QK2R b KQ -
+Sicilian: Sozin, Fischer variation
+r1bq1rk1/pp2bppp/2nppn2/8/3NPP2/2N1B3/PPP1B1PP/R2Q1RK1 b - -
+Sicilian: modern Scheveningen, main line
+r1bq1rk1/pp2bppp/3ppn2/6B1/3QPP2/2N5/PPP3PP/2KR1B1R b - -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 defense, 9...Nxd4
+r1bq1rk1/pp2bppp/3ppn2/6B1/3nPP2/2N5/PPPQ2PP/2KR1B1R w - -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 defense, 9...Nxd4
+r1bq1rk1/pp2bppp/n1n5/2p1p3/8/PPNPPN2/4BPPP/R1BQ1RK1 b - -
+Sicilian, Sz\'en, hedgehog variation *
+r1bq1rk1/pp2ppbp/2n2np1/2p5/2Pp4/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, Yugoslav Panno *
+r1bq1rk1/pp2ppbp/2n2np1/2pp2B1/8/2NP1NP1/PPP1PPBP/R2Q1RK1 b - -
+King's Indian: fianchetto, Simagin variation *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w - -
+English: symmetrical, main line with d4 *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 w - -
+King's Indian: fianchetto, Yugoslav, 7.O-O *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/3P1P2/2P1PN2/PP2B1PP/RNBQ1RK1 b - -
+Dutch: stonewall with Nc3 *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/3P1P2/4PN2/PPP1B1PP/RNBQ1RK1 w - -
+Dutch: stonewall with Nc3 *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/4P3/2NP1NP1/PPP2PBP/R1BQ1RK1 b - -
+King's Indian: fianchetto, Uhlmann (Szabo) variation *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 b - -
+King's Indian: fianchetto, classical variation *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5B2/2NP1NP1/PPP1PPBP/R2Q1RK1 b - -
+King's Indian: fianchetto, lesser Simagin (Spassky) variation *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5B2/2PP1NP1/PP2PPBP/RN1Q1RK1 b - -
+King's Indian: fianchetto, Larsen system *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5P2/2NP1NP1/PPP1P1BP/R1BQ1RK1 b - -
+Dutch: Leningrad, main variation with Nc6 *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5P2/2PP1NP1/PP2P1BP/RNBQ1RK1 b - -
+Dutch: Leningrad, main variation with c6 *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 b - -
+Dutch: Ilyin-Genevsky variation *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/1P2PN2/PBPPBPPP/RN1Q1RK1 w - -
+Queen's Indian: old main line, 7.Nc3 *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/P1NP1NP1/1PP1PPBP/R1BQ1RK1 b - -
+King's Indian: fianchetto, Panno variation *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/Q7/2PP1NP1/PP2PPBP/RNB2RK1 b - -
+King's Indian: fianchetto, Kavalek (Bronstein) variation *
+r1bq1rk1/pp2ppbp/2n2np1/3p4/2PN4/6P1/PP2PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O c5, 8.Nc3 *
+r1bq1rk1/pp2ppbp/2n2np1/3p4/2PP4/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+QGD: Tarrasch, Prague variation, Normal position *
+r1bq1rk1/pp2ppbp/2n2np1/8/2Pp4/3P1NP1/PP1N1PBP/R1BQ1RK1 b - -
+Benoni: fianchetto, 9...Nbd7 *
+r1bq1rk1/pp2ppbp/2n3p1/8/2BPP3/4B3/P3NPPP/R2Q1RK1 b - -
+Gr\"unfeld: Spassky variation, main line, 10...cd, 11.cd
+r1bq1rk1/pp2ppbp/2np1np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w - -
+English: symmetrical, main line with d3 *
+r1bq1rk1/pp2ppbp/2np1np1/2pP4/2P5/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+King's Indian: fianchetto, Yugoslav Panno
+r1bq1rk1/pp2ppbp/2np1np1/8/2BNP3/2N1BP2/PPPQ2PP/R3K2R b KQ -
+Sicilian: dragon, Yugoslav attack, 9.Bc4
+r1bq1rk1/pp2ppbp/2np1np1/8/2PNPP2/2N1B3/PP2B1PP/R2QK2R b KQ -
+King's Indian: Four pawns attack, main line
+r1bq1rk1/pp2ppbp/2np1np1/8/3NP3/2N1B3/PPPQBPPP/2KR3R b - -
+Sicilian: dragon, classical, Grigoriev variation
+r1bq1rk1/pp2ppbp/2np1np1/8/3NP3/2N1B3/PPPQBPPP/R4RK1 b - -
+Sicilian: dragon, classical, Richter variation
+r1bq1rk1/pp2ppbp/2np1np1/8/3NP3/2N1BP2/PPPQ2PP/2KR1B1R b - -
+Sicilian: dragon, Yugoslav attack, Rauser variation
+r1bq1rk1/pp2ppbp/2np1np1/8/4P3/1NN1B3/PPP1BPPP/R2Q1RK1 b - -
+Sicilian: dragon, classical, 9.Nb3
+r1bq1rk1/pp2ppbp/5np1/n7/2BP4/2N2N2/PP3PPP/R1BQ1RK1 w - -
+QGD: Tarrasch, R\'eti variation *
+r1bq1rk1/pp3pb1/2n2npp/2ppp3/4P3/2PP1NP1/PP1N1PBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, classical main line *
+r1bq1rk1/pp3pbp/2n2np1/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, classical variation, 8.e4 *
+r1bq1rk1/pp3ppp/2B2n2/2b1N3/3p4/2N5/PPPP1PPP/R1BQK2R w KQ -
+Giuoco Piano: M\"oller (Therkatz) attack *
+r1bq1rk1/pp3ppp/2B2n2/2bpN3/8/2N5/PPPP1PPP/R1BQK2R b KQ -
+Giuoco Piano *
+r1bq1rk1/pp3ppp/2N2n2/1Bbp4/8/2N5/PPPP1PPP/R1BQK2R b KQ -
+Giuoco Piano: Greco variation *
+r1bq1rk1/pp3ppp/2n1pn2/1Bbp4/2P5/4PN2/PP1N1PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, Gligori\'c system, Bronstein variation *
+r1bq1rk1/pp3ppp/2n1pn2/1Bbp4/2P5/4PN2/PP2QPPP/RNB2RK1 b - -
+Nimzo-Indian: 4.e3, Gligori\'c system, Smyslov variation *
+r1bq1rk1/pp3ppp/2n1pn2/1Bbp4/2P5/4PN2/PP3PPP/RNBQ1RK1 w - -
+Nimzo-Indian: 4.e3, Gligori\'c system with 7...dc *
+r1bq1rk1/pp3ppp/2n1pn2/2p5/2BP4/P1P1PN2/5PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, main line
+r1bq1rk1/pp3ppp/2n1pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, main line with 7...Nc6
+r1bq1rk1/pp3ppp/2n1pn2/2pp4/2PP4/P1PBPN2/5PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, main line with 8...Bxc3
+r1bq1rk1/pp3ppp/2n1pn2/8/1bBp4/P1N1PN2/1P3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, main line with 8...dc and 9...cd
+r1bq1rk1/pp3ppp/2n2n2/2bp4/N7/5NP1/PP2PPBP/R1BQ1RK1 b - -
+QGD: Tarrasch, R\'eti variation
+r1bq1rk1/pp3ppp/2nbpn2/1BPp4/8/2N1PN2/PPP2PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, Ragozin variation *
+r1bq1rk1/pp3ppp/2nbpn2/1Bpp4/2PP4/1P2PN2/P4PPP/RNBQ1RK1 b - -
+Nimzo-Indian: 4.e3, Keres variation *
+r1bq1rk1/pp3ppp/2nbpn2/1Bpp4/2PP4/2N1PN2/PP3PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, main line with 7...Nc6 *
+r1bq1rk1/pp3ppp/2nbpn2/1Bpp4/2PP4/4PN2/PP1N1PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, Gligori\'c system with 7...Nbd7 *
+r1bq1rk1/pp3ppp/2nbpn2/2pp2B1/3P4/2P2NP1/PP2PPBP/RN1Q1RK1 b - -
+Gr\"unfeld: Smyslov defense *
+r1bq1rk1/pp3ppp/2nbpn2/2pp4/2PP4/2NBPN2/PP3PPP/R1BQ1RK1 b - -
+QGD: Semi-Tarrasch, symmetrical variation *
+r1bq1rk1/pp3ppp/2nbpn2/2pp4/2PP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+QGD: Semi-Tarrasch, symmetrical variation
+r1bq1rk1/pp3ppp/2nbpn2/2pp4/3P1B2/2P2NP1/PP2PPBP/RN1Q1RK1 b - -
+Gr\"unfeld: Flohr defense *
+r1bq1rk1/pp3ppp/3b4/3P4/1P2n3/4PN2/5PPP/R1BQKB1R w KQ -
+QGD semi-Slav: Meran, Sozin variation *
+r1bq1rk1/pp4bp/2nppnp1/2p5/2P1PPPP/2N5/PP2B3/R1BQK1NR b KQ -
+King's Indian: Six pawns attack
+r1bq1rk1/ppbn1Npp/2p2n2/8/1PBPp3/P1N1B3/2P2PPP/R2Q1RK1 b - -
+Ruy Lopez: open, Dilworth variation *
+r1bq1rk1/ppp1b1pp/2n5/3npp2/8/P1NPPN2/1PQ2PPP/R1B1KB1R b KQ -
+Sicilian: Scheveningen, classical variation with ...Qc7 and ...Nc6 *
+r1bq1rk1/ppp1bppp/2n1pn2/8/3PN3/P5N1/1PP1BPPP/R1BQK2R w KQ -
+French: Winawer, Alekhine gambit, Alatortsev variation
+r1bq1rk1/ppp1bppp/2n5/3np3/8/P2PPN2/1P1N1PPP/R1BQKB1R b KQ -
+Sicilian: Scheveningen, classical, Nd7 system *
+r1bq1rk1/ppp1bppp/2n5/3np3/8/P2PPN2/1PQ2PPP/RNB1KB1R b KQ -
+Sicilian: Scheveningen (Paulsen), classical variation *
+r1bq1rk1/ppp1npbp/3p1np1/3Pp3/1PP1P3/2N2N2/P3BPPP/R1BQ1RK1 b - -
+King's Indian: orthodox, Aronin-Taimanov, bayonet attack
+r1bq1rk1/ppp1npbp/3p1np1/3Pp3/2P1P3/2N5/PP2BPPP/R1BQNRK1 b - -
+King's Indian: orthodox, Aronin-Taimanov, 9.Ne1
+r1bq1rk1/ppp1nppN/3p4/3P4/2B1R3/8/PP3PPP/R2Q2K1 b - -
+Giuoco Piano: Therkatz-Herzog variation
+r1bq1rk1/ppp1nppp/3p1n2/1B2p1B1/1b2P3/2NP1N2/PPP2PPP/R2Q1RK1 w - -
+Four knights: symmetrical, Pillsbury variation
+r1bq1rk1/ppp1nppp/3p1n2/1B2p3/1b1PP3/2N2N2/PPP1QPPP/R1B2RK1 b - -
+Four knights: Alatortsev variation *
+r1bq1rk1/ppp1nppp/3p1n2/1B2p3/1b2P3/2NP1N2/PPP2PPP/R1BQ1RK1 w - -
+Four knights: symmetrical, Mar\'oczy system *
+r1bq1rk1/ppp1p1bp/2np1np1/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+Dutch: Leningrad, main variation with Nc6
+r1bq1rk1/ppp1ppbp/2n2np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Russian, Byrne (Simagin) variation
+r1bq1rk1/ppp1ppbp/2n3p1/8/2BPP3/2P5/P3NPPP/R1BQK2R w KQ -
+Gr\"unfeld: exchange, Simagin's improved variation
+r1bq1rk1/ppp1ppbp/2np1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+King's Indian: fianchetto with ...Nc6
+r1bq1rk1/ppp1ppbp/2np1np1/8/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+King's Indian: S\"amisch, 6...Nc6
+r1bq1rk1/ppp1ppbp/n2p1np1/8/2PPP3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+King's Indian: Kazakh variation
+r1bq1rk1/ppp1ppbp/n4np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Russian, Prins variation
+r1bq1rk1/ppp2pbp/2np1np1/4p3/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, Uhlmann (Szabo) variation
+r1bq1rk1/ppp2pbp/2np1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+King's Indian: orthodox, Aronin-Taimanov variation (Yugoslav attack / Mar del Plata variation)
+r1bq1rk1/ppp2ppp/1b1p1n2/4p3/N3P3/3P1B2/PPP2PPP/R1BQ1RK1 w - -
+Four knights: Rubinstein counter-gambit Mar\'oczy variation
+r1bq1rk1/ppp2ppp/2Bp1n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQ1RK1 b - -
+Four knights *
+r1bq1rk1/ppp2ppp/2n1pn2/8/1bpP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, Ragozin variation
+r1bq1rk1/ppp2ppp/2n2n2/1B1pp3/4P3/2PP1N2/P1P2PPP/R1BQ1RK1 w - -
+Four knights: Svenonius variation
+r1bq1rk1/ppp2ppp/2n2n2/3Pp3/1b6/2NP1N2/PPPB1PPP/R2QKB1R b KQ -
+Ruy Lopez: closed Berlin defense, Wolf variation *
+r1bq1rk1/ppp2ppp/2n2n2/3pp3/1b2P3/2NP1N2/PPPBBPPP/R2QK2R b KQ -
+Ruy Lopez: Berlin defense, hedgehog variation *
+r1bq1rk1/ppp2ppp/2n2n2/3pp3/4P3/2bP1N2/PPPBBPPP/R2QK2R w KQ -
+Ruy Lopez: closed Berlin defense, Showalter variation *
+r1bq1rk1/ppp2ppp/2np1n2/1B2p3/1b2P3/2N2N2/PPPP1PPP/R1BQ1RK1 w - -
+Four knights: double Ruy Lopez *
+r1bq1rk1/ppp2ppp/2np1n2/1B2p3/1b2P3/2NP1N2/PPP2PPP/R1BQ1RK1 b - -
+Four knights: symmetrical variation *
+r1bq1rk1/ppp2ppp/2np1n2/1B2p3/1b2P3/2NP1N2/PPP2PPP/R1BQ1RK1 w - -
+Four knights: symmetrical variation
+r1bq1rk1/ppp2ppp/2np1n2/1B2p3/1b2P3/3P1N2/PPP1NPPP/R1BQ1RK1 b - -
+Four knights: symmetrical, Mar\'oczy system
+r1bq1rk1/ppp2ppp/2np1n2/1B2p3/4P3/2PP1N2/P1P2PPP/R1BQR1K1 b - -
+Four knights: Janowski variation
+r1bq1rk1/ppp2ppp/3p1b2/n3p3/4P3/1B1P1N2/PPP2PPP/R1BQ1RK1 b - -
+Four knights: Rubinstein counter-gambit Mar\'oczy variation *
+r1bq1rk1/ppp3pp/2n2P2/2bp1PB1/8/2p5/PPP2P1P/R2QKBNR w KQ -
+Vienna: Pierce gambit, Rushmere attack *
+r1bq1rk1/ppp3pp/2n5/1B1p1p2/1b2p3/2N2N2/PPPP1PPP/R1BQ1RK1 b - -
+Four knights: Bardeleben variation *
+r1bq1rk1/pppn1pb1/3p3p/3Pp1pn/2P1P2P/2N2NB1/PP2BPP1/R2QK2R b KQ -
+King's Indian: Petrosian system, Keres variation
+r1bq1rk1/pppn1pbp/3p1np1/3Pp3/2P1P3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+King's Indian: Petrosian system, main line
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, classical variation
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+King's Indian: orthodox, 7...Nbd7
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQR1K1 b - -
+King's Indian: orthodox, 7...Nbd7, 8.Re1
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2NP1/PP3PBP/R1BQ1RK1 b - -
+King's Indian: fianchetto, classical variation, 8.e4
+r1bq1rk1/pppn1ppp/1b3n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R w KQ -
+Ruy Lopez: open, Bernstein variation *
+r1bq1rk1/pppnbBpp/3p1n2/4p1N1/3PP3/2N5/PPP2PPP/R1BQK2R b KQ -
+Philidor: Nimzovich, L\"arobok variation
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/1QN1PN2/PP3PPP/R3KB1R b KQ -
+QGD: Orthodox defense, Rauzer variation
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/2RQKB1R b K -
+QGD: Orthodox defense, 7.Rc1
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QGD: Orthodox defense
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PPQ2PPP/R3KB1R b KQ -
+QGD: Orthodox defense, Rubinstein variation
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2NBPN2/PP3PPP/R2QK2R b KQ -
+QGD: Orthodox defense, Botvinnik variation
+r1bq1rk1/pppnbppp/4pn2/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Catalan: closed, 6...Nbd7
+r1bq1rk1/pppnbppp/4pn2/3p4/2PP4/5NP1/PPQ1PPBP/RNB2RK1 b - -
+Catalan: closed, 7.Qc2
+r1bq1rk1/pppnn1bp/3p2p1/3Ppp2/2P1P1P1/2N2P2/PP2B2P/R1BQNRK1 b - -
+King's Indian: orthodox, Aronin-Taimanov, Benk\"o attack
+r1bq1rk1/pppnn1bp/3p2p1/3Ppp2/2P1P3/2N2P2/PP2B1PP/R1BQNRK1 w - -
+King's Indian: orthodox, Aronin-Taimanov, main line
+r1bq1rk1/pppnppbp/3p1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+King's Indian: fianchetto with ...Nd7
+r1bq1rk1/pppnppbp/5np1/6N1/2BP4/1QN1P3/PP3PPP/R1B1K2R b KQ -
+Gr\"unfeld: Pachman variation
+r1bq1rk1/pppp1ppp/1bn2n2/1B2p3/3PP3/2P2N2/PP3PPP/RNBQ1RK1 w - -
+Ruy Lopez: classical defense, Benelux variation
+r1bq1rk1/pppp1ppp/2B2n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQ1RK1 b - -
+Four knights: Nimzovich (Paulsen) variation
+r1bq1rk1/pppp1ppp/2n2n2/1B2P3/1b1P1P2/2N5/PPP3PP/R1BQ1RK1 w - -
+Four knights: Bardeleben variation
+r1bq1rk1/pppp1ppp/2n2n2/1B2p3/1b2P3/2NP1N2/PPP2PPP/R1BQ1RK1 b - -
+Four knights: double Ruy Lopez
+r1bq1rk1/pppp1ppp/2n2n2/1B2p3/4P3/2b2N2/PPPP1PPP/R1BQ1RK1 w - -
+Four knights: Nimzovich (Paulsen) variation *
+r1bq1rk1/pppp1ppp/2n2n2/1B2p3/4P3/2bP1N2/PPP2PPP/R1BQ1RK1 w - -
+Four knights
+r1bq1rk1/pppp1ppp/2n2n2/3Np3/1b2P3/5N2/PPPP1PPP/R1BQKB1R w KQ -
+Four knights: Rubinstein counter-gambit, Henneberger variation *
+r1bq1rk1/pppp1ppp/2n2n2/b3N3/2BPP3/2P5/P4PPP/RNBQ1RK1 b - -
+Evans gambit: Richardson attack
+r1bq1rk1/pppp1ppp/2n2n2/b3N3/4P3/P1N5/1PPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, Knorre variation *
+r1bq1rk1/pppp1ppp/2n5/1B1P4/1b2p3/5N2/PPPP1PPP/R1BQ1RK1 w - -
+Four knights: Gunsberg counter-attack
+r1bq1rk1/pppp1ppp/2n5/3Np3/1bB1n3/5N2/PPPP1PPP/R1BQ1RK1 b - -
+Four knights: Marshall variation *
+r1bq1rk1/pppp1ppp/5n2/1B2P3/1b1p4/2N5/PPPP1PPP/R1BQ1RK1 b - -
+Four knights: Gunsberg counter-attack *
+r1bq1rk1/pppp1ppp/5n2/1Bb1N3/3nP3/2N5/PPPP1PPP/R1BQ1RK1 w - -
+Four knights: Marshall variation
+r1bq1rk1/pppp1ppp/5n2/4n1N1/1bB5/8/PB3PPP/RN1Q1RK1 w - -
+Scotch gambit: Hanneken variation
+r1bq1rk1/pppp2pp/2n2n2/2b1pPP1/8/2N5/PPPP1P1P/R1BQKBNR w KQ -
+Vienna: Hamppe-Muzio gambit *
+r1bq2k1/pp3p1p/5n2/2b1r1p1/3p4/3P1B2/PPP1NPPP/R1BQK2R w KQ -
+Giuoco Piano: M\"oller, bayonet attack *
+r1bq3r/pp3pkp/2n2np1/4p3/2Pp4/3P1NP1/4PPBP/RN1Q1RK1 w - -
+Benk\"o gambit: main line *
+r1bq3r/ppp2k1p/2n3p1/2Qp4/3pP3/8/PPP2PPP/RNB1K2R w KQ -
+Scotch gambit: Cochrane-Shumov defense
+r1bq3r/ppp3pp/5k2/3pN3/1n1Pn3/1Q3P2/PP4PP/RN2K2R b KQ -
+Giuoco Piano: Krause variation
+r1bqk1nr/1ppp1ppp/p1n5/2b1p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Classical defense deferred
+r1bqk1nr/1ppp1ppp/p1n5/4p3/Bb2P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Alapin's defense deferred
+r1bqk1nr/1ppp1ppp/pbn5/4p3/PPB1P3/2N2N2/2PP1PPP/R1BQK2R b KQkq -
+Evans gambit declined, Showalter variation
+r1bqk1nr/2pp1ppp/p1n5/1pb1p3/4P3/1B3N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Graz variation
+r1bqk1nr/5ppp/p1pbp3/2pp4/2P5/2N1PN2/PP1P1PPP/R1BQ1RK1 b kq -
+Nimzo-Indian: S\"amisch, main line *
+r1bqk1nr/5ppp/p1pbp3/2pp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 w kq -
+Nimzo-Indian: 4.e3, Botvinnik system *
+r1bqk1nr/p1pp1ppp/2n5/bp2p3/2BPP3/2P2N2/P4PPP/RNBQK2R w KQkq -
+Evans gambit: Leonhardt variation
+r1bqk1nr/p4ppp/2p5/2bpp3/8/6P1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: exchange, classical variation *
+r1bqk1nr/pp1n1ppp/2pb4/3p4/2PPp3/1P2P3/P2N1PPP/RNBQKB1R b KQkq -
+French: Tarrasch, Botvinnik variation *
+r1bqk1nr/pp1n1ppp/2pb4/3p4/2PPp3/2N1P3/PP1N1PPP/R1BQKB1R b KQkq -
+French: Tarrasch, closed variation *
+r1bqk1nr/pp1nbppp/2pp4/4P3/2B1P3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Philidor: Hanham, Steiner variation
+r1bqk1nr/pp1p1pbp/2n1p1p1/2p2P2/2B1P3/2N2N2/PPPP2PP/R1BQK2R b KQkq -
+Sicilian: Grand Prix attack, Schofman variation
+r1bqk1nr/pp1p1pbp/2n1p1p1/2p5/2P1P3/2N3P1/PP1P1PBP/R1BQK1NR b KQkq -
+English: symmetrical, Botvinnik system reversed *
+r1bqk1nr/pp1p1pbp/2n3p1/1Bp1p3/1P2P3/5N2/P1PP1PPP/RNBQR1K1 b kq -
+Sicilian: Nimzovich-Rossolimo attack, Gurgenidze variation
+r1bqk1nr/pp1p1pbp/2n3p1/2p1p3/2P5/2N1P1P1/PP1P1PBP/R1BQK1NR w KQkq -
+English: symmetrical, Botvinnik system reversed
+r1bqk1nr/pp1p1pbp/2n3p1/2p1p3/2P5/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+English: symmetrical, Botvinnik system reversed
+r1bqk1nr/pp1p1pbp/2n3p1/2p1p3/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: symmetrical, Botvinnik system *
+r1bqk1nr/pp1p1pbp/4p1p1/2p5/3nP3/3PB1P1/PPP1NPBP/R2QK1NR b KQkq -
+Sicilian: closed, Smyslov variation
+r1bqk1nr/pp1p1ppp/2n5/2b5/2pNp3/3PP3/PPP2PPP/RNBQKB1R b KQkq -
+Alekhine's defense: two pawns' attack, Mikenas variation *
+r1bqk1nr/pp1pppbp/2N3p1/8/8/6P1/PPP1PP1P/RNBQKB1R b KQkq -
+English: Anglo-Gr\"unfeld, Smyslov defense *
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P1P3/2N3P1/PP1P1PBP/R1BQK1NR b KQkq -
+English: symmetrical, Botvinnik system
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+English: symmetrical variation
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR b KQkq -
+English: ultra-symmetrical variation *
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: ultra-symmetrical variation
+r1bqk1nr/pp1pppbp/2n3p1/2p5/4P3/2N3P1/PPPP1PBP/R1BQK1NR b KQkq -
+English: closed system *
+r1bqk1nr/pp1pppbp/2n3p1/2p5/4P3/2NPB3/PPP2PPP/R2QKBNR b KQkq -
+English, Tr\"oger defense *
+r1bqk1nr/pp1pppbp/2n3p1/8/2P5/8/PPN1PPPP/RNBQKB1R b KQkq -
+English: symmetrical, Rubinstein system *
+r1bqk1nr/pp1pppbp/2n3p1/8/2PNP3/4B3/PP3PPP/RN1QKB1R b KQkq -
+Sicilian: accelerated fianchetto, Mar\'oczy bind, 6.Be3
+r1bqk1nr/pp1pppbp/2n3p1/8/2PNP3/8/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: accelerated fianchetto, Mar\'oczy bind, 5...Bg7
+r1bqk1nr/pp1pppbp/2n3p1/8/8/1N4P1/PPP1PP1P/RNBQKB1R b KQkq -
+English: Anglo-Gr\"unfeld, Czech defense *
+r1bqk1nr/pp2b1pp/2n5/2pppp2/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+King's Indian: Four pawns attack, 6.Be2 *
+r1bqk1nr/pp2b3/2n5/2p1pppp/2P5/2NPPNP1/PP4BP/R1BQ1RK1 w kq -
+King's Indian: Six pawns attack *
+r1bqk1nr/pp2bppp/2n5/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: 5.Be2 *
+r1bqk1nr/pp2ppbp/2n3p1/2pp4/5P2/2PP1N2/PPQ1P1PP/RNB1KB1R b KQkq -
+Dutch: Hort-Antoshin system *
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2N3P1/PPPP1PBP/R1BQK1NR w KQkq -
+English: closed system (without ...d6) *
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NP2P1/PPP2PBP/R1BQK1NR b KQkq -
+English: closed system *
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NP2P1/PPP2PBP/R1BQK1NR w KQkq -
+Sicilian: closed
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NPB1P1/PPP2PBP/R2QK1NR b KQkq -
+Sicilian: closed, 6.Be3
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4PP2/2NP2P1/PPP3BP/R1BQK1NR b KQkq -
+Sicilian: closed, 6.f4
+r1bqk1nr/pp3pbp/2np2p1/2p1p3/4P3/2NP2P1/PPP1NPBP/R1BQK2R w KQkq -
+Sicilian: closed, 6.Ne2 e5 (Botvinnik)
+r1bqk1nr/pp3pbp/2np2p1/2p1p3/4P3/2NP2P1/PPP2PBP/R1BQK1NR w KQkq -
+English: Botvinnik system *
+r1bqk1nr/pp3pbp/2np2p1/2p1p3/4PP2/2NP2P1/PPP3BP/R1BQK1NR w KQkq -
+Sicilian: closed, 6.f4 e5 (Botvinnik)
+r1bqk1nr/pp3ppp/2nbp3/1Bpp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: 4.e3 O-O, 5.Bd3 d5 *
+r1bqk1nr/pp3ppp/2nbp3/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+Nimzo-Indian: 4.e3 O-O, 5.Bd3 *
+r1bqk1nr/pp3ppp/2nbp3/2pp4/4P3/3P1N2/PPPN1PPP/R1BQKB1R w KQkq -
+Old Indian: Dus-Khotimirsky variation *
+r1bqk1nr/pp3ppp/8/1Pb1p3/1nPp4/3P1N2/4PPPP/RNBQKB1R w KQkq -
+Benk\"o gambit: Nescaf\'e Frapp\'e attack *
+r1bqk1nr/pp4pp/2n5/4pp2/1bPp4/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+Benoni: Taimanov variation *
+r1bqk1nr/ppp1bp1p/2n5/3pp1p1/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+Pirc: Chinese variation *
+r1bqk1nr/ppp1bpp1/2n5/3pp2p/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+Pirc: bayonet (Mariotti) attack *
+r1bqk1nr/ppp1bppp/2n5/3pp3/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Pirc defense *
+r1bqk1nr/ppp1ppbp/2np2p1/8/2PPP3/2N5/PP3PPP/R1BQKBNR w KQkq -
+Modern defense: Averbakh system, Kotov variation
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P1P3/2NP2P1/PP3PBP/R1BQK1NR b KQkq -
+English: Botvinnik system
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR b KQkq -
+Sicilian: closed *
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR w KQkq -
+English: closed system
+r1bqk1nr/ppp2ppp/1b1p4/n2P4/2B1P3/5N2/PB3PPP/RN1Q1RK1 b kq -
+Evans gambit: Ulvestad variation
+r1bqk1nr/ppp2ppp/1b1p4/n5B1/2BPP3/2N2N2/P4PPP/R2Q1RK1 b kq -
+Evans gambit: G\"oring attack
+r1bqk1nr/ppp2ppp/1bnp4/4p3/2BPP3/2P2N2/P4PPP/RNBQ1RK1 w kq -
+Evans gambit: Lasker defense
+r1bqk1nr/ppp2ppp/1bnp4/8/2BPP3/2N2N2/P4PPP/R1BQ1RK1 b kq -
+Evans gambit: Morphy attack
+r1bqk1nr/ppp2ppp/1bnp4/8/2BPP3/5N2/P4PPP/RNBQ1RK1 w kq -
+Evans gambit: normal variation
+r1bqk1nr/ppp2ppp/1bnp4/8/2BPP3/5N2/PP3PPP/RNBQK2R w KQkq -
+Giuoco Piano: LaBourdonnais variation
+r1bqk1nr/ppp2ppp/2n1p3/8/3Pp3/P1N5/1PP2PPP/R1BQKB1R w KQkq -
+French: Winawer, Alekhine gambit, Kan variation
+r1bqk1nr/ppp2ppp/2n5/2bpp3/1PB1P3/5N2/P1PP1PPP/RNBQK2R w KQkq -
+Evans counter-gambit
+r1bqk1nr/ppp2ppp/2n5/2bpp3/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Pirc: Holmov system *
+r1bqk1nr/ppp2ppp/2nb4/3pp3/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+French: Swiss variation *
+r1bqk1nr/ppp2ppp/2np4/b3p1B1/2BPP3/2P2N2/P4PPP/RN1QK2R b KQkq -
+Evans gambit: Sokolsky variation
+r1bqk1nr/ppp2ppp/2np4/b3p3/2B1P3/2P2N2/P2P1PPP/RNBQ1RK1 w kq -
+Evans gambit
+r1bqk1nr/ppp2ppp/2np4/b3p3/2BPP3/1QP2N2/P4PPP/RNB1K2R b KQkq -
+Evans gambit: Tartakower attack
+r1bqk1nr/ppp2ppp/2np4/b3p3/2BPP3/2P2N2/P4PPP/RNBQK2R w KQkq -
+Evans gambit
+r1bqk1nr/ppp2ppp/2np4/b7/2BpP3/1QP2N2/P4PPP/RNB2RK1 b kq -
+Evans gambit: Waller attack
+r1bqk1nr/ppp2ppp/3b4/3pn3/8/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+Caro-Kann: Alekhine gambit *
+r1bqk1nr/ppp2ppp/8/2bp4/8/2P2P2/PP3PPP/RNBQKB1R w KQkq -
+Caro-Kann: Forg\'acs variation *
+r1bqk1nr/ppp3bp/2np2p1/4pp2/2P1P3/2NP2P1/PP3PBP/R1BQK1NR b KQkq -
+Sicilian: closed, 6.f4 e5 (Botvinnik) *
+r1bqk1nr/ppp3bp/2np2p1/4pp2/2P5/2NP2P1/PP2PPBP/R1BQK1NR w KQkq -
+Sicilian: closed, 6.f4 *
+r1bqk1nr/ppp3pp/1b1p1p2/n7/2BPP3/2N1BN2/P4PPP/R2Q1RK1 b kq -
+Evans gambit: Steinitz variation
+r1bqk1nr/ppp3pp/2n5/2bppp2/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+Pirc: Austrian attack, Ljubojevi\'c variation *
+r1bqk1nr/pppn1ppp/3p4/2b1p3/4PP2/2N2N2/PPPP2PP/R1BQKB1R w KQkq -
+KGD: classical, Hanham variation
+r1bqk1nr/pppp1Bpp/2n5/2b1p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Giuoco Piano: Jerome gambit
+r1bqk1nr/pppp1pbp/2n3p1/4p3/2P5/2N3P1/PP1PPPBP/1RBQK1NR b Kkq -
+English: closed, 5.Rb1
+r1bqk1nr/pppp1pbp/2n3p1/4p3/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: closed system
+r1bqk1nr/pppp1pbp/2n3p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR b KQkq -
+English: closed system (without ...d6)
+r1bqk1nr/pppp1ppp/1bn5/1B2p3/4P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Ruy Lopez: classical defense, Charousek variation
+r1bqk1nr/pppp1ppp/1bn5/4p3/1PB1P3/5N2/PBPP1PPP/RN1QK2R b KQkq -
+Evans gambit declined, Cordel variation
+r1bqk1nr/pppp1ppp/1bn5/4p3/PPB1P3/5N2/2PP1PPP/RNBQK2R b KQkq -
+Evans gambit declined, 5.a4
+r1bqk1nr/pppp1ppp/2n5/1B2p3/1b2P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Alapin's defense
+r1bqk1nr/pppp1ppp/2n5/1Bb1p3/4P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+Ruy Lopez: classical defense, 4.c3
+r1bqk1nr/pppp1ppp/2n5/1Bb1p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: classical (Cordel) defense
+r1bqk1nr/pppp1ppp/2n5/2b1N3/4P3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Vienna game *
+r1bqk1nr/pppp1ppp/2n5/2b1p3/1PB1P3/5N2/P1PP1PPP/RNBQK2R b KQkq -
+Evans gambit declined
+r1bqk1nr/pppp1ppp/2n5/2b1p3/2B1P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+Giuoco Piano
+r1bqk1nr/pppp1ppp/2n5/2b1p3/2B1P3/3P1N2/PPP2PPP/RNBQK2R b KQkq -
+Giuoco Pianissimo
+r1bqk1nr/pppp1ppp/2n5/2b1p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Giuoco Piano
+r1bqk1nr/pppp1ppp/2n5/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Vienna game *
+r1bqk1nr/pppp1ppp/2n5/2b1p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Vienna game *
+r1bqk1nr/pppp1ppp/2n5/2b3N1/2BpP3/8/PPP2PPP/RNBQK2R b KQkq -
+Scotch gambit
+r1bqk1nr/pppp1ppp/2n5/2b5/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Scotch game
+r1bqk1nr/pppp1ppp/2n5/2b5/4P3/1N6/PPP2PPP/RNBQKB1R b KQkq -
+Scotch: Potter variation
+r1bqk1nr/pppp1ppp/2n5/4p3/1bB1P3/5N2/P1PP1PPP/RNBQK2R w KQkq -
+Evans gambit
+r1bqk1nr/pppp1ppp/2n5/8/1b2P3/1N6/PPP2PPP/RNBQKB1R w KQkq -
+Scotch: Romanishin variation
+r1bqk1nr/pppp1ppp/2n5/8/1b2P3/2N2N2/PP3PPP/R1BQKB1R w KQkq -
+Scotch: G\"oring gambit
+r1bqk1nr/pppp1ppp/2n5/8/1bB1P3/2P2N2/P4PPP/RNBQK2R b KQkq -
+Scotch gambit
+r1bqk1nr/pppp1ppp/2n5/8/1bBpP3/5N2/PPP2PPP/RNBQK2R w KQkq -
+Scotch gambit
+r1bqk1nr/pppp1ppp/2n5/b3P3/2B5/2P2N2/P4PPP/RNBQK2R b KQkq -
+Scotch gambit: Cochrane variation
+r1bqk1nr/pppp1ppp/2n5/b3p3/2B1P3/2P2N2/P2P1PPP/RNBQ1RK1 b kq -
+Evans gambit
+r1bqk1nr/pppp1ppp/2n5/b3p3/2B1P3/2P2N2/P2P1PPP/RNBQK2R w KQkq -
+Evans gambit
+r1bqk1nr/pppp1ppp/2n5/b7/2B1P3/2p2N2/P4PPP/RNBQ1RK1 w kq -
+Evans gambit: compromised defense
+r1bqk1nr/pppp1ppp/2nb4/4p3/2B1P3/2P2N2/P2P1PPP/RNBQK2R w KQkq -
+Evans gambit: Stone-Ware variation
+r1bqk1nr/pppp1ppp/8/1Bb1p3/1P1nP3/5N2/P1PP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: classical defense, Zaitsev variation
+r1bqk1nr/pppp2pp/2n5/1Bb1pp2/4P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Cordel gambit
+r1bqk1nr/pppp2pp/2n5/1Bb2P2/4p3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+KGA: bishop's gambit, Paulsen attack *
+r1bqk1nr/pppp2pp/2n5/2b1p1N1/2B1Pp2/3P4/PPP2PPP/RNBQK2R w KQkq -
+Giuoco Pianissimo: Dubois variation
+r1bqk1nr/pppp2pp/2n5/2b1pP2/8/2P2N2/PP1P1PPP/RNBQKB1R b KQkq -
+KGA: bishop's gambit, Jaenisch variation *
+r1bqk1nr/pppp2pp/2n5/2b1pP2/8/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+KGA: bishop's gambit, Bogolyubov variation *
+r1bqk1nr/ppppbppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Lucena defense
+r1bqk1nr/ppppbppp/2n5/4p3/2B1P3/2P2N2/P2P1PPP/RNBQK2R w KQkq -
+Evans gambit: 5...Be7
+r1bqk1nr/ppppbppp/2n5/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Hungarian defense
+r1bqk1nr/ppppbppp/2n5/4p3/4P3/2P2N2/PP1P1PPP/RNBQKB1R w KQkq -
+Ponziani: Romanishin variation
+r1bqk1nr/ppppbppp/2n5/8/2BpP3/5N2/PPP2PPP/RNBQK2R w KQkq -
+Scotch gambit: Benima defense
+r1bqk1nr/ppppbppp/2n5/8/4P3/2P1Q3/PP3PPP/RNB1KBNR w KQkq -
+Center game: Charousek variation
+r1bqk1nr/ppppbppp/8/n3p3/2BPP3/2P2N2/P4PPP/RNBQK2R w KQkq -
+Evans gambit: Cordel variation
+r1bqk2r/1p1p1ppp/p1n1pn2/8/1bPNP3/2N5/PPB2PPP/R1BQK2R b KQkq -
+Sicilian: Kan, Mar\'oczy bind - Bronstein variation
+r1bqk2r/1pp1bppp/p1np1n2/4p3/B3P3/5N2/PPPP1PPP/RNBQR1K1 w kq -
+Ruy Lopez: closed, Averbach variation
+r1bqk2r/1pp1bppp/p5n1/3pn3/8/2N1PN2/PPP1BPPP/R1BQ1RK1 b kq -
+French: Winawer, Alekhine gambit, Alatortsev variation *
+r1bqk2r/1ppn1p1p/p4b1Q/1B6/8/2N2N2/PP1P1PPP/n1BK3R w kq -
+Scotch: Berger variation *
+r1bqk2r/1ppp1ppp/p1n2n2/2b1p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: M\"oller defense
+r1bqk2r/1pppbppp/p1B2n2/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: Exchange variation doubly deferred (DERLD)
+r1bqk2r/1pppbppp/p1n2n2/4p3/B2PP3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: closed, center attack
+r1bqk2r/1pppbppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: closed defense
+r1bqk2r/1pppbppp/p1n2n2/4p3/B3P3/5N2/PPPPQPPP/RNB2RK1 b kq -
+Ruy Lopez: Worrall attack
+r1bqk2r/1pppbppp/p1n5/4P3/B2pn3/2P2N2/PP3PPP/RNBQ1RK1 b kq -
+Ruy Lopez: closed, Basque gambit (North Spanish variation)
+r1bqk2r/2p1bppp/p1np1n2/1p2p3/3PP3/1B3N2/PPP2PPP/RNBQR1K1 b kq -
+Ruy Lopez: closed, 7...d6, 8.d4
+r1bqk2r/2p1bppp/p1np1n2/1p2p3/4P3/1B3N2/PPPPQPPP/RNB2RK1 w kq -
+Ruy Lopez: Worrall attack, solid line
+r1bqk2r/2pp1ppp/2n2n2/ppb1p3/4P3/PBN5/1PPP1PPP/R1BQK1NR w KQkq -
+Evans gambit declined, Showalter variation *
+r1bqk2r/2ppbppp/p1n2n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQR1K1 b kq -
+Ruy Lopez: closed
+r1bqk2r/2ppbppp/p1n2n2/1p2p3/P3P3/1B3N2/1PPP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: Wing attack
+r1bqk2r/4bppp/p2p1n2/1pp5/3QP3/1B6/PPP2PPP/RNB1R1K1 w kq -
+Ruy Lopez: Noah's ark trap
+r1bqk2r/4nppp/p1pb4/2ppp3/2P5/1PN1P3/P2P1PPP/R1BQNRK1 b kq -
+Nimzo-Indian: S\"amisch, Capablanca variation *
+r1bqk2r/5ppp/p1n1pn2/1pb1P3/2B5/5N2/PP2QPPP/RNB2RK1 b kq -
+QGA: classical, Furman variation
+r1bqk2r/p1ppbppp/2p5/4Pn2/8/5N2/PPP1QPPP/RNB2RK1 w kq -
+Ruy Lopez: Berlin defense, Cordel variation
+r1bqk2r/p3nppp/2p5/2bpp3/2P5/6P1/PP2PPBP/RNBQ1RK1 b kq -
+Gr\"unfeld: exchange, Spassky variation *
+r1bqk2r/p3nppp/2p5/2bpp3/8/1P4P1/P1P1PPBP/RNBQ1RK1 b kq -
+Gr\"unfeld: exchange, Simagin's lesser variation *
+r1bqk2r/p3nppp/2p5/2bpp3/8/2N3P1/PPP1PPBP/R1BQ1RK1 b kq -
+Gr\"unfeld: exchange, Simagin's improved variation *
+r1bqk2r/p4ppp/2pbpn2/2pp4/2P5/2NPPN2/PP3PPP/R1BQK2R b KQkq -
+Nimzo-Indian: e3, H\"ubner variation *
+r1bqk2r/pnppbppp/2p5/4P3/2P5/5N2/PP2QPPP/RNB2RK1 b kq -
+Ruy Lopez: Berlin defense, Zukertort variation
+r1bqk2r/pnppbppp/2p5/4P3/3N4/8/PPP1QPPP/RNB2RK1 b kq -
+Ruy Lopez: Berlin defense, Winawer attack
+r1bqk2r/pnppbppp/2p5/4P3/8/1P3N2/P1P1QPPP/RNB2RK1 b kq -
+Ruy Lopez: Berlin defense, Pillsbury variation
+r1bqk2r/pp1n1ppp/2p1pn2/3p4/1bPP4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Romih variation
+r1bqk2r/pp1n1ppp/2pbpn2/3p4/2PP4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Chigorin defense
+r1bqk2r/pp1n1ppp/3bpn2/2pp4/2PP4/4PN2/PP1N1PPP/R1BQKB1R b KQkq -
+QGD Slav: Semmering variation *
+r1bqk2r/pp1n1ppp/3bpn2/2ppN3/3P1P2/2P1P3/PP4PP/RNBQKB1R b KQkq -
+QGD: Stonewall variation *
+r1bqk2r/pp1nbppp/2p1pn2/3p4/2PP4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Bogolyubov variation
+r1bqk2r/pp1nnppp/3b4/3p4/3Pp3/1NN1P3/PP3PPP/R1BQKB1R b KQkq -
+French: Tarrasch, Leningrad variation *
+r1bqk2r/pp1nnppp/3b4/3p4/3Pp3/2N1P3/PP1N1PPP/R1BQKB1R w KQkq -
+French: Tarrasch, closed variation, main line *
+r1bqk2r/pp1p1ppp/2n1p3/2P5/1bP5/1QN2N2/PP1nPPPP/R3KB1R w KQkq -
+Nimzo-Indian: Spielmann, Karlsbad variation
+r1bqk2r/pp1p1ppp/2n1p3/2n5/1bP5/1QN2N2/PP1BPPPP/R3KB1R w KQkq -
+Nimzo-Indian: Spielmann, San Remo variation
+r1bqk2r/pp1p1ppp/2n1pn2/2P5/1bP5/1QN5/PP2PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: Spielmann, 4...c5, 5.dc Nc6
+r1bqk2r/pp1p1ppp/2nNpn2/8/1b2P3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Sicilian: Taimanov, American attack
+r1bqk2r/pp1p1ppp/2nb1n2/2p1p3/8/1P2PN2/PBPP1PPP/RN1QKB1R w KQkq -
+English: Queens Indian, Romanishin variation *
+r1bqk2r/pp1p2pp/2n1p3/2n2p2/1bP5/2N2NP1/PPQBPP1P/R3KB1R b KQkq -
+Nimzo-Indian: Spielmann, St\aa hlberg variation
+r1bqk2r/pp1pnpbp/2n1p1p1/2p5/4P3/2NP2PN/PPP2PBP/R1BQK2R b KQkq -
+English: closed, Taimanov variation *
+r1bqk2r/pp1pnpbp/2n1p1p1/2p5/4P3/2NPB1P1/PPP2PBP/R2QK1NR b KQkq -
+English: closed, Hort variation *
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P1P3/2N3P1/PP1P1PBP/R1BQK1NR b KQkq -
+English: symmetrical, Botvinnik system reversed *
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+English: symmetrical variation *
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+English: symmetrical variation
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: symmetrical variation *
+r1bqk2r/pp1pppbp/2n2np1/8/2BNP3/2N1B3/PPP2PPP/R2QK2R b KQkq -
+Sicilian: accelerated fianchetto, modern variation with Bc4
+r1bqk2r/pp1pppbp/2n2np1/8/3NP3/6P1/PPP2PBP/RNBQK2R b KQkq -
+English: Anglo-Gr\"unfeld defense, Korchnoi variation *
+r1bqk2r/pp1pppbp/2n3p1/8/2PNP1n1/2N1B3/PP3PPP/R2QKB1R w KQkq -
+Sicilian: accelerated fianchetto, Breyer variation
+r1bqk2r/pp2b1pp/2n2n2/2p1pp2/2Pp4/3PPNP1/PP3PBP/RNBQ1RK1 w kq -
+King's Indian: Four pawns attack *
+r1bqk2r/pp2b1pp/2n2n2/2p2p2/2PPp3/3P1NP1/PP3PBP/RNBQ1RK1 w kq -
+King's Indian: Four pawns attack, Florentine gambit *
+r1bqk2r/pp2b1pp/2n2n2/2pppp2/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 w kq -
+King's Indian: Four pawns attack, with Be2 and Nf3 *
+r1bqk2r/pp2b1pp/2n2n2/4pp2/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 b kq -
+Benoni: four pawns attack, main line *
+r1bqk2r/pp2bppp/2n1p3/2pn4/8/2N2NP1/PP1PPPBP/R1BQ1RK1 w kq -
+English: Symmetrical, Keres defense
+r1bqk2r/pp2bppp/2n2n2/2p1p3/3pP3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+King's Indian: Petrosian system *
+r1bqk2r/pp2bppp/2n2n2/2p1p3/3pP3/3P1NP1/PPPN1PBP/R1BQ1RK1 b kq -
+King's Indian: Petrosian system, main line *
+r1bqk2r/pp2bppp/2n2n2/2p1p3/4p3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+King's Indian: Andersson variation *
+r1bqk2r/pp2bppp/2n2n2/2p1p3/P2pP3/3P1NP1/1PP2PBP/RNBQ1RK1 b kq -
+King's Indian: Petrosian system, Stein variation *
+r1bqk2r/pp2bppp/2n2n2/2pp4/3P4/2N2NP1/PP2PPBP/R1BQK2R w KQkq -
+QGD: Tarrasch, Prague variation, 7...Be7
+r1bqk2r/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 b kq -
+King's Indian: classical variation *
+r1bqk2r/pp2bppp/2n2n2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+King's Indian: 6.Be2 *
+r1bqk2r/pp2bppp/2n2n2/2ppp3/8/N2P1NP1/PPP1PPBP/R1BQ1RK1 b kq -
+King's Indian: Kazakh variation *
+r1bqk2r/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+Benoni: classical without 9.O-O *
+r1bqk2r/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+Benoni: classical without 9.O-O *
+r1bqk2r/pp2bppp/2nppn2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R w KQkq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7
+r1bqk2r/pp2bppp/2nppn2/8/2BNP3/2N1B3/PPP1QPPP/R3K2R b KQkq -
+Sicilian: Velimirovi\'c attack
+r1bqk2r/pp2bppp/2nppn2/8/3NPP2/2N1BQ2/PPP3PP/R3KB1R b KQkq -
+Sicilian: Scheveningen, Tal variation
+r1bqk2r/pp2npbp/2n3p1/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+King's Indian: Pomar system *
+r1bqk2r/pp2ppbp/2n2np1/2pp4/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+King's Indian: fianchetto, Yugoslav system *
+r1bqk2r/pp2ppbp/2n2np1/2pp4/8/1P2PN2/PBPPBPPP/RN1QK2R w KQkq -
+Queen's Indian: anti-Queen's Indian system *
+r1bqk2r/pp2ppbp/2n2np1/2pp4/8/2NP1NP1/PPP1PPBP/R1BQ1RK1 b kq -
+King's Indian: fianchetto with ...Nc6 *
+r1bqk2r/pp2ppbp/2n2np1/2pp4/8/3P1NP1/PPPNPPBP/R1BQ1RK1 b kq -
+King's Indian: fianchetto with ...Nd7 *
+r1bqk2r/pp2ppbp/2n2np1/3p2B1/2PP4/2N2N2/PP3PPP/R2QKB1R b KQkq -
+QGD: Tarrasch, Wagner variation *
+r1bqk2r/pp2ppbp/2n2np1/3p4/2PP4/2N2N2/PP2BPPP/R1BQK2R b KQkq -
+QGD: Tarrasch, Prague variation, 7...Be7 *
+r1bqk2r/pp2ppbp/2n2np1/8/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+Benoni: fianchetto variation *
+r1bqk2r/pp2ppbp/2np1np1/8/3NP3/2N1B3/PPP1BPPP/R2Q1RK1 b kq -
+Sicilian: dragon, classical, 8.O-O
+r1bqk2r/pp2ppbp/2np1np1/8/3NP3/2N1B3/PPPQBPPP/R3K2R b KQkq -
+Sicilian: dragon, classical, Amsterdam variation
+r1bqk2r/pp2ppbp/2np1np1/8/4P3/1NN1B3/PPP1BPPP/R2QK2R b KQkq -
+Sicilian: dragon, classical, Nottingham variation
+r1bqk2r/pp2ppbp/2np2pn/8/2P1P3/8/PPN1BPPP/RNBQK2R w KQkq -
+Sicilian: accelerated fianchetto, Simagin variation
+r1bqk2r/pp3ppp/2n1pn2/2bp4/1P6/2P1PN2/P2N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Meran variation *
+r1bqk2r/pp3ppp/2n1pn2/2bp4/8/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: 7.Bc4 *
+r1bqk2r/pp3ppp/2n2n2/1Bb1p3/8/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Scotch: G\"oring gambit, Bardeleben variation *
+r1bqk2r/pp3ppp/2n2n2/1Bbpp3/8/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Giuoco Piano: Greco's attack *
+r1bqk2r/pp3ppp/2nb1n2/1P1pp3/8/P1P1PN2/3N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Meran, Pir\'c variation *
+r1bqk2r/pp3ppp/2nb1n2/3p4/1PP1p3/P3PN2/3N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: Meran, old main line *
+r1bqk2r/pp3ppp/2nb1n2/3pp3/1PP5/P3PN2/3N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Meran *
+r1bqk2r/pp3ppp/2nb1n2/4p3/1PPp4/P3PN2/3N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: Meran, Reynolds' variation *
+r1bqk2r/pp3ppp/2nbpn2/1Bpp4/2PP4/4PN2/PP3PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: 4.e3, main line with ...c5 *
+r1bqk2r/pp3ppp/2nbpn2/1Bpp4/3P4/1P2PN2/P1P2PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: 4.e3, main line with ...b6 *
+r1bqk2r/pp3ppp/2nbpn2/1Bpp4/3P4/2P1PN2/PP1N1PPP/R1BQK2R b KQkq -
+QGD semi-Slav: Romih variation *
+r1bqk2r/pp3ppp/2nbpn2/1P1p4/8/2P1PN2/P2N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: neo-Meran (Lundin variation) *
+r1bqk2r/pp3ppp/2nbpn2/2pp4/3P4/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: 6.Bd3 *
+r1bqk2r/pp3ppp/2nbpn2/2pp4/3P4/2P1PN2/PP1NBPPP/R1BQK2R b KQkq -
+QGD semi-Slav: Bogolyubov variation *
+r1bqk2r/pp3ppp/2nbpn2/2pp4/3P4/2PBPN2/PP1N1PPP/R1BQK2R b KQkq -
+QGD semi-Slav: Chigorin defense *
+r1bqk2r/pp3ppp/2nbpn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Gr\"unfeld with e3 & Bd3 *
+r1bqk2r/pp3ppp/2nbpn2/2ppN3/3P1P2/2P1P3/PP4PP/RNBQKB1R b KQkq -
+QGD semi-Slav: stonewall defense *
+r1bqk2r/pp3ppp/2nbpn2/3p4/1P6/2P1PN2/PB1N1PPP/R2QKB1R b KQkq -
+QGD semi-Slav: Meran, Wade variation *
+r1bqk2r/pp3ppp/2nbpn2/3p4/1P6/P1P1PN2/3N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Meran, 8...a6 *
+r1bqk2r/pp3ppp/2nbpn2/3p4/2PN4/2N1P3/PP3PPP/R1BQKB1R w KQkq -
+QGD: Semi-Tarrasch, 7.Bd3 *
+r1bqk2r/pp3ppp/2nppn2/2p5/2PP4/2PBPN2/P4PPP/R1BQK2R w KQkq -
+Nimzo-Indian: e3, H\"ubner variation
+r1bqk2r/pp3ppp/3b1n2/3P2N1/1n2p3/P3P3/3N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Meran, Rabinovich variation *
+r1bqk2r/pp3ppp/3b1n2/3P4/1n2N3/P3PN2/5PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Meran, Sozin variation *
+r1bqk2r/pp3ppp/3b1n2/3P4/1n2p3/P3PN2/3N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: Meran, Blumenfeld variation *
+r1bqk2r/ppb2ppp/2n5/1Bpnp3/8/P1N1PN2/1P1P1PPP/R1BQK2R w KQkq -
+Sicilian: Kan, Mar\'oczy bind - Bronstein variation *
+r1bqk2r/ppp1bpp1/5n1p/3P4/2P1p3/5N2/PPP1QPPP/RNB1K2R w KQkq -
+two knights defense: Mar\'oczy variation
+r1bqk2r/ppp1bppp/1nn5/4p3/4P3/2NP1N2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Boleslavsky variation, 7.Nb3 *
+r1bqk2r/ppp1bppp/2n2n2/3pp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+Pirc: classical system, 5.Be2 *
+r1bqk2r/ppp1bppp/2n5/1B1pp3/3Pn3/5N2/PPP1QPPP/RNB2RK1 w kq -
+Ruy Lopez: Berlin defense, Trifunovi\'c variation
+r1bqk2r/ppp1bppp/2n5/3np3/4P3/2NP1N2/PP3PPP/R1BQKB1R b KQkq -
+Sicilian: Boleslavsky variation *
+r1bqk2r/ppp1bppp/2n5/3np3/8/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+Sicilian: classical *
+r1bqk2r/ppp1bppp/2n5/3np3/8/2NPPN2/PP3PPP/R1BQKB1R b KQkq -
+Sicilian: modern Scheveningen *
+r1bqk2r/ppp1bppp/2n5/3np3/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Scheveningen, 6.Be2 *
+r1bqk2r/ppp1bppp/2n5/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, Opo\v censky variation *
+r1bqk2r/ppp1bppp/2n5/3np3/8/P2PPN2/1P3PPP/RNBQKB1R b KQkq -
+Sicilian: Scheveningen (Paulsen), classical variation *
+r1bqk2r/ppp1bppp/2n5/3p4/2PPn3/3B1N2/PP3PPP/RNBQ1RK1 b kq -
+Petrov: classical attack, Jaenisch variation
+r1bqk2r/ppp1bppp/2n5/3p4/3Pn3/3B1N2/PPP2PPP/RNBQR1K1 b kq -
+Petrov: classical attack, Chigorin variation
+r1bqk2r/ppp1bppp/2n5/4p3/4P3/2nP1N2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Boleslavsky, Louma variation *
+r1bqk2r/ppp1npbp/2np2p1/4p3/2P1P3/2NP2P1/PP3PBP/R1BQK1NR b KQkq -
+Sicilian: closed, 6.Ne2 e5 (Botvinnik) *
+r1bqk2r/ppp1nppp/1b1p4/n2P4/2B1P3/5N2/PB3PPP/RN1Q1RK1 w kq -
+Evans gambit: Paulsen variation
+r1bqk2r/ppp1nppp/3p1b2/3P4/2B1R1P1/5N2/PP3P1P/R1BQ2K1 b kq -
+Giuoco Piano: M\"oller, bayonet attack
+r1bqk2r/ppp2pbp/2np2pn/4p3/2P5/2N1P1P1/PP1PNPBP/R1BQK2R w KQkq -
+English: closed, Taimanov variation
+r1bqk2r/ppp2pp1/5n1p/2bP4/2P1p3/8/PPPNQPPP/RNB1K2R b KQkq -
+two knights defense: Yankovich variation
+r1bqk2r/ppp2ppp/1bn5/3np3/1P6/P2PPN2/5PPP/RNBQKB1R b KQkq -
+Sicilian: Sozin with ...a6 and ...b5 *
+r1bqk2r/ppp2ppp/2n1pn2/3p4/2PP4/P1Q5/1P2PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, Botvinnik variation
+r1bqk2r/ppp2ppp/2n2n2/2bpP3/2Bp4/2P2N2/PP3PPP/RNBQK2R w KQkq d6
+Giuoco Piano
+r1bqk2r/ppp2ppp/2n2n2/2bpp3/4P3/2PP4/PP1N1PPP/R1BQKBNR w KQkq -
+Philidor: Hanham, Schlechter variation *
+r1bqk2r/ppp2ppp/2n2n2/3pp3/4P3/2bP1N2/PPPB1PPP/R2QKB1R w KQkq -
+Ruy Lopez: old Steinitz defense, Nimzovich attack *
+r1bqk2r/ppp2ppp/2n5/1B1pP3/1b1Pn3/5N2/PP3PPP/RNBQK2R w KQkq -
+Giuoco Piano: Anderssen variation
+r1bqk2r/ppp2ppp/2n5/2b5/4p3/2PP1NP1/P3PP1P/R1BQKB1R w KQkq -
+Sicilian: Magnus Smith trap *
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/1QNP1N2/PP2PPPP/R1B1KB1R b KQkq -
+Sicilian: Sozin, Benk\"o variation *
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+Sicilian: Sozin, not Scheveningen *
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/2NPPN2/PP3PPP/R1BQKB1R b KQkq -
+Sicilian: Sozin, Leonhardt variation *
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Sozin attack *
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, Lipnitzky attack *
+r1bqk2r/ppp2ppp/2n5/3np1N1/1bBP4/8/PPP2PPP/RNBQK2R w KQkq -
+two knights defense: Pincus variation
+r1bqk2r/ppp2ppp/2n5/3np3/1b2P3/3P1N2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Venice attack *
+r1bqk2r/ppp2ppp/2n5/3np3/1b6/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Scheveningen, Vitoli\'n\'s variation *
+r1bqk2r/ppp2ppp/2n5/3p4/2BP4/1Qb2N2/P4PPP/R1B2RK1 w kq -
+Giuoco Piano: Bernstein variation
+r1bqk2r/ppp2ppp/2n5/3p4/2BPn3/B1P2N2/P4PPP/R2Q1RK1 b kq -
+Giuoco Piano: Steinitz variation
+r1bqk2r/ppp2ppp/2n5/3pp3/2PPn3/P3P3/1PQ2PPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, San Remo variation
+r1bqk2r/ppp2ppp/2n5/3pp3/4P1n1/3P1N2/PPPNBbPP/R1BQ1RK1 w kq -
+Philidor: Nimzovich, L\"arobok variation *
+r1bqk2r/ppp2ppp/2nb4/1B1np3/4P3/5N2/PP1P1PPP/RNBQK2R b KQkq -
+Sicilian: Pin, Jaffe variation *
+r1bqk2r/ppp2ppp/2np1n2/2b1p1B1/2B1P3/2NP1N2/PPP2PPP/R2QK2R b KQkq -
+Giuoco Pianissimo: Canal variation
+r1bqk2r/ppp2ppp/2np1n2/2b1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Giuoco Pianissimo: Italian four knights variation *
+r1bqk2r/ppp2ppp/2np1n2/4p3/4P3/P1P2P2/1PP3PP/R1BQKBNR w KQkq -
+Ruy Lopez: exchange, Romanovsky variation *
+r1bqk2r/ppp2ppp/2nppn2/8/1bPP4/2N2N2/PPQ1PPPP/R1B1KB1R w KQkq -
+Nimzo-Indian: classical, Milner-Barry (Zurich) variation
+r1bqk2r/ppp2ppp/3p1n2/4p1B1/2BnP3/8/PPP2PPP/RN1Q1RK1 w kq -
+Giuoco piano
+r1bqk2r/ppp3p1/2n5/2bppPPp/4n2P/7B/PPPP1P1R/RNBQK1N1 w Qkq -
+KGA: Kieseritsky, long whip defense, Jaenisch variation *
+r1bqk2r/ppp3pp/2nb1n2/3ppp2/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Pirc: Austrian attack, 6.Bd3 *
+r1bqk2r/pppn1ppp/4pn2/3p2B1/1bPP4/2N1P3/PP3PPP/R2QKBNR w KQkq -
+QGD: Manhattan variation
+r1bqk2r/pppn1ppp/5n2/2bP4/8/4P3/PP3PPP/RNBQKBNR b KQkq -
+French: Tarrasch, Eliskases variation *
+r1bqk2r/pppnbppp/3p1n2/4p3/3P4/2N1PN2/PPP2PPP/R1BQKB1R w KQkq -
+French: Reversed Philidor formation *
+r1bqk2r/pppnbppp/3p1n2/4p3/3PP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Inverted Hanham *
+r1bqk2r/pppp1p2/5n1p/4p1p1/2BnPP1B/8/PPP3PP/RN1Q1RK1 b kq -
+Giuoco piano: Rosentreter variation
+r1bqk2r/pppp1pbp/2n3pn/4p3/2P5/2N3P1/PP1PPPBP/1RBQK1NR w Kkq -
+English: closed, 5.Rb1 Taimanov variation
+r1bqk2r/pppp1pp1/5n1p/4n3/2PN3B/2P5/P3PPPP/R2QKB1R w KQkq -
+English: Nenarokov variation
+r1bqk2r/pppp1ppp/1b5n/nP2N3/2B1P3/8/P1PP1PPP/RNBQK2R w KQkq -
+Evans gambit declined, Lange variation
+r1bqk2r/pppp1ppp/2n1pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+Nimzo-Indian: 4.e3, Taimanov variation
+r1bqk2r/pppp1ppp/2n1pn2/8/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, 4...Nc6
+r1bqk2r/pppp1ppp/2n2n2/1B2p3/1b2P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Four knights: double Ruy Lopez *
+r1bqk2r/pppp1ppp/2n2n2/1B2p3/1b2P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Four knights: double Ruy Lopez
+r1bqk2r/pppp1ppp/2n2n2/1Bb1p3/4P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Four knights: Spanish, classical defense
+r1bqk2r/pppp1ppp/2n2n2/1Bb1p3/4P3/3PBN2/PPP2PPP/RN1QK2R b KQkq -
+Ruy Lopez: Berlin defense, Kaufmann variation
+r1bqk2r/pppp1ppp/2n2n2/1Bb1p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Berlin defense, Beverwijk variation
+r1bqk2r/pppp1ppp/2n2n2/2b1N3/3PP3/8/PPP2PPP/RNBQKB1R b KQkq -
+Boden-Kieseritsky gambit: Lichtenhein defense *
+r1bqk2r/pppp1ppp/2n2n2/2b1N3/4P3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Boden-Kieseritsky gambit *
+r1bqk2r/pppp1ppp/2n2n2/2b1P3/2Bp4/5N2/PPP2PPP/RNBQ1RK1 b kq -
+two knights: Max Lange attack
+r1bqk2r/pppp1ppp/2n2n2/2b1p1N1/2B1P3/8/PPPP1PPP/RNBQK2R w KQkq -
+two knights defense: Wilkes Barre (Traxler) variation
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/1PB1P3/2P2N2/P2P1PPP/RNBQK2R b KQkq -
+Giuoco Piano: Bird's attack
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Giuoco Piano: four knights variation *
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Giuoco Piano: four knights variation
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2B1P3/2NP1N2/PPP2PPP/R1BQK2R b KQkq -
+Giuoco Pianissimo: Italian four knights variation
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2B1P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Giuoco Piano
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2B1P3/3P1N2/PPP2PPP/RNBQK2R w KQkq -
+Giuoco Pianissimo
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2B1PP2/2P5/PP1PQ1PP/RNB1K1NR b KQkq -
+Bishop's opening: Lopez gambit
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2BPP3/2P2N2/PP3PPP/RNBQK2R b KQkq -
+Giuoco Piano
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Italian variation *
+r1bqk2r/pppp1ppp/2n2n2/2b5/2BPP3/5N2/PP3PPP/RNBQK2R b KQkq -
+Giuoco Piano
+r1bqk2r/pppp1ppp/2n2n2/3Np3/1b2P3/5N2/PPPP1PPP/R1BQKB1R b KQkq -
+Four knights: Rubinstein counter-gambit *
+r1bqk2r/pppp1ppp/2n2n2/3Np3/1b2P3/5N2/PPPP1PPP/R1BQKB1R w KQkq -
+Three knights: Schlechter variation
+r1bqk2r/pppp1ppp/2n2n2/4N3/1b1PP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Four knights: Scotch, Krause variation
+r1bqk2r/pppp1ppp/2n2n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Spanish variation *
+r1bqk2r/pppp1ppp/2n2n2/4p3/1b2P3/2N3P1/PPPPNP1P/R1BQKB1R b KQkq -
+Ruy Lopez: Cozio defense, Paulsen variation *
+r1bqk2r/pppp1ppp/2n2n2/4p3/1b2PP2/2N5/PPPP2PP/R1BQKBNR w KQkq -
+Ruy Lopez: Schliemann defense, Berger variation *
+r1bqk2r/pppp1ppp/2n2n2/4p3/1bB1P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Four knights: Spanish, classical defense *
+r1bqk2r/pppp1ppp/2n2n2/4p3/2P5/2b1PN2/PPQP1PPP/R1B1KB1R w KQkq -
+English: four knights, Romanishin variation
+r1bqk2r/pppp1ppp/2n2n2/4p3/4P3/P1P5/1PP2PPP/R1BQKBNR w KQkq -
+Ruy Lopez: exchange, Keres variation *
+r1bqk2r/pppp1ppp/2n2n2/4p3/4P3/P1b2N2/1PPP1PPP/R1BQKB1R w KQkq -
+Four knights: Ranken variation *
+r1bqk2r/pppp1ppp/2n2n2/8/1bB1P3/2N2N2/PP3PPP/R1BQK2R w KQkq -
+Scotch: G\"oring gambit, Bardeleben variation
+r1bqk2r/pppp1ppp/2n2n2/8/1bBPP3/2N2N2/PP3PPP/R1BQK2R b KQkq -
+Giuoco Piano: Greco's attack
+r1bqk2r/pppp1ppp/2n2n2/8/1bBPP3/5N2/PP3PPP/RNBQ1K1R b kq -
+Giuoco Piano: Cracow variation
+r1bqk2r/pppp1ppp/2n2n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R w KQkq -
+Ruy Lopez: four knights (Tarrasch) variation *
+r1bqk2r/pppp1ppp/2n2n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQkq -
+Ruy Lopez: modern Steinitz defense, Three knights variation *
+r1bqk2r/pppp1ppp/2n4n/2b3NQ/2BpP3/8/PPP2PPP/RNB1K2R b KQkq -
+Scotch gambit: Vitzhum attack
+r1bqk2r/pppp1ppp/2n5/2b1P3/2Bp2n1/2P2N2/PP3PPP/RNBQ1RK1 b kq -
+two knights: Max Lange attack, Krause variation
+r1bqk2r/pppp1ppp/2n5/2b1P3/2Bp2n1/5N2/PPP2PPP/RNBQ1RK1 w kq -
+two knights: Max Lange attack, Steinitz variation
+r1bqk2r/pppp1ppp/2n5/2bBP3/8/2p2NK1/PP4PP/RNBQ3R b kq -
+Giuoco Piano: Ghulam Kassim variation
+r1bqk2r/pppp1ppp/2n5/2bPp3/4n3/2P2N2/PP3PPP/RNBQKB1R w KQkq -
+Ponziani: Fraser defense
+r1bqk2r/pppp1ppp/2n5/3P4/2B1n3/2b2N2/PP3PPP/R1BQ1RK1 b kq -
+Giuoco Piano: M\"oller (Therkatz) attack
+r1bqk2r/pppp1ppp/2n5/3np3/1b2P3/5N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Rubinstein counter-gambit, exchange variation *
+r1bqk2r/pppp1ppp/2n5/8/1bBP4/2n2N2/PP3PPP/R1BQ1RK1 w kq -
+Giuoco Piano: Greco variation
+r1bqk2r/pppp1ppp/2n5/8/2BP4/B1b2N2/P4PPP/R2Q1RK1 b kq -
+Giuoco Piano: Aitken variation
+r1bqk2r/pppp1ppp/2n5/8/2BPn3/2b2N2/PP3PPP/R1BQ1RK1 w kq -
+Giuoco Piano
+r1bqk2r/pppp2pp/2n2n2/1Bb1pQ2/4P3/8/PPPP1PPP/RNB1K1NR w KQkq -
+KGD: Norwalde variation, B\"ucker gambit *
+r1bqk2r/pppp2pp/2n2n2/2b1p3/2P2p2/2N1P1P1/PP1P1PBP/R1BQK1NR w KQkq -
+Sicilian: Grand Prix attack, Schofman variation *
+r1bqk2r/pppp2pp/2n2n2/2b1pPP1/8/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: MacDonnell gambit *
+r1bqk2r/pppp2pp/2n5/3Npp2/1b2n3/5N2/PPPPQPPP/R1B1KB1R w KQkq -
+Four knights: Rubinstein counter-gambit, Bogolyubov variation *
+r1bqk2r/ppppbppp/2n2n2/3Np3/4P3/5N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Rubinstein counter-gambit, 5.Be2 *
+r1bqk2r/ppppbppp/2n5/1B2P3/4n3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: Berlin defense, Minckwitz variation
+r1bqk2r/ppppbppp/2n5/1B2p3/3Pn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open Berlin defense, 5...Be7
+r1bqk2r/ppppbppp/2n5/4P3/2Bpn3/2P2N2/PP3PPP/RNBQK2R w KQkq -
+Hungarian defense: Tartakower variation
+r1bqk2r/ppppbppp/2nn4/4N2Q/8/1BN5/PPPP1PPP/R1B1K2R b KQkq -
+Vienna: Alekhine variation
+r1bqk3/ppp3p1/2n5/2bppP2/4n1P1/2PP4/PP3P2/RNBQK1NB w KQq -
+KGA: Greco gambit *
+r1bqkb1r/1p1n1ppp/p2ppn2/8/3NP3/2N5/PPP1BPPP/R1BQ1RK1 w kq -
+Sicilian: Scheveningen, classical, Nd7 system
+r1bqkb1r/1p1ppppp/p1n2n2/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+English: four knights, Marini variation *
+r1bqkb1r/1p2nppp/p1n1p3/2pp4/3P4/3BPN2/PPP2PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: Simagin variation *
+r1bqkb1r/1p2pp1p/2n3p1/p1np4/4PB2/2P2N2/PPQN1PPP/R3KB1R b KQkq -
+QGD Slav: Carlsbad variation *
+r1bqkb1r/1p2pppp/2n2n2/p1Pp2B1/8/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+QGD Slav: Steiner variation *
+r1bqkb1r/1p2pppp/2n2n2/p1Pp4/5B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+QGD Slav: Czech defense *
+r1bqkb1r/1p2pppp/2n2n2/p1Pp4/8/2P1PN2/PP3PPP/RNBQKB1R b KQkq -
+QGD Slav: Soultanb\'eieff variation *
+r1bqkb1r/1p2pppp/2n2n2/p1Pp4/8/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav accepted: Alapin variation *
+r1bqkb1r/1p2pppp/2n5/p1Pp4/4nB2/2P1PN2/PP3PPP/RN1QKB1R b KQkq -
+QGD Slav: Wiesbaden variation *
+r1bqkb1r/1p2pppp/2n5/p1Pp4/4nB2/2P2N2/PP2PPPP/RN1QKB1R w KQkq -
+QGD Slav: Krause attack *
+r1bqkb1r/1p3ppp/2n1pn2/p1Pp4/5B2/2P2N2/PP2PPPP/RN1QKB1R w KQkq -
+QGD Slav: Dutch variation *
+r1bqkb1r/1p3ppp/2n1pn2/p1Pp4/5B2/N1P2N2/PP2PPPP/R2QKB1R b KQkq -
+QGD Slav: Dutch, Lasker variation *
+r1bqkb1r/1p3ppp/2n2n2/p1Ppp1B1/8/N1P2N2/PP2PPPP/R2QKB1R b KQkq -
+QGD Slav: Smyslov variation *
+r1bqkb1r/1p3ppp/p1n1pn2/3p4/2P1P3/N1N5/PP3PPP/R1BQKB1R w KQkq -
+Sicilian, Sz\'en variation, Dely-Kasparov gambit
+r1bqkb1r/1p3ppp/p1nppn2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R w KQkq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6
+r1bqkb1r/1pp1nppp/p1B5/3pP3/8/4P3/PPP2PPP/RNBQK1NR b KQkq -
+French: Winawer, Alekhine gambit *
+r1bqkb1r/1pp2ppp/2P2n2/1p6/3Pp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+French: Winawer, advance, Rauzer variation *
+r1bqkb1r/1pp2ppp/p1n5/3pP3/8/2N1P3/PPP2PPP/R1BQK1NR b KQkq -
+French: Winawer, Alekhine gambit, Kan variation *
+r1bqkb1r/1pp2ppp/p1np1n2/4p3/B1P1P3/3P1N2/PP3PPP/RNBQK2R b KQkq -
+Ruy Lopez: Morphy defense, Duras variation
+r1bqkb1r/1pp2ppp/p1np1n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Steinitz defense deferred (Russian defense)
+r1bqkb1r/1ppn1ppp/p3pn2/8/3P4/6P1/PPQ1PPBP/RNB1K1NR b KQkq -
+Catalan: open, Alekhine variation
+r1bqkb1r/1ppp1ppp/p1B2n2/4p3/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Four knights: Ranken variation
+r1bqkb1r/1ppp1ppp/p1B2n2/4p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Ruy Lopez: Treybal (Bayreuth) variation (exchange var. deferred)
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Gunsberg variation *
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Ruy Lopez: four knights (Tarrasch) variation
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/3P1N2/PPP2PPP/RNBQK2R b KQkq -
+Ruy Lopez: Anderssen variation
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: 5.O-O
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Morphy defense
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/5N2/PPPPQPPP/RNB1K2R b KQkq -
+Ruy Lopez: Wormald (Alapin) attack
+r1bqkb1r/1ppp1ppp/p1n5/1B2p3/3Pn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Berlin defense, Rosenthal variation
+r1bqkb1r/1ppp1ppp/p1n5/4p3/B2Pn3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, 6.d4
+r1bqkb1r/1ppp1ppp/p1n5/4p3/B3n3/2N2N2/PPPP1PPP/R1BQ1RK1 b kq -
+Ruy Lopez: open, Knorre variation
+r1bqkb1r/1ppp1ppp/p1n5/4p3/B3n3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open (Tarrasch) defense
+r1bqkb1r/1ppp1ppp/p1n5/4p3/B3n3/5N2/PPPPQPPP/RNB2RK1 b kq -
+Ruy Lopez: open, Tartakower variation
+r1bqkb1r/1ppp1ppp/p1n5/8/B2pn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, Riga variation
+r1bqkb1r/1pppnppp/p1n5/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Cozio defense deferred
+r1bqkb1r/2p1nppp/p7/1p1pP3/4n3/1B3N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, Zukertort variation
+r1bqkb1r/2p2ppp/p1n5/1p1pP3/4n3/1B3N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, 8.de
+r1bqkb1r/2p2ppp/p1n5/1p1pp3/2PPn3/1B3N2/PP3PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, Harksen gambit
+r1bqkb1r/2p2ppp/p1np1n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: ...b5 & ...d6
+r1bqkb1r/2p2ppp/p1p2n2/3p4/2PPp3/4P3/PP2NPPP/RNBQK2R w KQkq -
+French: Winawer, advance, positional main line *
+r1bqkb1r/2p2ppp/p1pp4/4p3/3Pn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Steinitz defense deferred, Rubinstein variation
+r1bqkb1r/2p2ppp/p7/1p1p4/P2pn3/1BN5/1PP2PPP/R1BQ1RK1 b kq -
+Ruy Lopez: open, Berger variation
+r1bqkb1r/2p2ppp/p7/1p1pp3/P2nn3/1B3N2/1PP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, Schlechter defense
+r1bqkb1r/2p3pp/p1p5/3pPp2/4n3/2N2N2/PPP2PPP/R1BQR1K1 b kq -
+Ruy Lopez: Steinitz defense deferred, Boleslavsky variation
+r1bqkb1r/2pp1ppp/p1n5/1p1Pp3/B3n3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, Richter variation
+r1bqkb1r/2pp1ppp/p1n5/1p2N3/B2Pn3/8/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, Friess attack
+r1bqkb1r/2pp1ppp/p1n5/1p2p3/3Pn3/1B3N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, 7.Bb3
+r1bqkb1r/2pp1ppp/p1n5/1p2p3/B2Pn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, 6.d4 b5
+r1bqkb1r/3n1ppp/p1p1pn2/1p6/3P4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran, 8...a6
+r1bqkb1r/3n1ppp/p1p1pn2/8/1p1PP3/2NB1N2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran, Pir\'c variation
+r1bqkb1r/3n1ppp/p3p3/1N2P3/3p2n1/3B1N2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran, Rabinovich variation
+r1bqkb1r/3n1ppp/p3pn2/1N2P3/3p4/3B1N2/PP3PPP/R1BQK2R b KQkq -
+QGD semi-Slav: Meran, Blumenfeld variation
+r1bqkb1r/3n1ppp/p3pn2/1pp1P3/3P4/2NB1N2/PP3PPP/R1BQK2R b KQkq -
+QGD semi-Slav: Meran, old main line
+r1bqkb1r/3n1ppp/p3pn2/1pp5/3PP3/2NB1N2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran
+r1bqkb1r/3n1ppp/p3pn2/1ppP4/4P3/2NB1N2/PP3PPP/R1BQK2R b KQkq -
+QGD semi-Slav: Meran, Reynolds' variation
+r1bqkb1r/5p1p/p1np4/1p1Npp2/4P3/N7/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Sveshnikov variation
+r1bqkb1r/5ppp/4pn2/1p2N3/3p4/3B1Q2/PP3PPP/R1B1K2R b KQkq -
+QGD semi-Slav: Meran, Stahlberg variation
+r1bqkb1r/5ppp/4pn2/1p2N3/3p4/3B4/PP3PPP/R1BQ1RK1 b kq -
+QGD semi-Slav: Meran, Sozin variation
+r1bqkb1r/5ppp/p1np1n2/1p2p1B1/4P3/N1N5/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Pelikan, Chelyabinsk variation
+r1bqkb1r/5ppp/p3pn2/1N2n3/3p4/3B1N2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran, Sozin variation
+r1bqkb1r/p1p2ppp/2n2n2/1p1Pp1N1/2B5/8/PPPP1PPP/RNBQK2R w KQkq -
+two knights defense: Ulvestad variation
+r1bqkb1r/p1p2ppp/8/1p1np3/3nN3/2P5/PP1P1PPP/RNBQKB1R b KQkq -
+two knights defense: Fritz, Gruber variation
+r1bqkb1r/p1pn1ppp/1p2pn2/3p4/2PP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+Queen's pawn game, Zukertort variation *
+r1bqkb1r/p1pp1ppp/2p2n2/4P3/8/8/PPP2PPP/RNBQKB1R b KQkq -
+Scotch: Mieses variation
+r1bqkb1r/p1pp1ppp/2p2n2/8/4P3/8/PPPN1PPP/R1BQKB1R b KQkq -
+Scotch: Tartakower variation
+r1bqkb1r/p2n1p2/2p1pn2/1p2P1B1/2pP4/2N2Q2/PP3PPP/R3KB1R b KQkq -
+QGD semi-Slav: anti-Meran, Szab\'o variation
+r1bqkb1r/p2n1p2/2p1pn2/1p2P1B1/2pP4/2N3P1/PP3P1P/R2QKB1R b KQkq -
+QGD semi-Slav: anti-Meran, Lilienthal variation
+r1bqkb1r/p2n1ppp/2p1pn2/1p6/2BP4/2N1PN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran variation
+r1bqkb1r/p2n1ppp/2p1pn2/8/1p1P4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: neo-Meran (Lundin variation)
+r1bqkb1r/p3pp1p/2pp1np1/4P3/2B5/2N5/PPP2PPP/R1BQK2R b KQkq -
+Sicilian: Magnus Smith trap
+r1bqkb1r/p4pp1/2p2n1p/n3p1N1/8/8/PPPPBPPP/RNBQK2R w KQkq -
+Two knights defense
+r1bqkb1r/p4pp1/2p2n1p/n3p3/8/7N/PPPPBPPP/RNBQK2R b KQkq -
+two knights defense: Steinitz variation
+r1bqkb1r/p4ppp/2n1pn2/1ppp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Gr\"unfeld: Makogonov variation *
+r1bqkb1r/p4ppp/2p2n2/3pp3/8/6P1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: modern exchange variation *
+r1bqkb1r/p4ppp/2p2n2/n3p1N1/8/8/PPPPBPPP/RNBQK2R b KQkq -
+Two knights defense
+r1bqkb1r/p4ppp/2p2n2/nB2p1N1/8/5Q2/PPPP1PPP/RNB1K2R b KQkq -
+two knights defense: Bogolyubov variation
+r1bqkb1r/p4ppp/5n2/np2p1N1/8/5Q2/PPPP1PPP/RNB1K2R w KQkq -
+two knights defense: Blackburne variation
+r1bqkb1r/pp1n1ppp/2n1p3/2PpP3/5P2/2N5/PPP3PP/R1BQKBNR w KQkq -
+French: Steinitz variation
+r1bqkb1r/pp1n1ppp/2n1p3/2ppP3/3P1P2/2N1BN2/PPP3PP/R2QKB1R b KQkq -
+French: Steinitz, Boleslavsky variation
+r1bqkb1r/pp1n1ppp/2n1p3/2ppP3/3P4/2PB4/PP1N1PPP/R1BQK1NR w KQkq -
+French: Tarrasch, closed variation
+r1bqkb1r/pp1n1ppp/2n1p3/3pP3/3P4/3B4/PP1NNPPP/R1BQK2R b KQkq -
+French: Tarrasch, closed variation, main line
+r1bqkb1r/pp1n1ppp/2p1pn2/3p2B1/2PP4/2N1P3/PP3PPP/R2QKBNR w KQkq -
+QGD: 5...c6
+r1bqkb1r/pp1n1ppp/2p1pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R b KQkq -
+QGD
+r1bqkb1r/pp1n1ppp/2p1pn2/3p2B1/2PP4/4PN2/PP1N1PPP/R2QKB1R b KQkq -
+QGD: Capablanca variation
+r1bqkb1r/pp1n1ppp/2p1pn2/3p2B1/2PP4/P1N1P3/1P3PPP/R2QKBNR b KQkq -
+QGD: Capablanca anti-Cambridge Springs variation
+r1bqkb1r/pp1n1ppp/2p1pn2/3p2B1/2PPP3/2N2N2/PP3PPP/R2QKB1R b KQkq -
+QGD: Alekhine variation
+r1bqkb1r/pp1n1ppp/2p1pn2/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: 5...Nd7
+r1bqkb1r/pp1n1ppp/2p1pn2/3p4/2PP4/2N1PN2/PPQ2PPP/R1B1KB1R b KQkq -
+QGD semi-Slav: Stoltz variation
+r1bqkb1r/pp1n1ppp/2p1pn2/3p4/2PP4/2NBPN2/PP3PPP/R1BQK2R b KQkq -
+QGD semi-Slav: 6.Bd3
+r1bqkb1r/pp1n1ppp/2p1pn2/3p4/2PP4/4PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD Slav
+r1bqkb1r/pp1n1ppp/2p1pn2/3pN3/2PP4/2N1P3/PP3PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Rubinstein (anti-Meran) system
+r1bqkb1r/pp1n1ppp/2p1pn2/8/2BP4/2N1PN2/PP3PPP/R1BQK2R b KQkq -
+QGD semi-Slav: 7.Bc4
+r1bqkb1r/pp1n1ppp/4pn2/2pp4/2PP4/3BPN2/PP1N1PPP/R1BQK2R w KQkq -
+QGD Slav: Semmering variation
+r1bqkb1r/pp1n1ppp/4pn2/2pp4/3P4/2P1PN2/PP1N1PPP/R1BQKB1R b KQkq -
+QGD Slav *
+r1bqkb1r/pp1n1ppp/4pn2/2pp4/3P4/2P1PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD Slav *
+r1bqkb1r/pp1n1ppp/4pn2/2pp4/3P4/2P1PNP1/PP3P1P/RNBQKB1R b KQkq -
+QGD: Spielmann variation *
+r1bqkb1r/pp1npp1p/3p1np1/8/3NPP2/2N5/PPP3PP/R1BQKB1R w KQkq -
+Sicilian: dragon, Levenfish; Flohr variation
+r1bqkb1r/pp1npppp/2n5/8/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+Benoni: Nimzovich (knight's tour) variation *
+r1bqkb1r/pp1npppp/2n5/8/2Pp4/B2P1NP1/4PP1P/RN1QKB1R w KQkq -
+Benk\"o gambit: Nd2 variation *
+r1bqkb1r/pp1npppp/5n2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Bogo-Indian defense, Gr\"unfeld variation *
+r1bqkb1r/pp1npppp/5n2/2pP4/4p3/2N2P2/PPP3PP/R1BQKBNR b KQkq -
+QGD: Albin counter-gambit, Janowski variation *
+r1bqkb1r/pp1npppp/5n2/2pP4/4p3/2N5/PPP1QPPP/R1B1KBNR b KQkq -
+QGD: Albin counter-gambit, Balogh variation *
+r1bqkb1r/pp1npppp/5n2/2pP4/4p3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+QGD: Albin counter-gambit, Alapin variation *
+r1bqkb1r/pp1npppp/5n2/2pp4/3P4/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav: Breyer variation *
+r1bqkb1r/pp1p1Npp/2p1nn2/8/2B1P3/8/PPP2PPP/RNBQ1RK1 b kq -
+Scotch: Cochrane variation
+r1bqkb1r/pp1p1ppp/2n1pn2/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+English: four knights, 4.e3 *
+r1bqkb1r/pp1p1ppp/2n1pn2/8/2PN4/2N5/PP2PPPP/R1BQKB1R w KQkq -
+English: symmetrical variation
+r1bqkb1r/pp1p1ppp/2n2n2/2p1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+English: four knights, Nimzovich variation *
+r1bqkb1r/pp1p1ppp/2n2n2/4p3/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Pelikan (Lasker/Sveshnikov) variation
+r1bqkb1r/pp1p1ppp/2n5/2ppP3/3P4/5N2/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Nimzovich-Rubinstein; Rubinstein counter-gambit
+r1bqkb1r/pp1p1ppp/n1p2n2/8/2PNp3/2N5/PP1PPPPP/R1BQKB1R w KQkq -
+Sicilian: 2.c3, Heidenfeld variation *
+r1bqkb1r/pp1pnppp/2p2n2/1B2N3/4P3/3P4/PPP2PPP/RNBQK2R w KQkq -
+Ruy Lopez: Berlin defense, Mortimer trap
+r1bqkb1r/pp1ppp1p/2n2np1/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+English: four knights, kingside fianchetto *
+r1bqkb1r/pp1ppppp/2n2n2/1Bp5/8/4PN2/PPPP1PPP/RNBQK2R b KQkq -
+English: Nimzo-English opening *
+r1bqkb1r/pp1ppppp/2n2n2/2p3B1/4P3/3P4/PPP2PPP/RN1QKBNR b KQkq -
+English, Smyslov defense *
+r1bqkb1r/pp1ppppp/2n2n2/2p5/2P5/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+English: symmetrical, four knights system *
+r1bqkb1r/pp1ppppp/2n2n2/2p5/2P5/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+English: symmetrical, four knights system
+r1bqkb1r/pp1ppppp/2n2n2/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+English: four knights system *
+r1bqkb1r/pp1ppppp/2n2n2/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+English: three knights system *
+r1bqkb1r/pp1ppppp/2n2n2/2p5/4P3/3P4/PPP2PPP/RNBQKBNR w KQkq -
+English opening *
+r1bqkb1r/pp1ppppp/2n2n2/2p5/8/1P2PN2/P1PP1PPP/RNBQKB1R b KQkq -
+English: Queens Indian formation *
+r1bqkb1r/pp1ppppp/2n2n2/8/2PN4/8/PP2PPPP/RNBQKB1R b KQkq -
+English: symmetrical, three knights system *
+r1bqkb1r/pp1ppppp/2n2n2/8/3N4/8/PPP1PPPP/RNBQKB1R w KQkq -
+English: Anglo-Gr\"unfeld defense *
+r1bqkb1r/pp1ppppp/2n2n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian defense
+r1bqkb1r/pp1ppppp/2n5/2p1P3/1P4n1/5N2/P1PP1PPP/RNBQKB1R b KQkq -
+English: Bellon gambit *
+r1bqkb1r/pp1ppppp/2n5/2pnP3/8/N1P2N2/PP1P1PPP/R1BQKB1R b KQkq -
+Sicilian: 2.c3, Heidenfeld variation
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: 4.e3 c5, 5.Ne2 (Rubinstein, anti-H\"ubner system) *
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/8/1P2PN2/P1PP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: Fischer variation, 5.Ne2 *
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+Nimzo-Indian: Reshevsky variation *
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/8/BP2PN2/P1PP1PPP/RN1QK2R b KQkq -
+Nimzo-Indian: 4.e3, Bronstein (Byrne) variation *
+r1bqkb1r/pp2nppp/2n5/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: Kramer system *
+r1bqkb1r/pp2pp1p/2n2np1/2Pp4/3P4/2N5/PP3PPP/R1BQKBNR b KQkq -
+QGD: Tarrasch, Folkestone (Swedish) variation *
+r1bqkb1r/pp2pp1p/2n2np1/2pp4/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: fianchetto variation *
+r1bqkb1r/pp2pp1p/2n2np1/3p4/2PP4/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+QGD: Tarrasch, Prague variation *
+r1bqkb1r/pp2pp1p/2n2np1/3p4/2PP4/2N5/PP3PPP/R1BQKBNR w KQkq -
+QGD: Tarrasch, Schlechter-Rubinstein system *
+r1bqkb1r/pp2pp1p/2n2np1/8/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+Benoni: fianchetto variation *
+r1bqkb1r/pp2pp1p/2n2np1/8/2Pp4/B2P1NP1/4PP1P/RN1QKB1R w KQkq -
+Benk\"o gambit: fianchetto variation *
+r1bqkb1r/pp2pp1p/2n3p1/2pn4/8/1QN1PN2/PP1P1PPP/R1B1KB1R b KQkq -
+English: symmetrical, Geller variation *
+r1bqkb1r/pp2pp1p/2np1np1/6B1/3NP3/2N5/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Richter-Rauzer, Bondarevsky variation
+r1bqkb1r/pp2pp1p/3p1np1/8/2PQP3/2N5/PP3PPP/R1B1KB1R w KQkq -
+Sicilian: accelerated fianchetto, Gurgenidze variation
+r1bqkb1r/pp2pppp/2n2n2/1Bp1N3/2Pp4/4P3/PP1P1PPP/RNBQK2R b KQkq -
+Nimzo-Indian: three knights, Euwe variation *
+r1bqkb1r/pp2pppp/2n2n2/1Bp5/2Pp4/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: three knights, Korchnoi variation *
+r1bqkb1r/pp2pppp/2n2n2/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R b KQkq -
+QGD: Ragozin variation *
+r1bqkb1r/pp2pppp/2n2n2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: three knights variation *
+r1bqkb1r/pp2pppp/2n2n2/2Pp4/8/2N5/PPP1PPPP/R1BQKBNR w KQkq -
+QGD: Chigorin defense, Janowski variation *
+r1bqkb1r/pp2pppp/2n2n2/2Pp4/8/2P1P3/PP3PPP/RNBQKBNR b KQkq -
+QGD: semi-Slav, Noteboom variation *
+r1bqkb1r/pp2pppp/2n2n2/2Pp4/8/2P2N2/PP2PPPP/RNBQKB1R b KQkq -
+QGD Slav accepted *
+r1bqkb1r/pp2pppp/2n2n2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+QGA, 4.Nc3 *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/2PP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+QGD: Semi-Tarrasch defense *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/1QP2N2/PP2PPPP/RNB1KB1R b KQkq -
+QGD Slav: S\"uchting variation *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/2P1PN2/PP3PPP/RNBQKB1R b KQkq -
+QGD semi-Slav *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav: 4.Nc3 *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/2P2NP1/PP2PP1P/RNBQKB1R b KQkq -
+QGD Slav\Gr\"unfeld: Schlechter variation *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+QGD: 4.Nf3 *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Gr\"unfeld: Three knights variation *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R b KQkq -
+Gr\"unfeld: Three knights variation *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/4P3/3P1N2/PPP2PPP/RNBQKB1R w KQkq -
+Old Indian: Ukrainian variation, 4.Nf3 *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+Queen's Indian: 4.Nc3 *
+r1bqkb1r/pp2pppp/2n2n2/2ppP3/8/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+English: Bradley Beach variation *
+r1bqkb1r/pp2pppp/2n2n2/3p4/2PP4/8/PP3PPP/RNBQKBNR w KQkq -
+QGD: Tarrasch defense *
+r1bqkb1r/pp2pppp/2n2n2/3p4/2Pp4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD: Semi-Tarrasch, 5.cd *
+r1bqkb1r/pp2pppp/2n2n2/3p4/3P1B2/2PB4/PP3PPP/RN1QK1NR b KQkq -
+Caro-Kann: exchange, Rubinstein variation
+r1bqkb1r/pp2pppp/2n2n2/8/2Pp4/3P1NP1/PP3P1P/RNBQKB1R b KQkq -
+Benoni defense *
+r1bqkb1r/pp2pppp/2n5/2pn4/8/2N1PN2/PP1P1PPP/R1BQKB1R b KQkq -
+English: symmetrical variation *
+r1bqkb1r/pp2pppp/2np1n2/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+English: four knights, Capablanca variation *
+r1bqkb1r/pp2pppp/2np1n2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: Richter-Rauzer
+r1bqkb1r/pp2pppp/2np1n2/8/2BNP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Sicilian: Sozin, not Scheveningen
+r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+Sicilian: classical
+r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian
+r1bqkb1r/pp2pppp/5n2/n2P2B1/2p5/2N5/PP3PPP/R2QKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik, Herzog defense
+r1bqkb1r/pp3p1p/2n2np1/2Ppp3/3P4/2N5/PP3PPP/R1BQKBNR w KQkq -
+QGD: Tarrasch, Schlechter-Rubinstein system, Rey Ardid variation *
+r1bqkb1r/pp3ppp/1nn1p3/3pP3/3P4/3B4/PP1NNPPP/R1BQK2R w KQkq -
+French: Tarrasch, Leningrad variation
+r1bqkb1r/pp3ppp/2Np1n2/4p3/4P3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+Sicilian: Boleslavsky, Louma variation
+r1bqkb1r/pp3ppp/2Nppn2/6B1/4P3/2N5/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: Richter-Rauzer, Richter attack
+r1bqkb1r/pp3ppp/2n1p3/2pn4/3P4/2NBPN2/PP3PPP/R1BQK2R b KQkq -
+QGD: Semi-Tarrasch, 7.Bd3
+r1bqkb1r/pp3ppp/2n1p3/2pp4/3Pn3/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: Rubinstein (anti-Meran) system *
+r1bqkb1r/pp3ppp/2n1p3/3p4/3PnB2/4P3/PP1N1PPP/RN1QKB1R b KQkq -
+QGD Slav: Amsterdam variation *
+r1bqkb1r/pp3ppp/2n1pn2/1Bpp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: 4.e3 e8g8, 5.Nf3 d7d5 *
+r1bqkb1r/pp3ppp/2n1pn2/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+Nimzo-Indian: 4.e3 e8g8, 5.Nf3, without ...d5 *
+r1bqkb1r/pp3ppp/2n1pn2/2Pp4/8/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav: 5.e3 (Alekhine variation) *
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/2P1PN2/PP1N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: 5...Nd7 *
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/2P1PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD semi-Slav: 5.e3 *
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: 5.e3 *
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/P1P1PN2/1P3PPP/RNBQKB1R b KQkq -
+QGD semi-Slav: accelerated Meran (Alekhine variation) *
+r1bqkb1r/pp3ppp/2n1pn2/3p2B1/2PP4/2N5/PP3PPP/R2QKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik, normal variation
+r1bqkb1r/pp3ppp/2n1pn2/3p4/2PN4/4P3/PP3PPP/RNBQKB1R w KQkq -
+QGD: Semi-Tarrasch with e3 *
+r1bqkb1r/pp3ppp/2n1pn2/3p4/3P1B2/5N2/PP2PPPP/RN1QKB1R w KQkq -
+QGD Slav: exchange variation *
+r1bqkb1r/pp3ppp/2n2n2/1B2p3/8/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Scotch: G\"oring gambit *
+r1bqkb1r/pp3ppp/2n2n2/2Pp4/1P2p3/2P2N2/P3PPPP/RNBQKB1R w KQkq -
+QGD Slav: Tolush-Geller gambit *
+r1bqkb1r/pp3ppp/2n2n2/2Ppp3/8/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav: Slav gambit *
+r1bqkb1r/pp3ppp/2n2n2/2Ppp3/8/P4N2/1PP1PPPP/RNBQKB1R w KQkq -
+QGA, Bogolyubov variation *
+r1bqkb1r/pp3ppp/2n2n2/2pp4/3P4/2N2NP1/PP2PP1P/R1BQKB1R w KQkq -
+QGD: Tarrasch, Prague variation
+r1bqkb1r/pp3ppp/2n2n2/2ppp3/4P3/3P1N2/PPPN1PPP/R1BQKB1R w KQkq -
+Old Indian: main line *
+r1bqkb1r/pp3ppp/2n2n2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: 5.Nf3 *
+r1bqkb1r/pp3ppp/2n2n2/2ppp3/Q1P5/3P2P1/PP2PPBP/RNB1K1NR b KQkq -
+Pterodactyl defense *
+r1bqkb1r/pp3ppp/2n2n2/4p3/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+Benoni: classical with e4 and Nf3 *
+r1bqkb1r/pp3ppp/2np1n2/4p3/3NP3/2N5/PPP1BPPP/R1BQK2R w KQkq -
+Sicilian: Boleslavsky variation
+r1bqkb1r/pp3ppp/2np1n2/4p3/4P3/1NN5/PPP1BPPP/R1BQK2R b KQkq -
+Sicilian: Boleslavsky variation, 7.Nb3
+r1bqkb1r/pp3ppp/2nppn2/1B4B1/3NP3/2N5/PPP2PPP/R2QK2R b KQkq -
+Sicilian: Richter-Rauzer, Margate (Alekhine) variation
+r1bqkb1r/pp3ppp/2nppn2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Richter-Rauzer, 6...e6
+r1bqkb1r/pp3ppp/2nppn2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R b KQkq -
+Sicilian: Richter-Rauzer, Rauzer attack
+r1bqkb1r/pp3ppp/2nppn2/6B1/3NP3/2NQ4/PPP2PPP/R3KB1R b KQkq -
+Sicilian: Richter-Rauzer, Keres variation
+r1bqkb1r/pp3ppp/2nppn2/6B1/4P3/1NN5/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: Richter-Rauzer, Pod\v ebrady variation
+r1bqkb1r/pp3ppp/2nppn2/8/2BNP3/2N1B3/PPP2PPP/R2QK2R b KQkq -
+Sicilian: Sozin, 7.Be3
+r1bqkb1r/pp3ppp/2nppn2/8/2BNP3/2N5/PPP2PPP/R1BQK2R w KQkq -
+Sicilian: Sozin, Leonhardt variation
+r1bqkb1r/pp3ppp/2nppn2/8/3NP3/2N5/PPP1BPPP/R1BQK2R w KQkq -
+Sicilian: modern Scheveningen
+r1bqkb1r/pp3ppp/n1n5/2p1p3/3P4/P1N1PN2/1P3PPP/R1BQKB1R b KQkq -
+Sicilian, Sz\'en variation, Dely-Kasparov gambit *
+r1bqkb1r/pp4pp/2n2n2/2p1pp2/2Pp4/3P1NP1/PP2PPBP/RNBQ1RK1 w kq -
+King's Indian: Four pawns attack, dynamic line *
+r1bqkb1r/pp4pp/2n2n2/4pp2/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+Benoni: four pawns attack *
+r1bqkb1r/ppp1nppp/2n5/1B1pp3/3P4/4P3/PPP2PPP/RNBQK1NR w KQkq -
+French: Winawer, Alekhine (Mar\'oczy) gambit *
+r1bqkb1r/ppp1pppp/1nn5/4P3/2PP4/4B3/PP4PP/RN1QKBNR b KQkq -
+Alekhine's defense: four pawns attack, 7.Be3
+r1bqkb1r/ppp1pppp/1nn5/4P3/2PP4/8/PP4PP/RNBQKBNR w KQkq -
+Alekhine's defense: four pawns attack, 6...Nc6
+r1bqkb1r/ppp2Npp/2n5/3np3/2B5/8/PPPP1PPP/RNBQK2R b KQkq -
+two knights defense: Fegatello attack
+r1bqkb1r/ppp2p1p/2n3p1/3np3/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Scheveningen, fianchetto variation *
+r1bqkb1r/ppp2p1p/2n3p1/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, Zagreb (fianchetto) variation *
+r1bqkb1r/ppp2p1p/2n5/3np1p1/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Scheveningen, Keres attack *
+r1bqkb1r/ppp2p1p/2n5/3p2p1/Q3nB2/2P2N2/PP2PPPP/RN2KB1R w KQkq -
+Scandinavian defense, Gr\"unfeld variation *
+r1bqkb1r/ppp2pp1/2n2n1p/3p2B1/Q7/5N2/PPP1PPPP/RN2KB1R w KQkq -
+Scandinavian defense, Lasker variation *
+r1bqkb1r/ppp2pp1/2n2n1p/3pp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+Pirc: classical, h3 system *
+r1bqkb1r/ppp2pp1/2n4p/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, Adams attack *
+r1bqkb1r/ppp2pp1/5nn1/3p3p/8/2P3BP/PP1NPPP1/R2QKBNR b KQkq -
+Caro-Kann: classical, 7...Nd7 *
+r1bqkb1r/ppp2pp1/5nn1/3p4/7p/2P3BP/PP1NPPP1/R2QKBNR w KQkq -
+Caro-Kann: classical, Spassky variation *
+r1bqkb1r/ppp2ppp/2Bp1n2/4p3/4P3/3P1N2/PPP2PPP/RNBQK2R b KQkq -
+Ruy Lopez: Berlin defense, Anderssen variation
+r1bqkb1r/ppp2ppp/2n1pn2/3p4/3PP3/5N2/PPPN1PPP/R1BQKB1R w KQkq -
+French: Tarrasch, Guimard main line
+r1bqkb1r/ppp2ppp/2n1pn2/3p4/4P3/3P1N2/PPPNBPPP/R1BQK2R b KQkq -
+French: Reversed Philidor formation
+r1bqkb1r/ppp2ppp/2n2n2/3Pp3/8/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Four knights: Scotch, 4...exd4 *
+r1bqkb1r/ppp2ppp/2n2n2/3p2B1/3P4/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: exchange, Bogolyubov variation
+r1bqkb1r/ppp2ppp/2n2n2/3p2B1/Q3P3/8/PPP2PPP/RN2KBNR b KQkq -
+Scandinavian: Anderssen counter-attack, Collijn variation *
+r1bqkb1r/ppp2ppp/2n2n2/3p4/Q3P3/8/PPP2PPP/RNB1KBNR w KQkq -
+Scandinavian: Anderssen counter-attack, Goteborg system *
+r1bqkb1r/ppp2ppp/2n2n2/3p4/Q4B2/5N2/PPP1PPPP/RN2KB1R b KQkq -
+Scandinavian defense *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Scotch variation *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/4P3/3P1N2/PPPN1PPP/R1BQKB1R b KQkq -
+Philidor: Improved Hanham variation *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/4P3/3P1N2/PPPNBPPP/R1BQK2R b KQkq -
+Inverted Hanham
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/4PP2/3P4/PPP3PP/RNBQKBNR w KQkq -
+Philidor: Philidor counter-gambit, Zukertort variation *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/8/2PP2P1/PP2PPBP/RNBQK1NR b KQkq -
+Robatsch defense: two knights, Suttles variation *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Pirc: classical (two knights) system *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/8/3P1NP1/PPP1PPBP/RNBQK2R b KQkq -
+Pirc: classical (two knights) system *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/8/3P2P1/PPP1PPBP/RNBQK1NR w KQkq -
+Robatsch defense: two knights variation *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/Q3P3/2P2N2/PP1P1PPP/RNB1KB1R w KQkq -
+Ponziani: Leonhardt variation
+r1bqkb1r/ppp2ppp/2n5/1B1n4/4p3/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+Sicilian: Pin, Koch variation *
+r1bqkb1r/ppp2ppp/2n5/1B1np3/8/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+Sicilian: Pin variation (Sicilian counter-attack) *
+r1bqkb1r/ppp2ppp/2n5/1B1pp3/4n3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Four knights: Scotch, Krause variation *
+r1bqkb1r/ppp2ppp/2n5/1B2p3/8/2NnPN2/PP1P1PPP/R1BQK2R w KQkq -
+Sicilian: Taimanov, American attack *
+r1bqkb1r/ppp2ppp/2n5/3np1N1/2BP4/8/PPP2PPP/RNBQK2R b KQkq -
+two knights defense: Lolli attack
+r1bqkb1r/ppp2ppp/2n5/3np2Q/8/2N5/PPPP1PPP/R1B1KBNR w KQkq -
+Scotch: Steinitz variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/4P3/2N2N2/PP1P1PPP/R1BQKB1R b KQkq -
+Sicilian: Pelikan (Lasker/Sveshnikov) variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N1P3/PP1P1PPP/R1BQKBNR w KQkq -
+Sicilian: Taimanov variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N1P3/PPQP1PPP/R1B1KBNR b KQkq -
+Sicilian: Taimanov (Bastrikov) variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+Sicilian: accelerated fianchetto, modern variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2NP1N2/PP2PPPP/R1BQKB1R b KQkq -
+Sicilian *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3P1N2/PP2PPPP/RNBQKB1R w KQkq -
+Sicilian *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3P1NP1/PP2PP1P/RNBQKB1R b KQkq -
+Sicilian: dragon variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3PPN2/PP3PPP/RNBQKB1R b KQkq -
+Sicilian: Scheveningen variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P1N1P3/1P1P1PPP/R1BQKBNR b KQkq -
+Sicilian: Taimanov variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R b KQkq -
+Sicilian: Najdorf *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P3P3/1P1P1PPP/RNBQKBNR w KQkq -
+Sicilian: Kan, 5.Nc3 *
+r1bqkb1r/ppp2ppp/2n5/3p4/2Bpn3/2N2N2/PPP2PPP/R1BQR1K1 b kq -
+two knights defense: Canal variation
+r1bqkb1r/ppp2ppp/2n5/4P3/2BP2n1/4p3/PPP3PP/RNBQK1NR w KQkq -
+Philidor: Philidor counter-gambit, Berger variation *
+r1bqkb1r/ppp2ppp/2np1n2/1B2p3/2P1P3/3P1N2/PP3PPP/RNBQK2R b KQkq -
+Ruy Lopez: Berlin defense, Duras variation
+r1bqkb1r/ppp2ppp/2np1n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Berlin defense, 4.O-O, d6
+r1bqkb1r/ppp2ppp/2np1n2/4p3/2P5/1PN1P3/P2P1PPP/R1BQKBNR w KQkq -
+Amsterdam attack
+r1bqkb1r/ppp2ppp/4pn2/4N3/3P4/8/PPP2PPP/R1BQKB1R b KQkq -
+French: Rubinstein, Capablanca line
+r1bqkb1r/ppp2ppp/5n2/3Pp1N1/2Bn4/8/PPPP1PPP/RNBQK2R w KQkq -
+two knights defense: Fritz variation
+r1bqkb1r/ppp2ppp/5n2/3Pp3/3n4/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Belgrade gambit *
+r1bqkb1r/ppp2ppp/5n2/3Pp3/3n4/2N3P1/PPPP1P1P/R1BQKBNR w KQkq -
+Three knights: Steinitz, Rosenthal variation *
+r1bqkb1r/ppp2ppp/5n2/3p4/2PPp3/2N5/PP1P1PPP/R1BQKB1R b KQkq -
+Sicilian: Nimzovich-Rubinstein; Rubinstein counter-gambit *
+r1bqkb1r/ppp2ppp/5n2/3pn3/8/2B1P3/PPP2PPP/RN1QKBNR b KQkq -
+French: Fort Knox variation *
+r1bqkb1r/ppp2ppp/5n2/n2Pp1N1/2B5/3P4/PPP2PPP/RNBQK2R b KQkq -
+two knights defense: Kieseritsky variation
+r1bqkb1r/ppp2ppp/5n2/n2Pp1N1/2B5/8/PPPP1PPP/RNBQK2R w KQkq -
+two knights defense
+r1bqkb1r/ppp2ppp/5n2/nB1Pp1N1/8/8/PPPP1PPP/RNBQK2R b KQkq -
+Two knights defense
+r1bqkb1r/ppp2ppp/6nn/3p4/8/2P3B1/PP2PPPP/RN1QKBNR w KQkq -
+Caro-Kann: classical, Flohr variation *
+r1bqkb1r/ppp2ppp/8/3p4/4n3/4PN2/PPP2PPP/R1BQKB1R w KQkq -
+French: Rubinstein, Capablanca line *
+r1bqkb1r/ppp3pp/2n2n2/3p1p2/2PPp3/4P3/PP1N1PPP/RNBQKB1R w KQkq -
+French: Steinitz variation *
+r1bqkb1r/ppp3pp/2n2n2/3p1p2/4p3/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Pirc: Austrian attack, 6.e5 *
+r1bqkb1r/ppp3pp/2n2n2/3p4/8/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+Blackmar-Diemer: Euwe defense *
+r1bqkb1r/ppp3pp/2n2n2/3ppP2/6P1/2N5/PPPP1P1P/R1BQKBNR w KQkq -
+Vienna: Pierce gambit *
+r1bqkb1r/ppp3pp/2n2n2/3ppp2/2P5/3P1NP1/PP2PPBP/RNBQK2R b KQkq -
+Pirc: Austrian attack, dragon formation *
+r1bqkb1r/ppp3pp/2n2n2/3ppp2/8/3P1NP1/PPP1PPBP/RNBQ1RK1 b kq -
+Pirc: Austrian attack *
+r1bqkb1r/ppp3pp/2n5/3npp2/8/3P1NP1/PP1NPP1P/R1BQKB1R b KQkq -
+Sicilian: dragon, Levenfish; Flohr variation *
+r1bqkb1r/ppp3pp/2n5/3npp2/8/3P1NP1/PP2PP1P/RNBQKB1R w KQkq -
+Sicilian: dragon, Levenfish variation *
+r1bqkb1r/ppp3pp/2n5/3npp2/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Scheveningen, 6.f4 *
+r1bqkb1r/ppp3pp/2n5/3npp2/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, 6.f4 *
+r1bqkb1r/ppp4p/3p1nN1/8/3np2Q/8/PPP2PPP/RNB1KB1R w KQkq -
+Vienna gambit, Wurzburger trap *
+r1bqkb1r/pppn1ppp/2np4/1B2p3/3PP3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: closed Berlin defense, Chigorin variation
+r1bqkb1r/pppn1ppp/3p1n2/4p3/2PP4/2NBP3/PP3PPP/R1BQK1NR b KQkq -
+Old Indian: Dus-Khotimirsky variation
+r1bqkb1r/pppn1ppp/3p1n2/4p3/2PPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+Old Indian: main line
+r1bqkb1r/pppn1ppp/3p1n2/4p3/3PP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Philidor: Improved Hanham variation
+r1bqkb1r/pppn1ppp/4pn2/3p2B1/2PP4/2N1P3/PP3PPP/R2QKBNR b KQkq -
+QGD
+r1bqkb1r/pppn1ppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR w KQkq -
+QGD: 4.Bg5 Nbd7
+r1bqkb1r/pppn1ppp/4pn2/8/2QP4/6P1/PP2PPBP/RNB1K1NR b KQkq -
+Catalan: open, 5.Qa4 Nbd7, 6.Qxc4
+r1bqkb1r/pppn1ppp/5n2/3p4/2PP4/2N5/PP3PPP/R1BQKBNR b KQkq -
+French: Tarrasch, open variation, main line *
+r1bqkb1r/pppn1ppp/5n2/3p4/3P1B2/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+QGD: exchange, S\"amisch variation
+r1bqkb1r/pppn1ppp/5n2/3pp3/3P4/2N1PN2/PPP2PPP/R1BQKB1R b KQkq -
+French: Tarrasch, Guimard main line *
+r1bqkb1r/pppn1ppp/5n2/4N3/4p3/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Nimzovich, Sokolsky variation *
+r1bqkb1r/pppn1ppp/8/4p3/8/2P2N2/P1PP1PPP/R1BQKB1R w KQkq -
+Scotch: Tartakower variation *
+r1bqkb1r/pppp1ppp/2n1pn2/8/2P1P3/2N5/PP1P1PPP/R1BQKBNR w KQkq -
+English: Mikenas-Carls, Kevitz variation
+r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Four knights: Spanish variation
+r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: Berlin defense, 4.O-O
+r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Berlin defense
+r1bqkb1r/pppp1ppp/2n2n2/1B6/3pP3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: Berlin defense, Nyholm attack
+r1bqkb1r/pppp1ppp/2n2n2/3N4/3pP3/5N2/PPP2PPP/R1BQKB1R b KQkq -
+Four knights: Belgrade gambit
+r1bqkb1r/pppp1ppp/2n2n2/4N3/4P3/2N5/PPPP1PPP/R1BQKB1R b KQkq -
+Four knights: Schultze-M\"uller gambit
+r1bqkb1r/pppp1ppp/2n2n2/4N3/8/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: Nimzovich attack *
+r1bqkb1r/pppp1ppp/2n2n2/4p1B1/3P4/2P5/PP2PPPP/RN1QKBNR b KQkq -
+Caro-Kann: two knights, 3...Bg4 *
+r1bqkb1r/pppp1ppp/2n2n2/4p1N1/2B1P3/8/PPPP1PPP/RNBQK2R b KQkq -
+Two knights defense
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Four knights: Italian variation
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Vienna game
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/3P1N2/PPP2PPP/RNBQK2R b KQkq -
+Two knights defense (Modern bishop's opening)
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Two knights defense
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2BPP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+Two knights defense
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P1P3/2N2N2/PP1P1PPP/R1BQKB1R b KQkq -
+English: four knights, Nimzovich variation
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N1PN2/PP1P1PPP/R1BQKB1R b KQkq -
+English: four knights, 4.e3
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+English: four knights system
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N2NP1/PP1PPP1P/R1BQKB1R b KQkq -
+English: four knights, kingside fianchetto
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2NP1N2/PP2PPPP/R1BQKB1R b KQkq -
+English: four knights, Capablanca variation
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/P1N2N2/1P1PPPPP/R1BQKB1R b KQkq -
+English: four knights, Marini variation
+r1bqkb1r/pppp1ppp/2n2n2/4p3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: two knights variation *
+r1bqkb1r/pppp1ppp/2n2n2/4p3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: Two knights variation *
+r1bqkb1r/pppp1ppp/2n2n2/4p3/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+Four knights: Scotch variation
+r1bqkb1r/pppp1ppp/2n2n2/4p3/3PP3/5N2/PPP1BPPP/RNBQK2R b KQkq -
+Tayler opening
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Four knights game *
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights game
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+Three knights: Steinitz variation *
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Three knights game *
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2P2N2/PP1P1PPP/RNBQKB1R w KQkq -
+Ponziani: Jaenisch counter-attack
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov three knights game *
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R b KQkq -
+Four knights: Gunsberg variation
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Three knights: Winawer defense (Gothic defense) *
+r1bqkb1r/pppp1ppp/2n2n2/6N1/2BpP3/8/PPP2PPP/RNBQK2R b KQkq -
+Two knights defense, Perreux variation
+r1bqkb1r/pppp1ppp/2n2n2/8/2BpP3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Two knights defense
+r1bqkb1r/pppp1ppp/2n2n2/8/2BpP3/5N2/PPP2PPP/RNBQK2R w KQkq -
+Scotch gambit: Dubois-R\'eti defense
+r1bqkb1r/pppp1ppp/2n2n2/8/2PPp3/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+English: Bradley Beach variation
+r1bqkb1r/pppp1ppp/2n2n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Scotch: Schmidt variation
+r1bqkb1r/pppp1ppp/2n2n2/8/3pP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Four knights: Scotch, 4...exd4
+r1bqkb1r/pppp1ppp/2n2n2/8/4P3/4Q3/PPP2PPP/RNB1KBNR w KQkq -
+Center game: Berger variation
+r1bqkb1r/pppp1ppp/2n5/1B2p3/4n3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Berlin defense, open variation
+r1bqkb1r/pppp1ppp/2n5/2n1P3/3N4/8/PPP1QPPP/RNB1KB1R w KQkq -
+Petrov: modern attack, Bardeleben variation
+r1bqkb1r/pppp1ppp/2n5/4p3/4n3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Schultze-M\"uller gambit *
+r1bqkb1r/pppp1ppp/2n5/8/2Bpn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Two knights defense
+r1bqkb1r/pppp1ppp/2nn4/1B2P3/8/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open Berlin defense, l'Hermet variation
+r1bqkb1r/pppp1ppp/2nn4/4p2Q/3P4/1BN5/PPP2PPP/R1B1K1NR b KQkq -
+Vienna: Adams' gambit
+r1bqkb1r/pppp1ppp/2nn4/4p3/B2P4/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open Berlin defense, Showalter variation
+r1bqkb1r/pppp1ppp/5n2/1B2p3/3NP3/2N5/PPPP1PPP/R1BQK2R b KQkq -
+Four knights: Rubinstein counter-gambit, exchange variation
+r1bqkb1r/pppp1ppp/5n2/1B2p3/3nP3/2N2N2/PPPP1PPP/R1BQ1RK1 b kq -
+Four knights: Rubinstein counter-gambit, Henneberger variation
+r1bqkb1r/pppp1ppp/5n2/1B2p3/3nP3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Three knights: Schlechter variation *
+r1bqkb1r/pppp1ppp/5n2/1B2p3/3nP3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Four knights: Rubinstein counter-gambit
+r1bqkb1r/pppp1ppp/5n2/4p3/3nP3/2N2N2/PPPPBPPP/R1BQK2R b KQkq -
+Four knights: Rubinstein counter-gambit, 5.Be2
+r1bqkb1r/pppp2p1/2n5/4pPPp/6n1/2N5/PPPP1P1P/R1BQKBNR w KQkq -
+Vienna: Hamppe-Allgaier gambit *
+r1bqkb1r/pppp2p1/2n5/4pPPp/6n1/2NP4/PPP2P1P/R1BQKBNR b KQkq -
+Vienna: Hamppe-Allgaier gambit, Alapin variation *
+r1bqkb1r/pppp2p1/2n5/4pPPp/8/7P/PPPP1K2/RNBQ1BNR w kq -
+KGA: Allgaier, Blackburne gambit *
+r1bqkb1r/pppp2pp/2n2n2/4N3/3Pp3/8/PPP1BPPP/RNBQK2R b KQkq -
+Vienna gambit: Breyer variation *
+r1bqkb1r/pppp2pp/2n2n2/4pP2/6P1/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: Quaade gambit *
+r1bqkb1r/pppp2pp/2n2n2/4pP2/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna gambit *
+r1bqkb1r/pppp2pp/2n2n2/4pp2/2B1P3/3P4/PPPN1PPP/R1BQK1NR b KQkq -
+KGD: classical, Hanham variation *
+r1bqkb1r/ppppnp1p/2n3p1/1B2p3/4P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Ruy Lopez: Cozio defense, Paulsen variation
+r1bqkb1r/ppppnppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Cozio defense
+r1bqkb1r/ppppnppp/2n5/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Sicilian: chameleon variation *
+r1bqkb1r/ppppnppp/2n5/4p3/4P3/2P2N2/PP1P1PPP/RNBQKB1R w KQkq -
+Ponziani: R\'eti variation
+r1bqkb1r/ppppnppp/5n2/1B2p3/4P3/3P1N2/PPP2PPP/RNBQK2R w KQkq -
+Ruy Lopez: Berlin defense, Mortimer variation
+r1bqkb1r/ppppnppp/8/1B6/3pP3/8/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Bird's defense, Paulsen variation
+r1bqkb1r/pppppppp/2n2n2/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Kevitz-Trajkovich defense
+r1bqkbnr/1p1p1ppp/p1n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Taimanov variation
+r1bqkbnr/1pp2ppp/p1n5/1B1p4/2PPp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+French: Winawer, advance, 5.a3 *
+r1bqkbnr/1pp2ppp/p1np4/4p3/B1P1P3/5N2/PP1P1PPP/RNBQK2R b KQkq -
+Ruy Lopez: modern Steinitz defense, Duras (Keres) variation
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Ruy Lopez: modern Steinitz defense, Three knights variation
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+Ruy Lopez: modern Steinitz defense
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: modern Steinitz defense, 5.O-O
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense
+r1bqkbnr/1pp2ppp/p1p5/4p3/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Ruy Lopez: exchange, Keres variation
+r1bqkbnr/1pp2ppp/p1p5/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: exchange variation, 5.O-O
+r1bqkbnr/1pp3pp/p1np4/4pp2/B3P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense, siesta variation
+r1bqkbnr/1pp3pp/p1p2p2/4p3/4P3/2NP1N2/PPP2PPP/R1BQK2R b KQkq -
+Ruy Lopez: exchange, Romanovsky variation
+r1bqkbnr/1pp3pp/p1p2p2/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: exchange, Gligori\'c variation
+r1bqkbnr/1ppp1p1p/p1n3p1/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: fianchetto defense deferred
+r1bqkbnr/1ppp1ppp/p1B5/4p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Ruy Lopez: exchange variation
+r1bqkbnr/1ppp1ppp/p1n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Vienna: Mengarini variation *
+r1bqkbnr/1ppp1ppp/p1n5/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Ruy Lopez
+r1bqkbnr/1ppp1ppp/p7/4p3/B2nP3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Bird's defense deferred
+r1bqkbnr/1ppp2pp/p1n5/4pp2/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Schliemann defense deferred
+r1bqkbnr/1ppppppp/p1n5/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Battambang opening *
+r1bqkbnr/2p2ppp/2p5/p2p4/2PPp3/4P3/PP2NPPP/RNBQK2R w KQkq -
+French: Winawer, advance, Smyslov variation *
+r1bqkbnr/2p2ppp/p1p5/3p4/2PPp3/4P3/PP2NPPP/RNBQK2R b KQkq -
+French: Winawer, advance, 6...Ne7 *
+r1bqkbnr/2p2ppp/p1p5/3p4/2PPp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+French: Winawer, advance variation *
+r1bqkbnr/2p2ppp/p1p5/3p4/2PPp3/4P3/PPQ2PPP/RNB1K1NR b KQkq -
+French: Winawer, classical variation *
+r1bqkbnr/2p2ppp/p1pp4/4p3/3PP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+Ruy Lopez: modern Steinitz defense, Richter variation
+r1bqkbnr/2p2ppp/p1pp4/4p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense, exchange variation
+r1bqkbnr/2p3pp/p1pp1p2/4p3/3PP3/5N2/PPP2PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense, Alapin variation
+r1bqkbnr/2pp1ppp/p1n5/1p2p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Caro variation
+r1bqkbnr/2pp1ppp/p7/np2p3/4P3/1B3N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Taimanov (chase/wing/accelerated counterthrust) variation
+r1bqkbnr/4p1pp/p1p2p2/3p4/2Pp4/4PN2/PP3PPP/RNBQK2R w KQkq -
+Nimzo-Indian: S\"amisch variation *
+r1bqkbnr/4p1pp/p1p2p2/8/2pN1P2/4P3/PP4PP/RNBQK2R b KQkq -
+Nimzo-Indian: S\"amisch, Romanovsky variation *
+r1bqkbnr/4p1pp/p1p2p2/8/2pN4/4P3/PP3PPP/RNBQK2R w KQkq -
+Nimzo-Indian: S\"amisch, Keres variation *
+r1bqkbnr/4pppp/p1p5/2pp4/8/4PN2/PPPP1PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: S\"amisch variation *
+r1bqkbnr/4pppp/p1p5/2pp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: S\"amisch variation *
+r1bqkbnr/5ppp/p1p1p3/2pp4/2P5/1P2PN2/P2P1PPP/RNBQK2R b KQkq -
+Nimzo-Indian: S\"amisch, O'Kelly variation *
+r1bqkbnr/5ppp/p1p1p3/2pp4/2P5/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: S\"amisch variation *
+r1bqkbnr/5ppp/p1p1p3/2pp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+Nimzo-Indian: S\"amisch variation *
+r1bqkbnr/5ppp/p2p4/1pp5/3QP3/1B6/PPP2PPP/RNB1K2R w KQkq -
+Ruy Lopez: Noah's ark trap
+r1bqkbnr/6pp/p1p1pp2/3p4/2PN4/4P3/PP3PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: S\"amisch, Botvinnik variation *
+r1bqkbnr/p1pp1ppp/2n5/1p6/Q7/8/PPP1PPPP/RNB1KBNR w KQkq -
+Scandinavian, Mieses-Kotr\v c gambit *
+r1bqkbnr/p2p1ppp/1pn1p3/2p5/4P3/2NP1N2/PPP2PPP/R1BQKB1R b KQkq -
+Amsterdam attack *
+r1bqkbnr/p3pppp/2p5/2p5/2Pp1P2/6P1/PP1PP2P/RNBQK1NR b KQkq -
+Beefeater defense *
+r1bqkbnr/pp1n1ppp/2pp4/4p1N1/2BPP3/8/PPP2PPP/RNBQK2R b KQkq -
+Philidor: Hanham, Kmoch variation
+r1bqkbnr/pp1n1ppp/2pp4/4p3/2BPP3/2N2N2/PPP2PPP/R1BQK2R b KQkq -
+Philidor: Hanham, Schlechter variation
+r1bqkbnr/pp1n1ppp/2pp4/4p3/2BPP3/2P2N2/PP3PPP/RNBQK2R b KQkq -
+Philidor: Hanham, Delmar variation
+r1bqkbnr/pp1n1ppp/2pp4/4p3/2BPP3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Philidor: Hanham, Krause variation
+r1bqkbnr/pp1npppp/2p5/8/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+Caro-Kann: Steinitz variation
+r1bqkbnr/pp1p1p1p/2n3p1/2p1p3/2P4P/2NP4/PP2PPP1/R1BQKBNR b KQkq -
+Sicilian: Gloria variation *
+r1bqkbnr/pp1p1ppp/2n1p3/1N6/4P3/8/PPP2PPP/RNBQKB1R b KQkq -
+Sicilian, Sz\'en (`anti-Taimanov') variation
+r1bqkbnr/pp1p1ppp/2n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Sicilian: Taimanov variation
+r1bqkbnr/pp1p1ppp/2n1p3/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian defense
+r1bqkbnr/pp1p1ppp/2n5/2p1p3/2P5/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+English: Mikenas-Carls, Sicilian variation *
+r1bqkbnr/pp1p1ppp/2n5/2p1p3/8/2N1PN2/PPPP1PPP/R1BQKB1R b KQkq -
+English: Mikenas-Carls, Kevitz variation *
+r1bqkbnr/pp1p1ppp/2n5/2p1p3/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+English: Mikenas-Carls variation *
+r1bqkbnr/pp1p1ppp/2n5/2p5/3Pp3/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+English: Mikenas-Carls, Flohr variation *
+r1bqkbnr/pp1p1ppp/2n5/4p3/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Labourdonnais-L\"owenthal variation
+r1bqkbnr/pp1ppp1p/2N3p1/8/4P3/8/PPP2PPP/RNBQKB1R b KQkq -
+Sicilian: accelerated fianchetto, exchange variation
+r1bqkbnr/pp1ppp1p/2n3p1/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+English: Bremen, Smyslov system *
+r1bqkbnr/pp1ppp1p/2n3p1/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Sicilian: Nimzovich-Rossolimo attack (with ...g6, without ...d6)
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English: symmetrical variation *
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/2P5/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+English: symmetrical variation *
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+English: Bremen, reverse dragon *
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/2P2N2/PP1P1PPP/RNBQKB1R b KQkq -
+English: Bremen system, Keres variation *
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/2PP4/PP3PPP/RNBQKBNR b KQkq -
+English, Keres variation *
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+English: Carls' Bremen system *
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/5NP1/PPPP1P1P/RNBQKB1R b KQkq -
+English: Bremen system with ...g6 *
+r1bqkbnr/pp1ppp1p/2n3p1/8/2PNP3/8/PP3PPP/RNBQKB1R b KQkq -
+Sicilian: accelerated fianchetto, Mar\'oczy bind
+r1bqkbnr/pp1ppp1p/2n3p1/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Sicilian: accelerated fianchetto, modern variation
+r1bqkbnr/pp1ppppp/2n5/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Sicilian: Nimzovich-Rossolimo attack (without ...d6)
+r1bqkbnr/pp1ppppp/2n5/1Bp5/4P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+English, Kramnik-Shirov counterattack *
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+English: symmetrical variation
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+English: symmetrical variation *
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English: symmetrical variation
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English: symmetrical variation *
+r1bqkbnr/pp1ppppp/2n5/2p5/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+English: Anglo-Gr\"unfeld defense *
+r1bqkbnr/pp1ppppp/2n5/2p5/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Sicilian defense
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+Sicilian: closed
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+English: Sicilian reversed *
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Sicilian: closed, 2...Nc6
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/2N5/PPPPNPPP/R1BQKB1R b KQkq -
+Sicilian: chameleon variation
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+English opening *
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian defense
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+English opening *
+r1bqkbnr/pp1ppppp/2n5/2p5/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Sicilian: Grand Prix attack
+r1bqkbnr/pp1ppppp/2n5/2p5/8/2NP2P1/PPP1PP1P/R1BQKBNR b KQkq -
+Venezolana opening
+r1bqkbnr/pp1ppppp/2n5/2p5/8/4PN2/PPPP1PPP/RNBQKB1R b KQkq -
+English opening *
+r1bqkbnr/pp1ppppp/2n5/2p5/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+English opening *
+r1bqkbnr/pp1ppppp/2n5/8/7Q/2N5/PPP1PPPP/R1B1KBNR b KQkq -
+Novosibirsk opening
+r1bqkbnr/pp2p1pp/2n2p2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: Kmoch variation *
+r1bqkbnr/pp2pp1p/2n3p1/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: Romanishin-Kasparov (Steiner) system *
+r1bqkbnr/pp2pp1p/2n5/2pp2p1/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Gr\"unfeld: Spike gambit *
+r1bqkbnr/pp2ppp1/2np4/2p4p/2P1P3/2N3P1/PP1P1P1P/R1BQKBNR w KQkq -
+Sicilian: Gloria variation
+r1bqkbnr/pp2pppp/2n5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R b KQkq -
+Nimzo-Indian defense *
+r1bqkbnr/pp2pppp/2n5/2pp4/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+QGD: Tarrasch defense *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/1P2P3/P1P2PPP/RNBQKBNR b KQkq -
+QGD: Alapin variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/2P1P3/PP3PPP/RNBQKBNR b KQkq -
+QGD: semi-Slav *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/4P3/PPP1BPPP/RNBQK1NR b KQkq -
+QGD: Charousek (Petrosian) variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+QGD: 3.Nc3 *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+QGD: 3...Nf6 *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+Gr\"unfeld defense *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/P3P3/1PP2PPP/RNBQKBNR b KQkq -
+QGD: Janowski variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/3PP3/2P5/PP3PPP/RNBQKBNR b KQkq -
+QGD Slav: Winawer counter-gambit *
+r1bqkbnr/pp2pppp/2n5/2pp4/4P3/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+Old Indian: Ukrainian variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/5B2/3P1N2/PPP1PPPP/RN1QKB1R b KQkq -
+Old Indian: Janowski variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/5P2/4P3/PPPP2PP/RNBQKBNR w KQkq -
+Dutch defense, Rubinstein variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Dutch with c4 & Nc3 *
+r1bqkbnr/pp2pppp/2n5/2pp4/5P2/6PN/PPPPP2P/RNBQKB1R b KQkq -
+Dutch defense: Bladel variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/8/3P2P1/PPP1PPBP/RNBQK1NR b KQkq -
+Modern defense *
+r1bqkbnr/pp2pppp/2n5/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian defense, 3.Nc3 *
+r1bqkbnr/pp2pppp/2n5/3P4/3p4/4P3/PP3PPP/RNBQKBNR b KQkq -
+QGD: Tarrasch, von Hennig-Schara gambit *
+r1bqkbnr/pp2pppp/2n5/3p4/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+QGD: Tarrasch defense, 4.cd ed *
+r1bqkbnr/pp2pppp/2n5/3p4/3N4/6P1/PPP1PP1P/RNBQKB1R b KQkq -
+Gr\"unfeld: exchange variation *
+r1bqkbnr/pp2pppp/2n5/3p4/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Nimzovich variation
+r1bqkbnr/pp2pppp/2n5/3p4/3p4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+QGD: exchange variation *
+r1bqkbnr/pp2pppp/2n5/8/1pPp4/P4N2/3PPPPP/RNBQKB1R w KQkq -
+Benk\"o gambit: Zaitsev system *
+r1bqkbnr/pp2pppp/8/n2P4/1Pp5/8/P4PPP/RNBQKBNR b KQkq b3
+QGD: Tarrasch defense, Tarrasch gambit *
+r1bqkbnr/pp3p1p/2n3p1/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian with e4 & g3 *
+r1bqkbnr/pp3pp1/2n4p/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: Makagonov system (5.h3) *
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+Nimzo-Indian: 4.e3 c5 *
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/1P2PN2/P1PP1PPP/RNBQK2R b KQkq -
+Nimzo-Indian: Fischer variation *
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/2N1PN2/PPPP1PPP/R1BQK2R b KQkq -
+Nimzo-Indian: 4.e3, Taimanov variation *
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: 4.e3 O-O *
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: 4.e3 *
+r1bqkbnr/pp3ppp/2n1p3/2ppP3/3P4/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+French: advance, Paulsen attack
+r1bqkbnr/pp3ppp/2n1p3/2ppP3/3P4/2P5/PP3PPP/RNBQKBNR w KQkq -
+French: advance variation
+r1bqkbnr/pp3ppp/2n5/2P1p3/1PPp4/5N2/P3PPPP/RNBQKB1R b KQkq -
+QGA: Linares variation *
+r1bqkbnr/pp3ppp/2n5/2Ppp3/8/2P5/PP2PPPP/RNBQKBNR w KQkq -
+QGD Slav defense, Alekhine variation *
+r1bqkbnr/pp3ppp/2n5/2p1p3/2PpP3/3P1NP1/PP3P1P/RNBQKB1R b KQkq -
+Czech Benoni: King's Indian system *
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+QGD: Tarrasch, Schlechter-Rubinstein system
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+Caro-Kann: Panov-Botvinnik attack, 5...e6 *
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Caro-Kann: Panov-Botvinnik attack *
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/5N2/PPPN1PPP/R1BQKB1R w KQkq -
+French: Tarrasch, open variation, main line
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/5NP1/PP2PP1P/RNBQKB1R b KQkq -
+Caro-Kann: Panov-Botvinnik attack, 5...g6 *
+r1bqkbnr/pp3ppp/2n5/2ppp3/3P4/2P1P3/PP3PPP/RNBQKBNR w KQkq -
+QGD: semi-Slav, Marshall gambit *
+r1bqkbnr/pp3ppp/2n5/2ppp3/5P2/3P2P1/PPP1P1BP/RNBQK1NR b KQkq -
+Modern defense: Averbakh system, Randspringer variation *
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/2NP2P1/PPP1PPBP/R1BQK1NR b KQkq -
+Modern defense: Averbakh system, Kotov variation *
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/3P2P1/PPP1PPBP/RNBQK1NR w KQkq -
+Modern defense: Averbakh system *
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/5NP1/PPPPPPBP/RNBQK2R w KQkq -
+King's Indian: 4.e4 *
+r1bqkbnr/pp3ppp/2n5/3p4/2pP4/2N2NP1/PP2PP1P/R1BQKB1R w KQkq -
+QGD: Tarrasch, Folkestone (Swedish) variation
+r1bqkbnr/pp3ppp/2n5/3p4/2pPP3/2N2NP1/PP3P1P/R1BQKB1R b KQkq -
+QGD: Tarrasch, Schlechter-Rubinstein system, Rey Ardid variation
+r1bqkbnr/pp3ppp/2n5/3pp3/2PP4/8/PP3PPP/RNBQKBNR w KQkq -
+QGD: Tarrasch defense, Marshall gambit *
+r1bqkbnr/pp3ppp/2n5/4p3/2Pp4/3P1N2/PP3PPP/RNBQKB1R w KQkq -
+Benoni: 6.e4 *
+r1bqkbnr/pp3ppp/2n5/4p3/2Pp4/B2P1N2/4PPPP/RN1QKB1R w KQkq -
+Benk\"o gambit: 7.e4 *
+r1bqkbnr/pp3ppp/2np4/1N2p3/4P3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Labourdonnais-L\"owenthal (Kalashnikov) variation
+r1bqkbnr/pp4pp/2n2p2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, 5...O-O *
+r1bqkbnr/pp4pp/2n2p2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: S\"amisch variation *
+r1bqkbnr/pp4pp/2n5/2pppp2/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: Four pawns attack *
+r1bqkbnr/pp4pp/2n5/4pp2/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+Benoni: pawn storm variation *
+r1bqkbnr/pp4pp/2n5/5p2/2Ppp3/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+Benoni: Mikenas variation *
+r1bqkbnr/ppnppppp/2p5/8/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+de Bruycker defense
+r1bqkbnr/ppp1pp1p/2n5/3p2p1/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Dutch, Spielmann gambit *
+r1bqkbnr/ppp1pp1p/2np2p1/8/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Venezolana opening *
+r1bqkbnr/ppp1pppp/2n5/3p2B1/3P4/8/PPP1PPPP/RN1QKBNR b KQkq -
+Queen's pawn: Anti-Veresov *
+r1bqkbnr/ppp1pppp/2n5/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QGD: Chigorin defense
+r1bqkbnr/ppp1pppp/2n5/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's pawn game, Chigorin variation
+r1bqkbnr/ppp1pppp/2n5/3p4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn: Chigorin variation *
+r1bqkbnr/ppp1pppp/2n5/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+KP: Nimzovich defense, Bogolyubov variation
+r1bqkbnr/ppp1pppp/2n5/8/2Pp4/3P2P1/PP2PP1P/RNBQKBNR b KQkq -
+Old Benoni: Schmid's system *
+r1bqkbnr/ppp1pppp/2n5/8/2pP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+QGD: Chigorin defense, Janowski variation
+r1bqkbnr/ppp1pppp/2n5/8/Q1Pp4/5N2/PP1PPPPP/RNB1KB1R b KQkq -
+Woozle defense *
+r1bqkbnr/ppp2p1p/2n3p1/3pp3/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Pirc: Sveshnikov system *
+r1bqkbnr/ppp2p1p/2n5/3pP1p1/8/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Dutch: Staunton gambit, Tartakower variation *
+r1bqkbnr/ppp2p1p/2np4/6N1/4PppP/2N5/PPPP2P1/R1BQKB1R w KQkq -
+Vienna: Hamppe-Allgaier gambit, Alapin variation
+r1bqkbnr/ppp2pp1/6n1/3p3p/8/2P3B1/PP2PPPP/RN1QKBNR w KQkq -
+Caro-Kann: classical, 6.h4 *
+r1bqkbnr/ppp2ppp/2n1p3/3p4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+French: Tarrasch, Guimard variation
+r1bqkbnr/ppp2ppp/2n5/1B1p4/2PPp3/4P3/PP3PPP/RNBQK1NR b KQkq -
+French: Winawer, advance variation *
+r1bqkbnr/ppp2ppp/2n5/1B1p4/3Pp3/4P3/PPP2PPP/RNBQK1NR w KQkq -
+French: Winawer, advance variation *
+r1bqkbnr/ppp2ppp/2n5/1B1p4/3Pp3/4P3/PPPQ1PPP/RNB1K1NR b KQkq -
+French: Winawer, Petrosian variation *
+r1bqkbnr/ppp2ppp/2n5/1B1p4/3Pp3/4PN1P/PPP2PP1/RNBQK2R w KQkq -
+French: MacCutcheon, Dr. Olland (Dutch) variation *
+r1bqkbnr/ppp2ppp/2n5/1B1pp3/3P4/4P3/PPP2PPP/RNBQK1NR b KQkq -
+French: Winawer (Nimzovich) variation *
+r1bqkbnr/ppp2ppp/2n5/3p4/3Pp3/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+French: Steinitz variation *
+r1bqkbnr/ppp2ppp/2n5/3p4/3Q4/2N5/PPP1PPPP/R1B1KBNR w KQkq -
+KP: Nimzovich defense, Marshall gambit *
+r1bqkbnr/ppp2ppp/2n5/3p4/Q3P3/8/PPP2PPP/RNB1KBNR b KQkq -
+Scandinavian: Anderssen counter-attack *
+r1bqkbnr/ppp2ppp/2n5/3pP3/8/4P3/PPP2PPP/RNBQKBNR b KQkq -
+French: Rubinstein variation *
+r1bqkbnr/ppp2ppp/2n5/3pp3/1P1P4/2P5/P3PPPP/RNBQKBNR b KQkq -
+Caro-Kann: Gurgenidze counter-attack *
+r1bqkbnr/ppp2ppp/2n5/3pp3/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+French: Marshall variation *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/2N5/PPP1PPPP/R1BQKBNR w KQkq -
+KP: Nimzovich defense, Bogolyubov variation *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/2P3P1/PP2PP1P/RNBQKBNR b KQkq -
+Caro-Kann: Gurgenidze system *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann defense *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: Paulsen variation *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+French defense *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Blackmar-Diemer gambit *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Blackmar-Diemer: Lemberg counter-gambit *
+r1bqkbnr/ppp2ppp/2n5/3pp3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna: Fyfe gambit *
+r1bqkbnr/ppp2ppp/2n5/3pp3/8/2P5/PPNPPPPP/R1BQKBNR b KQkq -
+de Bruycker defense *
+r1bqkbnr/ppp2ppp/2n5/3pp3/8/2PP1N2/PP2PPPP/RNBQKB1R b KQkq -
+Pirc: Ufimtsev-Pytel variation *
+r1bqkbnr/ppp2ppp/2n5/3pp3/8/3P1NP1/PPP1PP1P/RNBQKB1R b KQkq -
+Pirc defense *
+r1bqkbnr/ppp2ppp/2n5/3pp3/8/3P2P1/PPP1PPBP/RNBQK1NR b KQkq -
+Robatsch (modern) defense *
+r1bqkbnr/ppp2ppp/2n5/3pp3/8/6P1/PPPPPPBP/RNBQK1NR w KQkq -
+Robatsch defense *
+r1bqkbnr/ppp2ppp/2n5/4P3/2Pp4/5N2/PP1NPPPP/R1BQKB1R b KQkq -
+QGD: Albin counter-gambit, Alapin variation
+r1bqkbnr/ppp2ppp/2n5/4P3/2Pp4/5NP1/PP2PP1P/RNBQKB1R b KQkq -
+QGD: Albin counter-gambit, 5.g3
+r1bqkbnr/ppp2ppp/2np4/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: old Steinitz defense
+r1bqkbnr/ppp2ppp/3p4/8/3QP3/3B4/PPP2PPP/RNB1K2R b KQkq -
+Scotch: Ghulam Kassim variation
+r1bqkbnr/ppp2ppp/8/3p4/8/2P2P2/PP2PP1P/RNBQKB1R b KQkq -
+Caro-Kann: Bronstein-Larsen variation *
+r1bqkbnr/ppp2ppp/8/3p4/8/2P2P2/PP3PPP/RNBQKB1R b KQkq -
+Caro-Kann: Tartakower (Nimzovich) variation *
+r1bqkbnr/ppp2ppp/8/3pn3/3Q4/4P3/PPP2PPP/RNB1KBNR b KQkq -
+French: Frere (Becker) variation *
+r1bqkbnr/ppp2ppp/8/3pn3/5B2/2P5/PP2PPPP/RN1QKBNR b KQkq -
+Caro-Kann: classical variation *
+r1bqkbnr/ppp2ppp/8/3pn3/8/2P5/PP1NPPPP/R1BQKBNR b KQkq -
+Caro-Kann: Steinitz variation *
+r1bqkbnr/ppp2ppp/8/3pn3/8/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann defense *
+r1bqkbnr/ppp2ppp/8/3pn3/8/4P3/PPPN1PPP/R1BQKBNR b KQkq -
+French: Rubinstein variation *
+r1bqkbnr/ppp3pp/2n2p2/3pP3/8/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: Rasa-Studier gambit *
+r1bqkbnr/ppp3pp/2n2p2/3pp3/Q3P3/2P2N2/PP1P1PPP/RNB1KB1R w KQkq -
+Ponziani: Steinitz variation
+r1bqkbnr/ppp3pp/2n2p2/4P3/2Pp4/5N2/PP1NPPPP/R1BQKB1R w KQkq -
+QGD: Albin counter-gambit, Janowski variation
+r1bqkbnr/ppp3pp/2n5/3p1p2/3Pp2P/2P3P1/PP2PPB1/RNBQK1NR b KQkq -
+Robatsch defense: Gurgenidze variation *
+r1bqkbnr/ppp3pp/2n5/3ppP2/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna: Steinitz gambit *
+r1bqkbnr/ppp3pp/2n5/3ppp2/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Pirc: Austrian attack *
+r1bqkbnr/ppp3pp/2n5/3ppp2/8/3P2P1/PPP1PPBP/RNBQK1NR w KQkq -
+Robatsch defense: Pseudo-Austrian attack *
+r1bqkbnr/ppp3pp/2n5/5p2/2pPp3/2N1P3/PP1N1PPP/R1BQKB1R b KQkq -
+French: Steinitz variation *
+r1bqkbnr/ppp3pp/2np4/3Ppp2/4P3/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+Ponziani counter-gambit, Schmidt attack
+r1bqkbnr/ppp3pp/2np4/4N3/3Pp3/8/PPP2PPP/RNBQKB1R w KQkq -
+Vienna gambit *
+r1bqkbnr/ppp3pp/2np4/4pp2/3PP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Vienna gambit, Steinitz variation *
+r1bqkbnr/ppp3pp/6n1/3p1p2/8/2P3B1/PP2PPPP/RN1QKBNR w KQkq -
+Caro-Kann: classical, Mar\'oczy attack *
+r1bqkbnr/pppn1ppp/3p4/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Hanham variation
+r1bqkbnr/pppn1ppp/4p3/8/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+French: Rubinstein variation
+r1bqkbnr/pppn1ppp/8/3p4/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+French: Tarrasch, open, 4.ed ed *
+r1bqkbnr/pppn1ppp/8/3pp3/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+French: Tarrasch, open variation *
+r1bqkbnr/pppn1ppp/8/3pp3/3P1P2/4P3/PPP3PP/RNBQKBNR b KQkq -
+French: Tarrasch, Haberditz variation *
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/1QP5/PP2PPPP/RNB1KBNR b KQkq -
+Caro-Kann: Edinburgh variation *
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/2N1P3/PPP2PPP/R1BQKBNR b KQkq -
+French: Tarrasch, Guimard variation *
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: 3.Nd2 *
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: Tarrasch *
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+French: Tarrasch, closed variation *
+r1bqkbnr/pppn2pp/3p4/4Pp2/3p4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+KGD: Falkbeer, Keres variation *
+r1bqkbnr/pppnpppp/3p4/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Valencia opening *
+r1bqkbnr/pppp1p1p/2n3p1/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: fianchetto (Smyslov/Barnes) defense
+r1bqkbnr/pppp1p1p/2n3p1/3N4/3pP3/5N2/PPP2PPP/R1BQKB1R b KQkq -
+Three knights: Steinitz, Rosenthal variation
+r1bqkbnr/pppp1p1p/2n3p1/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Sicilian: closed *
+r1bqkbnr/pppp1p1p/2n3p1/4p3/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+Sicilian: closed, Korchnoi variation *
+r1bqkbnr/pppp1p1p/2n3p1/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Three knights: Steinitz variation
+r1bqkbnr/pppp1p1p/2n3p1/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna: Paulsen variation *
+r1bqkbnr/pppp1p1p/2n3p1/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Vienna: Paulsen-Mieses variation *
+r1bqkbnr/pppp1p1p/2n5/1B2p1p1/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Brentano defense
+r1bqkbnr/pppp1p1p/2n5/4N3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Neumann defense
+r1bqkbnr/pppp1p1p/2n5/6N1/4PppP/2N5/PPPP2P1/R1BQKB1R b KQkq -
+Vienna: Hamppe-Allgaier gambit
+r1bqkbnr/pppp1p1p/2n5/6p1/2B1Pp2/5N2/PPPP2PP/RNBQK2R w KQkq -
+KGA: Blachly gambit
+r1bqkbnr/pppp1p1p/2n5/6p1/3PPp2/2N2N2/PPP3PP/R1BQKB1R b KQkq -
+Vienna: Pierce gambit
+r1bqkbnr/pppp1p1p/2n5/8/2B1Pp2/5Q2/PPPP2PP/RNB2RK1 w kq -
+KGA: Muzio gambit, Holloway defense
+r1bqkbnr/pppp1p1p/2n5/8/2B1Ppp1/2N2N2/PPPP2PP/R1BQ1RK1 b kq -
+Vienna: Hamppe-Muzio gambit
+r1bqkbnr/pppp1ppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Ruy Lopez (Spanish opening)
+r1bqkbnr/pppp1ppp/2n5/1B6/3pP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+Scotch: Relfsson gambit (`MacLopez')
+r1bqkbnr/pppp1ppp/2n5/4p3/2B1P3/2P2N2/P2P1PPP/RNBQK2R w KQkq -
+Evans gambit: Mayet defense
+r1bqkbnr/pppp1ppp/2n5/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+King's pawn game
+r1bqkbnr/pppp1ppp/2n5/4p3/2P1P3/5N2/PP1P1PPP/RNBQKB1R b KQkq -
+Dresden opening
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+English: three knights system
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+Sicilian: closed, 2...Nc6 *
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English: Sicilian reversed
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: closed *
+r1bqkbnr/pppp1ppp/2n5/4p3/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Alekhine's defense: Scandinavian variation *
+r1bqkbnr/pppp1ppp/2n5/4p3/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+Vienna: Fyfe gambit
+r1bqkbnr/pppp1ppp/2n5/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Scotch opening
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Three knights game
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+Vienna: Paulsen variation
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Vienna game, Max Lange defense *
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna game, Max Lange defense
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2P2N2/PP1P1PPP/RNBQKB1R b KQkq -
+Ponziani opening
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+Vienna: Falkbeer variation *
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+King's pawn game
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPPBPPP/RNBQK2R b KQkq -
+Inverted Hungarian
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5NP1/PPPP1P1P/RNBQKB1R b KQkq -
+Konstantinopolsky opening
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Vienna game *
+r1bqkbnr/pppp1ppp/2n5/4p3/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Vienna gambit
+r1bqkbnr/pppp1ppp/2n5/4p3/8/2P5/PP1PPPPP/RNBQKBNR w KQkq -
+Caro-Kann defense *
+r1bqkbnr/pppp1ppp/2n5/4p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French defense *
+r1bqkbnr/pppp1ppp/2n5/8/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Maurian defense
+r1bqkbnr/pppp1ppp/2n5/8/2BpP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+Scotch gambit
+r1bqkbnr/pppp1ppp/2n5/8/2Q1P3/8/PPP2PPP/RNB1KBNR b KQkq -
+Center game: Hall variation
+r1bqkbnr/pppp1ppp/2n5/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+Scotch game
+r1bqkbnr/pppp1ppp/2n5/8/3Np3/8/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: S\"amisch attack *
+r1bqkbnr/pppp1ppp/2n5/8/3P4/4p3/PPPNPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Spielmann variation *
+r1bqkbnr/pppp1ppp/2n5/8/3PPp2/2N5/PPP3PP/R1BQKBNR b KQkq -
+Vienna: Steinitz gambit
+r1bqkbnr/pppp1ppp/2n5/8/3QP3/8/PPP2PPP/RNB1KBNR w KQkq -
+Center game
+r1bqkbnr/pppp1ppp/2n5/8/3pP3/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+Scotch: G\"oring gambit
+r1bqkbnr/pppp1ppp/2n5/8/4P3/4Q3/PPP2PPP/RNB1KBNR b KQkq -
+Center game: Paulsen attack
+r1bqkbnr/pppp1ppp/2n5/8/4Pp2/2N2N2/PPPP2PP/R1BQKB1R b KQkq -
+Vienna gambit
+r1bqkbnr/pppp1ppp/2n5/8/8/3Q4/PPP1PPPP/RNB1KBNR b KQkq -
+Scandinavian: Pytel-Wade variation *
+r1bqkbnr/pppp1ppp/8/1B2p3/3nP3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Bird's defense
+r1bqkbnr/pppp1ppp/8/4n3/3PP3/8/PPP2PPP/RNBQKB1R b KQkq -
+Irish (Chicago) gambit
+r1bqkbnr/pppp1ppp/8/4p3/3nP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Scotch: Lolli variation
+r1bqkbnr/pppp1ppp/8/nB2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Pollock defense
+r1bqkbnr/pppp2pp/2n2p2/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Nuremberg variation
+r1bqkbnr/pppp2pp/2n5/1B2pp2/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Ruy Lopez: Schliemann defense, Berger variation
+r1bqkbnr/pppp2pp/2n5/1B2pp2/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Schliemann defense
+r1bqkbnr/pppp2pp/2n5/4Np2/4P3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Latvian: Fraser defense
+r1bqkbnr/pppp2pp/2n5/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Keres (Mason-Steinitz) gambit *
+r1bqkbnr/pppp2pp/2n5/4pp2/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Rousseau gambit
+r1bqkbnr/pppp2pp/2n5/4pp2/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Sicilian: Grand Prix attack *
+r1bqkbnr/pppp2pp/2n5/4pp2/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: Pelikan variation *
+r1bqkbnr/pppp2pp/2n5/4pp2/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Vienna gambit *
+r1bqkbnr/pppp2pp/2n5/4pp2/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+KGD: Falkbeer, Milner-Barry variation *
+r1bqkbnr/pppp2pp/2n5/4pp2/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Three knights: Winawer defense (Gothic defense)
+r1bqkbnr/pppp2pp/2n5/4pp2/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna gambit *
+r1bqkbnr/pppp2pp/2n5/4pp2/4P3/2P2N2/PP1P1PPP/RNBQKB1R w KQkq -
+Ponziani counter-gambit
+r1bqkbnr/pppp2pp/2n5/4pp2/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Vienna gambit *
+r1bqkbnr/pppp2pp/2n5/5p2/4P3/4Q3/PPP2PPP/RNB1KBNR w KQkq -
+Center game: l'Hermet variation
+r1bqkbnr/pppp3p/2n5/4Ppp1/8/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Bird's opening, Swiss gambit *
+r1bqkbnr/ppppp1pp/2n2p2/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+KP: Neo-Mongoloid defense
+r1bqkbnr/ppppp1pp/2n5/5p2/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+KP: Colorado counter
+r1bqkbnr/pppppppp/2n5/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn: Lundin (Kevitz-Mikenas) defense
+r1bqkbnr/pppppppp/2n5/8/3PP3/2P5/P4PPP/RNBQKBNR b KQkq -
+KP: Nimzovich defense, Wheeler gambit
+r1bqkbnr/pppppppp/2n5/8/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+KP: Nimzovich defense
+r1bqkbnr/pppppppp/2n5/8/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+KP: Nimzovich defense
+r1bqkbnr/pppppppp/2n5/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+Dunst (Sleipner,Heinrichsen) opening *
+r1bqkbnr/pppppppp/2n5/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: Nimzovich defense
+r1bqkbnr/pppppppp/2n5/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Dunst (Sleipner, Heinrichsen) opening *
+r1bqkbnr/pppppppp/n7/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Lemming defense
+r1bqkbnr/pppppppp/n7/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Durkin's attack *
+r1bqnrk1/p2p1ppp/1pn1p3/2p5/2PPP3/P1PB4/4NPPP/R1BQK2R w KQ -
+Nimzo-Indian: S\"amisch, Capablanca variation
+r1bqnrk1/pp2b1pp/2n2p2/2p1p3/3pPP2/3P2P1/PPPNN1BP/R1BQ1RK1 b - -
+King's Indian: orthodox, Aronin-Taimanov, main line *
+r1bqnrk1/pp2b2p/2n2p2/2p1p1p1/3pPP2/3P2P1/PPPNN1BP/R1BQ1RK1 w - -
+King's Indian: orthodox, Aronin-Taimanov, Benk\"o attack *
+r1bqnrk1/pp2bppp/2n5/2p1p3/3pP3/3P1NP1/PPP1NPBP/R1BQ1RK1 w - -
+King's Indian: orthodox, Aronin-Taimanov, 9.Ne1 *
+r1bqr1k1/1p1n1pbp/p2p1np1/2pP4/P7/2N3P1/1P1NPPBP/R1BQ1RK1 w - -
+Benoni: fianchetto, 11...Re8
+r1bqr1k1/p1p2ppp/2pp1n2/4p3/1b2P3/2NP1N2/PPP2PPP/R1BQ1RK1 w - -
+Four knights: Janowski variation *
+r1bqr1k1/pp1n1ppp/2p2n2/b2pp3/4P3/P1NP1N2/1PP1BPPP/R2QBRK1 b - -
+Ruy Lopez: Kecskem\'et variation *
+r1bqr1k1/pp1n1ppp/2pb1n2/3pN1B1/3P1P2/2N5/PPP1B1PP/R2QK2R w KQ -
+Petrov: classical attack, Berger variation *
+r1bqr1k1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+King's Indian: orthodox, 7...Nbd7, 8.Re1 *
+r1bqr1k1/pp2ppbp/2n2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 w - -
+Dutch: Ilyin-Genevsky, Winter variation *
+r1bqr1k1/pp3pbp/n2p1np1/2pP4/4P3/2N2P2/PP1NB1PP/R1BQ1RK1 b - -
+Benoni: classical, 11.f3
+r1bqr1k1/pp3pbp/n2p1np1/2pP4/4P3/2N5/PP1NBPPP/R1BQ1RK1 w - -
+Benoni: classical with ...Re8 and ...Na6
+r1bqr1k1/ppb2pp1/2p1nn1p/3pp3/NPP1P3/P2P1NP1/2QBBP1P/R3R1K1 b - -
+Ruy Lopez: closed, Chigorin, Yugoslav system *
+r1bqr1k1/ppbn1pp1/2p2n1p/3pp3/1PP1P3/P1NP1N2/2Q1BPPP/R1B2RK1 b - -
+Ruy Lopez: closed, Chigorin, 12...Nc6 *
+r1bqr1k1/ppbn1pp1/2p2n1p/3pp3/1PP1P3/P2P1N2/1B1NBPPP/R2Q1RK1 b - -
+Ruy Lopez: closed, Breyer, Gligori\'c variation *
+r1bqr1k1/ppbn1pp1/2p2n1p/4p3/1PPpP1P1/P2P1N2/2Q1BP1P/RNB1K2R b KQ -
+Ruy Lopez: closed, Leonhardt variation *
+r1bqr1k1/ppbn1pp1/2p2n1p/4p3/1Pp1P3/P1NP1N2/2Q1BPPP/R1B2RK1 w - -
+Ruy Lopez: closed, Chigorin, Rauzer attack *
+r1bqr1k1/ppbn1pp1/5n1p/3pp3/NP2P3/P2P1N2/2Q1BPPP/R1B2RK1 w - -
+Ruy Lopez: closed, Chigorin, 12...c5d4 *
+r1bqr1k1/ppp2ppp/2n2n2/2bPN3/3P4/2N5/PPP2PPP/R1BQKB1R w KQ -
+two knights defense: Canal variation *
+r1bqr1k1/ppp2ppp/2n2n2/3pp3/1b2P3/2NP1N2/PPPBBPPP/R2Q1RK1 b - -
+Ruy Lopez: Berlin defense, Tarrasch trap *
+r1bqr1k1/ppp2ppp/2n2n2/4N3/3PpP2/P1P5/2P3PP/R1BQKB1R w KQ -
+Ruy Lopez: Steinitz defense deferred, Boleslavsky variation *
+r1bqr1k1/ppp2ppp/2np1n2/8/1bB1P3/2N1Q2N/PPPB1PPP/2KR3R b - -
+Center game: Kupreichik variation
+r1bqr1k1/ppp2ppp/8/2PPn3/2B2Qn1/2N1Bp2/PPP2PPP/R3K2R w KQ -
+two knights: Max Lange attack, Marshall variation *
+r1bqr1k1/ppp2ppp/8/2PPn3/5Qn1/2N1Bp2/PPP2PPP/R3KB1R b KQ -
+two knights: Max Lange attack, Rubinstein variation *
+r1bqr1k1/ppp2ppp/8/3pn3/3Q4/P1P1B3/1PP2PPP/R3KB1R b KQ -
+Four knights: Spielmann variation *
+r1bqr1k1/ppp4p/8/2PPnpp1/6n1/1BN1BpQ1/PPP2PPP/2KR3R b - -
+two knights: Max Lange attack, Berger variation *
+r1bqr1k1/pppn1pbp/3p1np1/4p3/2PP4/2N1PN2/PP2BPPP/R1BQ1RK1 w - -
+R\'eti: King's Indian attack, French variation *
+r1bqr1k1/pppp1ppp/2n2n2/3NpQ2/1bP5/4PN2/PP1P1PPP/R1B1KB1R b KQ -
+English: four knights, Stean variation
+r1bqrbk1/pp3ppp/2n2n2/2ppp3/P3P3/2PP1NP1/1P1N1PBP/R1BQ1RK1 b - -
+King's Indian: orthodox, 7...Nbd7, main line *
+r1bqrnk1/ppp1bppp/5n2/3p2B1/3P4/2NBP3/PPQ1NPPP/2KR3R b - -
+QGD: exchange, chameleon variation
+r1br2k1/p1q1ppbp/1pn2np1/2pp4/1P1P4/2P1PN2/PB1NBPPP/R2Q1RK1 b - -
+Catalan: closed, Spassky gambit *
+r1br2k1/p3ppbp/1pn2np1/2pq4/8/PP1PPN2/1B1NBPPP/R2QK2R b KQ -
+English: symmetrical, hedgehog, flexible formation *
+r1br2k1/p4ppp/1qn2n2/2b5/B3p3/2N3Q1/PPPPNPPP/R1B1K2R w KQ -
+Evans gambit: compromised defense, Potter variation *
+r1br2k1/pp2qppp/1bn1pn2/3p4/1PP5/P2BPN2/1B1N1PPP/R2QK2R b KQ -
+QGA: classical, Smyslov variation *
+r1br2k1/ppq2ppp/2n1pn2/2P5/1P1p4/P3PN2/1BQ2PPP/R3KB1R b KQ -
+QGA: classical, Flohr variation *
+r1q2rk1/pp2ppbp/2npbnp1/8/4PP2/1NN1B3/PPP1B1PP/R2Q1RK1 w - -
+Sicilian: dragon, classical, R\'eti-Tartakower variation
+r1r3k1/pp1bppbp/2np1np1/q7/3NP2P/1BN1BP2/PPPQ2P1/2KR3R b - -
+Sicilian: dragon, Yugoslav attack, 12.h4
+r2n1rk1/ppp1qppp/3p1n2/1B2p1B1/3PP1b1/2P2N2/P1P2PPP/R2QR1K1 w - -
+Four knights: symmetrical, Capablanca variation
+r2q1bnr/ppp1kBpp/3p4/3NN3/4P3/8/PP3PPP/R1Bb1RK1 b - -
+Scotch: Sea-cadet mate
+r2q1knr/pppb1Bpp/1b1p4/n7/3PP3/2N2N2/P1Q2PPP/R1B2RK1 b - -
+Evans gambit: Fraser-Mortimer attack
+r2q1rk1/1b1nbppp/p2p1n2/1pp1p3/3PP3/2P2N1P/PPBN1PP1/R1BQR1K1 w - -
+Ruy Lopez: closed, Breyer, Gligori\'c variation
+r2q1rk1/1bp1bppp/p1np1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Flohr-Zaitsev system (Lenzerheide variation)
+r2q1rk1/2p1bppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP1NQPPP/R1B2RK1 b - -
+Ruy Lopez: open, Malkin variation
+r2q1rk1/2p1bppp/p1np1n2/1p2p3/3PP1b1/1BP2N2/PP3PPP/RNBQR1K1 w - -
+Ruy Lopez: closed, Bogolyubov variation
+r2q1rk1/2p1bppp/p1npbn2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Kholmov variation
+r2q1rk1/2p1bppp/p3b3/1p1pn3/3Nn3/1BP5/PP3PPP/RNBQR1K1 w - -
+Ruy Lopez: open, Breslau variation
+r2q1rk1/2p2ppp/p1n1b3/1pbpP3/8/2P2N2/PPBN1nPP/R1BQ1RK1 w - -
+Ruy Lopez: open, Dilworth variation
+r2q1rk1/3nbppp/bpp1pn2/p2p4/2PP4/1P3NP1/PBQNPPBP/R4RK1 w - -
+Catalan: closed, Sokolsky variation
+r2q1rk1/p1p2ppp/2pp1n2/4p3/1b2P1b1/2NP1N2/PPP1QPPP/R1B2RK1 b - -
+Four knights: symmetrical, Metger unpin *
+r2q1rk1/p3bppp/1pn1bn2/2pp2B1/3P4/2N2NP1/PP2PPBP/2RQ1RK1 w - -
+QGD: Tarrasch, Stoltz variation
+r2q1rk1/p3n1pp/2p1bp2/3pp1B1/N1P5/6P1/PP2PbBP/R2Q1RK1 w - -
+Gr\"unfeld: exchange, Seville variation *
+r2q1rk1/p3n1pp/3bbp2/3pp3/N7/4B1P1/PP2PPBP/R2Q1RK1 b - -
+Gr\"unfeld: Spassky variation, main line, 13.Bd3 *
+r2q1rk1/p3n1pp/3bbp2/4p3/N2p4/4B1P1/PP2PPBP/R2Q1RK1 w - -
+Gr\"unfeld: exchange, Sokolsky variation *
+r2q1rk1/p3nppp/4b3/2bpp3/8/2N3P1/PP2PPBP/R1BQ1RK1 w - -
+Gr\"unfeld: Spassky variation, main line, 10...cd, 11.cd *
+r2q1rk1/p4ppp/2n1bn2/2bpp3/N7/1B1P1P2/PPP3PP/R1BQK1NR w KQ -
+Evans gambit: Steinitz variation *
+r2q1rk1/p4ppp/2n2n2/2bpp3/N5b1/1B1P4/PPP2PPP/R1BQK1NR w KQ -
+Evans gambit: G\"oring attack *
+r2q1rk1/p4ppp/b1B2n2/2bp4/8/2N5/PPPP1PPP/R1BQK2R w KQ -
+Giuoco Piano: Aitken variation *
+r2q1rk1/p4ppp/b1p2n2/2bpN3/3P4/2N5/PPP2PPP/R1BQK2R w KQ -
+Giuoco Piano: Steinitz variation *
+r2q1rk1/pb1nbppp/2p1pn2/1p1p4/2PP4/1PN2NP1/P1Q1PPBP/R1BR2K1 w - -
+Catalan: closed, Spassky gambit
+r2q1rk1/pp1bbppp/2nppn2/8/4PP2/1NN1B3/PPP1B1PP/R2Q1RK1 b - -
+Sicilian: modern Scheveningen, main line with Nb3
+r2q1rk1/pp1bppbp/2np1np1/8/2BNP3/2N1BP2/PPPQ2PP/2KR3R b - -
+Sicilian: dragon, Yugoslav attack, 10.O-O-O
+r2q1rk1/pp1bppbp/2np1np1/8/2BNP3/2N1BP2/PPPQ2PP/R3K2R w KQ -
+Sicilian: dragon, Yugoslav attack, 9...Bd7
+r2q1rk1/pp2b1pp/2n1bn2/2pp4/4pB2/1NN1P3/PPPQBPPP/2KR3R b - -
+Alekhine's defense: four pawns attack, Tartakower variation *
+r2q1rk1/pp2bpp1/2n2n1p/2pp1b2/5B2/1NNP2P1/PP2PPBP/R2Q1RK1 w - -
+Alekhine's defense: exchange, Karpov variation *
+r2q1rk1/pp2bppp/2n1bn2/3p2B1/2pP4/2N2NP1/PP2PPBP/2RQ1RK1 w - -
+QGD: Tarrasch, Bogolyubov variation
+r2q1rk1/pp2bppp/2npbn2/2p3B1/4P3/2N2N2/PPP1BPPP/R2QR1K1 b - -
+Philidor: Berger variation
+r2q1rk1/pp2pBbp/6p1/n1p5/3PP1b1/2P1BP2/P3N1PP/R2Q1RK1 b - -
+Gr\"unfeld: exchange, Seville variation
+r2q1rk1/pp2ppbp/1nnp2p1/5b2/2PP1B2/2N2N1P/PP2BPP1/R2Q1RK1 b - -
+Alekhine's defense: exchange, Karpov variation
+r2q1rk1/pp2ppbp/2n2np1/3p4/2PP2b1/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+QGD: Tarrasch, Prague variation, 9.Bg5 *
+r2q1rk1/pp2ppbp/3p1np1/n4P2/2b1P3/1NNBB3/PPP3PP/R2Q1RK1 b - -
+Sicilian: dragon, classical, Spielmann variation
+r2q1rk1/pp2ppbp/4b1p1/n2P4/4P3/3BBP2/P3N1PP/R2Q1RK1 b - -
+Gr\"unfeld: exchange, Sokolsky variation
+r2q1rk1/pp2ppbp/4b1p1/n7/3PP3/3BBP2/P3N1PP/R2Q1RK1 w - -
+Gr\"unfeld: Spassky variation, main line, 13.Bd3
+r2q1rk1/pp2ppbp/5np1/n2p1P2/4P3/1NNPB3/PP4PP/R2Q1RK1 w - -
+Sicilian: dragon, classical, Bernard defense
+r2q1rk1/pp4pp/1nnpb3/4p3/N2P1p2/5NP1/PP2PPBP/R2Q1RK1 b - -
+Sicilian: dragon, classical, Bernard defense *
+r2q1rk1/ppp1b1pp/1nn1b3/4pp2/8/2NPBNP1/PP2PPBP/R1Q2RK1 b - -
+Sicilian: dragon, classical, R\'eti-Tartakower variation *
+r2q1rk1/ppp1b1pp/1nn1b3/4pp2/8/2NPPN2/PP1BBPPP/R2Q1RK1 w - -
+Sicilian: modern Scheveningen, main line with Nb3 *
+r2q1rk1/ppp1b1pp/2n1b3/3n1p2/4p3/1QNP1NP1/PP2PPBP/R1B2RK1 w - -
+Sicilian: dragon, classical, Zollner gambit *
+r2q1rk1/ppp1b1pp/2n1b3/3npp2/8/2NPPN2/PP2BPPP/R1BQ1RK1 w - -
+Sicilian: modern Scheveningen, main line *
+r2q1rk1/ppp1b1pp/2n1b3/3npp2/8/P1NPPN2/1PQ2PPP/R1B1KB1R w KQ -
+Sicilian: Scheveningen, classical *
+r2q1rk1/ppp1bppp/1nn1b3/4p3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+Sicilian: dragon, classical, 9.Nb3 *
+r2q1rk1/ppp1bppp/1nn1b3/4p3/P7/2NP1NP1/1P2PPBP/R1BQ1RK1 b - -
+Sicilian: dragon, classical, Alekhine variation *
+r2q1rk1/ppp1bppp/2n1b3/3np3/8/2NP1NP1/PP2PPBP/R1BQK2R w KQ -
+Sicilian: dragon, classical, 8.O-O *
+r2q1rk1/ppp1ppbp/1nn3p1/8/3PP1b1/2NQBN2/PP2BPPP/2KR3R b - -
+Gr\"unfeld: Russian, Keres variation
+r2q1rk1/ppp1ppbp/2np1np1/5b2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, lesser Simagin (Spassky) variation
+r2q1rk1/ppp1ppbp/2np1np1/8/2PP2b1/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, Simagin variation
+r2q1rk1/ppp2ppp/1bnp4/1B2p2n/3PP1b1/2PQ1N2/PP2NPPP/R1B2RK1 b - -
+Four knights: symmetrical, Blake variation *
+r2q1rk1/ppp2ppp/2n2n2/3pp3/1b2P1b1/2NP1N2/PPPBBPPP/R2QK2R w KQ -
+Ruy Lopez: closed Berlin defense, Bernstein variation *
+r2q1rk1/ppp2ppp/2np1n2/1B2p3/1b2P1b1/2NPBN2/PPP2PPP/R2Q1RK1 b - -
+Four knights: symmetrical, Tarrasch variation *
+r2q1rk1/ppp2ppp/2np1n2/1B2p3/1b2P1b1/3P1N2/PPP1NPPP/R1BQ1RK1 b - -
+Four knights: symmetrical, Pillsbury variation *
+r2q1rk1/ppp2ppp/2npbn2/1B2p1B1/1b2P3/2NP1N2/PPP2PPP/R2Q1RK1 w - -
+Four knights: symmetrical, Tarrasch variation
+r2q1rk1/ppp3pp/1nnbb3/2B1p3/N4p2/3P1NP1/PP2PPBP/R2Q1RK1 w - -
+Sicilian: dragon, classical, Spielmann variation *
+r2q1rk1/ppp3pp/2n5/2bNp3/4P1b1/5N2/PPP1QPPP/R1B1K2R w KQ -
+Giuoco piano: Holzhausen attack *
+r2q1rk1/pppbbppp/2np1n2/1B2p3/3PP3/2N2N2/PPP2PPP/R1BQR1K1 w - -
+Ruy Lopez: Berlin defense, Tarrasch trap
+r2q1rk1/pppnbppp/8/8/1n6/2N3Q1/PPPP1PPP/R1BK2NR b - -
+Scotch: Rosenthal variation *
+r2q2k1/pp3ppp/8/2b1r3/3p4/3P4/PPP1NPPn/R1BQ1RK1 w - -
+Giuoco Piano: Therkatz-Herzog variation *
+r2qbrk1/1pp1bppp/p1np1n2/4p3/B2PP3/2P2N2/PP1N1PPP/R1BQR1K1 w - -
+Ruy Lopez: Kecskem\'et variation
+r2qk1nr/pp2bppp/2n1b3/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+King's Indian: Semi-Averbakh system *
+r2qk1nr/pp2bppp/2n5/2p1p3/2Pp2b1/3PPNP1/PP3PBP/RNBQ1RK1 b kq -
+King's Indian: Averbakh, main line *
+r2qk1nr/pp2bppp/2n5/2ppp3/2P3b1/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+King's Indian: Averbakh, 6...c5 *
+r2qk1nr/pp2bppp/2n5/2ppp3/6b1/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+King's Indian: Averbakh system *
+r2qk1nr/pp4pp/2nbbp2/2ppp3/8/P1PP1NP1/1P2PPBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, Byrne variation *
+r2qk1nr/ppp1npbp/3pb1p1/3Np3/2P5/4P1P1/PP1P1PBP/R1BQK1NR w KQkq -
+Sicilian: closed, Smyslov variation *
+r2qk1nr/ppp2pbp/2npb1p1/4p3/2P5/2N1P1P1/PP1PNPBP/R1BQK2R w KQkq -
+English: closed, Hort variation
+r2qk1nr/ppp2pbp/2npb1p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR w KQkq -
+Sicilian: closed, 6.Be3 *
+r2qk1nr/ppp2ppp/1bnp4/8/2BPP1b1/2N2N2/P4PPP/R1BQ1RK1 w kq -
+Evans gambit
+r2qk1nr/ppp2ppp/1bnp4/8/Q1BPP1b1/2N2N2/P4PPP/R1B2RK1 b kq -
+Evans gambit: Fraser attack
+r2qk1nr/ppp2ppp/2nb4/3p4/3Pp3/4P3/PPPNQPPP/RNB1K2R w KQkq -
+French: classical, Tarrasch variation *
+r2qk1nr/ppp2ppp/2np4/2b5/2BpP1b1/2P2N2/PP3PPP/RNBQ1RK1 w kq -
+Scotch gambit: Anderssen (Paulsen, Suhle) counter-attack
+r2qk1nr/ppp2ppp/2np4/b3p3/2BPP1b1/2P2N2/P4PPP/RNBQ1RK1 w kq -
+Evans gambit: Alapin-Steinitz variation
+r2qk1nr/pppb1ppp/2nb4/1B1p4/2PQ4/4P3/PP3PPP/RNB1K1NR w KQkq -
+French: Winawer, Kondratiyev variation *
+r2qk1nr/pppb1ppp/2np4/b3p3/2BPP3/2P2N2/P4PPP/RNBQ1RK1 w kq -
+Evans gambit: Sanders-Alapin variation
+r2qk2r/1b1n1ppp/p2bpn2/1pp5/3P4/1BN1PN2/PP2QPPP/R1BR2K1 w kq -
+QGA: classical, Smyslov variation
+r2qk2r/1b1nbppp/pp1ppn2/8/2PQ4/1PN2NP1/P3PPBP/R1BR2K1 w kq -
+English: symmetrical, hedgehog, flexible formation
+r2qk2r/1bppbppp/p1n2n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQR1K1 w kq -
+Ruy Lopez: Trajkovi\'c counter-attack
+r2qk2r/1p1bbppp/p1nppn2/6B1/3NPP2/2N5/PPPQ2PP/2KR1B1R w kq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 defense, 9...Be7
+r2qk2r/2p1bppp/p1n1b3/1p1pP3/2P1n3/1B3N2/PP2QPPP/RNB2RK1 b kq -
+Ruy Lopez: open, Howell attack, Adam variation
+r2qk2r/2p1bppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP3PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, classical defense
+r2qk2r/2p1bppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP3PPP/RNBQR1K1 b kq -
+Ruy Lopez: open, 9...Be7, 10.Re1
+r2qk2r/2p1bppp/p1np1n2/1p2p3/3PP1b1/1BP2N2/PP2QPPP/RNB1K2R w KQkq -
+Ruy Lopez: Wormald attack, Gr\"unfeld variation
+r2qk2r/2p1nppp/p3b3/1pbpP3/4n3/1BPQ1N2/PP3PPP/RNB2RK1 w kq -
+Ruy Lopez: open, Motzko attack, Nenarokov variation
+r2qk2r/2p2ppp/p1n1b3/1pbpP3/4n3/1BP2N2/PP1N1PPP/R1BQ1RK1 b kq -
+Ruy Lopez: open, St. Petersburg variation
+r2qk2r/2p2ppp/p1n1b3/1pbpP3/4n3/1BP2N2/PP3PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, Italian variation
+r2qk2r/2p2ppp/p1n1b3/1pbpP3/4n3/1BPQ1N2/PP3PPP/RNB2RK1 b kq -
+Ruy Lopez: open, Motzko attack
+r2qk2r/3bbppp/p1nppB2/1p6/4PP2/2N2N2/PPPQ2PP/2KR1B1R b kq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 defense, 11.Bxf6
+r2qk2r/p1pn1ppp/8/3pp3/Np2b1Q1/1B6/PPP2K1P/R1B3R1 w kq -
+Evans gambit declined, Pavlov variation *
+r2qk2r/pp1bppbp/2n2np1/2ppN3/8/1P2P3/PBPPBPPP/RN1QK2R w KQkq -
+Queen's Indian: Opo\v censky variation *
+r2qk2r/pp2b1pp/2n1b3/2pnpp2/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w kq -
+King's Indian: Four pawns attack, main line *
+r2qk2r/pp2bpp1/2n2nb1/2p1p2p/3pP1PN/3P3P/PPPN1PB1/R1BQ1RK1 w kq -
+King's Indian: Petrosian system, Keres variation *
+r2qk2r/pp2bppp/2n1bn2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+King's Indian: Gligori\'c-Taimanov system *
+r2qk2r/pp3ppp/2n1pn2/3p1b2/1b1P1B2/1QN1PN2/PP3PPP/R3KB1R w KQkq -
+QGD Slav: exchange, Trifunovi\'c variation
+r2qk2r/pp3ppp/2nbp3/3p4/3Pn1b1/1P3N2/PBP1BPPP/RN1Q1RK1 w kq -
+QGD: Pillsbury attack *
+r2qk2r/pp3ppp/2nbpn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w kq -
+QGD: Orthodox defense, Botvinnik variation *
+r2qk2r/ppp1b1pp/2n5/3p1p2/2PPn1b1/3B1N2/PP3PPP/RNBQR1K1 b kq -
+Petrov: classical attack, Krause variation
+r2qk2r/ppp1b1pp/2n5/3p1p2/3Pn1b1/2PB1N2/PP1N1PPP/R1BQR1K1 b kq -
+Petrov: classical attack, Berger variation
+r2qk2r/ppp1bppp/1nn1b3/4p3/8/2NP1NP1/PP2PPBP/R1BQK2R w KQkq -
+Sicilian: dragon, classical, Nottingham variation *
+r2qk2r/ppp1bppp/2n1b3/3np3/8/3P1NP1/PP2PPBP/RNBQK2R w KQkq -
+Sicilian: dragon, classical attack *
+r2qk2r/ppp1bppp/2n1b3/3np3/8/P1N1P3/1PQP1PPP/R1B1KBNR w KQkq -
+Sicilian: Taimanov variation *
+r2qk2r/ppp2p1p/2n1bPp1/2b3N1/2pp4/8/PPP2PPP/RNBQR1K1 w kq -
+two knights: Max Lange attack, Loman defense
+r2qk2r/ppp2pPp/2n1b3/2b5/2pp4/5N2/PPP2PPP/RNBQR1K1 b kq -
+two knights: Max Lange attack, Schlechter variation
+r2qk2r/ppp2ppp/2n1b3/2bnp3/8/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+Sicilian: accelerated fianchetto, modern variation with Bc4 *
+r2qk2r/ppp2ppp/2n1b3/2bnp3/8/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Sozin, 7.Be3 *
+r2qk2r/ppp2ppp/2n5/3np3/1b4b1/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Richter-Rauzer, Margate (Alekhine) variation *
+r2qk2r/ppp2ppp/2np1n2/2b1p3/2B1P1b1/2NP1N2/PPP2PPP/R1BQK2R w KQkq -
+Giuoco Pianissimo: Canal variation *
+r2qk2r/ppp2ppp/2np1n2/2b5/2B1Pp2/2NP1Q1P/PPP3P1/R1B1K2R w KQkq -
+KGD: classical, Svenonius variation
+r2qk2r/ppp3pp/1bn1b3/3npp2/8/2NPPN2/PP2BPPP/R1BQ1RK1 w kq -
+Sicilian: Sozin, Fischer variation *
+r2qk2r/ppp3pp/2n5/3p1p2/2PPn1bb/3B1N2/PP3PPP/RNBQR1K1 w kq -
+Petrov: classical attack, Mar\'oczy variation
+r2qk2r/pppbbppp/2Bp1n2/4p3/3PP3/2N2N2/PPP2PPP/R1BQ1RK1 b kq -
+Ruy Lopez: closed Berlin defense, Showalter variation
+r2qk2r/pppbbppp/2np1n2/1B2p1B1/3PP3/2N2N2/PPP2PPP/R2Q1RK1 b kq -
+Ruy Lopez: closed Berlin defense, Bernstein variation
+r2qk2r/pppbbppp/2np1n2/1B2p3/3PP3/2N2N2/PPP2PPP/R1BQ1RK1 w kq -
+Ruy Lopez: Berlin defense, hedgehog variation
+r2qkb1r/1bpp1ppp/p1n2n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Archangelsk (counterthrust) variation
+r2qkb1r/1p1b1ppp/2n1pn2/pBPp4/1P6/1QP1P3/P4PPP/RNB1K1NR b KQkq -
+QGD: semi-Slav, Junge variation *
+r2qkb1r/1p1b1ppp/2n1pn2/pBPp4/1P6/2P1P3/P3QPPP/RNB1K1NR b KQkq -
+QGD: semi-Slav, Koomen variation *
+r2qkb1r/1p1b1ppp/2n1pn2/pBPp4/PP6/2P1P3/5PPP/RNBQK1NR b KQkq -
+QGD: semi-Slav, Abrahams variation *
+r2qkb1r/1p1b1ppp/p1nppn2/6B1/3NP3/2N5/PPPQ1PPP/2KR1B1R w kq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 defense, 8...Bd7
+r2qkb1r/1p3ppp/p1npbn2/4p1B1/4P3/N1N5/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Pelikan, Bird variation
+r2qkb1r/1ppbnppp/p1np4/4p3/B2PP3/2P2N2/PP3PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense, Rubinstein variation
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1B3N2/PPP1QPPP/RNB2RK1 b kq -
+Ruy Lopez: open, Howell attack
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1B3N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, 8...Be6
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1B3N2/PPPN1PPP/R1BQ1RK1 b kq -
+Ruy Lopez: open, Bernstein variation
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP3PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, 9.c3
+r2qkb1r/2p2ppp/p1n1b3/1pn1P1N1/3p4/1BP5/PP1N1PPP/R1BQ1RK1 b kq -
+Ruy Lopez: open, Bernstein variation, Karpov gambit
+r2qkb1r/2p2ppp/p1n1b3/1pnpP3/8/1BP2N2/PP3PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, Berlin variation
+r2qkb1r/2p2ppp/p1pp1n2/4p3/3PP1b1/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Steinitz defense deferred, Lipnitsky variation
+r2qkb1r/p2b1ppp/5n2/1B1pp3/Q7/4P3/PP3PPP/RNB1K2R b KQkq -
+QGD: Semi-Tarrasch, San Sebastian variation *
+r2qkb1r/p3pppp/2p5/2pn3b/4N3/5N1P/PPPP1PP1/R1BQK2R b KQkq -
+English: Nenarokov variation *
+r2qkb1r/p4ppp/2p1pn2/3p4/3p4/4P2P/PPP1QPP1/RNB2RK1 w kq -
+QGD: Lasker defense, main line *
+r2qkb1r/pb1n1ppp/2p1pn2/1p6/3P4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran, Wade variation
+r2qkb1r/pp1b1ppp/2n1pn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Gr\"unfeld: Opo\v censky variation *
+r2qkb1r/pp1bppp1/5n1p/1BpP4/4p3/2N5/PPP1QPPP/R3K1NR b KQkq -
+QGD: Albin counter-gambit, Kr\'enosz variation *
+r2qkb1r/pp1bpppp/2np1n2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Richter-Rauzer, Larsen variation
+r2qkb1r/pp1bpppp/2np1n2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R b KQkq -
+Sicilian: Richter-Rauzer, Larsen variation, 7.Qd2
+r2qkb1r/pp1n1ppp/2n1p3/2Pp4/Q5b1/2P1PN2/PP1N1PPP/R1B1KB1R b KQkq -
+QGD: Cambridge Springs defense, Rubinstein variation *
+r2qkb1r/pp1n1ppp/4pn2/2pp4/3P2b1/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD: Capablanca variation *
+r2qkb1r/pp2n1pp/2n1bp2/2p1p3/3PP3/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, orthodox main line *
+r2qkb1r/pp2n1pp/2n1bp2/2ppp3/4P3/2PP1NP1/PP3PBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, orthodox, 7.Nge2 c6 *
+r2qkb1r/pp2n1pp/2n1bp2/2ppp3/8/2NP1NP1/PPP1PPBP/1RBQ1RK1 b kq -
+King's Indian: S\"amisch, Ruban variation *
+r2qkb1r/pp2n1pp/2n1bp2/2ppp3/8/P1NP1NP1/1PP1PPBP/R1BQ1RK1 b kq -
+King's Indian: S\"amisch, Panno formation *
+r2qkb1r/pp2pppp/2n2n2/1BPp4/6b1/4PN2/PPP2PPP/RNBQK2R b KQkq -
+QGD: Ragozin, Vienna variation *
+r2qkb1r/pp2pppp/2n2n2/1Bpp3b/8/1P2PN1P/PBPP1PP1/RN1QK2R b KQkq -
+Queen's Indian: 4.Nc3, main line *
+r2qkb1r/pp2pppp/2n2n2/2Pp4/6b1/2P1PN2/PP3PPP/RNBQKB1R b KQkq -
+QGD semi-Slav: 5.Bg5 dc *
+r2qkb1r/pp2pppp/2n2n2/2pp1b2/3P4/4PN2/PPP1BPPP/RNBQK2R w KQkq -
+QGD: classical variation (5.Bf4) *
+r2qkb1r/pp2pppp/2n2n2/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: 5.Bf4 *
+r2qkb1r/pp2pppp/2n2n2/2pp4/2PP2b1/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD: Semi-Tarrasch defense, Pillsbury variation *
+r2qkb1r/pp2pppp/2n2n2/2pp4/3P2b1/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: 5.Bg5 *
+r2qkb1r/pp2pppp/2n2n2/2pp4/6b1/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: Smyslov system *
+r2qkb1r/pp2pppp/2n2n2/3p1b2/3P1B2/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+QGD Slav: exchange variation, 6.Bf4 Bf5 *
+r2qkb1r/pp2pppp/2n2n2/3p1b2/3P1B2/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+QGD Slav: exchange variation, 6.Bf4 Bf5
+r2qkb1r/pp2pppp/2n2n2/3p1b2/3P4/5N2/PPPN1PPP/R1BQKB1R w KQkq -
+QGD: exchange, S\"amisch variation *
+r2qkb1r/pp2pppp/2n2n2/8/2Pp2b1/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+Benoni: Uhlmann variation *
+r2qkb1r/pp2pppp/2n2nb1/2pp4/6PN/1P2P2P/PBPP1P2/RN1QKB1R b KQkq -
+Queen's Indian: 4.Nc3, Botvinnik variation *
+r2qkb1r/pp2pppp/n1p2n2/5b2/P1pP4/2N1PN2/1P3PPP/R1BQKB1R w KQkq -
+QGD Slav: Dutch, Lasker variation
+r2qkb1r/pp2pppp/n1p2n2/8/P1pPP1b1/2N2N2/1P3PPP/R1BQKB1R w KQkq -
+QGD Slav: Smyslov variation
+r2qkb1r/pp3p1p/2n3p1/2Pp4/1P2p1b1/2P1PN2/P2N1P2/R1BQKB1R w KQkq -
+QGD semi-Slav: anti-Meran, Lilienthal variation *
+r2qkb1r/pp3ppp/2n1b3/2pnp1N1/8/2N3P1/PP1PPPBP/R1BQK2R b KQkq -
+Sicilian: accelerated fianchetto, Breyer variation *
+r2qkb1r/pp3ppp/2n1bn2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+King's Indian: Larsen variation *
+r2qkb1r/pp3ppp/2n1pn2/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Gr\"unfeld with Bf4 & e3 *
+r2qkb1r/pp3ppp/2n1pn2/2pp3b/3P4/1P2PN1P/P1P1BPP1/RNBQ1RK1 b kq -
+QGD: Tartakower (Makagonov-Bondarevsky) system *
+r2qkb1r/pp3ppp/2n1pn2/2pp3b/3P4/4PN1P/PPP1BPP1/RNBQ1RK1 w kq -
+QGD: Neo-orthodox variation, 7.Bh4 *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN1P/PPP1BPP1/RNBQ1RK1 b kq -
+QGD: Neo-orthodox variation *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQ1RK1 w kq -
+QGD: 6.Nf3 *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 b kq -
+QGD: Orthodox defense *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P4/4Pb1P/PPP1BPP1/RNBQ1RK1 w kq -
+QGD: Neo-orthodox variation, 7.Bxf6 *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/Q2P2b1/2P1PN2/PP1N1PPP/R1B1KB1R b KQkq -
+QGD: Cambridge Springs defense *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/Q2P4/2P1Pb2/PP1N1PPP/R1B1KB1R w KQkq -
+QGD: Cambridge Springs defense, Capablanca variation *
+r2qkb1r/pp3ppp/2n1pn2/2ppN2b/3P4/4P2P/PPP1BPP1/RNBQ1RK1 b kq -
+QGD: Lasker defense *
+r2qkb1r/pp3ppp/2n1pn2/3p3b/3N4/1P2P2P/P1P1BPP1/RNBQ1RK1 b kq -
+QGD: Tartakower (Makagonov-Bondarevsky) system, 8.cd Nxd5 *
+r2qkb1r/pp3ppp/2n1pn2/3p4/Q2N2b1/2P1P3/PP1N1PPP/R1B1KB1R b KQkq -
+QGD: Cambridge Springs defense, Yugoslav variation *
+r2qkb1r/pp3ppp/2n1pn2/3p4/Q2p2b1/2P1PN2/PP1N1PPP/R1B1KB1R w KQkq -
+QGD: Cambridge Springs defense, 7.cd *
+r2qkb1r/pp3ppp/2n2n2/2Ppp3/6b1/2P1PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD semi-Slav: Botvinnik system (anti-Meran) *
+r2qkb1r/pp3ppp/2n2n2/2pp4/3P2b1/2N2NP1/PP2PPBP/R1BQK2R w KQkq -
+QGD: Tarrasch, Wagner variation
+r2qkb1r/pp3ppp/2n2n2/2ppp3/3P2b1/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD: Alekhine variation *
+r2qkb1r/pp3ppp/2n2n2/2ppp3/6b1/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+King's Indian: Zinnowitz variation *
+r2qkb1r/pp3ppp/2n2n2/4p3/2Pp2b1/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+Benoni: classical, 8.Bg5 *
+r2qkb1r/pp3ppp/2n5/2Pp3P/1P2n3/2P1Pp1P/P4P2/RNBQKB1R w KQkq -
+QGD semi-Slav: Ekstrom variation *
+r2qkb1r/pp3ppp/2n5/2Pp3b/1P1Np1n1/2P1P2P/P4P2/RNBQKB1R b KQkq -
+QGD semi-Slav: anti-Meran, Alatortsev system *
+r2qkb1r/pp3ppp/2n5/2Pp3b/1P2p1n1/2P1PN1P/P4P2/RNBQKB1R w KQkq -
+QGD semi-Slav: anti-Meran gambit *
+r2qkb1r/ppp1p1pp/1nn1p3/2P5/3P2b1/5N2/PP4PP/RNBQKB1R b KQkq -
+Alekhine's defense: four pawns attack, Ilyin-Genevsky variation
+r2qkb1r/ppp2ppp/1nn5/4p3/6b1/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Richter-Rauzer, Pod\v ebrady variation *
+r2qkb1r/ppp2ppp/2n1b3/3np3/8/2N1P3/PPQP1PPP/R1B1KBNR w KQkq -
+Sicilian: Taimanov variation *
+r2qkb1r/ppp2ppp/2n1b3/3np3/8/3P1NP1/PP2PP1P/RNBQKB1R w KQkq -
+Sicilian: dragon, 6.Be3 *
+r2qkb1r/ppp2ppp/2n1b3/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, Byrne (English) attack *
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NP1N2/PP1BPPPP/R2QKB1R b KQkq -
+Sicilian: Richter-Rauzer, Larsen variation *
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+Sicilian: Richter-Rauzer *
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NP1NP1/PP2PP1P/R1BQKB1R b KQkq -
+Sicilian: Richter-Rauzer, Bondarevsky variation *
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NPPN2/PP3PPP/R1BQKB1R b KQkq -
+Sicilian: Richter-Rauzer, 6...e6 *
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, 6.Bg5 *
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/P2PPN2/1P3PPP/RNBQKB1R b KQkq -
+Sicilian: Najdorf, 6...e6 *
+r2qkb1r/ppp2ppp/2n5/4p3/6b1/2nPPN2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Richter-Rauzer, Richter attack *
+r2qkb1r/ppp2ppp/n1n5/4p3/1P2P1b1/P1NP1N2/5PPP/R1BQKB1R b KQkq -
+Sicilian: Pelikan, Chelyabinsk variation *
+r2qkb1r/ppp2ppp/n1n5/4p3/4P1b1/P1NPBN2/1P3PPP/R2QKB1R b KQkq -
+Sicilian: Pelikan, Bird variation *
+r2qkb1r/ppp2ppp/n7/4p3/1P1nPP2/P1NP4/5P1P/R1BQKB1R b KQkq -
+Sicilian: Sveshnikov variation *
+r2qkb1r/ppp3pp/2n1bn2/3p1p2/2PPp3/2N1P3/PP1N1PPP/R1BQKB1R w KQkq -
+French: Steinitz, Boleslavsky variation *
+r2qkb1r/ppp3pp/2n1bn2/3ppp2/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Pirc: Austrian attack, 6.Be3 *
+r2qkb1r/ppp3pp/2n1bp2/3np3/8/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+Sicilian: dragon, Yugoslav attack, 7...O-O *
+r2qkb1r/ppp3pp/2n1bp2/3np3/8/3P1NP1/PP2PPBP/RNBQK2R w KQkq -
+Sicilian: dragon, Yugoslav attack *
+r2qkb1r/ppp3pp/2n5/3npp2/1P4b1/P2PPN2/5PPP/RNBQKB1R b KQkq -
+Sicilian: Najdorf, Polugayevsky variation *
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/P2PPN2/1P2BPPP/RNBQK2R b KQkq -
+Sicilian: Najdorf, 7...Be7 *
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/P2PPN2/1P3PPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, 7.f4 *
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/PQ1PPN2/1P3PPP/RNB1KB1R b KQkq -
+Sicilian: Najdorf, 7...Qb6 *
+r2qkb1r/pppb1ppp/2Bp1n2/4p3/3PP3/2N2N2/PPP2PPP/R1BQK2R b KQkq -
+Ruy Lopez: old Steinitz defense, Nimzovich attack
+r2qkb1r/pppb1ppp/2n2n2/1B6/Q3p3/2N5/PPP2PPP/R1B1K1NR w KQkq -
+Scandinavian: Anderssen counter-attack orthodox attack *
+r2qkb1r/pppb1ppp/2np1n2/1B6/3pP3/2N2N2/PPP2PPP/R1BQ1RK1 w kq -
+Ruy Lopez: closed Berlin defense, Wolf variation
+r2qkb1r/pppn2p1/8/3pNbPp/3Pn3/8/PPP2P1P/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Brentano defense, Caro variation *
+r2qkbnr/1p3ppp/p1n1p3/2pp4/3P2b1/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD: Capablanca anti-Cambridge Springs variation *
+r2qkbnr/1pp2pp1/p1p5/4p2p/4P1b1/5N1P/PPPP1PP1/RNBQ1RK1 w kq -
+Ruy Lopez: exchange variation, Alapin gambit
+r2qkbnr/1pp3pp/p1np4/4pb2/B7/2P2N2/PP1P1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: Siesta, Kopayev variation
+r2qkbnr/1ppb1p1p/p1np2p1/4p3/B2PP3/2P2N2/PP3PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense, fianchetto (Bronstein) variation
+r2qkbnr/1ppb1ppp/p1np4/4p3/B3P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense
+r2qkbnr/pp1b1ppp/2n1p3/2ppP3/3P4/2P2N2/PP3PPP/RNBQKB1R w KQkq -
+French: advance, Euwe variation
+r2qkbnr/pp1nppp1/2p3bp/7P/3P4/5NN1/PPP2PP1/R1BQKB1R b KQkq -
+Caro-Kann: classical, Spassky variation
+r2qkbnr/pp1nppp1/2p3bp/8/3P3P/5NN1/PPP2PP1/R1BQKB1R w KQkq -
+Caro-Kann: classical, 7...Nd7
+r2qkbnr/pp2pppp/2n5/1Bp4b/1PPp4/4PN1P/P2P1PP1/RNBQK2R b KQkq -
+Nimzo-Indian: Leningrad, ...b5 gambit *
+r2qkbnr/pp2pppp/2n5/1Bp4b/2Pp4/3PPN1P/PP3PP1/RNBQK2R b KQkq -
+Nimzo-Indian: Leningrad, main line *
+r2qkbnr/pp2pppp/2n5/1Bpp4/6b1/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: Leningrad variation *
+r2qkbnr/pp2pppp/2n5/2pp1b2/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+QGD: Harrwitz attack *
+r2qkbnr/pp2pppp/2n5/2pp1b2/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Gr\"unfeld: 4.Bf4 *
+r2qkbnr/pp2pppp/2n5/2pp4/2PP2b1/4PN2/PP3PPP/RNBQKB1R b KQkq -
+QGD: Been-Koomen variation *
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+QGD: 4.Bg5 Be7 *
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+QGD: 4.Bg5 *
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPPN1PPP/R1BQKB1R b KQkq -
+QGD: 4.Bg5 Nbd7 *
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Gr\"unfeld: Stockholm variation *
+r2qkbnr/pp2pppp/2n5/3p4/2Pp2b1/1Q2PN2/PP3PPP/RNB1KB1R b KQkq -
+QGD: Canal (Venice) variation *
+r2qkbnr/pp2pppp/2n5/3p4/2Pp2b1/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD: Semi-Tarrasch *
+r2qkbnr/pp2pppp/2n5/3p4/3P2b1/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+QGD: exchange, positional line, 5...c6 *
+r2qkbnr/pp2pppp/2n5/3p4/3P2b1/5N2/PPP2PPP/RNBQKB1R w KQkq -
+QGD: exchange, positional line *
+r2qkbnr/pp3ppp/2n1p3/1Bpp4/3P2b1/4PN2/PPPN1PPP/R1BQK2R b KQkq -
+QGD: Manhattan variation *
+r2qkbnr/pp3ppp/2n1p3/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQ1RK1 b kq -
+Gr\"unfeld: Gr\"unfeld gambit *
+r2qkbnr/pp3ppp/2n1p3/2pp4/3P2b1/2P1PN2/PP1N1PPP/R1BQKB1R b KQkq -
+QGD: 5...c6 *
+r2qkbnr/pp3ppp/2n1p3/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQ1RK1 b kq -
+QGD: 4.Bg5 Be7, 5.e3 O-O *
+r2qkbnr/pp3ppp/2n1p3/2pp4/3P2b1/4PN2/PPPN1PPP/R1BQKB1R w KQkq -
+QGD *
+r2qkbnr/pp3ppp/2n1p3/2ppN3/3P2b1/4P3/PPP1BPPP/RNBQK2R b KQkq -
+QGD: Lasker variation *
+r2qkbnr/pp3ppp/2n5/2P5/N2p2b1/5N2/PP2PPPP/R1BQKB1R b KQkq -
+Caro-Kann: Panov-Botvinnik, Herzog defense *
+r2qkbnr/pp3ppp/2n5/2pp4/3P2b1/1QN2N2/PP2PPPP/R1B1KB1R b KQkq -
+Caro-Kann: Panov-Botvinnik, Reifir (Spielmann) variation *
+r2qkbnr/pp3ppp/2n5/2pp4/3P2b1/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+Caro-Kann: Panov-Botvinnik, normal variation *
+r2qkbnr/pp3ppp/2n5/2pp4/Q2P2b1/2N2N2/PP2PPPP/R1B1KB1R b KQkq -
+Caro-Kann: Panov-Botvinnik, Czerniak variation *
+r2qkbnr/pp3ppp/2n5/2ppp3/6b1/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: accelerated Averbakh system *
+r2qkbnr/pp3ppp/4p3/3p4/3Q4/6P1/PPb1PPBP/RNB2RK1 w kq -
+Gr\"unfeld: Gr\"unfeld gambit accepted *
+r2qkbnr/pp3ppp/8/3pn3/8/8/PPP1NPPP/RNBQK2R b KQkq -
+Bishop's opening: Lisitsyn variation
+r2qkbnr/pp4pp/2n1bp2/2p1p3/3pP3/2PP1NP1/PP3PBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, orthodox, 7.d5 c6 *
+r2qkbnr/pp4pp/2n1bp2/2p1p3/3pP3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+King's Indian: S\"amisch, orthodox, 7.d5 *
+r2qkbnr/pp4pp/2n1bp2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, orthodox variation *
+r2qkbnr/pp4pp/2n1bp2/2ppp3/8/1P1P1NP1/P1P1PPBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, double fianchetto variation *
+r2qkbnr/pp4pp/2n1bp2/2ppp3/8/2NP1NP1/PPP1PPBP/R1BQ1RK1 b kq -
+King's Indian: S\"amisch, 6...Nc6 *
+r2qkbnr/ppp1p1pp/2n2p2/3p4/3P1Bb1/5N2/PPP1PPPP/RN1QKB1R w KQkq -
+Richter-Veresov attack, Richter variation *
+r2qkbnr/ppp1pppp/2n5/3p4/3P1B2/5b2/PPP1PPPP/RN1QKB1R w KQkq -
+Richter-Veresov attack, Veresov variation *
+r2qkbnr/ppp1pppp/2n5/3p4/3P2b1/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Richter-Veresov attack *
+r2qkbnr/ppp2p1p/2P5/8/2BP1pb1/2N2p2/PPP3PP/R1BQ1RK1 b kq -
+Vienna: Pierce gambit, Rushmere attack
+r2qkbnr/ppp2pp1/2n5/3p3p/2PPp1b1/4P3/PP1NBPPP/RNBQK2R b KQkq -
+French: Albin-Alekhine-Ch\^atard attack, Breyer variation *
+r2qkbnr/ppp2pp1/2n5/3p3p/3Pp1b1/4P3/PPPNBPPP/RNBQ1RK1 b kq -
+French: Albin-Alekhine-Ch\^atard attack, Spielmann variation *
+r2qkbnr/ppp2pp1/2n5/3p3p/3Pp1b1/4P3/PPPNBPPP/RNBQK2R w KQkq -
+French: Albin-Alekhine-Ch\^atard attack *
+r2qkbnr/ppp2pp1/2n5/3p3p/3Pp1b1/4PP2/PPPNB1PP/RNBQK2R b KQkq -
+French: Albin-Alekhine-Ch\^atard attack, Teichmann variation *
+r2qkbnr/ppp2pp1/2n5/3p3p/3Pp1b1/P3P3/1PPNBPPP/RNBQK2R b KQkq -
+French: Albin-Alekhine-Ch\^atard attack, Mar\'oczy variation *
+r2qkbnr/ppp2pp1/2n5/3pP2p/6b1/5NP1/PPPPP2P/RNBQKB1R w KQkq -
+Dutch: Staunton gambit, Alekhine variation *
+r2qkbnr/ppp2ppp/2n1b3/1B1p4/3Pp3/4PN1P/PPP2PP1/RNBQK2R w KQkq -
+French: MacCutcheon, Janowski variation *
+r2qkbnr/ppp2ppp/2n1b3/3p4/3Pp3/1P2P3/P1P1BPPP/RNBQK1NR b KQkq -
+French: classical, Frankfurt variation *
+r2qkbnr/ppp2ppp/2n1b3/3pp3/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+French: Henneberger variation *
+r2qkbnr/ppp2ppp/2n5/1B1p3b/3Pp3/4PN1P/PPP2PP1/RNBQK2R w KQkq -
+French: MacCutcheon, Bernstein variation *
+r2qkbnr/ppp2ppp/2n5/1B1p4/3P2b1/4Pp1P/PPP2PP1/RNBQK2R w KQkq -
+French: MacCutcheon, Chigorin variation *
+r2qkbnr/ppp2ppp/2n5/1B1p4/3Pp1b1/4PN2/PPP2PPP/RNBQK2R w KQkq -
+French: MacCutcheon, advance variation *
+r2qkbnr/ppp2ppp/2n5/1B1pp3/3P2b1/4PN2/PPP2PPP/RNBQK2R b KQkq -
+French: MacCutcheon variation *
+r2qkbnr/ppp2ppp/2n5/3p4/3P2b1/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+French: exchange, Bogolyubov variation *
+r2qkbnr/ppp2ppp/2n5/3p4/3P2b1/5N2/PPP2PPP/RNBQKB1R w KQkq -
+French: exchange, Svenonius variation *
+r2qkbnr/ppp2ppp/2n5/3p4/3Pp1b1/4P3/PPP1BPPP/RNBQK1NR b KQkq -
+French: classical, Vistaneckis (Nimzovich) variation *
+r2qkbnr/ppp2ppp/2n5/3p4/3Pp3/4P3/PPPNQPPP/RNB1K2R b KQkq -
+French: classical variation *
+r2qkbnr/ppp2ppp/2n5/3pN3/3Pp1b1/4P3/PPP1BPPP/RNBQK2R b KQkq -
+French: classical, Tartakower variation *
+r2qkbnr/ppp2ppp/2n5/3pP3/6b1/1P3N2/P1PPP1PP/RNBQKB1R b KQkq -
+Dutch: Staunton gambit, Nimzovich variation *
+r2qkbnr/ppp2ppp/2n5/3pP3/6b1/2P2N2/PP1PP1PP/RNBQKB1R b KQkq -
+Dutch: Staunton gambit, Chigorin variation *
+r2qkbnr/ppp2ppp/2n5/3pP3/6b1/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+French: Burn variation *
+r2qkbnr/ppp2ppp/2n5/3pP3/6b1/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Dutch: Staunton gambit, Staunton's line *
+r2qkbnr/ppp2ppp/2n5/3pp3/3P2b1/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+French: classical *
+r2qkbnr/ppp2ppp/2n5/3pp3/3P4/4Pb2/PPP1BPPP/RNBQK2R w KQkq -
+French: classical, Anderssen variation *
+r2qkbnr/ppp2ppp/2n5/3pp3/6b1/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Pirc: Byrne variation *
+r2qkbnr/ppp2ppp/2npb3/4p3/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English, Tr\"oger defense
+r2qkbnr/ppp2ppp/8/3p4/1n1Pp3/4P3/PPPNQPPP/RNB1K2R w KQkq -
+French: classical, Alapin variation *
+r2qkbnr/ppp3pp/2n2p2/3pP3/6b1/5NP1/PPPPP2P/RNBQKB1R w KQkq -
+Dutch: Staunton gambit, Lasker variation *
+r2qkbnr/ppp3pp/2n5/3p1p2/3Pp3/4P3/PPPNQPPP/RNB1K2R w KQkq -
+French: classical, Steinitz variation *
+r2qkbnr/pppb1ppp/2B5/3p4/3Pp3/4PN1P/PPP2PP1/RNBQK2R b KQkq -
+French: MacCutcheon, Lasker variation *
+r2qkbnr/pppb1ppp/2n5/1B1p4/2PPp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+French: Winawer, advance, Bogolyubov variation *
+r2qkbnr/pppb1ppp/2n5/1B1p4/3Pp3/4P2P/PPPN1PP1/RNBQK2R b KQkq -
+French: MacCutcheon, Tartakower variation *
+r2qkbnr/pppb1ppp/2n5/1B1pp3/3P4/4P3/PPP2PPP/RNBQK1NR w KQkq -
+French: Winawer, fingerslip variation *
+r2qkbnr/pppb1ppp/2n5/3pp3/Q3P3/2P2N2/PP1P1PPP/RNB1KB1R w KQkq -
+Ponziani: Caro variation
+r2qkbnr/pppb1ppp/2np4/1B2p3/2PPP3/5N2/PP3PPP/RNBQK2R b KQkq -
+Ruy Lopez: old Steinitz defense, semi-Duras variation
+r2qkbnr/pppb2pp/2npP3/1B3p2/3p4/5N2/PPP2PPP/RNBQK2R b KQkq -
+KGD: Falkbeer, Morphy gambit *
+r2qkbnr/pppnpppp/8/3p4/6b1/5NP1/PPPPPPBP/RNBQK2R w KQkq -
+R\'eti: King's Indian attack, Keres variation
+r2qr1k1/p1p2ppp/2p2n2/3pp1B1/1b2P1b1/3P1N2/PPP1QPPP/R2N1RK1 b - -
+Four knights: symmetrical, Capablanca variation *
+r2qr1k1/p1p2ppp/5n2/1p1P3b/Q5P1/2N1Bn1P/PPP1KP2/R4B1R w - -
+two knights defense: Yurdansky attack *
+r2qr1k1/ppp1bppp/2n2n2/4p3/2P3b1/2NPBN2/PP2BPPP/R2Q1RK1 w - -
+Philidor: Berger variation *
+r2r2k1/ppq2ppp/2n1pn2/2bp4/2P5/2N1PN1P/PP1BQPP1/R4RK1 b - -
+QGD: Lasker defense, Russian variation *
+r3k1nr/ppp1qppp/2n5/4P3/1bPp4/5N1P/PP1BPPP1/R2QKB1R w KQkq -
+QGD: Albin counter-gambit, Kr\'enosz variation
+r3k2r/p2q1ppp/5n2/3pp3/1b6/4P3/PP3PPP/RNBQ1RK1 w kq -
+QGD: Semi-Tarrasch, Kmoch variation *
+r3k2r/ppp1qppp/2n1b3/2bnp3/8/2NPPN2/PP2BPPP/R1BQK2R w KQkq -
+Sicilian: Velimirovi\'c attack *
+r3k2r/ppp2ppp/2n1bP2/2b2qN1/2ppN3/8/PPP2PPP/R1BQR1K1 b kq -
+two knights: Max Lange attack, Marshall variation
+r3k2r/pppq2pp/2n1bp2/2bnp3/8/2NP1NP1/PP1BPPBP/R2Q1RK1 b kq -
+Sicilian: dragon, Yugoslav attack, 9...Bd7 *
+r3k2r/pppq2pp/2n1bp2/2bnp3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w kq -
+Sicilian: dragon, Yugoslav attack, 9.Bc4 *
+r3k2r/pppq2pp/2n1bp2/2bnp3/P7/2NP1NP1/1P2PPBP/R1BQ1RK1 b kq -
+Sicilian: dragon, Yugoslav attack, Byrne variation *
+r3k2r/pppqbppp/2n1b3/3np3/8/2NP1NP1/PP2PPBP/R1BQK2R w KQkq -
+Sicilian: dragon, classical, Amsterdam variation *
+r3k2r/ppq1ppbp/2N3p1/2pp4/6n1/1P2P3/PBPP1PPP/RN1Q1RK1 w kq -
+Bogo-Indian defense, Monticelli trap *
+r3kb1r/1b3ppp/p2ppn2/qpn1P1B1/3N4/1BN5/PPPQ1PPP/2KRR3 b kq -
+Sicilian: Najdorf, Ivkov variation
+r3kb1r/1bq2ppp/p3pn2/1p1P4/2p5/2N1PN2/PPQ2PPP/R1BR2K1 w kq -
+QGA: classical, Flohr variation
+r3kb1r/1pp2ppp/p1p1b3/3q4/3PN3/8/PPP2PPP/R1BQR1K1 w kq -
+Four knights: Spielmann variation
+r3kb1r/5ppp/b3pn2/1p1qN1B1/3p4/3B4/PP2QPPP/R4RK1 b kq -
+QGD semi-Slav: Meran, Rellstab attack
+r3kb1r/p4ppp/1qp1pn2/3p4/3P4/3Q3P/PPP2PP1/RNB2RK1 b kq -
+QGD: Lasker defense, Bernstein variation *
+r3kb1r/pp1Npppp/1qn2n2/1Bp5/2p5/2N1P3/PP1P1PPP/R1BQK2R b KQkq -
+Nimzo-Indian: Spielmann, Karlsbad variation *
+r3kb1r/pp1b1ppp/nq2pn2/3p4/3P1B2/4PN2/PP3PPP/RNQ1KB1R w KQkq -
+QGD Slav: Landau variation *
+r3kb1r/pp1bpppp/1qn2n2/1Bp5/2N5/2N1P3/PP1P1PPP/R1BQK2R b KQkq -
+Nimzo-Indian: Spielmann, San Remo variation *
+r3kb1r/pp1qn1pp/2n1bp2/2ppp3/8/P1NP1NP1/1PP1PPBP/1RBQ1RK1 b kq -
+King's Indian: S\"amisch, Panno main line *
+r3kb1r/pp1qpppp/2np1n2/2p5/3PP3/2P2N2/PP3PPP/RNBQ1RK1 b kq -
+Sicilian: Canal-Sokolsky attack, Bronstein gambit
+r3kb1r/pp2pppp/1qn2n2/2pp4/3P4/2P1PQ1P/PP3PP1/RNB1KB1R w KQkq -
+QGD/QGD semi-Slav: Hastings variation *
+r3kb1r/pp2pppp/2n2n2/2pq4/3P2b1/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD: Semi-Tarrasch, Primitive Pillsbury variation *
+r3kb1r/pp2pppp/2n5/q1p5/1n1PP1b1/P4N2/1P3PPP/RNBQKB1R w KQkq -
+QGD: Semi-Tarrasch, Krause variation *
+r3kb1r/pp3ppp/1qn1bn2/3pp1B1/2P5/6P1/PP1NPPBP/RN1Q1RK1 b kq -
+Gr\"unfeld defense: Smyslov, Yugoslav variation *
+r3kb1r/pp3ppp/1qn1bn2/3pp1B1/8/6P1/PPPNPPBP/RN1Q1RK1 w kq -
+Gr\"unfeld defense: Smyslov, main line *
+r3kb1r/pp3ppp/1qn1pn2/1B1p1b2/3P1B2/2N1PN2/PP3PPP/R2QK2R b KQkq -
+QGD Slav: exchange, Trifunovi\'c variation *
+r3kb1r/pp3ppp/1qn1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w kq -
+QGD: Orthodox defense, Rauzer variation *
+r3kb1r/pp3ppp/2n2q2/2Pp4/1P2p1b1/2P1PN2/P2N1P2/R1BQKB1R w KQkq -
+QGD semi-Slav: anti-Meran, Szab\'o variation *
+r3kb1r/ppp1q1pp/2n5/3n4/1P2p1b1/P3PN2/2Q2PPP/RNB1KB1R w KQkq -
+Sicilian: Najdorf, Polugayevsky, Simagin variation *
+r3kb1r/ppp2ppp/2n1bP2/5qN1/2ppN3/8/PPP2PPP/R1BQR1K1 w kq -
+two knights: Max Lange attack, Rubinstein variation
+r3kb1r/ppp2ppp/2nq4/3np3/6b1/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Richter-Rauzer, Keres variation *
+r3kb1r/ppp3pp/2n1bq2/3npp2/8/2NPPN2/PP2BPPP/R1BQK2R w KQkq -
+Sicilian: Scheveningen, Tal variation *
+r3kb1r/ppp3pp/2n2q2/3npp1b/6P1/P2PPN1P/1P2BP2/RNBQK2R b KQkq -
+Sicilian: Najdorf, G\"oteborg (Argentine) variation *
+r3kb1r/ppp3pp/2n2q2/3npp1b/8/P2PPN1P/1PQ1BPP1/RNB1K2R b KQkq -
+Sicilian: Najdorf, Browne variation *
+r3kb1r/ppp3pp/2n2q2/3npp2/6b1/P2PPN2/1PQ1BPPP/RNB1K2R b KQkq -
+Sicilian: Najdorf variation *
+r3kb1r/pppq1ppp/2n1b3/3np3/8/P2PPN2/1P3PPP/RNBQKB1R w KQkq -
+Sicilian: Scheveningen, English variation *
+r3kb1r/pppq1ppp/2n5/3np3/6b1/2NP1N2/PP1BPPPP/R2QKB1R w KQkq -
+Sicilian: Richter-Rauzer, Larsen variation, 7.Qd2 *
+r3kb1r/pppq1ppp/2n5/3np3/6b1/2NPPN2/PP2BPPP/R1BQK2R b KQkq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 *
+r3kb1r/pppq1ppp/2n5/3np3/6b1/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Richter-Rauzer, Rauzer attack *
+r3kb1r/pppq1ppp/2n5/3np3/6b1/P1NPPN2/1P3PPP/R1BQKB1R b KQkq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 *
+r3kb1r/ppq2ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w kq -
+QGD: Orthodox defense, Rubinstein variation *
+r3kb1r/ppq2ppp/2n1pn2/2ppN3/3P4/4P2P/PPP1QPP1/RNB2RK1 w kq -
+QGD: Lasker defense, Teichmann variation *
+r3kb1r/ppq2ppp/2n1pn2/3p4/2Pp2b1/4PN2/PP1NBPPP/R1BQ1RK1 w kq -
+QGD: Orthodox defense, 7.Qc2 c5, 8.cd (Rubinstein) *
+r3kb1r/ppqbpp1p/2n2np1/1Bp5/2N2P2/2N1P3/PP1P2PP/R1BQK2R w KQkq -
+Nimzo-Indian: Spielmann, St\aa hlberg variation *
+r3kb1r/ppqn1ppp/2n1p3/1Bpp3b/Q2P4/2P1PN2/PP1N1PPP/R1B2RK1 w kq -
+QGD: Cambridge Springs defense, Argentine variation *
+r3kb1r/ppqn1ppp/2n1p3/1Bpp4/Q2P2b1/2P1PN2/PP1N1PPP/R1B1K2R w KQkq -
+QGD: Cambridge Springs defense, Bogolyubov variation *
+r3kb1r/ppqn1ppp/2p2n2/4pb2/P1NP4/2N3P1/1P2PP1P/R1BQKB1R w KQkq -
+QGD Slav: Carlsbad variation
+r3kbnr/1ppb1ppp/p1p5/8/3NP3/8/PPP2PPP/RNB1K2R w KQkq -
+Ruy Lopez: exchange, Alekhine variation
+r3kbnr/p1pb1ppp/2p5/3pN1q1/3Pp3/4P1PP/PPP2P2/RNBQK2R b KQkq -
+French: MacCutcheon, Lasker variation, 8...g6 *
+r3kbnr/pp1qpppp/8/2ppP3/2P3b1/6P1/PP2PP1P/RNBQKB1R b KQkq -
+Gr\"unfeld: Lundin variation *
+r3kbnr/ppp2pp1/2n5/1B1p2qP/3P4/4P3/PPP2Pp1/RNBQK1R1 w Qkq -
+French: MacCutcheon, Grigoriev variation *
+r3kbnr/ppp2ppp/2n5/3p2q1/3Pp3/4P3/PPP1BPPP/RNBQK2R w KQkq -
+French: classical, Anderssen-Richter variation *
+r3kbnr/ppp2ppp/2n5/3p2q1/3Pp3/4P3/PPPNQPPP/RNB1K2R w KQkq -
+French: classical, Pollock variation *
+r3kbnr/pppq1ppp/2n1b3/3pp3/8/2PP1NP1/PP2PP1P/RNBQKB1R w KQkq -
+Pirc: 150 attack *
+r3kbnr/pppq1ppp/2n5/1B1p4/Q7/4PP2/PPP2P1P/RNB1K2R b KQkq -
+French: MacCutcheon, Bogolyubov variation *
+r3kbnr/pppq1ppp/2n5/3p4/3Pp3/4P3/PPPNQPPP/RNB1K2R w KQkq -
+French: classical, Rubinstein variation *
+r3kbnr/ppq1pppp/2n5/3p4/3P2b1/2P2N2/PP3PPP/RNBQKB1R w KQkq -
+QGD: exchange, positional line, 6.Qc2 *
+r3qrk1/ppp1b1pp/2n1b3/3npp2/8/P1NPPN2/1PQ1BPPP/R1B2RK1 b - -
+Sicilian: Scheveningen, classical main line *
+r3r1k1/1p1n1p1p/1bpqb1p1/p2p2B1/1P1N3Q/P1PBR3/5PPP/5RK1 b - -
+Ruy Lopez: Marshall, main line, Spassky variation *
+r3r1k1/2qbbp1p/p2p1np1/npp1p3/3PP3/2P1NN1P/PPB2PP1/R1BQR1K1 w - -
+Ruy Lopez: closed, Chigorin, Yugoslav system
+r3r1k1/ppp1qppp/2n5/3b4/2P1p3/8/P1PPBPPP/R1BQ1RK1 b - -
+Ruy Lopez: Berlin defense, Rio de Janeiro variation *
+r4b1r/ppp1kp2/2n1bN1p/q5p1/1P1p3B/5N2/P1P2PPP/R2QR1K1 b - -
+two knights defense: Yurdansky attack
+r4rk1/2pqb1pp/p1n1p3/1p1pP3/4R3/1BP5/PP3PPP/RNBQ2K1 b - -
+Ruy Lopez: open, Tarrasch trap
+r4rk1/2pqbppp/p1n1b3/3pP3/2B1n3/5N2/PP2QPPP/RNBR2K1 w - -
+Ruy Lopez: open, Howell attack, Ekstr\"om variation
+r4rk1/p4ppp/bqn2n2/2b5/B3p3/2N3Q1/PPPPNPPP/R1B1K2R w KQ -
+Evans gambit: compromised defense, Paulsen variation *
+r4rk1/pbqnppbp/1p3np1/2pp4/P2P4/BPP1PN2/3NBPPP/R2Q1RK1 b - -
+Catalan: closed, Sokolsky variation *
+r4rk1/pp1bqpp1/2n1pn1p/2p5/2BP4/2N1PN2/PPQ2PPP/R2R2K1 w - -
+QGD: Lasker defense, Russian variation
+r4rk1/pp2ppbp/3p1np1/q4P2/4P1P1/2N1B3/PPP1Q2P/R4RK1 b - -
+Sicilian: dragon, classical, Stockholm attack
+r4rk1/pp2qppp/3b4/3P4/1P1Qn1b1/B3PN2/5PPP/R3KB1R w KQ -
+QGD semi-Slav: Meran, Rellstab attack *
+r4rk1/ppp1q2p/2n1b3/4p1p1/Q4p2/3P1NP1/PP2PPBP/R4RK1 w - -
+Sicilian: dragon, classical, Stockholm attack *
+r4rk1/ppp3pp/2n1bq2/4pP2/8/5Q2/PPPP1K1P/RNB2BNR w - -
+KGA: Lolli gambit, Young variation *
+r4rk1/pppqbppp/2n1b3/3np3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+Sicilian: dragon, classical, Richter variation *
+r4rk1/ppq1ppbp/2n2np1/2pp4/3P1Pb1/2P1PN2/PP2B1PP/RNB1QRK1 w - -
+Dutch: stonewall: Chekhover variation *
+r5nr/pp2k2p/2n2p2/2N1p2q/3pP3/3P2P1/PPP2PBP/RNB2RK1 b - -
+King's Indian: S\"amisch, orthodox, Bronstein variation *
+rn1q1rk1/1p3pbp/p2p1np1/2pP4/P3P1b1/2N2N2/1P2BPPP/R1BQ1RK1 w - -
+Benoni: classical with ...a6 and 10...Bg4
+rn1q1rk1/4ppbp/3p1np1/2pP4/4P3/2N2NP1/PP3PKP/R1BQ3R b - -
+Benk\"o gambit: main line
+rn1q1rk1/p3ppbp/bp3np1/2pp4/3P1P2/2P1PN2/PP2B1PP/RNBQ1RK1 w - -
+Dutch: stonewall with Ba3 *
+rn1q1rk1/pb1pbppp/1p2pn2/8/2PN4/1P1BP3/PB3PPP/RN1Q1RK1 b - -
+Queen's Indian: Averbakh variation
+rn1q1rk1/pb3ppp/1p1bp3/2pn4/8/1P2PN2/PB1PBPPP/RN1Q1RK1 w - -
+Queen's Indian: Averbakh variation *
+rn1q1rk1/pb3ppp/5n2/2b1p3/N2p4/1B1P4/PPP1NPPP/R1BQK2R b KQ -
+Evans gambit: Paulsen variation *
+rn1q1rk1/pb3ppp/5n2/2b1p3/N2p4/1B1P4/PPP2PPP/R1BQK1NR w KQ -
+Evans gambit: Ulvestad variation *
+rn1q1rk1/pb3ppp/8/1Bb5/4N1n1/5N2/PPPP1PPP/R1BQ1RK1 b - -
+Scotch gambit: Hanneken variation *
+rn1q1rk1/pbp1bppp/1p3n2/3pN1B1/3P4/2NBP3/PP3PPP/R2QK2R b KQ -
+QGD: Pillsbury attack
+rn1q1rk1/pbpp1ppp/1p2p3/6N1/2PP4/2n3P1/PPQ1PPBP/R3K2R b KQ -
+Bogo-Indian defense, Monticelli trap
+rn1q1rk1/pbppbppp/1p2p3/8/2PP4/2Q2NP1/PP2PPBP/R1B2RK1 b - -
+Queen's Indian: old main line, 9.Qxc3
+rn1q1rk1/pbppbppp/1p2pn2/8/2PP4/1P3NP1/P3PPBP/RNBQ1RK1 b - -
+Queen's Indian: Euwe variation
+rn1q1rk1/pbppbppp/1p2pn2/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+Queen's Indian: old main line, 7.Nc3
+rn1q1rk1/pp1nppbp/6p1/2p5/3PP1b1/1QN1BN2/PP3PPP/R3KB1R w KQ -
+Gr\"unfeld defense: Smyslov, Yugoslav variation
+rn1q1rk1/pp2ppbp/2p2np1/3p1b2/2PP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+Gr\"unfeld: Flohr defense
+rn1q1rk1/pp2ppbp/2p2np1/3p4/2PP2b1/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+Gr\"unfeld: Smyslov defense
+rn1q1rk1/pp2ppbp/2pp1np1/5b2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, Larsen system
+rn1q1rk1/pp2ppbp/4bnp1/2Pp4/2P2B2/2N1P3/PP3PPP/2RQKBNR w K -
+Gr\"unfeld: Gr\"unfeld gambit, Botvinnik variation
+rn1q1rk1/pp3ppp/2p1p3/5b2/PbBPn1P1/2N1PN2/1P2QP1P/R1B2RK1 b - -
+QGD Slav: Dutch, S\"amisch variation
+rn1q1rk1/pp3ppp/2p1pn2/5b2/PbBP4/2N1PN2/1P2QPPP/R1B2RK1 b - -
+QGD Slav: Dutch variation, main line
+rn1q1rk1/ppp1b1pp/1n2pp2/4Pb2/2PP4/2N2N2/PP2B1PP/R1BQ1RK1 w - -
+Alekhine's defense: four pawns attack, Korchnoi variation
+rn1q1rk1/ppp1ppbp/5np1/8/2QPP1b1/2N2N2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Russian, Smyslov variation
+rn1q1rk1/ppp2ppp/3b4/3p4/2PPn1b1/3B1N2/PP3PPP/RNBQ1RK1 w - -
+Petrov: classical attack, Tarrasch variation
+rn1q1rk1/ppp2ppp/8/2bNp3/4P1b1/3P1N2/PPP2PPP/R1BQK2R b KQ -
+Giuoco piano *
+rn1q1rk1/ppp2ppp/8/2bP1b2/4nPP1/5N2/PPP1Q2P/RNB1KB1R w KQ -
+KGD: Falkbeer, Tarrasch variation
+rn1q1rk1/ppp3pp/8/2bNpp1b/4P1P1/5N1P/PPPP1P2/R1BQK2R w KQ -
+Giuoco piano: Rosentreter variation *
+rn1q1rk1/ppp3pp/8/3P1p2/3Pn1b1/3B1N2/PP3PPb/RNBQR1K1 w - -
+Petrov: classical attack, Marshall trap
+rn1q1rk1/pppnppbp/6p1/8/3PP1b1/1QN1BN2/PP3PPP/R3KB1R b KQ -
+Gr\"unfeld defense: Smyslov, main line
+rn1qk1nr/pb3ppp/8/2b1p3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+Danish gambit: Schlechter defense *
+rn1qk1nr/pb3ppp/8/2b1p3/8/8/PPPPQPPP/RNB1KBNR b KQkq -
+Danish gambit: Collijn defense *
+rn1qk1nr/pp1bppbp/6p1/2pp4/5P2/4PN2/PPPPB1PP/RNBQK2R b KQkq -
+Dutch-Indian, Alekhine variation *
+rn1qk1nr/pp3ppp/2pb4/3p1b2/3P4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+Caro-Kann: exchange, Rubinstein variation *
+rn1qk1nr/ppp1ppbp/3p2p1/8/2PPP1b1/5N2/PP3PPP/RNBQKB1R w KQkq -
+Robatsch defense: Rossolimo variation
+rn1qk1nr/ppp2ppp/8/2b1p3/Q3P1b1/2P2N2/PP1P2PP/RNB1KB1R b KQkq -
+KGD: classical, Marshall attack
+rn1qk2r/1bpp1ppp/1p2pn2/p7/1bPP4/5NP1/PP1BPPBP/RN1QK2R w KQkq -
+Queen's Indian: Yates variation
+rn1qk2r/p1pp1ppp/bp2pn2/8/1bPP4/2N1P3/PP2NPPP/R1BQKB1R w KQkq -
+Nimzo-Indian: 4.e3, Bronstein (Byrne) variation
+rn1qk2r/p4ppp/2p2n2/2bpp3/B3P1b1/2NP4/PPP2PPP/R1BQK1NR w KQkq -
+Evans gambit: Sokolsky variation *
+rn1qk2r/pb1pbppp/1p2pn2/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w kq -
+English: symmetrical, hedgehog system
+rn1qk2r/pbpp1pp1/1p2pn1p/8/1bPP3B/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+Queen's Indian: 4.Nc3, main line
+rn1qk2r/pbpp1ppp/1p2pn2/8/1bPP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+Queen's Indian: Capablanca variation
+rn1qk2r/pbpp1ppp/5n2/1pb1p3/4P3/1BN5/PPPP1PPP/R1BQK1NR w KQkq -
+Evans gambit declined, Cordel variation *
+rn1qk2r/pbppbppp/1p2p3/8/2PPn3/2N2NP1/PP1BPPBP/R2QK2R b KQkq -
+Queen's Indian: Opo\v censky variation
+rn1qk2r/pbppbppp/1p2pn2/8/2PP4/2N2NP1/PP2PPBP/R1BQK2R b KQkq -
+Queen's Indian: anti-Queen's Indian system
+rn1qk2r/pbppbppp/1p2pn2/8/2PP4/5NP1/PP1BPPBP/RN1QK2R w KQkq -
+Queen's Indian: Riumin variation
+rn1qk2r/pbppbppp/1p2pn2/8/2PP4/5NP1/PP2PPBP/RNBQ1RK1 b kq -
+Queen's Indian: old main line, 6.O-O
+rn1qk2r/pbppbppp/1p2pn2/8/2PP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+Queen's Indian: 5.Bg2 Be7
+rn1qk2r/pp1bppbp/5np1/1Bpp4/P7/1P2PN2/1BPP1PPP/RN1QK2R b KQkq -
+Queen's Indian: Yates variation *
+rn1qk2r/pp1bppbp/5np1/2pp4/8/1P2PN2/PBPPBPPP/RN1QK2R b KQkq -
+Queen's Indian: Riumin variation *
+rn1qk2r/pp3ppp/2p1b3/3np3/1bB5/2N2Q2/PPPPNPPP/R1B1K2R w KQkq -
+Scotch: Paulsen attack *
+rn1qk2r/pp3ppp/2p1b3/3np3/1bB5/5Q2/PPPPNPPP/R1BNK2R b KQkq -
+Scotch: Paulsen, Gunsberg defense *
+rn1qk2r/pp3ppp/2p1pn2/5b2/PbBP4/2N1PN2/1P3PPP/R1BQ1RK1 b kq -
+QGD Slav: Dutch variation
+rn1qk2r/pp3ppp/2p2n2/2bpp3/4P1b1/1BN5/PPPPQPPP/R1B1K1NR w KQkq -
+Giuoco Piano: Mestel variation *
+rn1qk2r/ppp2ppp/3pbn2/4p3/1bB1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Ruy Lopez: Berlin defense, Kaufmann variation *
+rn1qk2r/ppp2ppp/8/2bP1b2/4nP2/5N2/PPP1Q1PP/RNB1KB1R w KQkq -
+KGD: Falkbeer, main line, 7...Bf5
+rn1qk2r/ppp3p1/8/2bpP1Pp/4b3/7P/PPP3K1/RNBQ1BNR w kq -
+KGA: Allgaier, Cook variation *
+rn1qk2r/pppbbppp/8/3pP3/N3n3/2PB1N1P/P1Q2PP1/R1B1K2R w KQkq -
+two knights defense: Knorre variation *
+rn1qkb1r/1b3ppp/p3pn2/1pp5/3P4/1B2PN2/PP2QPPP/RNB2RK1 w kq -
+QGA: classical, 8...Bb7
+rn1qkb1r/4pp1p/3p1np1/2pP4/4P3/2N3P1/PP3P1P/R1BQ1KNR b kq -
+Benk\"o gambit
+rn1qkb1r/4pp1p/3p1np1/2pP4/4P3/2N5/PP2NPPP/R1BQ1K1R b kq -
+Benk\"o gambit: Ne2 variation
+rn1qkb1r/4pp1p/b2p1np1/2pP4/8/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+Benk\"o gambit: fianchetto variation
+rn1qkb1r/4pp1p/b2p1np1/2pP4/8/2N5/PP1NPPPP/R1BQKB1R b KQkq -
+Benk\"o gambit: Nd2 variation
+rn1qkb1r/4pppp/b2p1n2/2pP4/4P3/2N5/PP3PPP/R1BQKBNR b KQkq -
+Benk\"o gambit: 7.e4
+rn1qkb1r/p1pp1ppp/bp2pn2/8/2PP4/5NP1/PP2PP1P/RNBQKB1R w KQkq -
+Queen's Indian: Nimzovich variation (exaggerated fianchetto)
+rn1qkb1r/pb1p1ppp/1p2pn2/2p5/2PP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+English: Wimpey system *
+rn1qkb1r/pb1p1ppp/1p3n2/2pp2N1/2P5/6P1/PP2PPBP/RNBQK2R b KQkq -
+Queen's Indian: B\"urger variation
+rn1qkb1r/pb1p1ppp/1p3n2/2pp4/2P4N/6P1/PP2PPBP/RNBQK2R b KQkq -
+Queen's Indian: Rubinstein variation
+rn1qkb1r/pb1ppppp/1p3n2/2p3B1/3P4/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+English: Capablanca's variation *
+rn1qkb1r/pb1ppppp/1p3n2/2p5/3P1B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+English: New York (London) defensive system *
+rn1qkb1r/pb1ppppp/1p3n2/2p5/3P4/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+English: Caro-Kann defensive system *
+rn1qkb1r/pb1ppppp/1p3n2/2p5/3P4/2P2NP1/PP2PP1P/RNBQKB1R b KQkq -
+English: Bled variation *
+rn1qkb1r/pb1ppppp/1p3n2/2p5/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Queen's Indian: Marienbad system
+rn1qkb1r/pb1ppppp/1p3n2/8/2PQ4/5NP1/PP2PPBP/RNB1K2R b KQkq -
+Queen's Indian: Marienbad system, Berg variation
+rn1qkb1r/pbpp1p2/1p2p2p/6pn/2PP4/2N2NB1/PP2PPPP/R2QKB1R w KQkq -
+Queen's Indian: 4.Nc3, Botvinnik variation
+rn1qkb1r/pbpp1ppp/1p2pn2/8/2P1P3/2NB1N2/PP1P1PPP/R1BQK2R b KQkq -
+English: Queens Indian, Romanishin variation
+rn1qkb1r/pbpp1ppp/1p2pn2/8/2PP4/5NP1/PP2PP1P/RNBQKB1R w KQkq -
+Queen's Indian: 4.g3 Bb7
+rn1qkb1r/pp1bpppp/5n2/1Bpp4/8/4PN2/PPPPQPPP/RNB1K2R b KQkq -
+Bogo-Indian defense, Nimzovich variation *
+rn1qkb1r/pp1n1ppp/4p3/3pNb2/3P4/2N1P3/PP3PPP/R1BQKB1R w KQkq -
+QGD Slav: Amsterdam variation
+rn1qkb1r/pp2pppp/2p2n2/3p1b2/2P5/1P3N2/PB1PPPPP/RN1QKB1R w KQkq -
+English: New York (London) defensive system
+rn1qkb1r/pp2pppp/2p2n2/3p1b2/2P5/1P3NP1/P2PPP1P/RNBQKB1R w KQkq -
+English: London defensive system
+rn1qkb1r/pp2pppp/2p2n2/3p1b2/2PP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD Slav: 4.e3 Bf5
+rn1qkb1r/pp2pppp/2p2n2/3p4/2P3b1/1P3N2/PB1PPPPP/RN1QKB1R w KQkq -
+English: Capablanca's variation
+rn1qkb1r/pp2pppp/2p2n2/3p4/2P3b1/1P3NP1/P2PPP1P/RNBQKB1R w KQkq -
+English: Torre defensive system
+rn1qkb1r/pp2pppp/2p2n2/3p4/6b1/5NP1/PPPPPPBP/RNBQ1RK1 w kq -
+R\'eti: King's Indian attack, Yugoslav variation
+rn1qkb1r/pp2pppp/2p2n2/4Nb2/P1pP4/2N5/1P2PPPP/R1BQKB1R b KQkq -
+QGD Slav: Krause attack
+rn1qkb1r/pp2pppp/2p2n2/5b2/P1pP4/2N1PN2/1P3PPP/R1BQKB1R b KQkq -
+QGD Slav: Dutch variation
+rn1qkb1r/pp2pppp/2p2n2/5b2/P1pP4/2N2N2/1P2PPPP/R1BQKB1R w KQkq -
+QGD Slav: Czech defense
+rn1qkb1r/pp2pppp/2p2n2/8/P1pP2b1/2N2N2/1P2PPPP/R1BQKB1R w KQkq -
+QGD Slav: Steiner variation
+rn1qkb1r/pp2pppp/2pp4/3nP3/3P2b1/5N2/PPP1BPPP/RNBQK2R w KQkq -
+Alekhine's defense: modern, Flohr variation
+rn1qkb1r/pp2pppp/5n2/1Bpp4/3P2b1/4PN2/PPP2PPP/RNBQK2R b KQkq -
+QGD: Vienna variation *
+rn1qkb1r/pp2pppp/5n2/2p5/1PPp2b1/4PN2/P2P1PPP/RNBQKB1R w KQkq -
+Blumenfeld counter-gambit, Dus-Chotimursky variation *
+rn1qkb1r/pp2pppp/5n2/2pp1b2/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+Queen's Indian: Miles variation *
+rn1qkb1r/pp2pppp/5n2/2pp4/3P2b1/4PN1P/PPP2PP1/RNBQKB1R b KQkq -
+QGD: Capablanca-Duras variation *
+rn1qkb1r/pp2pppp/5n2/2pp4/3P2b1/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+QGD *
+rn1qkb1r/pp2pppp/5n2/3p1b2/3P4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+QGD Slav: exchange variation
+rn1qkb1r/pp2pppp/5n2/8/1PPp2b1/5N1P/P2P1PP1/RNBQKB1R b KQkq -
+Blumenfeld counter-gambit, Spielmann variation *
+rn1qkb1r/pp3ppp/2p1pn2/4Nb2/P1pP4/2N5/1P2PPPP/R1BQKB1R w KQkq -
+QGD Slav: Wiesbaden variation
+rn1qkb1r/pp3ppp/4b3/2pnp3/8/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+Sicilian: accelerated fianchetto, Mar\'oczy bind, 6.Be3 *
+rn1qkb1r/ppn2ppp/2p1b3/4p3/2B5/2N2Q2/PPPPNPPP/R1B1K2R w KQkq -
+Scotch: Meitner variation *
+rn1qkb1r/ppp1pppp/1n1p4/3PP3/2P3b1/5N2/PP3PPP/RNBQKB1R b KQkq -
+Alekhine's defense: modern, Vitolins attack
+rn1qkb1r/ppp1pppp/1n1p4/4Pb2/2PP1P2/8/PP4PP/RNBQKBNR w KQkq -
+Alekhine's defense: four pawns attack, Trifunovi\'c variation
+rn1qkb1r/ppp1pppp/3p1n2/5b2/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Old Indian: Janowski variation
+rn1qkb1r/ppp1pppp/3p4/3nP3/2PP2b1/5N2/PP3PPP/RNBQKB1R b KQkq -
+Alekhine's defense: modern, Alekhine variation
+rn1qkb1r/ppp1pppp/3p4/3nP3/3P2b1/5N1P/PPP2PP1/RNBQKB1R b KQkq -
+Alekhine's defense: modern, Panov variation
+rn1qkb1r/ppp1pppp/3p4/3nP3/3P2b1/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Alekhine's defense: modern variation, 4...Bg4
+rn1qkb1r/ppp1pppp/4bn2/8/2pP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGA, Flohr variation
+rn1qkb1r/ppp1pppp/5B2/3p1b2/3P4/2N5/PPP1PPPP/R2QKBNR b KQkq -
+Richter-Veresov attack, Veresov variation
+rn1qkb1r/ppp1pppp/5n2/3p1b2/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's bishop game *
+rn1qkb1r/ppp1pppp/5n2/3p1b2/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian: London system *
+rn1qkb1r/ppp1pppp/5n2/3p1bB1/3P4/2N2P2/PPP1P1PP/R2QKBNR b KQkq -
+Richter-Veresov attack, Richter variation
+rn1qkb1r/ppp1pppp/5n2/3p4/3P2b1/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Torre attack (Tartakower variation) *
+rn1qkb1r/ppp1pppp/5n2/3p4/6b1/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+Queen's pawn: Torre attack *
+rn1qkb1r/ppp1pppp/5n2/3p4/6b1/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian: Torre attack *
+rn1qkb1r/ppp1pppp/5n2/8/2pP2b1/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGA, Janowsky-Larsen variation
+rn1qkb1r/ppp2ppp/4b3/4p3/1nB5/2N2Q2/PPPP1PPP/R1B1K1NR w KQkq -
+Scotch: Blumenfeld attack *
+rn1qkb1r/ppp2ppp/5n2/3pp3/2P3b1/4PN2/PP1P1PPP/RNBQKB1R w KQkq -
+Queen's pawn: Torre attack, Wagner gambit *
+rn1qkb1r/ppp2ppp/8/3pP3/4n1b1/2N2N2/PPPPQ1PP/R1B1KB1R b KQkq -
+Vienna gambit: Kaufmann variation
+rn1qkb1r/ppp3p1/8/3ppbPp/3Pn3/5N2/PPP2P1P/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Brentano defense *
+rn1qkb1r/pppb1ppp/8/1B2p2Q/1n6/2N5/PPPP1PPP/R1B1K1NR w KQkq -
+Scotch game *
+rn1qkbnr/1bpp1ppp/p7/1P6/3Q4/8/PP2PPPP/RNB1KBNR w KQkq -
+Sicilian: wing gambit, Marienbad variation *
+rn1qkbnr/1pp2ppp/p3p3/3P4/2B3b1/4PN2/PP3PPP/RNBQK2R b KQkq -
+QGA: Alekhine defense, Alatortsev variation
+rn1qkbnr/p1pppppp/bp6/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Guatemala defense
+rn1qkbnr/pp1b1ppp/4P3/1Bp5/4p3/8/PPP2PPP/RNBQK1NR b KQkq -
+QGD: Albin counter-gambit, Lasker trap *
+rn1qkbnr/pp1bpppp/3p4/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Sicilian: Canal-Sokolsky attack, 3...Bd7
+rn1qkbnr/pp2pppp/2p3b1/8/3P1P2/6N1/PPP3PP/R1BQKBNR b KQkq -
+Caro-Kann: classical, Mar\'oczy attack
+rn1qkbnr/pp2pppp/2p3b1/8/3P3P/6N1/PPP2PP1/R1BQKBNR b KQkq -
+Caro-Kann: classical, 6.h4
+rn1qkbnr/pp2pppp/2p3b1/8/3P4/6NN/PPP2PPP/R1BQKB1R b KQkq -
+Caro-Kann: classical, Flohr variation
+rn1qkbnr/pp2pppp/2p5/3p4/2P3b1/1P3N2/P2PPPPP/RNBQKB1R w KQkq -
+English: Caro-Kann defensive system, Bogolyubov variation
+rn1qkbnr/pp2pppp/2p5/3p4/4P1b1/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Caro-Kann: two knights, 3...Bg4
+rn1qkbnr/pp2pppp/2p5/5b2/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+Caro-Kann: classical variation
+rn1qkbnr/pp2pppp/8/2p2bN1/4p3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Budapest: Rubinstein variation *
+rn1qkbnr/pp2pppp/8/2pp4/6b1/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+Neo-Indian (Seirawan) attack *
+rn1qkbnr/pp3ppp/2p1p3/3pPb2/3P4/2P5/PP2BPPP/RNBQK1NR b KQkq -
+Caro-Kann: advance, Short variation
+rn1qkbnr/pp4pp/4b3/2pp4/4p3/1NN5/PPP1PPPP/R1BQKB1R w KQkq -
+Alekhine's defense: four pawns attack, 7.Be3 *
+rn1qkbnr/ppp1pppp/3p4/8/3P2b1/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Old Indian: Tartakower (Wade) variation
+rn1qkbnr/ppp1pppp/3p4/8/4P1b1/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+R\'eti: Wade defense
+rn1qkbnr/ppp1pppp/4b3/8/2p5/4PN2/PP1P1PPP/RNBQKB1R w KQkq -
+R\'eti accepted: Keres variation
+rn1qkbnr/ppp1pppp/8/3p1b2/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+Queen's pawn, Mason variation, Steinitz counter-gambit *
+rn1qkbnr/ppp1pppp/8/3p1b2/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QGD: Grau (Sahovic) defense
+rn1qkbnr/ppp1pppp/8/3p1b2/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn, Mason variation *
+rn1qkbnr/ppp1pppp/8/3p1b2/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Queen's pawn: London system *
+rn1qkbnr/ppp1pppp/8/3p4/2P3b1/8/PP1PPPBP/RNBQK1NR b KQkq -
+Grob: Fritz gambit
+rn1qkbnr/ppp1pppp/8/3p4/3P2b1/2N5/PPP1PPPP/R1BQKBNR w KQkq -
+Queen's pawn: Anti-Veresov
+rn1qkbnr/ppp1pppp/8/3p4/3P2b1/8/PPP1PPPP/RNBQKBNR w KQkq -
+Levitsky attack (Queen's bishop attack) *
+rn1qkbnr/ppp1pppp/8/3p4/5Pb1/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch, 2.Bg5 variation *
+rn1qkbnr/ppp1pppp/8/3p4/6b1/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Trompovsky attack (Ruth, Opo\v censk\'y opening) *
+rn1qkbnr/ppp1pppp/8/8/2Pp2b1/8/PP1PPPBP/RNBQK1NR w KQkq -
+Grob: Romford counter-gambit
+rn1qkbnr/ppp2ppp/2b1p3/8/3PN3/5N2/PPP2PPP/R1BQKB1R w KQkq -
+French: Fort Knox variation
+rn1qkbnr/ppp2ppp/3p4/4p3/2P3b1/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+English, Smyslov defense
+rn1qkbnr/ppp2ppp/4b3/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: Alapin variation *
+rn1qkbnr/ppp2ppp/8/3p4/5p2/6PB/PPPPP2P/RNBQK2R w KQkq -
+Amar gambit
+rn1qkbnr/pppb1ppp/3p4/8/3QP3/5N2/PPP2PPP/RNB1KB1R w KQkq -
+Philidor: Boden variation
+rn2k2r/pbpp1ppp/8/2b1p3/Np2Q3/1B6/PPPP1qPP/R1BK2NR w kq -
+Evans gambit declined, Hicken variation *
+rn2k2r/pp4pp/1q3p2/1N1pN3/3Pn3/5K2/PPP3PP/R1BQ3R w kq -
+Giuoco Piano: Krause variation *
+rn2kb1r/pp1q1ppp/2p1b3/3np3/2B5/2N2Q2/PPPPNPPP/R1B1K2R w KQkq -
+Scotch: Blackburne attack *
+rn2kb1r/pp2pppp/2p2n2/q3Nb2/3P2P1/2N5/PPP2P1P/R1BQKB1R b KQkq -
+Scandinavian defense, Gr\"unfeld variation
+rn2kb1r/pp3ppp/2p1q3/1N6/3p4/5Q2/PP3PPP/1RB2RK1 b kq -
+Scotch: Gottschall variation *
+rn2kb1r/ppp1pppp/5n2/q4b2/3P4/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Scandinavian defense
+rn2kb1r/ppp1pppp/5n2/q7/3P2b1/2N2N1P/PPP2PP1/R1BQKB1R b KQkq -
+Scandinavian defense, Lasker variation
+rn2kbnr/pp1b1ppp/1q2p3/2ppP3/3P4/2P2N2/PP3PPP/RNBQKB1R w KQkq -
+French: advance, Wade variation
+rn2kbnr/pp1qpppp/3p4/2p5/2P1P3/5N2/PP1P1PPP/RNBQK2R b KQkq -
+Sicilian: Canal-Sokolsky attack, Sokolsky variation
+rn2kbnr/ppp2ppp/8/q3p3/3P2b1/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Scandinavian: Anderssen counter-attack, Collijn variation
+rn3rk1/p1p1qpp1/1p2b2p/3p4/3P4/4PN2/PP3PPP/2RQKB1R w K -
+QGD: Tartakower variation
+rn3rk1/p4ppp/bqp5/2b1p3/N3n3/1B6/PPPQ1PPP/R1B1K1NR w KQ -
+Evans gambit: Levenfish variation *
+rnb1k1nr/p3qppp/2p1p3/1p6/PbpP4/2N1PN2/1P1B1PPP/R2QKB1R w KQkq -
+QGD: semi-Slav, Koomen variation
+rnb1k1nr/p4ppp/1qp1p3/1p6/PbpP4/2N1PN2/1P1B1PPP/R2QKB1R w KQkq -
+QGD: semi-Slav, Junge variation
+rnb1k1nr/pp1pq1pp/2p5/2b1pp2/2B1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Bishop's opening: Lopez gambit *
+rnb1k1nr/pp2ppbp/3p2p1/q1p5/2PPP3/2N2N2/PP3PPP/R1BQKB1R w KQkq -
+Pterodactyl defense
+rnb1k1nr/pp2ppbp/6p1/2qp4/8/4PN2/PPPN1PPP/R1BQKB1R w KQkq -
+Catalan: open, 5.Qa4 Nbd7, 6.Qxc4 *
+rnb1k1nr/pp2ppbp/6p1/q1Pp4/8/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+Catalan: open, 5.Qa4 *
+rnb1k1nr/pp3ppp/2p5/2PP4/2B4q/5p2/PPP2PPP/RNBQ1RK1 b kq -
+Bishop's opening: Pratt variation *
+rnb1k1nr/pp3ppp/4p3/2pq4/1b1P4/2NB4/PPPB1PPP/R2QK1NR b KQkq -
+French: Winawer, Kondratiyev variation
+rnb1k1nr/ppp2pbp/3p4/4P1p1/2BP1p1q/2N5/PPP3PP/R1BQ1KNR b kq -
+KGA: bishop's gambit, Grimm attack
+rnb1k1nr/ppp2ppp/3b4/3B4/4Pp1q/8/PPPP2PP/RNBQ1KNR w kq -
+KGA: bishop's gambit, Bor\'en-Svenonius variation
+rnb1k1nr/pppp1pbp/8/6p1/2B1P2q/2N2Qp1/PPPP3P/R1B2KNR b kq -
+KGA: bishop's gambit, Fraser variation
+rnb1k1nr/pppp1pbp/8/6p1/2B1Pp1q/2N3P1/PPPP3P/R1BQ1KNR b kq -
+KGA: bishop's gambit, McDonnell attack
+rnb1k1nr/pppp1ppp/8/2b1p1q1/2B1P3/2P5/PP1P1PPP/RNBQK1NR w KQkq -
+Bishop's opening: del Rio variation
+rnb1k1nr/pppp1ppp/8/2b5/2B1Pp1q/8/PPPP2PP/RNBQ1KNR w kq -
+KGA: bishop's gambit, Greco variation
+rnb1k1nr/pppp1ppp/8/4p3/1bB1Pq2/2N2N2/PPPP2PP/R1BQK2R b KQkq -
+KGD: Norwalde variation, B\"ucker gambit
+rnb1k1nr/ppppqppp/1b1P4/4p3/2B1P3/2P2N2/PP3PPP/RNBQK2R b KQkq -
+Giuoco Piano: Eisinger variation
+rnb1k1nr/pppq1ppp/4p3/3pP3/1b1P4/2N5/PPP2PPP/R1BQKBNR w KQkq -
+French: Winawer, Petrosian variation
+rnb1k1nr/ppq1ppbp/6p1/3p4/8/P3PN2/1PPN1PPP/R1BQKB1R w KQkq -
+Catalan: open, Alekhine variation *
+rnb1k1nr/ppq2ppp/4p3/2ppP3/3P4/P1P5/2P2PPP/R1BQKBNR w KQkq -
+French: Winawer, classical variation
+rnb1k1r1/ppq1np1Q/4p3/3pP3/3p4/P1P5/2P1NPPP/R1B1KB1R b KQq -
+French: Winawer, advance, poisoned pawn, Konstantinopolsky variation
+rnb1k1r1/ppq1np1Q/4p3/3pP3/3p4/P1P5/2P2PPP/R1BK1BNR b q -
+French: Winawer, advance, poisoned pawn, Euwe-Gligori\'c variation
+rnb1k2r/1pq1bpp1/p2ppn1p/8/3NPP1B/2N2Q2/PPP3PP/R3KB1R w KQkq -
+Sicilian: Najdorf, Browne variation
+rnb1k2r/1pq1bppp/p2ppn2/6B1/3NPP2/2N2Q2/PPP3PP/R3KB1R w KQkq -
+Sicilian: Najdorf variation
+rnb1k2r/2q1bp1p/p2p1n2/1ppPp1p1/4P3/2P2N1P/PPBN1PP1/R1BQR1K1 w kq -
+Ruy Lopez: closed, Leonhardt variation
+rnb1k2r/p1pp1ppp/8/4p3/Np2n1Qq/1B6/PPPPKbPP/R1B3NR w kq -
+Evans gambit declined, V\'asquez variation *
+rnb1k2r/p4ppp/1qp2n2/2bpp3/B3P3/2NP4/PPP2PPP/R1BQK1NR w KQkq -
+Evans gambit: Tartakower attack *
+rnb1k2r/pp2ppbp/5np1/2pq4/8/1P3N2/PB1PPPPP/RN1QKB1R w KQkq -
+Queen's Indian: Marienbad system, Berg variation *
+rnb1k2r/pp2qppp/1bp2n2/3pp1B1/1P2P3/P1NP1N2/2P1BPPP/R2QK2R b KQkq -
+Ruy Lopez: Wormald attack, Gr\"unfeld variation *
+rnb1k2r/pp3ppp/4p3/q7/1b1PP3/5N2/P2B1PPP/R2QKB1R w KQkq -
+QGD: Semi-Tarrasch, San Sebastian variation
+rnb1k2r/ppp1qppp/5n2/2p1P3/3p4/5N1P/PPP1BPP1/R1BQK2R b KQkq -
+two knights defense: Mar\'oczy variation *
+rnb1k2r/ppp1qppp/5n2/3P4/1bBp4/2P2N2/PP3PPP/RNBQK2R w KQkq -
+Bishop's opening: Urusov gambit, Panov variation
+rnb1k2r/ppp2p1p/4pp2/q7/1b1P4/2N5/PPPQ1PPP/R3KBNR w KQkq -
+French: MacCutcheon, Bogolyubov variation
+rnb1k2r/ppp2p1p/5n2/3qN3/1b1P1ppP/2N5/PPP2KP1/R1BQ1B1R b kq -
+KGA: Kieseritsky, Brentano defense, Kaplanek variation
+rnb1k2r/ppp2ppp/1b6/3qp3/1PP5/P2P4/5PPP/R1BQKBNR b KQkq -
+Ruy Lopez: Noah's ark trap *
+rnb1k2r/ppp2ppp/3b4/3qp3/8/3P4/PPP2PPP/R1BQKBNR w KQkq -
+Scotch: Ghulam Kassim variation *
+rnb1k2r/ppp2ppp/5n2/3qp3/1b6/2NP4/PP1QPPPP/R1B1KBNR b KQkq -
+Sicilian: Chekhover, Zaitsev variation *
+rnb1k2r/ppp2ppp/8/2bPp3/2B3nq/2N4N/PPPP1PPP/R1BQK2R w KQkq -
+Scotch gambit: Vitzhum attack *
+rnb1k2r/ppp2ppp/8/3Pp3/2qP4/2N3P1/PPP2K1P/R1BQ3R b kq -
+Scotch gambit: Cochrane-Shumov defense *
+rnb1k2r/ppp2ppp/8/3np3/8/P1P5/1PPB1PPP/R3KBNR b KQkq -
+Ruy Lopez: exchange, Alekhine variation *
+rnb1k2r/ppp2ppp/8/3q4/4nP2/8/PPPNQbPP/RNBK1B1R b kq -
+KGD: Falkbeer, Alapin variation
+rnb1k2r/ppp3p1/3q1n2/2bppP1p/6P1/3P3P/PPP2PB1/RNBQK1NR w KQkq -
+KGA: Philidor gambit, Schultz variation *
+rnb1k2r/pppnqppp/4p3/1N1pP3/3P4/8/PPP2PPP/R2QKBNR b KQkq -
+French: classical, Alapin variation
+rnb1k2r/pppnqppp/4p3/3pP3/3P1P2/2N5/PPP3PP/R2QKBNR b KQkq -
+French: classical, Steinitz variation
+rnb1k2r/pppnqppp/4p3/3pP3/3P2Q1/2N5/PPP2PPP/R3KBNR b KQkq -
+French: classical, Pollock variation
+rnb1k2r/pppnqppp/4p3/3pP3/3P4/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: classical variation
+rnb1k2r/pppnqppp/4p3/3pP3/3P4/2N5/PPPQ1PPP/R3KBNR b KQkq -
+French: classical, Rubinstein variation
+rnb1k2r/pppnqppp/4p3/3pP3/3P4/2NB4/PPP2PPP/R2QK1NR b KQkq -
+French: classical, Tarrasch variation
+rnb1k2r/pppnqppp/8/2p1P3/2Bp4/5N1P/PPP2PP1/R1BQK2R w KQkq -
+two knights defense: Yankovich variation *
+rnb1k2r/pppp1ppp/3b1q2/8/N3P1n1/2P2N2/P1Q2PPP/R1B1KB1R w KQkq -
+two knights defense: Paoli variation *
+rnb1k2r/pppp1ppp/5q2/8/NP2P1n1/5N2/P4PPP/R1BQKB1R b KQkq -
+two knights defense: Blackburne variation *
+rnb1k2r/pppp1ppp/5q2/8/Nb2P1n1/2P2N2/P4PPP/1RBQKB1R b Kkq -
+two knights defense: Colman variation *
+rnb1k2r/pppp1ppp/5q2/8/Nb2P1n1/2P2N2/P4PPP/R1BQKB1R w KQkq -
+two knights defense: Bogolyubov variation *
+rnb1k2r/ppppnpbp/8/6p1/2BPPp1q/2N3P1/PPP4P/R1BQ1KNR b kq -
+KGA: bishop's gambit, McDonnell attack
+rnb1k2r/ppppnpbp/8/6p1/2BPPp1q/2N5/PPP3PP/R1BQ1KNR w kq -
+KGA: bishop's gambit, classical defense
+rnb1k2r/ppppqppp/4pn2/8/1bPP4/5N2/PP1BPPPP/RN1QKB1R w KQkq -
+Bogo-Indian defense, Nimzovich variation
+rnb1k2r/ppppqppp/5n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R w KQkq -
+Ruy Lopez: Wormald (Alapin) attack *
+rnb1kb1N/ppp3pp/5n2/3p4/2B1p3/8/PPPP1PqP/RNBQKR2 w Qkq -
+Latvian: Behting variation
+rnb1kb1r/1p3ppp/p2ppn2/6B1/3NPP2/q1N5/P1PQ2PP/1R2KB1R w Kkq -
+Sicilian: Najdorf, Poisoned pawn variation
+rnb1kb1r/1p3ppp/pq1ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+Sicilian: Najdorf, 7...Qb6
+rnb1kb1r/1pq2ppp/p2ppn2/8/3NP3/2N5/PPP1BPPP/R1BQ1RK1 w kq -
+Sicilian: Scheveningen (Paulsen), classical variation
+rnb1kb1r/2q2ppp/p3pn2/1p2P1B1/3N4/2N5/PPP1Q1PP/R3KB1R b KQkq -
+Sicilian: Najdorf, Polugayevsky, Simagin variation
+rnb1kb1r/pp1p1ppp/2p2n2/q3p3/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+Ponziani: Leonhardt variation *
+rnb1kb1r/pp1p1ppp/2p2n2/q3p3/3PP3/2N2P2/PPP3PP/R1BQKBNR b KQkq -
+Ponziani: Steinitz variation *
+rnb1kb1r/pp1p1ppp/2p2n2/q3p3/3PP3/2N5/PPPB1PPP/R2QKBNR b KQkq -
+Ponziani: Caro variation *
+rnb1kb1r/pp1p2pp/2p2n2/q3p1B1/2B1P3/8/PPP2PPP/RN1QK1NR w KQkq -
+KGD: classical, Marshall attack *
+rnb1kb1r/pp1ppppp/5n2/q1pP4/8/2N5/PPP1PPPP/R1BQKBNR w KQkq -
+Woozle defense
+rnb1kb1r/pp2pppp/1qp2n2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD Slav: S\"uchting variation
+rnb1kb1r/pp2pppp/5n2/q1Pp4/8/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+QGA: Mannheim variation *
+rnb1kb1r/pp3pp1/2p1pq1p/3p4/2PP4/1QN2N2/PP2PPPP/R3KB1R b KQkq -
+QGD/QGD semi-Slav: Hastings variation
+rnb1kb1r/pp3ppp/1q2pn2/2pP2B1/3P4/2N5/PP2PPPP/R2QKBNR w KQkq -
+QGD: Canal (Venice) variation
+rnb1kb1r/ppp1pppp/5n2/8/3q4/2N2N2/PPPPQ1PP/R1B1KB1R b KQkq -
+Queen's pawn: Englund gambit *
+rnb1kb1r/ppp1q1pp/5n2/4Np2/2Bp1B2/8/PPP2PPP/RN1QK2R b KQkq -
+KGD: Falkbeer, main line, 7...Bf5 *
+rnb1kb1r/ppp1q2p/5n2/4Npp1/2Bp1B2/8/PPP2PPP/RN1Q1RK1 b kq -
+KGD: Falkbeer, Tarrasch variation *
+rnb1kb1r/ppp1qppp/5n2/3PN3/4p3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov: modern attack, Steinitz variation *
+rnb1kb1r/ppp1qppp/8/3n4/2N1p3/2N5/PPPP1PPP/R1BQKB1R b KQkq -
+Petrov: modern attack, Bardeleben variation *
+rnb1kb1r/ppp2p1p/3p3n/4N3/2BPPppq/8/PPP3PP/RNBQ1K1R w kq -
+KGA: Salvio gambit, Anderssen counter-attack
+rnb1kb1r/ppp2ppp/5n2/3qN3/4p3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov: modern attack, main line *
+rnb1kb1r/ppp2ppp/5n2/3qp3/8/3P4/PP2PPPP/RNBQKBNR w KQkq -
+Sicilian, Chekhover variation *
+rnb1kb1r/ppp2ppp/5n2/3qp3/8/3P4/PPPB1PPP/RN1QKBNR b KQkq -
+Philidor: Boden variation *
+rnb1kb1r/ppp2ppp/5n2/4N3/3qp3/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Nimzovich, Rellstab variation *
+rnb1kb1r/ppp2ppp/8/3NP2q/8/3P1Nn1/PPP4P/R1BQKB1R b KQkq -
+Vienna gambit, Wurzburger trap
+rnb1kb1r/ppp3pp/8/3q1p2/4nPP1/8/PPPNQ2P/R1B1KBNR b KQkq -
+KGD: Falkbeer, Charousek variation
+rnb1kb1r/pppp1p1p/7n/4N3/2BPP1pq/5p2/PPP3PP/RNBQ1K1R w kq -
+KGA: Silberschmidt gambit
+rnb1kb1r/pppp2p1/8/4pq1p/8/3B1N1P/PPPP1K2/RNBQ3R b kq -
+KGA: Allgaier, Horny defense *
+rnb1kb1r/ppppqppp/5n2/4N3/8/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: Cozio (Lasker) attack *
+rnb1kb1r/ppq1p1pp/2pp1n2/5p2/2PP4/2N3P1/PP2PPBP/R1BQK1NR w KQkq -
+Dutch: Hort-Antoshin system
+rnb1kbnr/p1pp1ppp/8/1p6/2B1Pp1q/8/PPPP2PP/RNBQ1KNR w kq -
+KGA: bishop's gambit, Bryan counter-gambit
+rnb1kbnr/pp1ppppp/8/q1p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian: Stiletto (Althouse) variation
+rnb1kbnr/pp2pppp/1qp5/3p4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+Caro-Kann: Edinburgh variation
+rnb1kbnr/pp2pppp/8/3q4/1p6/P7/1BPP1PPP/RN1QKBNR b KQkq -
+Sicilian: wing gambit, Marienbad variation
+rnb1kbnr/pp3ppp/2p1q3/4p3/8/2N5/PPPPBPPP/R1BQK1NR b KQkq -
+Center game: Charousek variation *
+rnb1kbnr/ppp1pp1p/3q4/3p2p1/5P2/4P3/PPPP2PP/RNBQKBNR w KQkq -
+Dutch, Von Pretzel gambit *
+rnb1kbnr/ppp1pppp/3q4/3p4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch, Manhattan (Alapin, Ulvestad) variation *
+rnb1kbnr/ppp1pppp/3q4/8/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Scandinavian: Pytel-Wade variation
+rnb1kbnr/ppp1pppp/8/q7/1P6/2N5/P1PP1PPP/R1BQKBNR b KQkq -
+Scandinavian, Mieses-Kotr\v c gambit
+rnb1kbnr/ppp1q1pp/3p4/4Pp2/3p4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+KGD: Falkbeer, R\'eti variation *
+rnb1kbnr/ppp1q1pp/8/4Np2/3p4/8/PPP2PPP/RNBQKB1R w KQkq -
+KGD: Falkbeer, Charousek gambit *
+rnb1kbnr/ppp2p1p/8/3B2p1/4Pp1q/6P1/PPPP3P/RNBQ1KNR b kq -
+KGA: bishop's gambit, Chigorin's attack (Gifford variation)
+rnb1kbnr/ppp2ppp/4p3/3q4/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+French: Frere (Becker) variation
+rnb1kbnr/ppp2ppp/4q3/4p3/5P2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Center game: l'Hermet variation *
+rnb1kbnr/ppp2ppp/4q3/4p3/8/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Center game: Berger variation *
+rnb1kbnr/ppp2ppp/4q3/4p3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Center game: Paulsen attack *
+rnb1kbnr/ppp2ppp/8/2q1p3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Center game: Hall variation *
+rnb1kbnr/ppp2ppp/8/3p2q1/2PPp3/4P3/PP3PPP/RNBQKBNR w KQkq -
+French: advance, Nimzovich variation *
+rnb1kbnr/ppp2ppp/8/3qp3/8/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Center game *
+rnb1kbnr/ppp2ppp/8/3qp3/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+Center game *
+rnb1kbnr/ppp2ppp/8/q3p3/3P4/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+Scandinavian: Anderssen counter-attack, Goteborg system
+rnb1kbnr/ppp2ppp/8/q3p3/3P4/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Scandinavian: Anderssen counter-attack
+rnb1kbnr/ppp3pp/3p1q2/8/3Pp3/4N3/PPP2PPP/RNBQKB1R b KQkq -
+Latvian: Nimzovich variation
+rnb1kbnr/pppp1B1p/8/4q3/5p2/5Q2/PPPP2PP/RNB2RK1 b kq -
+KGA: double Muzio gambit
+rnb1kbnr/pppp1p1p/8/4N3/2B1P1pq/5p2/PPPP2PP/RNBQ1K1R w kq -
+KGA: Cochrane gambit
+rnb1kbnr/pppp1p1p/8/6p1/2B1Pp1q/5Q2/PPPP2PP/RNB2KNR b kq -
+KGA: bishop's gambit, classical defense, Cozio attack
+rnb1kbnr/pppp1p1p/8/6p1/2B1Pp1q/8/PPPP2PP/RNBQ1KNR w kq -
+KGA: bishop's gambit, classical defense
+rnb1kbnr/pppp1ppp/5q2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Greco defense
+rnb1kbnr/pppp1ppp/5q2/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: Napoleon's opening *
+rnb1kbnr/pppp1ppp/5q2/4p3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: Norwalde variation
+rnb1kbnr/pppp1ppp/8/4p3/4P2q/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: Patzer opening *
+rnb1kbnr/pppp2pp/5q2/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Breyer gambit *
+rnb1kbnr/ppppq1pp/8/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Carrera (Basman) gambit *
+rnb1kbnr/ppppq2p/8/4Np2/2BPPppP/8/PPP3P1/RNBQK2R b KQkq -
+KGA: Kieseritsky, Salvio defense, Cozio variation
+rnb1kbnr/ppppqp1p/8/4N3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Salvio (Rosenthal) defense
+rnb1kbnr/ppppqp1p/8/8/2B1Pp2/5Q2/PPPP2PP/RNB2RK1 w kq -
+KGA: Muzio gambit, From defense
+rnb1kbnr/ppppqp1p/8/8/2B1Ppp1/5N2/PPPP2PP/RNBQ1RK1 w kq -
+KGA: Muzio gambit, Kling and Horwitz counter-attack
+rnb1kbnr/ppppqppp/8/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Gunderam defense
+rnb1kbnr/ppppqppp/8/4p3/4PP2/6P1/PPPP3P/RNBQKBNR w KQkq -
+KGD: Keene's defense
+rnb1kbnr/ppppqppp/8/4p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French: Chigorin variation *
+rnb1kbnr/ppppqppp/8/8/2B1P3/8/PB3PPP/RN1QK1NR w KQkq -
+Danish gambit: Collijn defense
+rnb1kbnr/ppq1pppp/8/2p1N3/4p3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Budapest: Fajarowicz, Steiner variation *
+rnb1kbnr/ppq1pppp/8/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+Queen's pawn: Mengarini attack *
+rnb1kbnr/ppqppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian: Quinteros variation
+rnb1qrk1/pp2b1pp/2p1pn2/3p1pB1/2PP4/2N2NP1/PPQ1PPBP/R4RK1 b - -
+Dutch: stonewall: Chekhover variation
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/1PN2NP1/P3PPBP/R1BQ1RK1 b - -
+Dutch: Ilyin-Genevsky variation with b3
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+Dutch: Ilyin-Genevsky variation
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/2N2NP1/PP2PPBP/R1BQR1K1 b - -
+Dutch: Ilyin-Genevsky, Winter variation
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/2N2NP1/PPQ1PPBP/R1B2RK1 b - -
+Dutch: Ilyin-Genevsky variation with Qc2
+rnb1r1k1/ppp2ppp/1b6/3qp3/1PP5/P2P1N2/4BPPP/R1BQK2R b KQ -
+Ruy Lopez: Noah's ark trap *
+rnb2bnr/pppp1k1p/5q2/8/4Pp2/2N1BQ2/PPP3PP/R4RK1 b - -
+KGA: Lolli gambit, Young variation
+rnb2knr/pppp2pp/5q2/2b1pP1Q/6P1/8/PPPP1P1P/RNB1KBNR w KQ -
+KGA: bishop's gambit, classical defense, Cozio attack *
+rnb2rk1/p1p1qppp/1p3n2/8/4p3/2P5/PNPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Berlin defense, Pillsbury variation *
+rnb2rk1/p1pqppbp/1p4p1/8/2BPP3/2P5/P3NPPP/R1BQ1RK1 w - -
+Gr\"unfeld: exchange, Larsen variation
+rnb2rk1/p1q1ppbp/1p3np1/2pp4/3P4/2P1PN2/PP1NBPPP/R1BQ1RK1 w - -
+Catalan: closed, Qc2 & b3 *
+rnb2rk1/p4ppp/1qp2n2/2bPp3/B7/2NP4/PPP2PPP/R1BQK1NR w KQ -
+Evans gambit: Waller attack *
+rnb2rk1/pp2ppbp/2pp1np1/q7/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, Kavalek (Bronstein) variation
+rnb2rk1/pp2qppp/1b2pn2/3p4/1PP5/P3PN2/1B3PPP/RN1QKB1R b KQ -
+QGA: classical, 8...Bb7 *
+rnb2rk1/pp2qppp/1b3n2/2p1N3/1P1Pp3/P1N1B3/2P1BPPP/R2QK2R w KQ -
+Ruy Lopez: open, Howell attack, Adam variation *
+rnb2rk1/pp2qppp/4pn2/2bp4/1PP5/P3PN2/5PPP/RNBQKB1R b KQ -
+QGA: classical, 7...b5 *
+rnb2rk1/pp2qppp/4pn2/2bp4/2P5/P3PN2/1P3PPP/RNBQKB1R w KQ -
+QGA: classical, 7.Qe2 *
+rnb2rk1/pp2qppp/4pn2/2p5/1bBP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, Gligori\'c system, Smyslov variation
+rnb2rk1/pp2qppp/5n2/2b5/1PB1p3/P1N1PN2/5PPP/R1BQK2R w KQ -
+QGA: classical, Furman variation *
+rnb2rk1/pp2qppp/5n2/2p5/4p3/2P5/PNPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Berlin defense, Zukertort variation *
+rnb2rk1/pp3ppp/1bpq1n2/4N3/1PBPp3/P1N1B3/2P2PPP/R2QK2R w KQ -
+Ruy Lopez: open, Motzko attack *
+rnb2rk1/pp3ppp/1bpq1n2/4N3/1PBPp3/P3B3/2P1NPPP/R2QK2R b KQ -
+Ruy Lopez: open, Motzko attack, Nenarokov variation *
+rnb2rk1/ppB1ppbp/6p1/3q4/3P4/4P3/PP3PPP/R2QKBNR b KQ -
+Gr\"unfeld: Gr\"unfeld gambit accepted
+rnb2rk1/ppp1qpp1/4p2p/3P4/3P4/2P1PN2/P4PPP/R2QKB1R b KQ -
+QGD: Lasker defense, main line
+rnb2rk1/ppp1qpp1/4p2p/3p4/2PPn3/2N1PN2/PPQ2PPP/R3KB1R b KQ -
+QGD: Lasker defense, Teichmann variation
+rnb2rk1/ppp1qppp/1b3n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R w KQ -
+Ruy Lopez: open, Howell attack *
+rnb2rk1/ppp1qppp/5n2/3pN3/1b1PP3/2N5/PPP1BPPP/R1BQK2R b KQ -
+Ruy Lopez: Berlin defense, Trifunovi\'c variation *
+rnb2rk1/ppp1qppp/5n2/8/4pN2/2P5/P1PPBPPP/R1BQK2R b KQ -
+Ruy Lopez: Berlin defense, Cordel variation *
+rnb2rk1/ppp1qppp/8/3n4/4p3/2P5/PNPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Berlin defense, Winawer attack *
+rnb2rk1/ppp2pbp/3p2p1/3Pp3/2n1P2Q/2N2P2/PP2K2P/R5NR w - -
+King's Indian: S\"amisch, orthodox, Bronstein variation
+rnb2rk1/ppp2pp1/3q3p/3p4/3P4/1QP1PN2/P4PPP/R3KB1R w KQ -
+QGD: Lasker defense, Bernstein variation
+rnb2rk1/pppp2pp/5q2/2b1pP2/8/2N5/PPPP1P1P/R1BQKBNR b KQ -
+KGA: Muzio gambit, Holloway defense *
+rnb2rk1/pppp2pp/5q2/2b1pP2/8/8/PPPPQP1P/RNB1KBNR b KQ -
+KGA: Muzio gambit, From defense *
+rnb2rk1/pppp2pp/5q2/5P2/4Q3/8/PPPP1b1P/RNB1KBNR w KQ -
+KGA: double Muzio gambit *
+rnb2rk1/ppppqppp/1b3n2/4p3/1P2P3/P1N2N2/2PPBPPP/R1BQ1RK1 b - -
+Ruy Lopez: Worrall attack, sharp line *
+rnb2rk1/ppppqppp/1b3n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQK2R b KQ -
+Ruy Lopez: Worrall attack, solid line *
+rnb2rk1/ppppqppp/5n2/b3N3/4P3/P1N5/1PPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, Tartakower variation *
+rnb2rk1/ppppqppp/5n2/b3p3/4P3/P1N2N2/1PPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Worrall attack *
+rnb2rk1/ppq1ppbp/5np1/2pp4/3P4/4PN2/PPPNBPPP/R1BQ1RK1 w - -
+Catalan: closed, 7.Qc2 *
+rnbk1b1r/pppnqBpp/8/4Np2/3Q4/8/PPP2PPP/RNB1K2R w KQ -
+KGD: Falkbeer, Alapin variation *
+rnbk1bnr/pppp2pp/8/8/2B1pp1q/2N5/PPPPQ1PP/R1BK2NR w - -
+KGA: L\'opez-Gianutio counter-gambit, Hein variation
+rnbq1bnr/ppp3k1/7p/3B4/3PPppP/8/PPP3P1/RNBQK2R b KQ -
+KGA: Allgaier, Urusov attack
+rnbq1bnr/ppp3k1/7p/4B3/2BPp1pP/8/PPP3P1/RN1QK2R b KQ -
+KGA: Allgaier, Cook variation
+rnbq1bnr/pppp1k2/7p/8/2B1PppP/8/PPPP2P1/RNBQK2R b KQ -
+KGA: Allgaier, Walker attack
+rnbq1bnr/pppp1k2/7p/8/3PPppP/8/PPP3P1/RNBQKB1R b KQ -
+KGA: Allgaier, Thorold variation
+rnbq1bnr/pppp1k2/7p/8/4PppP/2N5/PPPP2P1/R1BQKB1R b KQ -
+KGA: Allgaier, Blackburne gambit
+rnbq1bnr/pppp1kpp/8/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQ -
+KGA: Tumbleweed gambit *
+rnbq1bnr/pppppkpp/5p2/8/3PP3/8/PPP2PPP/RNBQKBNR w KQ -
+Fried fox defense
+rnbq1bnr/pppppkpp/5p2/8/4P3/8/PPPP1PPP/RNBQKBNR w KQ -
+Hammerschlag (Fried fox/Pork chop opening) *
+rnbq1k1r/pp3ppp/5n2/1Bbpp3/8/2N2N2/PPPP1PPP/R1BQK2R w KQ -
+Giuoco Piano: Cracow variation *
+rnbq1k1r/ppp2Bpp/8/4N2Q/1b1Pp3/2n5/PPP2PPP/R1B1K2R b KQ -
+Two knights defense, Keidanz variation *
+rnbq1k1r/ppp2pp1/4p2p/3pP3/3Pn1Q1/2P5/P1P2PPP/R1B1KBNR b KQ -
+French: MacCutcheon, Duras variation
+rnbq1k1r/ppp3pp/5P2/2bpp1PQ/4n3/7N/PPPP1P1P/RNB1KB1R b KQ -
+KGA: Silberschmidt gambit *
+rnbq1k1r/ppp3pp/8/2bppPPQ/4n3/3P3N/PPP2P1P/RNB1KB1R b KQ -
+KGA: Salvio gambit, Anderssen counter-attack *
+rnbq1k1r/pppp2pp/5P2/2b1p1PQ/4n3/8/PPPP1P1P/RNB1KBNR b KQ -
+KGA: Cochrane gambit *
+rnbq1k1r/pppp2pp/8/2b1pPPQ/4n3/2N5/PPPP1P1P/R1B1KBNR b KQ -
+KGA: Herzfeld gambit *
+rnbq1knr/pppp2pp/8/2b1pP1Q/1P6/8/P1PP1PPP/RNB1KBNR b KQ -
+KGA: bishop's gambit, Bryan counter-gambit *
+rnbq1knr/pppp2pp/8/2b1pP1Q/2B5/8/PPPP1PPP/RNB1K1NR b KQ -
+KGA: bishop's gambit, Greco variation *
+rnbq1knr/pppp2pp/8/2b1pP1Q/6P1/8/PPPP1P1P/RNB1KBNR b KQ -
+KGA: bishop's gambit, classical defense *
+rnbq1knr/pppp2pp/8/2b1pP1Q/8/2N5/PPPP1PPP/R1B1KBNR b KQ -
+KGA: bishop's gambit, Boden defense *
+rnbq1knr/pppp2pp/8/4pP1Q/3b4/3B4/PPP2PPP/RNB1K1NR b KQ -
+KGA: bishop's gambit, Bor\'en-Svenonius variation *
+rnbq1knr/pppp3p/6p1/4pP1Q/3b2P1/8/PPP2P1P/RNB1KBNR w KQ -
+KGA: bishop's gambit, Chigorin's attack (Gifford variation) *
+rnbq1r1k/p1p4P/5n2/2bpp2B/8/8/PPPP1PPP/RNBQK1NR w KQ -
+Bishop's opening: Four pawns' gambit *
+rnbq1r1k/pppp3P/5n2/2b1p2B/8/8/PPPP1PPP/RNBQK1NR w KQ -
+KGA: Cunningham, three pawns gambit *
+rnbq1rk1/1p2ppbp/p1pp1np1/8/2PPP3/2NBBP2/PP4PP/R2QK1NR w KQ -
+King's Indian: S\"amisch, Byrne variation
+rnbq1rk1/1p3pbp/p2p1np1/2pP4/P3P3/2N2N2/1P2BPPP/R1BQ1RK1 b - -
+Benoni: classical, 9...a6, 10.a4
+rnbq1rk1/1p3ppp/4pn2/p1bp4/2P5/P3PN2/1P3PPP/RNBQKB1R w KQ -
+QGA: classical, Rubinstein variation *
+rnbq1rk1/1pp1ppbp/p4np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Russian, Alekhine (Hungarian) variation
+rnbq1rk1/1pp2pbp/3p1np1/p2Pp3/2P1P3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+King's Indian: Petrosian system, Stein variation
+rnbq1rk1/1pp2ppp/1b3n2/p2NN3/1P1PP3/P7/2P2PPP/R1BQKB1R b KQ -
+Ruy Lopez: open, Schlechter defense *
+rnbq1rk1/1ppp1ppp/1b3n2/p3p3/1P2P3/P1N2N2/2PPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Wing attack *
+rnbq1rk1/2p1bppp/p2p1n2/1p2p3/3PP3/1BP2N1P/PP3PP1/RNBQR1K1 b - -
+Ruy Lopez: closed, Breyer, 10.d4
+rnbq1rk1/2p1bppp/p2p1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Breyer defense
+rnbq1rk1/p1p1bpp1/1p2p2p/3n4/3P3B/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QGD: Tartakower (Makagonov-Bondarevsky) system, 8.cd Nxd5
+rnbq1rk1/p1p1bpp1/1p2pn1p/3p4/2PP3B/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QGD: Tartakower (Makagonov-Bondarevsky) system
+rnbq1rk1/p1p1ppbp/1p1p1np1/8/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+King's Indian: S\"amisch, double fianchetto variation
+rnbq1rk1/p1p1ppbp/1p3np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Russian, Levenfish variation
+rnbq1rk1/p1p1ppbp/1p4p1/8/2BPP3/2P5/P3NPPP/R1BQK2R w KQ -
+Gr\"unfeld: exchange, Simagin's lesser variation
+rnbq1rk1/p1p2ppp/1p2pn2/3p4/1bPP4/2NBPN2/PP3PPP/R1BQK2R w KQ -
+Nimzo-Indian: 4.e3, main line with ...b6
+rnbq1rk1/p1pp1ppp/4pn2/1p6/2PP4/P1Q5/1P2PPPP/R1B1KBNR w KQ -
+Nimzo-Indian: classical, Adorjan gambit
+rnbq1rk1/p1pp1ppp/5n2/1p1Np3/1bB1P3/8/PPPP1PPP/R1BQK1NR w KQ -
+Ruy Lopez: classical defense, Zaitsev variation *
+rnbq1rk1/p2p1ppp/2p2n2/2b1p3/B3P3/2N5/PPPP1PPP/R1BQK1NR w KQ -
+Evans gambit *
+rnbq1rk1/p2p1ppp/2p2n2/2b1p3/B3P3/2NP4/PPP2PPP/R1BQK1NR b KQ -
+Evans gambit *
+rnbq1rk1/p3ppbp/1p3np1/2pp4/3P1P2/4PN2/PPP1B1PP/RNBQ1RK1 w - -
+Dutch: stonewall, Botwinnik variation *
+rnbq1rk1/p3ppbp/1p3np1/2pp4/8/1P2PN2/PBPPBPPP/RN1Q1RK1 w - -
+Queen's Indian: Euwe variation *
+rnbq1rk1/p4ppp/1p2pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, Keres variation
+rnbq1rk1/p4ppp/2P2n2/2b1p3/B7/2N5/PPPP1PPP/R1BQK1NR b KQ -
+Evans gambit: compromised defense *
+rnbq1rk1/p4ppp/2p2n2/2bpp1B1/B3P3/2NP4/PPP2PPP/R2QK1NR b KQ -
+Evans gambit: Alapin-Steinitz variation *
+rnbq1rk1/p4ppp/2p2n2/2bpp3/4P3/1BNP4/PPP2PPP/R1BQK1NR b KQ -
+Evans gambit: Lasker defense *
+rnbq1rk1/p4ppp/2p2n2/2bpp3/B3P3/2NP4/PPPB1PPP/R2QK1NR b KQ -
+Evans gambit: Sanders-Alapin variation *
+rnbq1rk1/p4ppp/2p5/2bpp3/B3n3/2N2N2/PPPP1PPP/R1BQ1RK1 w - -
+Evans gambit: Richardson attack *
+rnbq1rk1/p4ppp/5n2/2bpp3/8/1BNP4/PPP2PPP/R1BQK1NR b KQ -
+Evans gambit: normal variation *
+rnbq1rk1/pp1p1ppp/2p2n2/b7/4PB2/P1NP4/1PP3PP/R2QKBNR w KQ -
+Ruy Lopez: Siesta, Kopayev variation *
+rnbq1rk1/pp1p1ppp/4pn2/2P5/1bP5/2N5/PPQ1PPPP/R1B1KBNR w KQ -
+Nimzo-Indian: classical, Pir\'c variation
+rnbq1rk1/pp1pppbp/5np1/2p5/3P4/4PN2/PPP1BPPP/RNBQK2R w KQ -
+English: Neo-Catalan declined *
+rnbq1rk1/pp2b1pp/2p1pn2/3p1p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+Dutch: stonewall with Nc3
+rnbq1rk1/pp2b1pp/2p1pn2/3p1p2/2PP4/BP3NP1/P3PPBP/RN1Q1RK1 b - -
+Dutch: stonewall with Ba3
+rnbq1rk1/pp2p1bp/2pp1np1/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+Dutch: Leningrad, main variation with c6
+rnbq1rk1/pp2ppbp/2p2np1/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.O-O c6
+rnbq1rk1/pp2ppbp/2p2np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Russian, Szabo (Boleslavsky) variation
+rnbq1rk1/pp2ppbp/3p1np1/2p3B1/2PPP3/2N5/PP2BPPP/R2QK1NR w KQ -
+King's Indian: Averbakh, 6...c5
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+King's Indian: fianchetto, Yugoslav, 7.O-O
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+King's Indian: fianchetto, Yugoslav system
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PPPP2/2N2N2/PP2B1PP/R1BQK2R b KQ -
+King's Indian: Four pawns attack, with Be2 and Nf3
+rnbq1rk1/pp2ppbp/3p1np1/2pP4/2P1PP2/2N2N2/PP4PP/R1BQKB1R b KQ -
+King's Indian: Four pawns attack, dynamic line
+rnbq1rk1/pp2ppbp/3p1np1/8/3NP3/2N1BP2/PPP3PP/R2QKB1R w KQ -
+Sicilian: dragon, Yugoslav attack, 7...O-O
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P1P2/4PN2/PPP1B1PP/RNBQ1RK1 b - -
+Dutch: stonewall variation *
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/2P2NP1/PP2PPBP/RNBQ1RK1 b - -
+Neo-Gr\"unfeld, 6.O-O c6 *
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/4PN2/PPPNBPPP/R1BQ1RK1 b - -
+Catalan: closed, 6...Nbd7 *
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.O-O *
+rnbq1rk1/pp2ppbp/5np1/2pp4/5P2/3PPN2/PPP1B1PP/RNBQ1RK1 b - -
+Dutch: classical variation *
+rnbq1rk1/pp2ppbp/5np1/2pp4/8/1P2PN2/PBPPBPPP/RN1QK2R w KQ -
+Queen's Indian: old main line, 6.O-O *
+rnbq1rk1/pp2ppbp/5np1/2ppN3/5P2/4P3/PPPPB1PP/RNBQ1RK1 b - -
+Dutch defense, Alekhine variation *
+rnbq1rk1/pp2ppbp/5np1/3p4/3N4/6P1/PPP1PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O *
+rnbq1rk1/pp2ppbp/5np1/3p4/3P4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+Neo-Gr\"unfeld, 6.O-O, main line *
+rnbq1rk1/pp2ppbp/5np1/3p4/3P4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.O-O, main line
+rnbq1rk1/pp2ppbp/5np1/3p4/8/1N4P1/PPP1PPBP/RNBQ1RK1 b - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O Nb6 *
+rnbq1rk1/pp2ppbp/5np1/8/2pN4/6P1/PP2PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O c5, 8.dc *
+rnbq1rk1/pp2ppbp/6p1/2Pn4/8/5NP1/PP2PPBP/RNBQ1RK1 b - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O c5, 8.dc
+rnbq1rk1/pp2ppbp/6p1/2p5/2BPP3/2P5/P3NPPP/R1BQK2R w KQ -
+Gr\"unfeld: exchange, Spassky variation
+rnbq1rk1/pp2ppbp/6p1/2pn4/3P4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O c5, 8.Nc3
+rnbq1rk1/pp3pbp/2pp1np1/3Pp3/2P1P3/2N1BP2/PP4PP/R2QKBNR w KQ -
+King's Indian: S\"amisch, orthodox, 7.d5 c6
+rnbq1rk1/pp3pbp/2pp1np1/4p3/2PPP3/2N1BP2/PP2N1PP/R2QKB1R w KQ -
+King's Indian: S\"amisch, orthodox, 7.Nge2 c6
+rnbq1rk1/pp3pbp/2pp1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+King's Indian: orthodox, Donner variation
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+Benoni: classical, 9.O-O
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+Benoni: classical without 9.O-O
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4PP2/2N2N2/PP4PP/R1BQKB1R w KQ -
+Benoni: four pawns attack
+rnbq1rk1/pp3pbp/3p1np1/2pP4/8/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+Benoni: fianchetto variation
+rnbq1rk1/pp3pbp/3p1np1/2ppP3/2P2P2/2N2N2/PP2B1PP/R1BQK2R b KQ -
+King's Indian: Four pawns attack, Florentine gambit
+rnbq1rk1/pp3pbp/3p1np1/3pp3/2P1P3/2N1BP2/PP2N1PP/R2QKB1R w KQ -
+King's Indian: S\"amisch, orthodox main line
+rnbq1rk1/pp3pbp/3ppnp1/2pP2B1/2P1P3/2N5/PP2BPPP/R2QK1NR w KQ -
+King's Indian: Averbakh, main line
+rnbq1rk1/pp3pbp/3ppnp1/2pP4/2P1PP2/2N2N2/PP2B1PP/R1BQK2R b KQ -
+King's Indian: Four pawns attack
+rnbq1rk1/pp3ppp/1b3n2/2ppN3/1P1PP3/P1N5/2P2PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, Harksen gambit *
+rnbq1rk1/pp3ppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P1BPPP/R2QK2R b KQ -
+Ruy Lopez: open, classical defense *
+rnbq1rk1/pp3ppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R w KQ -
+Ruy Lopez: open, 9.c3 *
+rnbq1rk1/pp3ppp/1bp2n2/4N3/1PBPp3/P1N1B3/2P2PPP/R2QK2R b KQ -
+Ruy Lopez: open, Italian variation *
+rnbq1rk1/pp3ppp/1bp2n2/8/1PNPp3/P1N1B3/2P2PPP/R2QKB1R b KQ -
+Ruy Lopez: open, Berlin variation *
+rnbq1rk1/pp3ppp/2p2n2/2bP2N1/2B1p3/2N5/PPPP1PPP/R1BQK2R w KQ -
+two knights: Max Lange attack, Krause variation *
+rnbq1rk1/pp3ppp/2p2n2/2bPp1B1/2B5/2NP4/PPP2PPP/R2QK1NR b KQ -
+Scotch gambit: Anderssen (Paulsen, Suhle) counter-attack *
+rnbq1rk1/pp3ppp/2p2n2/3pp3/1b2P3/1BN2N2/PPPP1PPP/R1BQ1RK1 b - -
+Ruy Lopez: classical defense, Benelux variation *
+rnbq1rk1/pp3ppp/2p2n2/3pp3/2P5/2NP1N2/PP1QPPPP/R3KB1R w KQ -
+Sicilian: Canal-Sokolsky attack, Bronstein gambit *
+rnbq1rk1/pp3ppp/2p2n2/b2PN3/4p3/P1N5/1PPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: closed, Basque gambit (North Spanish variation) *
+rnbq1rk1/pp3ppp/3b1n2/2ppN1B1/3P4/3B4/PPP2PPP/RN1Q1RK1 b - -
+Petrov: classical attack, Tarrasch variation *
+rnbq1rk1/pp3ppp/3b1n2/2ppN3/3P4/2N5/PPP1BPPP/R1BQK2R w KQ -
+Petrov: classical attack, Jaenisch variation *
+rnbq1rk1/pp3ppp/3b4/2pnp3/8/P2PPNP1/1P3P1P/RNBQKB1R b KQ -
+Sicilian: Kan, Gipslis variation *
+rnbq1rk1/pp3ppp/3b4/2ppN3/3PB3/8/PPP2PPP/RNBQ1RK1 b - -
+Petrov: modern attack, Trifunovi\'c variation *
+rnbq1rk1/pp3ppp/4p3/1B6/3PP3/5N2/P2Q1PPP/R3K2R b KQ -
+QGD: Semi-Tarrasch, Kmoch variation
+rnbq1rk1/pp3ppp/4p3/2pn4/3P4/P1P1PP2/6PP/R1BQKBNR w KQ -
+Nimzo-Indian: S\"amisch, Botvinnik variation
+rnbq1rk1/pp3ppp/4pn2/2bP4/8/4PN2/PP3PPP/RNBQKB1R b KQ -
+QGA: classical, Steinitz variation *
+rnbq1rk1/pp3ppp/4pn2/2bp4/2P5/4PN2/PP3PPP/RNBQKB1R w KQ -
+QGA: classical variation, 6.O-O *
+rnbq1rk1/pp3ppp/4pn2/2bp4/2P5/P3PN2/1P3PPP/RNBQKB1R b KQ -
+QGA: classical, 6...a6 *
+rnbq1rk1/pp3ppp/4pn2/2p5/1bBP4/2N1PN2/PP3PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, Gligori\'c system with 7...dc
+rnbq1rk1/pp3ppp/4pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQK2R w KQ -
+Nimzo-Indian: 4.e3, main line with ...c5
+rnbq1rk1/pp3ppp/5n2/2bpp3/2P5/P3PN2/1P3PPP/RNBQKB1R w KQ -
+QGA: classical, Geller variation *
+rnbq1rk1/pp4pp/2p5/2bppp2/3PP1n1/2P4N/PP1NBPPP/R1BQ1RK1 b - -
+Philidor: Hanham, Berger variation *
+rnbq1rk1/ppp1b1pp/3ppn2/5p2/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Dutch: classical variation
+rnbq1rk1/ppp1b1pp/4pn2/3p1p2/2PP4/1P3NP1/P3PPBP/RNBQ1RK1 b - -
+Dutch: stonewall, Botwinnik variation
+rnbq1rk1/ppp1b1pp/4pn2/3p1p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+Dutch: stonewall with Nc3
+rnbq1rk1/ppp1b1pp/4pn2/3p1p2/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Dutch: stonewall variation
+rnbq1rk1/ppp1bpp1/4p2p/3p4/2PPn2B/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QGD: Lasker defense
+rnbq1rk1/ppp1bpp1/4pB1p/3p4/2PP4/2N1PN2/PP3PPP/R2QKB1R b KQ -
+QGD: Neo-orthodox variation, 7.Bxf6
+rnbq1rk1/ppp1bpp1/4pn1p/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QGD: Neo-orthodox variation
+rnbq1rk1/ppp1bpp1/4pn1p/3p4/2PP3B/2N1PN2/PP3PPP/R2QKB1R b KQ -
+QGD: Neo-orthodox variation, 7.Bh4
+rnbq1rk1/ppp1bppp/4pn2/3p2B1/2PP4/2N1P3/PP3PPP/2RQKBNR b K -
+QGD: Anti-neo-orthodox variation
+rnbq1rk1/ppp1bppp/4pn2/3p2B1/2PP4/2N1P3/PP3PPP/R2QKBNR w KQ -
+QGD: 4.Bg5 Be7, 5.e3 O-O
+rnbq1rk1/ppp1bppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R b KQ -
+QGD: 6.Nf3
+rnbq1rk1/ppp1bppp/8/3p4/3Pn3/3B1N2/PPP2PPP/RNBQ1RK1 w - -
+Petrov: classical attack, Mason variation
+rnbq1rk1/ppp1ppbp/1n4p1/8/3P4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O Nb6
+rnbq1rk1/ppp1ppbp/3p1np1/4P3/3P1P2/2N2N2/PPP3PP/R1BQKB1R b KQ -
+Pirc: Austrian attack, 6.e5
+rnbq1rk1/ppp1ppbp/3p1np1/6B1/2PPP3/2N2N2/PP3PPP/R2QKB1R b KQ -
+King's Indian: Zinnowitz variation
+rnbq1rk1/ppp1ppbp/3p1np1/6B1/2PPP3/2N5/PP2BPPP/R2QK1NR b KQ -
+King's Indian: Averbakh system
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N1B3/PP2BPPP/R2QK1NR b KQ -
+King's Indian: Semi-Averbakh system
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N1BN2/PP3PPP/R2QKB1R b KQ -
+King's Indian: Larsen variation
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2N2/PP2BPPP/R1BQK2R b KQ -
+King's Indian: 6.Be2
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2P2/PP4PP/R1BQKBNR w KQ -
+King's Indian: S\"amisch, 5...O-O
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPPP2/2N5/PP2B1PP/R1BQK1NR b KQ -
+King's Indian: Four pawns attack, 6.Be2
+rnbq1rk1/ppp1ppbp/3p1np1/8/3PP3/6P1/PPP1NPBP/RNBQK2R b KQ -
+R\'eti: King's Indian attack, Pachman system *
+rnbq1rk1/ppp1ppbp/3p1np1/8/3PPP2/2N1BN2/PPP3PP/R2QKB1R b KQ -
+Pirc: Austrian attack, 6.Be3
+rnbq1rk1/ppp1ppbp/3p1np1/8/3PPP2/2N2N2/PPP3PP/R1BQKB1R w KQ -
+Pirc: Austrian attack
+rnbq1rk1/ppp1ppbp/3p1np1/8/3PPP2/2NB1N2/PPP3PP/R1BQK2R b KQ -
+Pirc: Austrian attack, 6.Bd3
+rnbq1rk1/ppp1ppbp/5np1/3p4/1PPP4/2N1PN2/P4PPP/R1BQKB1R b KQ -
+Gr\"unfeld: Makogonov variation
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP1B2/2N1P3/PP3PPP/2RQKBNR b K -
+Gr\"unfeld: Gr\"unfeld gambit, Capablanca variation
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP1B2/2N1P3/PP3PPP/R2QKBNR w KQ -
+Gr\"unfeld: Gr\"unfeld gambit
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP1B2/2N1PN2/PP3PPP/R2QKB1R b KQ -
+Gr\"unfeld with Bf4 & e3
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/1QN1PN2/PP3PPP/R1B1KB1R b KQ -
+Gr\"unfeld with e3 & Qb3
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/2N1PN2/PP1B1PPP/R2QKB1R b KQ -
+Gr\"unfeld: Opo\v censky variation
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/2NBPN2/PP3PPP/R1BQK2R b KQ -
+Gr\"unfeld with e3 & Bd3
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+Neo-Gr\"unfeld, 6.O-O
+rnbq1rk1/ppp1ppbp/5np1/3p4/5P2/2P3PN/PP1PP1BP/RNBQK2R b KQ -
+Dutch: Leningrad, Basman system *
+rnbq1rk1/ppp1ppbp/5np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R b KQ -
+Gr\"unfeld: Russian variation with e4
+rnbq1rk1/ppp1ppbp/6p1/3n4/3P4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O
+rnbq1rk1/ppp2pbp/3p1np1/3Pp3/2P1P3/2N1BP2/PP4PP/R2QKBNR b KQ -
+King's Indian: S\"amisch, orthodox, 7.d5
+rnbq1rk1/ppp2pbp/3p1np1/3Pp3/2P1P3/2N2N2/PP2BPPP/R1BQK2R b KQ -
+King's Indian: Petrosian system
+rnbq1rk1/ppp2pbp/3p1np1/4P3/2P1P3/2N2N2/PP2BPPP/R1BQK2R b KQ -
+King's Indian: Andersson variation
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N1BN2/PP2BPPP/R2QK2R b KQ -
+King's Indian: Gligori\'c-Taimanov system
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+King's Indian: S\"amisch, orthodox variation
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+King's Indian: orthodox variation
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+King's Indian: classical variation
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N3P1/PP2NPBP/R1BQK2R b KQ -
+King's Indian: Pomar system
+rnbq1rk1/ppp2pbp/4pnp1/3p4/2PP4/1QN1PN2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Botvinnik variation
+rnbq1rk1/ppp2ppp/1b3n2/3pN3/1P2P3/P1N5/2PP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, 7.Bb3 *
+rnbq1rk1/ppp2ppp/1b3n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R b KQ -
+Ruy Lopez: open, 8...Be6 *
+rnbq1rk1/ppp2ppp/1b3n2/4N3/1P1Pp3/P1N5/2P2PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, 8.de *
+rnbq1rk1/ppp2ppp/1b3n2/4N3/1P1Pp3/P7/2P1NPPP/R1BQKB1R b KQ -
+Ruy Lopez: open, Zukertort variation *
+rnbq1rk1/ppp2ppp/3b1n2/3pN3/3P4/8/PPP1BPPP/RNBQ1RK1 b - -
+Petrov: classical attack, Mason variation *
+rnbq1rk1/ppp2ppp/3bpn2/3p4/2PP4/P1N1P3/1P2NPPP/R1BQKB1R w KQ -
+Nimzo-Indian: Simagin variation
+rnbq1rk1/ppp2ppp/4pn2/3p4/1bPP4/2N1PN2/PP3PPP/R1BQKB1R w KQ -
+Nimzo-Indian: 4.e3 e8g8, 5.Nf3 d7d5
+rnbq1rk1/ppp2ppp/4pn2/3p4/1bPP4/2NBP3/PP3PPP/R1BQK1NR w KQ -
+Nimzo-Indian: 4.e3 O-O, 5.Bd3 d5
+rnbq1rk1/ppp2ppp/4pn2/3p4/2PP4/P1PBP3/5PPP/R1BQK1NR b KQ -
+Nimzo-Indian: 4.e3, Botvinnik system
+rnbq1rk1/ppp2ppp/5P2/2b4Q/2pp4/2P5/PP3PPP/RNB1K1NR w KQ -
+Bishop's opening: Pratt variation
+rnbq1rk1/ppp2ppp/5n2/2b1p3/4p3/2PP4/PP1NBPPP/R1BQK1NR w KQ -
+Philidor: Hanham, Steiner variation *
+rnbq1rk1/ppp2ppp/5n2/2bP2N1/2B1p3/2N5/PPPP1PPP/R1BQK2R b KQ -
+two knights: Max Lange attack, Steinitz variation *
+rnbq1rk1/ppp2ppp/5n2/2bP4/2B1p3/2N2N2/PPPP1PPP/R1BQK2R w KQ -
+two knights: Max Lange attack *
+rnbq1rk1/ppp2ppp/5n2/2bPN3/8/2N5/PPPP1PPP/R1BQKB1R b KQ -
+Two knights defense *
+rnbq1rk1/ppp2ppp/5n2/2bPp3/8/2N2N2/PPPP1PPP/R1BQKB1R w KQ -
+Two knights defense *
+rnbq1rk1/ppp2ppp/5n2/2bpp3/4P3/2PP4/PP1N1PPP/R1BQKBNR w KQ -
+Philidor: Hanham, Krause variation *
+rnbq1rk1/ppp2ppp/5n2/3Pp3/1b6/2N2N2/PPPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: Berlin defense, Nyholm attack *
+rnbq1rk1/ppp2ppp/5n2/3pN3/1b2P3/2N5/PPPPBPPP/R1BQK2R b KQ -
+Ruy Lopez: open Berlin defense, 5...Be7 *
+rnbq1rk1/ppp2ppp/5n2/3pN3/1b2P3/P1N5/1PPP1PPP/R1BQKB1R b KQ -
+Ruy Lopez: Berlin defense, Rosenthal variation *
+rnbq1rk1/ppp2ppp/5n2/3pN3/4P3/P1PP4/2P2PPP/R1BQKB1R b KQ -
+Ruy Lopez: Steinitz defense deferred, Rubinstein variation *
+rnbq1rk1/ppp2ppp/5n2/3pp1B1/4P3/P1PP1N2/2P2PPP/R2QKB1R b KQ -
+Ruy Lopez: Steinitz defense deferred, Lipnitsky variation *
+rnbq1rk1/ppp2ppp/5n2/3pp3/1b2P3/2NP4/PPPN1PPP/R1BQKB1R b KQ -
+Ruy Lopez: closed Berlin defense, Chigorin variation *
+rnbq1rk1/ppp2ppp/5n2/4N3/1b2p3/2N5/PPPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Berlin defense, Minckwitz variation *
+rnbq1rk1/ppp2ppp/5n2/8/1b2p3/2NN4/PPPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open Berlin defense, l'Hermet variation *
+rnbq1rk1/ppp2ppp/5n2/b2PN3/8/P1N5/1PPP1PPP/R1BQKB1R b KQ -
+Ruy Lopez: open, Riga variation *
+rnbq1rk1/ppp2ppp/5n2/b2p4/4P3/2NN4/PPPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open Berlin defense, Showalter variation *
+rnbq1rk1/ppp2ppp/5n2/b2pN3/1P2P3/P1N5/2PP1PPP/R1BQKB1R b KQ -
+Ruy Lopez: open, 6.d4 b5 *
+rnbq1rk1/ppp2ppp/5n2/b2pN3/4P3/P1N5/1PPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, 6.d4 *
+rnbq1rk1/ppp2ppp/5n2/b2pp3/4P3/P1N2N2/1PPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: closed, center attack *
+rnbq1rk1/ppp2ppp/5n2/b3N3/1P1pP3/P1N5/2PP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, Richter variation *
+rnbq1rk1/ppp2ppp/8/2b1p3/8/2P1NN2/PP1P1nPP/R1BQKB1R w KQ -
+Scotch: Cochrane variation *
+rnbq1rk1/ppp2ppp/8/3pb3/2PPn3/3B4/PP3PPP/RNBQ1RK1 w - -
+Petrov: modern attack, Trifunovi\'c variation
+rnbq1rk1/ppp2ppp/8/b2pN3/1P2n3/P1N5/2PP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, Friess attack *
+rnbq1rk1/pppnbppp/4p3/3pP1B1/3P3P/2N5/PPP2PP1/R2QKBNR w KQ -
+French: Albin-Alekhine-Ch\^atard attack, Spielmann variation
+rnbq1rk1/pppp1pp1/5n1p/4p1B1/4P2P/P1P5/1PP2PP1/R2QKBNR b KQ -
+Ruy Lopez: exchange variation, Alapin gambit *
+rnbq1rk1/pppp1ppp/1b3n2/4p3/1P2P3/P1N2N2/1BPP1PPP/R2QKB1R b KQ -
+Ruy Lopez: Archangelsk (counterthrust) variation *
+rnbq1rk1/pppp1ppp/1b3n2/4p3/1P2P3/P1NP1N2/2P2PPP/R1BQKB1R b KQ -
+Ruy Lopez: ...b5 & ...d6 *
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQ -
+Nimzo-Indian: Reshevsky variation
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQ -
+Nimzo-Indian: 4.e3 O-O
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2N1PN2/PP3PPP/R1BQKB1R b KQ -
+Nimzo-Indian: 4.e3 e8g8, 5.Nf3, without ...d5
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2NBP3/PP3PPP/R1BQK1NR b KQ -
+Nimzo-Indian: 4.e3 O-O, 5.Bd3
+rnbq1rk1/pppp1ppp/4pn2/8/2PP4/P1P1P3/5PPP/R1BQKBNR b KQ -
+Nimzo-Indian: S\"amisch variation
+rnbq1rk1/pppp1ppp/4pn2/8/2PP4/P1P5/4PPPP/R1BQKBNR w KQ -
+Nimzo-Indian: S\"amisch variation
+rnbq1rk1/pppp1ppp/5n2/4N3/1b2P3/2N5/PPPP1PPP/R1BQKB1R b KQ -
+Ruy Lopez: Berlin defense, open variation *
+rnbq1rk1/pppp1ppp/5n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: Berlin defense, 4.O-O *
+rnbq1rk1/pppp1ppp/5n2/4p3/1b2P3/2NP1N2/PPP2PPP/R1BQKB1R b KQ -
+Ruy Lopez: Berlin defense, 4.O-O, d6 *
+rnbq1rk1/pppp1ppp/5n2/4p3/1bB1P3/2N2N2/PPPP1PPP/R1BQK2R b KQ -
+Ruy Lopez: Berlin defense, Beverwijk variation *
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1P2P2/1PP3PP/R1BQKBNR b KQ -
+Ruy Lopez: exchange, Gligori\'c variation *
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1P5/1PP2PPP/R1BQKBNR w KQ -
+Ruy Lopez: exchange variation, 5.O-O *
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1PQ4/1PP2PPP/R1B1KBNR b KQ -
+Ruy Lopez: exchange, Bronstein variation *
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1b2N2/1PPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Exchange variation doubly deferred (DERLD) *
+rnbq1rk1/pppp1ppp/5n2/b3N3/4P3/P1N5/1PPP1PPP/R1BQKB1R b KQ -
+Ruy Lopez: open (Tarrasch) defense *
+rnbq1rk1/pppp1ppp/5n2/b3p3/2B1P3/P1N2N2/1PPP1PPP/R1BQK2R b KQ -
+Ruy Lopez: M\"oller defense *
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: 5.O-O *
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPPBPPP/R1BQK2R b KQ -
+Ruy Lopez: closed defense *
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1NP1N2/1PP2PPP/R1BQKB1R b KQ -
+Ruy Lopez: Steinitz defense deferred (Russian defense) *
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQ -
+Ruy Lopez: modern Steinitz defense, 5.O-O *
+rnbq1rk1/pppp1ppp/8/3Pp3/1b6/8/PPPPNPPP/R1BQKB1R b KQ -
+Ruy Lopez: Bird's defense, Paulsen variation *
+rnbq1rk1/pppp2p1/8/2b2PPp/3pn3/3B1N2/PPP2P1P/RNBQK2R w KQ -
+KGA: Kieseritsky, Rice gambit *
+rnbq1rk1/pppp2pp/5n2/2b1pP2/6P1/8/PPPP1PBP/RNBQK1NR w KQ -
+KGA: Hanstein gambit *
+rnbq1rk1/pppp2pp/5n2/2b1pPP1/3P4/8/PPP2P1P/RNBQKBNR b KQ -
+KGA: Muzio gambit, Brentano defense *
+rnbq1rk1/pppp2pp/5n2/2b1pPP1/8/8/PPPP1P1P/RNBQKBNR w KQ -
+KGA: Muzio gambit *
+rnbq1rk1/pppp2pp/5n2/2b1pPP1/8/8/PPPPQP1P/RNB1KBNR b KQ -
+KGA: Muzio gambit, Kling and Horwitz counter-attack *
+rnbq1rk1/ppppb1pp/4p3/5p2/2PPn3/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Dutch defense, Alekhine variation
+rnbq1rk1/ppppb1pp/4pn2/5p2/2PP4/5NP1/PP2PPBP/RNBQK2R w KQ -
+Dutch defense
+rnbq1rk1/ppppppbp/5np1/6B1/3P4/2P2N2/PP2PPPP/RN1QKB1R b KQ -
+R\'eti: King's Indian attack, Yugoslav variation *
+rnbq2k1/pp1p1ppp/1bp5/8/1P1Nr3/P1P5/4BPPP/R1BQ1RK1 b - -
+Ruy Lopez: Marshall counter-attack, 11...c6 *
+rnbq2k1/pp3ppp/1bp5/3p4/1P1Nr3/P1P5/4BPPP/R1BQ1RK1 w - -
+Ruy Lopez: Marshall, main line, 12.d2d4 *
+rnbq2k1/pp3ppp/1bp5/4r3/1P1Pp3/P1N1P3/2PQB1PP/R4RK1 w - -
+Ruy Lopez: open, Tarrasch trap *
+rnbq2k1/pp3ppp/2p1r3/3p4/1P1P4/P2B4/5PPP/R1BQ1RK1 w - -
+Ruy Lopez: Marshall, Kevitz variation *
+rnbq2k1/pppp1ppp/1b6/3N4/1PBpr1n1/P4N2/2P2PPP/R1BQ1K1R b - -
+Ruy Lopez: Rabinovich variation *
+rnbq3r/pp4pp/2P2nk1/8/2Bbp3/2N5/PPPP1PPP/R1BQK2R w KQ -
+Giuoco Piano: Ghulam Kassim variation *
+rnbq3r/pppp1k2/3b1n1p/8/4PQ1P/8/PPPP2P1/RNB1KB1R w KQ -
+KGA: Allgaier, Horny defense
+rnbqk1n1/pppp1p1r/7b/4N2p/2BPPppP/2N5/PPP3P1/R1BQK2R b KQq -
+KGA: Kieseritsky, long whip defense, Jaenisch variation
+rnbqk1nb/pp3p2/2pp4/4N1p1/2BPPp2/2N5/PPP3P1/R1BQK3 b Qkq -
+KGA: Greco gambit
+rnbqk1nr/1p1p1ppp/p3p3/2b5/3NP3/3B4/PPP2PPP/RNBQK2R w KQkq -
+Sicilian: Kan, Polugaievsky variation
+rnbqk1nr/5ppp/2p1p3/pp6/PbpP4/2N1PN2/1P1B1PPP/R2QKB1R w KQkq -
+QGD: semi-Slav, Abrahams variation
+rnbqk1nr/p1p1bppp/1p2p3/3pP3/3P4/2N1B3/PPP2PPP/R2QKBNR w KQkq -
+French: classical, Frankfurt variation
+rnbqk1nr/p1pp1ppp/8/1pb1p3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Wing gambit *
+rnbqk1nr/p1pp2pp/8/1Bb1pp2/4P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: MacDonnell double gambit *
+rnbqk1nr/pp1p1ppp/2p5/2b1p3/2B1P1Q1/8/PPPP1PPP/RNB1K1NR b KQkq -
+Bishop's opening: del Rio variation *
+rnbqk1nr/pp1p1ppp/2p5/2b1p3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Philidor variation *
+rnbqk1nr/pp1p1ppp/2p5/2b1p3/2BPP3/8/PPP2PPP/RNBQK1NR b KQkq -
+Bishop's opening: Lewis counter-gambit *
+rnbqk1nr/pp1pp2p/6p1/2pP1p2/2P5/2P5/P3PPPP/R1BQKBNR w KQkq -
+Beefeater defense
+rnbqk1nr/pp1ppp1p/6pb/2p5/2P1P3/5N2/PP1P1PPP/RNBQKB1R w KQkq -
+Sicilian: Acton extension
+rnbqk1nr/pp1pppbp/8/2p3B1/3P4/8/PPP1PPPP/RN1QKBNR w KQkq -
+Grob: Fritz gambit *
+rnbqk1nr/pp1pppbp/8/2pP2B1/8/8/PPP1PPPP/RN1QKBNR b KQkq -
+Grob: Romford counter-gambit *
+rnbqk1nr/pp2bppp/2p5/3p4/3PpB2/2P1P3/PP3PPP/RN1QKBNR w KQkq -
+Caro-Kann: advance, Short variation *
+rnbqk1nr/pp2ppb1/2p3p1/3pP2p/3P1P2/2N5/PPP3PP/R1BQKBNR w KQkq -
+Robatsch defense: Gurgenidze variation
+rnbqk1nr/pp2ppbp/2pp2p1/8/3PP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Robatsch defense: two knights, Suttles variation
+rnbqk1nr/pp2ppbp/6p1/1Bpp4/5P2/4PN2/PPPP2PP/RNBQK2R b KQkq -
+Dutch defense: Dutch-Indian (Nimzo-Dutch) variation *
+rnbqk1nr/pp2ppbp/6p1/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+Catalan: closed *
+rnbqk1nr/pp2ppbp/6p1/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R b KQkq -
+King's Indian: 3.g3, counterthrust variation *
+rnbqk1nr/pp2ppbp/6p1/2pp4/5P2/4PN2/PPPP2PP/RNBQKB1R w KQkq -
+Dutch defense *
+rnbqk1nr/pp2ppbp/6p1/2pp4/5P2/4PN2/PPPPB1PP/RNBQK2R b KQkq -
+Dutch defense *
+rnbqk1nr/pp2ppbp/6p1/3p4/3N4/6P1/PPP1PPBP/RNBQK2R b KQkq -
+Neo-Gr\"unfeld, 5.cd *
+rnbqk1nr/pp3ppp/4p3/2ppP3/1b1P2Q1/2N5/PPP2PPP/R1B1KBNR b KQkq -
+French: Winawer, advance, Russian variation
+rnbqk1nr/pp3ppp/4p3/2ppP3/1b1P4/2N5/PPP2PPP/R1BQKBNR w KQkq -
+French: Winawer, advance variation
+rnbqk1nr/pp3ppp/4p3/2ppP3/1b1P4/2N5/PPPB1PPP/R2QKBNR b KQkq -
+French: Winawer, advance, Bogolyubov variation
+rnbqk1nr/pp3ppp/4p3/2ppP3/1b1P4/P1N5/1PP2PPP/R1BQKBNR b KQkq -
+French: Winawer, advance, 5.a3
+rnbqk1nr/pp3ppp/4p3/2ppP3/3P4/P1P5/2P2PPP/R1BQKBNR b KQkq -
+French: Winawer, advance variation
+rnbqk1nr/pp3ppp/4p3/3pP3/1P6/2p2N2/1PP2PPP/R1BQKB1R b KQkq -
+French: Winawer, advance, Rauzer variation
+rnbqk1nr/ppp1bppp/3p4/4p3/2B1P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+Philidor: Steinitz variation
+rnbqk1nr/ppp1bppp/4p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: Charousek (Petrosian) variation
+rnbqk1nr/ppp1bppp/4p3/3pP1B1/3P4/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: classical, Vistaneckis (Nimzovich) variation
+rnbqk1nr/ppp1p1bp/3p2p1/5p2/2PPP3/2N5/PP3PPP/R1BQKBNR w KQkq -
+Modern defense: Averbakh system, Randspringer variation
+rnbqk1nr/ppp1ppbp/3p2p1/8/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Modern defense
+rnbqk1nr/ppp1ppbp/3p2p1/8/2PPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+Modern defense: Averbakh system
+rnbqk1nr/ppp1ppbp/3p2p1/8/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+Robatsch defense: two knights variation
+rnbqk1nr/ppp1ppbp/3p2p1/8/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Robatsch (modern) defense
+rnbqk1nr/ppp1ppbp/3p2p1/8/3PP3/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+Robatsch defense: Geller's system
+rnbqk1nr/ppp1ppbp/3p2p1/8/3PPP2/2N5/PPP3PP/R1BQKBNR b KQkq -
+Robatsch defense: Pseudo-Austrian attack
+rnbqk1nr/ppp1ppbp/6p1/3p4/5P2/5NP1/PPPPP2P/RNBQKB1R b KQkq -
+Dutch defense *
+rnbqk1nr/ppp2p1p/3b4/6p1/8/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Bird: From gambit, Lasker variation
+rnbqk1nr/ppp2pb1/3p3p/6p1/2BPPp1P/3Q1N2/PPP3P1/RNB1K2R b KQkq -
+KGA: Philidor gambit, Schultz variation
+rnbqk1nr/ppp2ppp/1b1p4/8/2P1p3/1N6/PP1PPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Kmoch variation *
+rnbqk1nr/ppp2ppp/3b4/3Pp3/8/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+QP counter-gambit: Maroczy gambit
+rnbqk1nr/ppp2ppp/3b4/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: Schlechter variation *
+rnbqk1nr/ppp2ppp/3bp3/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's pawn: stonewall attack *
+rnbqk1nr/ppp2ppp/3p4/2b1P3/4P3/5N2/PPPP2PP/RNBQKB1R b KQkq -
+KGD: classical, Soldatenkov variation
+rnbqk1nr/ppp2ppp/3p4/2b1p3/1P2PP2/5N2/P1PP2PP/RNBQKB1R b KQkq -
+KGD: classical, Heath variation
+rnbqk1nr/ppp2ppp/3p4/2b1p3/4PP2/2P2N2/PP1P2PP/RNBQKB1R b KQkq -
+KGD: classical, 4.c3
+rnbqk1nr/ppp2ppp/3p4/2b1p3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+Bishop's opening: Calabrese counter-gambit, Jaenisch variation *
+rnbqk1nr/ppp2ppp/4p3/3p4/1b1PP3/2N5/PPP1NPPP/R1BQKB1R b KQkq -
+French: Winawer, Alekhine (Mar\'oczy) gambit
+rnbqk1nr/ppp2ppp/4p3/3p4/1b1PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+French: Winawer (Nimzovich) variation
+rnbqk1nr/ppp2ppp/4p3/3p4/1b1PP3/2N5/PPPB1PPP/R2QKBNR b KQkq -
+French: Winawer, fingerslip variation
+rnbqk1nr/ppp2ppp/4p3/3pP3/1b1P4/2N5/PPP2PPP/R1BQKBNR b KQkq -
+French: Winawer, advance variation
+rnbqk1nr/ppp2ppp/4p3/8/3Pp3/P1b5/1PP1NPPP/R1BQKB1R w KQkq -
+French: Winawer, Alekhine gambit
+rnbqk1nr/ppp2ppp/8/2bp4/3Np3/3P4/PPP1PPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Balogh variation *
+rnbqk1nr/ppp2ppp/8/2bpp3/2B1P3/2P5/PP1P1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Lewis counter-gambit
+rnbqk1nr/ppp2ppp/8/2bpp3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Lewis gambit *
+rnbqk1nr/ppp2ppp/8/2bpp3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Bishop's opening: Ponziani gambit *
+rnbqk1nr/ppp2ppp/8/4P3/1bP5/4p3/PP1B1PPP/RN1QKBNR w KQkq -
+QGD: Albin counter-gambit, Lasker trap
+rnbqk1nr/ppp3pp/3p4/2b1pp2/4PP2/2P2N2/PP1P2PP/RNBQKB1R w KQkq -
+KGD: classical counter-gambit
+rnbqk1nr/ppp3pp/4P3/2bp2N1/4p3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Philidor: Philidor counter-gambit, Berger variation
+rnbqk1nr/ppp3pp/8/2b2p2/2BpP3/2P2N2/PP4PP/RNBQK2R b KQkq -
+KGD: classical, R\'eti variation
+rnbqk1nr/pppp1pbp/8/4N3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Paulsen defense
+rnbqk1nr/pppp1pbp/8/6p1/2B1Pp1P/5N2/PPPP2P1/RNBQK2R b KQkq -
+KGA: Philidor gambit
+rnbqk1nr/pppp1pbp/8/6p1/2B1Pp2/5N2/PPPP2PP/RNBQ1RK1 b kq -
+KGA: Hanstein gambit
+rnbqk1nr/pppp1pbp/8/6p1/2B1Pp2/5N2/PPPP2PP/RNBQK2R w KQkq -
+King's knight's gambit
+rnbqk1nr/pppp1ppp/4p3/8/1bPP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Queen's pawn: Franco-Indian (Keres) defense
+rnbqk1nr/pppp1ppp/8/2b1p3/1PB1P3/8/P1PP1PPP/RNBQK1NR b KQkq -
+Bishop's opening: Wing gambit
+rnbqk1nr/pppp1ppp/8/2b1p3/2B1P3/2P5/PP1P1PPP/RNBQK1NR b KQkq -
+Bishop's opening: Philidor variation
+rnbqk1nr/pppp1ppp/8/2b1p3/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+Bishop's opening: Classical variation *
+rnbqk1nr/pppp1ppp/8/2b1p3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Classical variation
+rnbqk1nr/pppp1ppp/8/2b1p3/2BPP3/8/PPP2PPP/RNBQK1NR b KQkq -
+Bishop's opening: Lewis gambit
+rnbqk1nr/pppp1ppp/8/2b1p3/4P3/2P5/PP1P1PPP/RNBQKBNR b KQkq -
+Bishop's opening: Philidor counter-attack *
+rnbqk1nr/pppp1ppp/8/2b1p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+Bishop's opening: Berlin defense *
+rnbqk1nr/pppp1ppp/8/2b1p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Bishop's opening *
+rnbqk1nr/pppp1ppp/8/2b1p3/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+Bishop's opening: Calabrese counter-gambit *
+rnbqk1nr/pppp1ppp/8/2b1p3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: classical variation
+rnbqk1nr/pppp1ppp/8/2b1p3/8/2P5/PP1PPPPP/RNBQKBNR w KQkq -
+Caro-Kann: Hillbilly attack *
+rnbqk1nr/pppp1ppp/8/2b1p3/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Krejcik variation *
+rnbqk1nr/pppp1ppp/8/4p3/1bB1PP2/8/P1PP2PP/RNBQK1NR b KQkq -
+Bishop's opening: MacDonnell double gambit
+rnbqk1nr/pppp1ppp/8/4p3/1bP5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English, Kramnik-Shirov counterattack
+rnbqk1nr/pppp1ppp/8/8/2B1P2b/5N2/PPPP3p/RNBQ1R1K b kq -
+KGA: Cunningham, three pawns gambit
+rnbqk1nr/pppp1ppp/8/8/2B1Pp1b/5NP1/PPPP3P/RNBQK2R b KQkq -
+KGA: Cunningham, Bertin gambit
+rnbqk1nr/pppp1ppp/8/8/2BPP2b/5N2/P1P4p/RNBQ1R1K b kq -
+Bishop's opening: Four pawns' gambit
+rnbqk1nr/pppp2pp/3b4/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Schurig gambit *
+rnbqk1nr/pppp2pp/8/2b1pP2/1P6/8/P1PP1PPP/RNBQKBNR b KQkq -
+KGA: bishop's gambit, Bryan counter-gambit *
+rnbqk1nr/pppp2pp/8/2b1pP2/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+KGA: bishop's gambit, Bledow variation *
+rnbqk1nr/pppp2pp/8/2b1pP2/5P2/8/PPPP2PP/RNBQKBNR b KQkq -
+KGA: bishop's gambit, L\'opez-Gianutio counter-gambit *
+rnbqk1nr/pppp2pp/8/2b1pP2/8/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+KGA: bishop's gambit, Maurian defense *
+rnbqk1nr/pppp2pp/8/2b1pP2/8/2P5/PP1P1PPP/RNBQKBNR b KQkq -
+KGA: bishop's gambit, Ruy L\'opez defense *
+rnbqk1nr/pppp2pp/8/2b1pP2/8/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+KGA: bishop's gambit, Cozio (Morphy) defense *
+rnbqk1nr/pppp2pp/8/2b1pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: bishop's gambit *
+rnbqk1nr/pppp2pp/8/2b1pP2/8/8/PPPPNPPP/RNBQKB1R b KQkq -
+KGA: bishop's gambit, Steinitz defense *
+rnbqk1nr/pppp2pp/8/2b1pp2/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Bishop's opening: Greco gambit *
+rnbqk1nr/pppp2pp/8/4Pp2/1b1p4/8/PPP2PPP/RNBQKBNR w KQkq -
+KGD: Falkbeer, Nimzovich variation *
+rnbqk1nr/pppp2pp/8/4pP2/3b4/2P5/PP3PPP/RNBQKBNR b KQkq -
+KGA: bishop's gambit, Anderssen variation *
+rnbqk1nr/pppp2pp/8/4pP2/3b4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+KGA: bishop's gambit, Morphy variation *
+rnbqk1nr/ppppb1pp/8/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Lesser bishop's (Petroff-Jaenisch-Tartakower) gambit *
+rnbqk1nr/ppppbp1p/8/4N3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Polerio defense
+rnbqk1nr/ppppbppp/8/8/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Cunningham defense
+rnbqk1nr/ppppp1bp/6p1/5p2/3P4/6PN/PPP1PPBP/RNBQK2R b KQkq -
+Dutch: Leningrad, Karlsbad variation
+rnbqk1nr/ppppppbp/6p1/8/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+Robatsch defense
+rnbqk1nr/ppppppbp/6p1/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Robatsch (modern) defense
+rnbqk1nr/ppppppbp/6p1/8/3PPP2/8/PPP3PP/RNBQKBNR b KQkq -
+Robatsch defense: three pawns attack
+rnbqk1nr/ppppppbp/8/8/3P2p1/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Grob: spike attack *
+rnbqk1r1/ppp2pP1/4p3/3p4/1b1P2Qp/2N5/PPP2PP1/R3KBNR b KQq -
+French: MacCutcheon, Grigoriev variation
+rnbqk2r/1p2bp2/p2ppn1p/6p1/3NPP1B/2N2Q2/PPP3PP/R3KB1R w KQkq -
+Sicilian: Najdorf, G\"oteborg (Argentine) variation
+rnbqk2r/1p2bppp/p2ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+Sicilian: Najdorf, 7...Be7
+rnbqk2r/1pp2ppp/1b3n2/p2p4/4p3/1N1P2P1/PPP1PPBP/RNBQK2R w KQkq -
+Alekhine's defense: modern, Keres variation *
+rnbqk2r/1ppnbppp/p3p3/3pP1B1/3P3P/2N5/PPP2PP1/R2QKBNR w KQkq -
+French: Albin-Alekhine-Ch\^atard attack, Mar\'oczy variation
+rnbqk2r/2pp1ppp/5n2/ppb1p3/4P3/1BN5/PPPP1PPP/R1BQK1NR w KQkq -
+Evans gambit declined, 5.a4 *
+rnbqk2r/p1p2ppp/1p1bpn2/3p4/2PP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+Queen's pawn game, Rubinstein (Colle-Zukertort) variation *
+rnbqk2r/p1pp1ppp/1p2pn2/8/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQkq -
+Nimzo-Indian: Fischer variation, 5.Ne2
+rnbqk2r/p1pp1ppp/1p2pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+Nimzo-Indian: Fischer variation
+rnbqk2r/p1pp1ppp/5n2/1Bb1p3/4P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Evans gambit *
+rnbqk2r/p1pp1ppp/5n2/1pb1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Evans gambit declined *
+rnbqk2r/p1pp1ppp/5n2/1pb1p3/2BPP3/2N5/PPP2PPP/R1BQK1NR b KQkq -
+Evans counter-gambit *
+rnbqk2r/p1pp1ppp/8/2b1p3/Np2n1Q1/1B6/PPPP1PPP/R1B1K1NR b KQkq -
+Evans gambit declined, Hirschbach variation *
+rnbqk2r/p1pp1ppp/8/2b1p3/Np2n3/1B5N/PPPP1PPP/R1BQK2R b KQkq -
+Evans gambit declined, Lange variation *
+rnbqk2r/p2p1pp1/4pn1p/1ppP4/1bP4B/2N5/PP2PPPP/R2QKBNR w KQkq -
+Nimzo-Indian: Leningrad, ...b5 gambit
+rnbqk2r/p2p1ppp/1p2pn2/2p5/2PP4/P1P1P3/5PPP/R1BQKBNR w KQkq -
+Nimzo-Indian: S\"amisch, O'Kelly variation
+rnbqk2r/p2p1ppp/2p2n2/1pb1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Giuoco Piano: Bird's attack *
+rnbqk2r/p2p1ppp/2p2n2/2b1p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Evans gambit: Mayet defense *
+rnbqk2r/p2p1ppp/2p2n2/2b1p3/4P3/2N5/PPPPBPPP/R1BQK1NR b KQkq -
+Evans gambit: 5...Be7 *
+rnbqk2r/p2p1ppp/2p2n2/2b1p3/4P3/2NB4/PPPP1PPP/R1BQK1NR b KQkq -
+Evans gambit: Stone-Ware variation *
+rnbqk2r/p2p1ppp/2p2n2/2b1p3/B3P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Evans gambit *
+rnbqk2r/p4ppp/2p2n2/1Bb1p3/8/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Scotch gambit *
+rnbqk2r/p4ppp/2p2n2/2b5/B3p3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Scotch gambit: Cochrane variation *
+rnbqk2r/p4ppp/2p2n2/2bpp3/B3P3/2NP4/PPP2PPP/R1BQK1NR b KQkq -
+Evans gambit *
+rnbqk2r/p4ppp/2p2n2/2bpp3/BP2P3/2N5/P1PP1PPP/R1BQK1NR b KQkq -
+Evans gambit: Leonhardt variation *
+rnbqk2r/p4ppp/2p2n2/2bpp3/N3P3/8/PPPPBPPP/R1BQK1NR b KQkq -
+Evans gambit: Cordel variation *
+rnbqk2r/pp1n1ppp/4p3/2bpP3/5PQ1/2N5/PPP3PP/R1B1KBNR b KQkq -
+French: Steinitz, Bradford attack
+rnbqk2r/pp1nbppp/4p3/2ppP1B1/3P3P/2N5/PPP2PP1/R2QKBNR w KQkq -
+French: Albin-Alekhine-Ch\^atard attack, Breyer variation
+rnbqk2r/pp1p1ppp/2p2n2/2b1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Giuoco Piano *
+rnbqk2r/pp1p1ppp/2p2n2/2b1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Giuoco Piano *
+rnbqk2r/pp1p1ppp/2p2n2/2b1p3/2B1P3/2N5/PPPPQPPP/R1B1K1NR b KQkq -
+Giuoco Piano: close variation *
+rnbqk2r/pp1p1ppp/2p2n2/2b1p3/4P3/3P4/PPP1BPPP/RNBQK1NR w KQkq -
+Philidor: Steinitz variation *
+rnbqk2r/pp1p1ppp/2p2n2/4p3/1b2P3/1BN5/PPPP1PPP/R1BQK1NR b KQkq -
+Ruy Lopez: classical defense, Charousek variation *
+rnbqk2r/pp1p1ppp/2p2n2/4p3/1bB1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Ruy Lopez: classical defense, 4.c3 *
+rnbqk2r/pp1p1ppp/2p2n2/4p3/1bB1P3/2N5/PPPPQPPP/R1B1K1NR b KQkq -
+Ruy Lopez: classical defense, Boden variation *
+rnbqk2r/pp1p1ppp/2p2n2/4p3/1bB1PP2/2N5/PPPP2PP/R1BQK1NR b KQkq -
+Ruy Lopez: Cordel gambit *
+rnbqk2r/pp1p1ppp/2p2n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQkq -
+Ruy Lopez: modern Steinitz defense *
+rnbqk2r/pp1p1ppp/2p2n2/b3p3/4P3/P1NP4/1PPB1PPP/R2QKBNR b KQkq -
+Ruy Lopez: modern Steinitz defense *
+rnbqk2r/pp1p1ppp/2p2n2/b3p3/4PP2/P1NP4/1PP3PP/R1BQKBNR b KQkq -
+Ruy Lopez: modern Steinitz defense, siesta variation *
+rnbqk2r/pp1p1ppp/4p3/2pP4/1bP1n3/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+Nimzo-Indian: three knights, Euwe variation
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQkq -
+Nimzo-Indian: 4.e3 c5, 5.Ne2 (Rubinstein, anti-H\"ubner system)
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+Nimzo-Indian: 4.e3 c5
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, 4...c5
+rnbqk2r/pp1p1ppp/4pn2/2p5/2PP4/P1P1P3/5PPP/R1BQKBNR b KQkq -
+Nimzo-Indian: S\"amisch variation
+rnbqk2r/pp1p1ppp/4pn2/2pP4/1bP5/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+Nimzo-Indian: three knights, Korchnoi variation
+rnbqk2r/pp1p1ppp/4pn2/4P3/1b1N4/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Sicilian: Pin, Koch variation
+rnbqk2r/pp1p1ppp/4pn2/8/1b1NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Pin variation (Sicilian counter-attack)
+rnbqk2r/pp1p1ppp/5n2/2p1p3/2P5/3P4/PP1QPPPP/RN2KBNR w KQkq -
+Sicilian: Canal-Sokolsky attack, Sokolsky variation *
+rnbqk2r/pp1p1ppp/5n2/4p3/1b1NP3/2NB4/PPP2PPP/R1BQK2R w KQkq -
+Sicilian: Pin, Jaffe variation
+rnbqk2r/pp1p1ppp/5n2/b1p1p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQkq -
+Ruy Lopez: modern Steinitz defense, Duras (Keres) variation *
+rnbqk2r/pp1pp1bp/2p3pn/5p2/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Dutch: Leningrad, Basman system
+rnbqk2r/pp1pppbp/5np1/2P5/8/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+English: Neo-Catalan accepted *
+rnbqk2r/pp1pppbp/5np1/2p5/1P6/P3PN2/2PP1PPP/RNBQKB1R b KQkq -
+English: Romanishin gambit *
+rnbqk2r/pp2npbp/6p1/3pp3/8/1N4P1/PPP1PPBP/RNBQK2R w KQkq -
+Neo-Gr\"unfeld, 5.cd, main line *
+rnbqk2r/pp2nppp/4p3/2ppP3/3P2Q1/P1P5/2P2PPP/R1B1KBNR b KQkq -
+French: Winawer, advance, poisoned pawn variation
+rnbqk2r/pp2nppp/4p3/2ppP3/3P4/P1P2N2/2P2PPP/R1BQKB1R b KQkq -
+French: Winawer, advance, positional main line
+rnbqk2r/pp2nppp/4p3/2ppP3/3P4/P1P5/2P2PPP/R1BQKBNR w KQkq -
+French: Winawer, advance, 6...Ne7
+rnbqk2r/pp2nppp/4p3/2ppP3/P2P4/2P5/2P2PPP/R1BQKBNR b KQkq -
+French: Winawer, advance, Smyslov variation
+rnbqk2r/pp2ppbp/3p1np1/2p5/3PPP2/2N2N2/PPP3PP/R1BQKB1R w KQkq -
+Pirc: Austrian attack, dragon formation
+rnbqk2r/pp2ppbp/3p1np1/8/3NP3/2N1B3/PPP1BPPP/R2QK2R b KQkq -
+Sicilian: dragon, classical attack
+rnbqk2r/pp2ppbp/3p1np1/8/3NP3/2N1BP2/PPP3PP/R2QKB1R b KQkq -
+Sicilian: dragon, Yugoslav attack
+rnbqk2r/pp2ppbp/5np1/1Bpp4/8/1P2PN2/PBPP1PPP/RN1QK2R b KQkq -
+Queen's Indian: Capablanca variation *
+rnbqk2r/pp2ppbp/5np1/2Pp4/8/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+Catalan: open, classical line *
+rnbqk2r/pp2ppbp/5np1/2Pp4/8/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+Catalan: open, 5.Nf3 *
+rnbqk2r/pp2ppbp/5np1/2pp4/3P4/4PN2/PPP1BPPP/RNBQK2R w KQkq -
+Catalan: closed, 5.Nf3 *
+rnbqk2r/pp2ppbp/5np1/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Neo-Gr\"unfeld, 5.Nf3 *
+rnbqk2r/pp2ppbp/5np1/2pp4/5P2/4PN2/PPPPB1PP/RNBQ1RK1 b kq -
+Dutch defense *
+rnbqk2r/pp2ppbp/5np1/2pp4/5P2/5NP1/PPPPP1BP/RNBQK2R w KQkq -
+Dutch: Leningrad, main variation *
+rnbqk2r/pp2ppbp/5np1/2pp4/8/1P2PN2/PBPPBPPP/RN1QK2R b KQkq -
+Queen's Indian: 5.Bg2 Be7 *
+rnbqk2r/pp2ppbp/6p1/2p4n/2PP4/1P3N2/PB1P1PPP/RN1QKB1R w KQkq -
+Queen's Indian: Rubinstein variation *
+rnbqk2r/pp2ppbp/6p1/2p5/2PP2n1/1P3N2/PB1P1PPP/RN1QKB1R w KQkq -
+Queen's Indian: B\"urger variation *
+rnbqk2r/pp3pbp/3p1np1/1BpP4/4PP2/2N5/PP4PP/R1BQK1NR b KQkq -
+Benoni: Taimanov variation
+rnbqk2r/pp3pbp/3p1np1/2pP2B1/4P3/2N2N2/PP3PPP/R2QKB1R b KQkq -
+Benoni: classical, 8.Bg5
+rnbqk2r/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQK2R b KQkq -
+Benoni: classical without 9.O-O
+rnbqk2r/pp3pbp/3p1np1/2pPP3/5P2/2N5/PP4PP/R1BQKBNR b KQkq -
+Benoni: Mikenas variation
+rnbqk2r/pp3pp1/3ppn1p/2pP4/1bP4B/2N5/PP2PPPP/R2QKBNR w KQkq -
+Nimzo-Indian: Leningrad, main line
+rnbqk2r/pp3ppp/2p2n2/1BbP4/3p4/5N2/PPP1QPPP/RNB1K2R b KQkq -
+Bishop's opening: Urusov gambit, Panov variation *
+rnbqk2r/pp3ppp/2p2n2/2b1p3/4P3/1B1p4/PPPPQPPP/RNB1K1NR w KQkq -
+Giuoco Piano: Eisinger variation *
+rnbqk2r/pp3ppp/2p2n2/2bP4/2BPp3/2N2N2/PPP2PPP/R1BQK2R b KQkq d3
+Giuoco Piano *
+rnbqk2r/pp3ppp/2p2n2/2bPN3/4p3/2N5/PPPPBPPP/R1BQK2R b KQkq -
+Hungarian defense: Tartakower variation *
+rnbqk2r/pp3ppp/2p2n2/2bpp3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Giuoco Piano *
+rnbqk2r/pp3ppp/2p2n2/2bpp3/4P3/1BN5/PPPPQPPP/R1B1K1NR b KQkq -
+Giuoco Piano: center-holding variation *
+rnbqk2r/pp3ppp/2p2n2/2bpp3/4P3/2PP4/PP1N1PPP/R1BQKBNR w KQkq -
+Philidor: Hanham, Delmar variation *
+rnbqk2r/pp3ppp/2p2n2/b2pp3/4P3/P1NP2P1/1PPB1P1P/R2QKBNR b KQkq -
+Ruy Lopez: modern Steinitz defense, fianchetto (Bronstein) variation *
+rnbqk2r/pp3ppp/2p2n2/b2pp3/4P3/P1NP4/1PPBNPPP/R2QKB1R b KQkq -
+Ruy Lopez: modern Steinitz defense, Rubinstein variation *
+rnbqk2r/pp3ppp/2pb1n2/3p4/2PPp3/1QN1P3/PP3PPP/R1B1KBNR w KQkq -
+French: advance, Milner-Barry gambit *
+rnbqk2r/pp3ppp/2pb4/4n3/3pP3/3P1N2/PPP1B1PP/RNBQK2R b KQkq -
+Ponziani counter-gambit, Cordel variation *
+rnbqk2r/pp3ppp/2pbpn2/3p4/2PP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+Colle system *
+rnbqk2r/pp3ppp/3p1n2/2p1p3/1b2P3/2NP1N2/PPP2PPP/R1BQKB1R w KQkq -
+Ruy Lopez: Berlin defense, Duras variation *
+rnbqk2r/pp3ppp/3p1n2/b1p1p3/4P3/P1NP1N2/1PP2PPP/R1BQKB1R w KQkq -
+Ruy Lopez: Morphy defense, Duras variation *
+rnbqk2r/pp3ppp/4p3/2Pn4/8/P1P2P2/4P1PP/R1BQKBNR b KQkq -
+Nimzo-Indian: S\"amisch, Keres variation
+rnbqk2r/pp3ppp/4pn2/2b3B1/3p4/P3P3/1PP2PPP/RN1QKBNR w KQkq -
+QGA: Alekhine defense, Alatortsev variation *
+rnbqk2r/pp3ppp/4pn2/2bp4/2P5/4PN2/PP3PPP/RNBQKB1R b KQkq -
+QGA: classical variation *
+rnbqk2r/pp3ppp/4pn2/2pP4/3P4/P1P2P2/4P1PP/R1BQKBNR b KQkq -
+Nimzo-Indian: S\"amisch variation
+rnbqk2r/pp3ppp/5n2/1B1pN3/1b1Pp3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Giuoco Piano: Anderssen variation *
+rnbqk2r/pp3ppp/5n2/2bpp3/2B5/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Giuoco Piano *
+rnbqk2r/pp3ppp/5n2/2bpp3/8/1BNP4/PPP2PPP/R1BQK1NR b KQkq -
+Giuoco Piano: LaBourdonnais variation *
+rnbqk2r/pp3ppp/5n2/2ppp3/1b2P3/2NP4/PPPB1PPP/R2QKBNR w KQkq -
+Ruy Lopez: old Steinitz defense, semi-Duras variation *
+rnbqk2r/pp4pp/2p2n2/2bPp3/2B2P2/8/PPP3PP/RNBQK1NR w KQkq -
+KGD: classical, R\'eti variation *
+rnbqk2r/pp4pp/4p3/2Pn1p2/8/P1P2P2/4P1PP/R1BQKBNR w KQkq -
+Nimzo-Indian: S\"amisch, Romanovsky variation
+rnbqk2r/ppn1bppp/8/2p1p3/8/2NP2PN/PP2PPBP/R1BQK2R b KQkq -
+Sicilian: accelerated fianchetto, Simagin variation *
+rnbqk2r/ppp1b1pp/3p1n2/3Pp3/4N3/2PB4/PP3PPP/RNBQK2R w KQkq -
+Ponziani counter-gambit, Cordel variation
+rnbqk2r/ppp1bppp/4p3/3p2B1/2PPn3/2N1P3/PP3PPP/R2QKBNR w KQkq -
+QGD: Lasker variation
+rnbqk2r/ppp1bppp/4p3/3pP1B1/3Pn3/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: classical, Tartakower variation
+rnbqk2r/ppp1bppp/4p3/3pP3/3P2Q1/2N5/PPP2PPP/R3KBNR b KQkq -
+French: classical, Anderssen-Richter variation
+rnbqk2r/ppp1bppp/4pB2/3p4/3PP3/2N5/PPP2PPP/R2QKBNR b KQkq -
+French: classical, Anderssen variation
+rnbqk2r/ppp1bppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR w KQkq -
+QGD: 4.Bg5 Be7
+rnbqk2r/ppp1bppp/4pn2/3p2B1/3PP3/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: classical
+rnbqk2r/ppp1bppp/4pn2/3p4/2P5/5NP1/PP1PPPBP/RNBQ1RK1 b kq -
+English: Neo-Catalan declined
+rnbqk2r/ppp1bppp/4pn2/3p4/2PP1B2/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+QGD: classical variation (5.Bf4)
+rnbqk2r/ppp1bppp/4pn2/3p4/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+Catalan: closed, 5.Nf3
+rnbqk2r/ppp1bppp/4pn2/8/2pP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+Catalan: open, classical line
+rnbqk2r/ppp1bppp/5n2/3p2B1/3Np3/2PP4/PP2PPPP/RN1QKB1R b KQkq -
+Alekhine's defense: modern, Flohr variation *
+rnbqk2r/ppp1bppp/5n2/3pp3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Tayler opening *
+rnbqk2r/ppp1bppp/8/3pP3/4n3/2N2N2/PPPP2PP/R1BQKB1R w KQkq -
+Vienna gambit: Breyer variation
+rnbqk2r/ppp1npbp/6p1/3pp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+R\'eti: King's Indian attack, Pachman system
+rnbqk2r/ppp1nppp/8/8/3PN3/8/PP3PPP/R2QKBNR w KQkq -
+Bishop's opening: Lisitsyn variation *
+rnbqk2r/ppp1ppbp/1n1p2p1/4P3/P2P4/1B3N2/1PP2PPP/RNBQK2R b KQkq -
+Alekhine's defense: modern, Keres variation
+rnbqk2r/ppp1ppbp/1n4p1/8/3PP3/6P1/PP2NPBP/RNBQK2R b KQkq -
+Neo-Gr\"unfeld, 5.cd, main line
+rnbqk2r/ppp1ppbp/3p1np1/6B1/2PP4/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+King's Indian: Smyslov system
+rnbqk2r/ppp1ppbp/3p1np1/6B1/2PPP3/2N5/PP3PPP/R2QKBNR b KQkq -
+King's Indian: accelerated Averbakh system
+rnbqk2r/ppp1ppbp/3p1np1/8/2BPPP2/2N5/PPP3PP/R1BQK1NR b KQkq -
+Pirc: Austrian attack, Ljubojevi\'c variation
+rnbqk2r/ppp1ppbp/3p1np1/8/2PP4/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+King's Indian: fianchetto variation
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+King's Indian: 5.Nf3
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N2P2/PP4PP/R1BQKBNR b KQkq -
+King's Indian: S\"amisch variation
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N3P1/PP3P1P/R1BQKBNR b KQkq -
+King's Indian with e4 & g3
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N4P/PP3PP1/R1BQKBNR b KQkq -
+King's Indian: Makagonov system (5.h3)
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N5/PP2BPPP/R1BQK1NR b KQkq -
+King's Indian: 5.Be2
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N5/PP2NPPP/R1BQKB1R b KQkq -
+King's Indian: Kramer system
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPPP2/2N5/PP4PP/R1BQKBNR b KQkq -
+King's Indian: Four pawns attack
+rnbqk2r/ppp1ppbp/3p1np1/8/3PP1P1/2N5/PPP1BP1P/R1BQK1NR b KQkq -
+Pirc: Chinese variation
+rnbqk2r/ppp1ppbp/3p1np1/8/3PP2P/2N5/PPP1BPP1/R1BQK1NR b KQkq -
+Pirc: bayonet (Mariotti) attack
+rnbqk2r/ppp1ppbp/3p1np1/8/3PP3/2N2N1P/PPP2PP1/R1BQKB1R b KQkq -
+Pirc: classical, h3 system
+rnbqk2r/ppp1ppbp/3p1np1/8/3PP3/2N2N2/PPP1BPPP/R1BQK2R b KQkq -
+Pirc: classical system, 5.Be2
+rnbqk2r/ppp1ppbp/3p1np1/8/3PP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Pirc: classical (two knights) system
+rnbqk2r/ppp1ppbp/5np1/3p2B1/2PP4/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+Gr\"unfeld: 5.Bg5
+rnbqk2r/ppp1ppbp/5np1/3p4/2P5/1P3N2/PB1PPPPP/RN1QKB1R b KQkq -
+Queen's Indian: Marienbad system *
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP1B2/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+Gr\"unfeld: 5.Bf4
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/1QN2N2/PP2PPPP/R1B1KB1R b KQkq -
+Gr\"unfeld: Russian variation
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+Gr\"unfeld: 5.e3
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+Gr\"unfeld: Three knights variation
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+Neo-Gr\"unfeld, 5.Nf3
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+King's Indian: 3.g3, counterthrust variation
+rnbqk2r/ppp1ppbp/5np1/3p4/Q1PP4/2N2N2/PP2PPPP/R1B1KB1R b KQkq -
+Gr\"unfeld: Flohr variation
+rnbqk2r/ppp1ppbp/6p1/3n4/3P4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+Neo-Gr\"unfeld, 5.cd
+rnbqk2r/ppp1ppbp/6p1/8/2BPP3/2P5/P4PPP/R1BQK1NR b KQkq -
+Gr\"unfeld: exchange, classical variation
+rnbqk2r/ppp1ppbp/6p1/8/3PP3/2P2N2/P4PPP/R1BQKB1R b KQkq -
+Gr\"unfeld: modern exchange variation
+rnbqk2r/ppp1ppbp/6pn/3p4/5P2/4PN2/PPPP2PP/RNBQKB1R w KQkq -
+Dutch defense, Blackburne variation *
+rnbqk2r/ppp1ppbp/6pn/3p4/5P2/6P1/PPPPP1BP/RNBQK1NR w KQkq -
+Dutch: Leningrad, Karlsbad variation *
+rnbqk2r/ppp2p1p/3b1n2/3PN3/2B2ppP/8/PPPP2P1/RNBQ1RK1 b kq -
+KGA: Kieseritsky, Rice gambit
+rnbqk2r/ppp2p2/4p1pp/3pP3/3Pn1Q1/2P5/P1PB1PPP/R3KBNR w KQkq -
+French: MacCutcheon, Lasker variation, 8...g6
+rnbqk2r/ppp2pbp/6p1/3np3/8/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+English: Anglo-Gr\"unfeld defense, Korchnoi variation
+rnbqk2r/ppp2pp1/4pP1p/3p2B1/1b1P4/2N5/PPP2PPP/R2QKBNR b KQkq -
+French: MacCutcheon, Chigorin variation
+rnbqk2r/ppp2pp1/4pn1p/3pP3/1b1P3B/2N5/PPP2PPP/R2QKBNR b KQkq -
+French: MacCutcheon, Bernstein variation
+rnbqk2r/ppp2pp1/4pn1p/3pP3/1b1P4/2N1B3/PPP2PPP/R2QKBNR b KQkq -
+French: MacCutcheon, Janowski variation
+rnbqk2r/ppp2pp1/4pn1p/3pP3/1b1P4/2N5/PPP2PPP/R1BQKBNR b KQkq -
+French: MacCutcheon, Dr. Olland (Dutch) variation
+rnbqk2r/ppp2pp1/4pn1p/3pP3/3P4/2b5/PPPB1PPP/R2QKBNR w KQkq -
+French: MacCutcheon, Lasker variation
+rnbqk2r/ppp2ppp/3b1n2/3pN3/3P4/3B4/PPP2PPP/RNBQK2R b KQkq -
+Petrov: classical attack, Marshall variation *
+rnbqk2r/ppp2ppp/3b3n/8/3P4/5N2/PPP1P1PP/RNBQKB1R b KQkq -
+Bird: From gambit, Lipke variation
+rnbqk2r/ppp2ppp/3b4/3np3/2B5/P3P3/1P1P1PPP/RNBQK1NR b KQkq -
+Sicilian: Kan, Polugaievsky variation *
+rnbqk2r/ppp2ppp/3b4/3np3/8/P3P1P1/1P1P1P1P/RNBQKBNR b KQkq -
+Sicilian: Kan, Swiss cheese variation *
+rnbqk2r/ppp2ppp/3b4/3np3/8/P3P3/1P1P1PPP/RNBQKBNR w KQkq -
+Sicilian: Kan, 5.Bd3 *
+rnbqk2r/ppp2ppp/3b4/3p4/3Pn3/3B1N2/PPP2PPP/RNBQK2R w KQkq -
+Petrov: classical attack, Marshall variation
+rnbqk2r/ppp2ppp/3bpn2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+Queen's pawn game *
+rnbqk2r/ppp2ppp/3p1n2/2b1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Giuoco Pianissimo *
+rnbqk2r/ppp2ppp/3p1n2/2b1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Giuoco Pianissimo *
+rnbqk2r/ppp2ppp/3p1n2/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Two knights defense (Modern bishop's opening) *
+rnbqk2r/ppp2ppp/3p1n2/4p3/1b2P3/5N2/PPPPNPPP/R1BQKB1R b KQkq -
+Ruy Lopez: Berlin defense, Mortimer variation *
+rnbqk2r/ppp2ppp/3p1n2/4p3/4P3/2bP1N2/PPP2PPP/R1BQKB1R w KQkq -
+Ruy Lopez: Berlin defense, Anderssen variation *
+rnbqk2r/ppp2ppp/3p1n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R w KQkq -
+Ruy Lopez: Anderssen variation *
+rnbqk2r/ppp2ppp/3p4/2b1pP2/2B1P1n1/2N5/PPPP2PP/R1BQK1NR b KQkq -
+Giuoco Pianissimo: Dubois variation *
+rnbqk2r/ppp2ppp/3p4/2b5/N2pP1n1/5N2/PPP2PPP/R1BQKB1R w KQkq -
+two knights defense: Kieseritsky variation *
+rnbqk2r/ppp2ppp/3p4/4p3/1b2n3/2P2N2/PP1PNPPP/R1BQKB1R b KQkq -
+Ruy Lopez: Berlin defense, Mortimer trap *
+rnbqk2r/ppp2ppp/4p3/3p4/2PPn3/P1Q5/1P2PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, Noa variation, main line
+rnbqk2r/ppp2ppp/4p3/3p4/2PPn3/P7/1PQ1PPPP/R1B1KBNR b KQkq -
+Nimzo-Indian: classical, Noa variation, main line, 7.Qc2
+rnbqk2r/ppp2ppp/4pn2/3p2B1/1b1PP3/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: MacCutcheon variation
+rnbqk2r/ppp2ppp/4pn2/3p2B1/1bPP4/5N2/PP2PPPP/RN1QKB1R w KQkq -
+QGD: Vienna variation
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD: Ragozin variation
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, Noa variation
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/P1N5/1PQ1PPPP/R1B1KBNR b KQkq -
+Nimzo-Indian: classical, Noa variation, 5.a3
+rnbqk2r/ppp2ppp/4pn2/3pP1B1/1b1P4/2N5/PPP2PPP/R2QKBNR b KQkq -
+French: MacCutcheon, advance variation
+rnbqk2r/ppp2ppp/4pn2/6B1/1bpP4/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+QGD: Ragozin, Vienna variation
+rnbqk2r/ppp2ppp/5n2/1BbPp3/8/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Scotch gambit *
+rnbqk2r/ppp2ppp/5n2/2bPp3/1PP5/8/P2P1PPP/RNBQKBNR b KQkq -
+Center game, Kieseritsky variation *
+rnbqk2r/ppp2ppp/5n2/2bPp3/8/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Scotch gambit: Dubois-R\'eti defense *
+rnbqk2r/ppp2ppp/5n2/2bPp3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Scotch gambit *
+rnbqk2r/ppp2ppp/5n2/2bPp3/8/2N5/PPPPBPPP/R1BQK1NR b KQkq -
+Scotch gambit: Benima defense *
+rnbqk2r/ppp2ppp/5n2/2bPp3/8/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Bishop's opening/Petrov: Urusov gambit *
+rnbqk2r/ppp2ppp/5n2/2bpp3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Two knights defense *
+rnbqk2r/ppp2ppp/5n2/2bpp3/4P3/3P1N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Nimzovich, Klein variation *
+rnbqk2r/ppp2ppp/5n2/3P4/1b3P2/2NPp3/PPPB2PP/R2QKBNR w KQkq -
+KGD: Falkbeer, Morphy gambit
+rnbqk2r/ppp2ppp/5n2/3Pp3/1b6/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Scotch: Relfsson gambit (`MacLopez') *
+rnbqk2r/ppp2ppp/5n2/3p4/1b1P4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, Noa variation, 5.cd ed
+rnbqk2r/ppp2ppp/5n2/3pp3/4P3/P1PP1P2/2P3PP/R1BQKBNR b KQkq -
+Ruy Lopez: modern Steinitz defense, Alapin variation *
+rnbqk2r/ppp2ppp/5n2/3pp3/4P3/P1PP4/2P2PPP/R1BQKBNR w KQkq -
+Ruy Lopez: modern Steinitz defense, Richter variation *
+rnbqk2r/ppp2ppp/8/1Bbp4/3NP1n1/2N5/PPP2PPP/R1BQK2R b KQkq -
+two knights defense: Pincus variation *
+rnbqk2r/ppp2ppp/8/2bPp3/2B3n1/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Scotch gambit *
+rnbqk2r/ppp2ppp/8/2bPp3/5P2/3P3N/PPP3Pn/RNBQKB1R w KQkq -
+Philidor: L\'opez counter-gambit, Jaenisch variation *
+rnbqk2r/ppp2ppp/8/2bPp3/6n1/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Two knights defense, Perreux variation *
+rnbqk2r/ppp2ppp/8/2bp4/3NP1n1/2N5/PPP2PPP/R1BQKB1R w KQkq -
+two knights defense: Lolli attack *
+rnbqk2r/ppp2ppp/8/2bpp3/4P1n1/2PP4/PP1N1PPP/R1BQKBNR w KQkq -
+Philidor: Hanham, Kmoch variation *
+rnbqk2r/ppp3p1/8/2bppPPp/4nP2/8/PPPPQ2P/RNB1KBNR w KQkq -
+KGA: Kieseritsky, Salvio defense, Cozio variation *
+rnbqk2r/ppp3p1/8/3ppPPp/3b4/7P/PPP3K1/RNBQ1BNR w kq -
+KGA: Allgaier, Urusov attack *
+rnbqk2r/ppp3pp/5n2/2bppPP1/8/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: Ghulam Kassim gambit *
+rnbqk2r/ppp3pp/5p2/3np3/1b2P3/3P1N2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Prins variation, Venice attack *
+rnbqk2r/pppn1pp1/4p2p/3pP3/1b1P4/2N5/PPPB1PPP/R2QKBNR w KQkq -
+French: MacCutcheon, Tartakower variation
+rnbqk2r/pppnb1pp/4pp2/3pP1B1/3P3P/2N5/PPP2PP1/R2QKBNR w KQkq -
+French: Albin-Alekhine-Ch\^atard attack, Teichmann variation
+rnbqk2r/pppnbppp/4p3/3pP1B1/3P3P/2N5/PPP2PP1/R2QKBNR b KQkq -
+French: Albin-Alekhine-Ch\^atard attack
+rnbqk2r/pppp1ppp/1b3n2/4p3/1PB1P3/P1N5/2PP1PPP/R1BQK1NR b KQkq -
+Ruy Lopez: Graz variation *
+rnbqk2r/pppp1ppp/1b3n2/4p3/NP2P3/P7/2PP1PPP/R1BQKBNR b KQkq -
+Ruy Lopez: Taimanov (chase/wing/accelerated counterthrust) variation *
+rnbqk2r/pppp1ppp/4pn2/6B1/1bPP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+Nimzo-Indian: Leningrad variation
+rnbqk2r/pppp1ppp/4pn2/8/1bP5/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+English: Nimzo-English opening
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/1QN5/PP2PPPP/R1B1KBNR b KQkq -
+Nimzo-Indian: Spielmann variation
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR b KQkq -
+Nimzo-Indian: 4.e3
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+Nimzo-Indian: three knights variation
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N2P2/PP2P1PP/R1BQKBNR b KQkq -
+Nimzo-Indian: Kmoch variation
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N3P1/PP2PP1P/R1BQKBNR b KQkq -
+Nimzo-Indian: Romanishin-Kasparov (Steiner) system
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Nimzo-Indian defense
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N5/PPQ1PPPP/R1B1KBNR b KQkq -
+Nimzo-Indian: classical variation
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2NQ4/PP2PPPP/R1B1KBNR b KQkq -
+Nimzo-Indian: Mikenas attack
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/5N2/PP1NPPPP/R1BQKB1R b KQkq -
+Bogo-Indian defense, Gr\"unfeld variation
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Bogo-Indian defense
+rnbqk2r/pppp1ppp/4pn2/8/2PP4/P1P5/4PPPP/R1BQKBNR b KQkq -
+Nimzo-Indian: S\"amisch variation
+rnbqk2r/pppp1ppp/5n2/1B2p3/1b2P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Ruy Lopez: Alapin's defense *
+rnbqk2r/pppp1ppp/5n2/2b1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Giuoco Piano *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Two knights defense *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+King's pawn game *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/2N5/PPPPBPPP/R1BQK1NR b KQkq -
+Hungarian defense *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov: Italian variation *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Rousseau gambit *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4PP2/3P4/PPP3PP/RNBQKBNR b KQkq -
+Philidor: L\'opez counter-gambit *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+Latvian gambit, 3.Bc4 *
+rnbqk2r/pppp1ppp/5n2/3Np3/1b2P3/8/PPPP1PPP/R1BQKBNR b KQkq -
+Ruy Lopez: Bird's defense *
+rnbqk2r/pppp1ppp/5n2/4P3/1bB2p2/2N5/PPPP2PP/R1BQK1NR b KQkq -
+KGA: bishop's gambit, Paulsen attack
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P1P1/2N5/PPPP1P1P/R1BQKBNR b KQkq -
+Ruy Lopez: Brentano defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P1Q1/2N5/PPPP1PPP/R1B1KBNR w KQkq -
+Vienna: Zhuravlev countergambit
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Ruy Lopez: Berlin defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N2P2/PPPP2PP/R1BQKBNR b KQkq -
+Ruy Lopez: Nuremberg variation *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+Ruy Lopez: fianchetto (Smyslov/Barnes) defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Ruy Lopez (Spanish opening) *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N5/PPPPBPPP/R1BQK1NR b KQkq -
+Ruy Lopez: Lucena defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N5/PPPPNPPP/R1BQKB1R b KQkq -
+Ruy Lopez: Cozio defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N5/PPPPQPPP/R1B1KBNR b KQkq -
+Ruy Lopez: Vinogradov variation *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2NP4/PPP2PPP/R1BQKBNR b KQkq -
+Ruy Lopez: old Steinitz defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Ruy Lopez: Schliemann defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1bB1P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Ruy Lopez: classical (Cordel) defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+Sicilian: Nimzovich-Rossolimo attack (with ...g6, without ...d6) *
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+English: Bremen, Smyslov system
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Sicilian: Nimzovich-Rossolimo attack (without ...d6) *
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/3P4/PP1BPPPP/RN1QKBNR b KQkq -
+Sicilian: Canal-Sokolsky attack, 3...Bd7 *
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/3P4/PP2PPPP/RNBQKBNR w KQkq -
+Sicilian: Canal-Sokolsky (Nimzovich-Rossolimo, Moscow) attack *
+rnbqk2r/pppp1ppp/5n2/4p3/2B1P3/2N5/PPPP1bPP/R1BQK1NR w KQkq -
+Giuoco Piano: Jerome gambit *
+rnbqk2r/pppp1ppp/5n2/4p3/4P3/P1PP4/2P2PPP/R1BQKBNR b KQkq -
+Ruy Lopez: modern Steinitz defense, exchange variation *
+rnbqk2r/pppp1ppp/5n2/4p3/4P3/P1b2N2/1PPP1PPP/R1BQKB1R w KQkq -
+Ruy Lopez: Treybal (Bayreuth) variation (exchange var. deferred) *
+rnbqk2r/pppp1ppp/5n2/4p3/4P3/P1b5/1PPP1PPP/R1BQKBNR w KQkq -
+Ruy Lopez: exchange variation *
+rnbqk2r/pppp1ppp/5n2/4p3/Nb2P3/8/PPPP1PPP/R1BQKBNR b KQkq -
+Ruy Lopez: Pollock defense *
+rnbqk2r/pppp1ppp/5n2/b2Np3/4P3/P7/1PPP1PPP/R1BQKBNR b KQkq -
+Ruy Lopez: Bird's defense deferred *
+rnbqk2r/pppp1ppp/5n2/b3p3/1P2P3/P1N5/2PP1PPP/R1BQKBNR b KQkq -
+Ruy Lopez: Caro variation *
+rnbqk2r/pppp1ppp/5n2/b3p3/2B1P3/P1N5/1PPP1PPP/R1BQK1NR b KQkq -
+Ruy Lopez: Classical defense deferred *
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R b KQkq -
+Ruy Lopez: Morphy defense *
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N3P1/1PPP1P1P/R1BQKBNR b KQkq -
+Ruy Lopez: fianchetto defense deferred *
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N5/1PPP1PPP/R1BQKBNR w KQkq -
+Ruy Lopez *
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N5/1PPPNPPP/R1BQKB1R b KQkq -
+Ruy Lopez: Cozio defense deferred *
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR b KQkq -
+Ruy Lopez: modern Steinitz defense *
+rnbqk2r/pppp1ppp/5n2/b3p3/4PP2/P1N5/1PPP2PP/R1BQKBNR b KQkq -
+Ruy Lopez: Schliemann defense deferred *
+rnbqk2r/pppp1ppp/5n2/bB2p3/4P3/P1N5/1PPP1PPP/R1BQK1NR b KQkq -
+Ruy Lopez: Alapin's defense deferred *
+rnbqk2r/pppp1ppp/8/2b1P3/3Pn3/8/PPP3PP/RNBQKBNR b KQkq -
+Latvian: Polerio variation *
+rnbqk2r/pppp1ppp/8/2b1P3/4n3/5N2/PPPP2PP/RNBQKB1R b KQkq -
+Latvian: corkscrew counter-gambit *
+rnbqk2r/pppp1ppp/8/2b1p3/2B1P1n1/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+two knights defense: Wilkes Barre (Traxler) variation *
+rnbqk2r/pppp1ppp/8/2b1p3/4P1n1/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Two knights defense *
+rnbqk2r/pppp1ppp/8/2b5/1P1pP1n1/2N2N2/P1P2PPP/R1BQKB1R b KQkq -
+two knights defense: Ulvestad variation *
+rnbqk2r/pppp1ppp/8/2b5/3NP3/2N5/PPP2nPP/R1BQKB1R w KQkq -
+two knights defense: Fegatello attack *
+rnbqk2r/pppp1ppp/8/2b5/N2pP1n1/5N2/PPP2PPP/R1BQKB1R b KQkq -
+two knights defense *
+rnbqk2r/pppp1ppp/8/2bN4/3pP1n1/5N2/PPP2PPP/R1BQKB1R b KQkq -
+two knights defense: Fritz variation *
+rnbqk2r/pppp1ppp/8/8/Nb1pP1n1/5N2/PPP2PPP/R1BQKB1R w KQkq -
+Two knights defense *
+rnbqk2r/pppp2p1/5n2/2b1pP1p/6P1/8/PPPP1PBP/RNBQK1NR w KQkq -
+KGA: Philidor gambit *
+rnbqk2r/pppp2p1/8/2b1pPPp/4n3/5N2/PPPP1P1P/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Berlin defense, 6.Bc4 *
+rnbqk2r/pppp2p1/8/2b1pPPp/8/7P/PPPP1K2/RNBQ1BNR w kq -
+KGA: Allgaier, Walker attack *
+rnbqk2r/pppp2pp/4pn2/5p2/1bPP4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+Dutch defense: Dutch-Indian (Nimzo-Dutch) variation
+rnbqk2r/pppp2pp/5n2/2b1pP2/6P1/2N5/PPPP1P1P/R1BQKBNR b KQkq -
+KGA: Blachly gambit *
+rnbqk2r/pppp2pp/5n2/2b1pP2/6P1/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: King's knight's gambit *
+rnbqk2r/pppp2pp/5n2/2b1pP2/6P1/8/PPPP1PBP/RNBQK1NR b KQkq -
+King's knight's gambit *
+rnbqk2r/pppp2pp/5n2/2b1pP2/8/5N2/PPPPBPPP/RNBQK2R b KQkq -
+KGA: Cunningham, Euwe defense *
+rnbqk2r/pppp2pp/5n2/2b2P2/3N4/2P5/P4PPP/RNBQKB1R b KQkq -
+KGA: Abbazia defense, Botvinnik variation *
+rnbqk2r/pppp2pp/5n2/4pPP1/8/8/PPPP1b1P/RNBQKBNR w KQkq -
+KGA: Lolli gambit (wild Muzio gambit) *
+rnbqk2r/pppp2pp/8/2b1pPP1/4n3/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: Salvio gambit *
+rnbqk2r/pppp3p/5np1/2b1pP1B/8/8/PPPP1PPP/RNBQK1NR w KQkq -
+KGA: Cunningham, Bertin gambit *
+rnbqk2r/ppppb1pp/4pn2/5p2/2PP4/6P1/PP1BPPBP/RN1QK1NR w KQkq -
+Dutch-Indian, Alekhine variation
+rnbqk2r/ppppb1pp/4pn2/5p2/2PP4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+Dutch defense
+rnbqk2r/ppppbppp/3n4/4p2Q/8/1BN5/PPPP1PPP/R1B1K1NR w KQkq -
+Vienna game
+rnbqk2r/ppppbppp/5n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Inverted Hungarian *
+rnbqk2r/ppppbppp/5n2/8/2B1Pp2/5N2/PPPP2PP/RNBQK2R w KQkq -
+KGA: Cunningham, Euwe defense
+rnbqk2r/ppppbppp/7n/8/N3P3/2P2N1P/P4PP1/R1BQKB1R w KQkq -
+two knights defense: Steinitz variation *
+rnbqk2r/ppppbppp/8/4P3/N3n3/2P2N1P/P1Q2PP1/R1B1KB1R b KQkq -
+two knights defense: G\"oring variation *
+rnbqk2r/ppppbppp/8/8/N3P1n1/2P2N1P/P4PP1/R1BQKB1R b KQkq -
+Two knights defense *
+rnbqk2r/ppppbppp/8/8/N3P1n1/2P2N2/P4PPP/R1BQKB1R w KQkq -
+Two knights defense *
+rnbqk2r/ppppp1bp/5np1/5p2/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+Dutch: Leningrad, main variation
+rnbqk2r/ppppp2p/6pb/5P2/3P4/8/PPP2PPP/RN1QKBNR b KQkq -
+Amar gambit *
+rnbqk2r/ppppppbp/5np1/6B1/3P4/8/PPPNPPPP/R2QKBNR b KQkq -
+R\'eti: King's Indian attack, Keres variation *
+rnbqk2r/ppppppbp/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+R\'eti: King's Indian attack *
+rnbqk2r/ppppppbp/5np1/8/2PPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+King's Indian: 4.e4
+rnbqkb1r/1p2pppp/p2p1n2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: Najdorf, 6.Bg5
+rnbqkb1r/1p2pppp/p2p1n2/8/2BNP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Sicilian: Najdorf, Lipnitzky attack
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N1B3/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: Najdorf, Byrne (English) attack
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N3P1/PPP2P1P/R1BQKB1R b KQkq -
+Sicilian: Najdorf, Zagreb (fianchetto) variation
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N4P/PPP2PP1/R1BQKB1R b KQkq -
+Sicilian: Najdorf, Adams attack
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+Sicilian: Najdorf, Opo\v censky variation
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Najdorf
+rnbqkb1r/1p2pppp/p2p1n2/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+Sicilian: Najdorf, 6.f4
+rnbqkb1r/1p2pppp/p4n2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+Queen's Indian: Petrosian system *
+rnbqkb1r/1p3p1p/p2ppnp1/8/2PNP3/3B4/PP3PPP/RNBQ1RK1 w kq -
+Sicilian: Kan, Gipslis variation
+rnbqkb1r/1p3ppp/p1p1pn2/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: accelerated Meran (Alekhine variation)
+rnbqkb1r/1p3ppp/p2ppn2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Najdorf, 6...e6
+rnbqkb1r/1p3ppp/p2ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R b KQkq -
+Sicilian: Najdorf, 7.f4
+rnbqkb1r/1p3ppp/p2ppn2/8/3NP3/2N1B3/PPPQ1PPP/R3KB1R b KQkq -
+Sicilian: Scheveningen, English variation
+rnbqkb1r/1p3ppp/p2ppn2/8/3NP3/2N5/PPP1BPPP/R1BQK2R w KQkq -
+Sicilian: Scheveningen (Paulsen), classical variation
+rnbqkb1r/1p3ppp/p3pn2/2p5/2BP4/4PN2/PP2QPPP/RNB2RK1 b kq -
+QGA: classical, 7.Qe2
+rnbqkb1r/1p3ppp/p3pn2/2p5/2BP4/4PN2/PP3PPP/RNBQ1RK1 w kq -
+QGA: classical, 6...a6
+rnbqkb1r/1p3ppp/p3pn2/2p5/2BPP3/5N2/PP3PPP/RNBQ1RK1 b kq -
+QGA: classical, Geller variation
+rnbqkb1r/1p3ppp/p3pn2/2p5/P1BP4/4PN2/1P3PPP/RNBQ1RK1 b kq -
+QGA: classical, Rubinstein variation
+rnbqkb1r/1p3ppp/p4n2/1N1pp1B1/Q1P5/2N5/PP2PPPP/R3KB1R b KQkq -
+QGD: Semi-Tarrasch, Krause variation
+rnbqkb1r/1pp1pppp/p4n2/8/2pPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+QGA, Bogolyubov variation
+rnbqkb1r/1ppp1ppp/p3pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Dzindzikhashvili defense
+rnbqkb1r/2pp1ppp/p3pn2/1p6/2P5/5NP1/PP1PPPBP/RNBQK2R w KQkq -
+English: Romanishin gambit
+rnbqkb1r/3ppppp/P4n2/2pP4/8/8/PP2PPPP/RNBQKBNR b KQkq -
+Benk\"o gambit accepted
+rnbqkb1r/3ppppp/p4n2/1PpP4/8/2N5/PP2PPPP/R1BQKBNR b KQkq -
+Benk\"o gambit: Zaitsev system
+rnbqkb1r/3ppppp/p4n2/1PpP4/8/8/PP2PPPP/RNBQKBNR w KQkq -
+Benk\"o gambit half accepted
+rnbqkb1r/4pppp/3p1n2/1NpP4/1pB1P3/8/PP3PPP/R1BQK1NR b KQkq -
+Benk\"o gambit: Nescaf\'e Frapp\'e attack
+rnbqkb1r/5ppp/p2ppn2/1p4B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+Sicilian: Najdorf, Polugayevsky variation
+rnbqkb1r/5ppp/p2ppn2/1p6/3NP3/1BN5/PPP2PPP/R1BQK2R w KQkq -
+Sicilian: Sozin with ...a6 and ...b5
+rnbqkb1r/5ppp/p3pn2/1pp5/2BP4/4PN2/PP2QPPP/RNB2RK1 w kq -
+QGA: classical, 7...b5
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2P5/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+English: Queens Indian formation
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP1B2/5N2/PP2PPPP/RN1QKB1R b KQkq -
+Queen's Indian: Miles variation
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+Queen's Indian: 4.Nc3
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+Queen's Indian: 4.e3
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Queen's Indian defense
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/5NP1/PP2PP1P/RNBQKB1R b KQkq -
+Queen's Indian: 4.g3
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/P4N2/1P2PPPP/RNBQKB1R b KQkq -
+Queen's Indian: Petrosian system
+rnbqkb1r/p1pp1ppp/5n2/1p2p3/2P5/3P4/PP2PPPP/RNBQKBNR w KQkq -
+Sicilian: wing gambit deferred *
+rnbqkb1r/p1pp1ppp/5n2/1p4N1/2P1p3/2N5/PP1PPPPP/R1BQKB1R w KQkq -
+English: Bellon gambit
+rnbqkb1r/p1pp1ppp/5n2/1p6/2PPp3/4P3/PP3PPP/RNBQKBNR w KQkq -
+French: Wing gambit *
+rnbqkb1r/p1pp2pp/5n2/1p2pp2/2B1P3/3P4/PPP2PPP/RNBQK1NR w KQkq -
+KGD: classical, Heath variation *
+rnbqkb1r/p1ppp1pp/1p3n2/6B1/3Pp3/2N5/PPP2PPP/R2QKBNR w KQkq -
+Dutch: Staunton gambit, Nimzovich variation
+rnbqkb1r/p1pppp1p/5np1/1p1P4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+King's Indian: Danube gambit
+rnbqkb1r/p1pppp1p/5np1/1p6/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+R\'eti: King's Indian attack, R\'eti-Smyslov variation *
+rnbqkb1r/p1pppppp/1p3n2/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Queen's Indian accelerated
+rnbqkb1r/p1pppppp/1p3n2/8/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's Indian defense
+rnbqkb1r/p1pppppp/1p3n2/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+R\'eti: Nimzovich-Larsen attack *
+rnbqkb1r/p1pppppp/5n2/1p6/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Santasiere's folly *
+rnbqkb1r/p1pppppp/5n2/1p6/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+R\'eti: King's Indian attack, Spassky's variation
+rnbqkb1r/p1pppppp/8/1p1nP3/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+Alekhine's defense: O'Sullivan gambit
+rnbqkb1r/p2n1ppp/1p2p3/2ppP3/3P4/2PB4/PP1N1PPP/R1BQK1NR w KQkq -
+French: Tarrasch, Botvinnik variation
+rnbqkb1r/p2p1pp1/5n1p/1ppP2B1/8/5N2/PP2PPPP/RN1QKB1R w KQkq -
+Blumenfeld counter-gambit, Spielmann variation
+rnbqkb1r/p2p1ppp/4pn2/1ppP2B1/2P5/5N2/PP2PPPP/RN1QKB1R b KQkq -
+Blumenfeld counter-gambit, Dus-Chotimursky variation
+rnbqkb1r/p2p1ppp/4pn2/1ppP4/2P5/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Blumenfeld counter-gambit
+rnbqkb1r/p2ppp1p/1p3np1/2p3B1/3P4/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+English: Torre defensive system *
+rnbqkb1r/p2ppp1p/1p3np1/2p5/3P1B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+English: London defensive system *
+rnbqkb1r/p2ppppp/1p3n2/2p3B1/3P4/2P5/PP2PPPP/RN1QKBNR b KQkq -
+English: Caro-Kann defensive system, Bogolyubov variation *
+rnbqkb1r/p2ppppp/1p3n2/2p5/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+English: Caro-Kann defensive system *
+rnbqkb1r/p2ppppp/5n2/1ppP4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+Benk\"o gambit
+rnbqkb1r/p3pppp/2p2n2/1p2P3/2pP4/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+QGD Slav: Tolush-Geller gambit
+rnbqkb1r/p3pppp/5n2/1ppP4/2p1P3/2N5/PP3PPP/R1BQKBNR w KQkq -
+QGA: Linares variation
+rnbqkb1r/p4p2/2p1p2p/1p1nP1N1/2pP3B/2N5/PP3PPP/R2QKB1R w KQkq -
+QGD semi-Slav: anti-Meran, Alatortsev system
+rnbqkb1r/p4p2/2p1pP1p/1p2N3/2pP3p/2N5/PP3PPP/R2QKB1R b KQkq -
+QGD semi-Slav: Ekstrom variation
+rnbqkb1r/p4p2/2p1pn1p/1p2P1N1/2pP3B/2N5/PP3PPP/R2QKB1R b KQkq -
+QGD semi-Slav: anti-Meran gambit
+rnbqkb1r/p4ppp/2p5/3n4/2B2p2/5N2/PPPP2PP/RNBQK2R w KQkq -
+KGA: Abbazia defense, Botvinnik variation
+rnbqkb1r/p5pp/4pn2/1Ppp4/8/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Blumenfeld counter-gambit accepted
+rnbqkb1r/pp1n1ppp/4p3/2ppP3/3P1P2/2N2N2/PPP3PP/R1BQKB1R b KQkq -
+French: Steinitz variation
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+English: Bremen system, Keres variation
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Ponziani: Jaenisch counter-attack *
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Ponziani opening *
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/4P3/2N5/PPPPBPPP/R1BQK1NR b KQkq -
+Ponziani: Romanishin variation *
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/4P3/2N5/PPPPNPPP/R1BQKB1R b KQkq -
+Ponziani: R\'eti variation *
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Ponziani counter-gambit *
+rnbqkb1r/pp1p1ppp/2p2n2/8/2B1Pp2/2N5/PPPP2PP/R1BQK1NR w KQkq -
+KGA: bishop's gambit, Jaenisch variation
+rnbqkb1r/pp1p1ppp/2p5/3Nn3/1P1NP3/8/P1P2PPP/R1BQKB1R w KQkq -
+two knights defense: Fritz, Gruber variation *
+rnbqkb1r/pp1p1ppp/4pn2/2P5/8/4B3/PPP1PPPP/RN1QKBNR b KQkq -
+R\'eti accepted: Keres variation *
+rnbqkb1r/pp1p1ppp/4pn2/2p3B1/3PP3/5N2/PPP2PPP/RN1QKB1R b KQkq -
+Queen's pawn: Torre attack, Wagner gambit
+rnbqkb1r/pp1p1ppp/4pn2/2p5/2P1P3/2N5/PP1P1PPP/R1BQKBNR w KQkq -
+English: Mikenas-Carls, Sicilian variation
+rnbqkb1r/pp1p1ppp/4pn2/2pP4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+Benoni defense
+rnbqkb1r/pp1p1ppp/4pn2/8/2PN4/8/PP2PPPP/RNBQKB1R w KQkq -
+English: symmetrical variation
+rnbqkb1r/pp1p1ppp/4pn2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Anderssen variation
+rnbqkb1r/pp1p1ppp/5n2/2p1N3/8/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: Kaufmann attack *
+rnbqkb1r/pp1p1ppp/5n2/2p1p3/2P5/6PB/PP1PPP1P/RNBQK1NR b KQkq -
+Sicilian: Acton extension *
+rnbqkb1r/pp1p1ppp/5n2/2p1p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Dresden opening *
+rnbqkb1r/pp1p1ppp/5n2/2pPp3/2P5/8/PP2PPPP/RNBQKBNR w KQkq e6
+Czech Benoni defense
+rnbqkb1r/pp1p2pp/2p2n2/4pp2/2B1P3/3P4/PPP2PPP/RNBQK1NR w KQkq -
+KGD: classical, 4.c3 *
+rnbqkb1r/pp1p2pp/2p2n2/4pp2/2B1PP2/3P4/PPP3PP/RNBQK1NR b KQkq -
+KGD: classical counter-gambit *
+rnbqkb1r/pp1pp1pp/2p2n2/6B1/3Pp3/2N5/PPP2PPP/R2QKBNR w KQkq -
+Dutch: Staunton gambit, Chigorin variation
+rnbqkb1r/pp1ppp1p/5np1/2p5/3P4/2P1P3/PP3PPP/RNBQKBNR b KQkq -
+English: Kurajica defense *
+rnbqkb1r/pp1ppp1p/5np1/2p5/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+English opening: Agincourt variation *
+rnbqkb1r/pp1ppp1p/5np1/2p5/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+English: Neo-Catalan *
+rnbqkb1r/pp1ppppp/1n6/2p1P3/8/1B1P4/PPP2PPP/RNBQK1NR b KQkq -
+Alekhine's defense: Kmoch variation
+rnbqkb1r/pp1ppppp/2p2n2/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Caro-Masi defense
+rnbqkb1r/pp1ppppp/5n2/2P5/8/8/PPP1PPPP/RNBQKBNR b KQkq -
+R\'eti accepted *
+rnbqkb1r/pp1ppppp/5n2/2p1P3/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+English, Nimzovich, Flohr variation *
+rnbqkb1r/pp1ppppp/5n2/2p5/2P5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+English: symmetrical variation
+rnbqkb1r/pp1ppppp/5n2/2p5/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+English: symmetrical, Benoni formation
+rnbqkb1r/pp1ppppp/5n2/2p5/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Benoni defense
+rnbqkb1r/pp1ppppp/5n2/2p5/3P4/4P3/PPP2PPP/RNBQKBNR b KQkq -
+English opening: Agincourt variation *
+rnbqkb1r/pp1ppppp/5n2/2p5/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+R\'eti opening *
+rnbqkb1r/pp1ppppp/5n2/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian: Nimzovich-Rubinstein variation
+rnbqkb1r/pp1ppppp/5n2/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+English, Nimzovich variation *
+rnbqkb1r/pp1ppppp/5n2/2p5/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+English opening *
+rnbqkb1r/pp1ppppp/5n2/2pP4/8/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Old Benoni defense
+rnbqkb1r/pp1ppppp/5n2/2pP4/8/8/PPP1PPPP/RNBQKBNR b KQkq -
+R\'eti: advance variation *
+rnbqkb1r/pp1ppppp/5n2/2pP4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+Old Benoni defense
+rnbqkb1r/pp1ppppp/5n2/3P4/2p5/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Hawk (Habichd) defense
+rnbqkb1r/pp1ppppp/8/2pP4/2P1n3/8/PP2PPPP/RNBQKBNR w KQkq -
+Vulture defense
+rnbqkb1r/pp2pp1p/2p2np1/3p4/2P5/1P3N2/PB1PPPPP/RN1QKB1R w KQkq -
+English: Bled variation
+rnbqkb1r/pp2pp1p/2p2np1/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD Slav\Gr\"unfeld: Schlechter variation
+rnbqkb1r/pp2pp1p/2p2p2/8/3P4/8/PPP2PPP/R1BQKBNR w KQkq -
+Caro-Kann: Bronstein-Larsen variation
+rnbqkb1r/pp2pp1p/2pp1np1/8/3PP3/2N1B3/PPPQ1PPP/R3KBNR b KQkq -
+Pirc: 150 attack
+rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N1B3/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: dragon, 6.Be3
+rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: dragon variation
+rnbqkb1r/pp2pp1p/3p1np1/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+Sicilian: dragon, Levenfish variation
+rnbqkb1r/pp2pp1p/5np1/2pP4/4p3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+QGD: Albin counter-gambit, 5.g3 *
+rnbqkb1r/pp2pp1p/5np1/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+Queen's Indian: 4.g3 *
+rnbqkb1r/pp2pp1p/5np1/2pp4/8/1P2PN2/PBPP1PPP/RN1QKB1R b KQkq -
+Queen's Indian: 4.g3 Bb7 *
+rnbqkb1r/pp2pp1p/5np1/2pp4/8/BP2PN2/P1PP1PPP/RN1QKB1R b KQkq -
+Queen's Indian: Nimzovich variation (exaggerated fianchetto) *
+rnbqkb1r/pp2pp1p/5np1/3p4/2PP4/2N5/PP3PPP/R1BQKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik attack, 5...g6
+rnbqkb1r/pp2pp1p/6p1/2p3B1/2PPp3/8/PP1QPPPP/R3KBNR w KQkq -
+Gr\"unfeld: Lundin variation
+rnbqkb1r/pp2pppp/2p2n2/3P4/2P5/8/PP1P1PPP/RNBQKBNR w KQkq -
+Scandinavian gambit
+rnbqkb1r/pp2pppp/2p2n2/3p4/2P5/1P3N2/PB1PPPPP/RN1QKB1R b KQkq -
+English: Caro-Kann defensive system
+rnbqkb1r/pp2pppp/2p2n2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+QGD Slav: 4.Nc3
+rnbqkb1r/pp2pppp/2p2n2/3p4/2PP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+QGD Slav: 4.e3
+rnbqkb1r/pp2pppp/2p2n2/3p4/2PP4/5N2/PP1NPPPP/R1BQKB1R b KQkq -
+QGD Slav: Breyer variation
+rnbqkb1r/pp2pppp/2p2n2/8/2pP4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+QGD Slav: 5.e3 (Alekhine variation)
+rnbqkb1r/pp2pppp/2p2n2/8/2pP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD Slav accepted
+rnbqkb1r/pp2pppp/2p2n2/8/2pPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+QGD Slav: Slav gambit
+rnbqkb1r/pp2pppp/2p2n2/8/3PN3/3B4/PPP2PPP/R1BQK1NR b KQkq -
+Caro-Kann: Alekhine gambit
+rnbqkb1r/pp2pppp/2p2n2/8/P1pP4/2N2N2/1P2PPPP/R1BQKB1R b KQkq -
+QGD Slav accepted: Alapin variation
+rnbqkb1r/pp2pppp/2pp1n2/8/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Pirc: Ufimtsev-Pytel variation
+rnbqkb1r/pp2pppp/3p1n2/2p5/3PP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Cortlever (Alatortsev) variation
+rnbqkb1r/pp2pppp/3p1n2/2pP4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+Benoni defense, Hromodka system
+rnbqkb1r/pp2pppp/3p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Sicilian
+rnbqkb1r/pp2pppp/3p1n2/8/3NP3/5P2/PPP3PP/RNBQKB1R b KQkq -
+Sicilian: Prins (Moscow) variation
+rnbqkb1r/pp2pppp/5n2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R b KQkq -
+Bogo-Indian defense *
+rnbqkb1r/pp2pppp/5n2/2Pp4/1P6/8/P1P1PPPP/RNBQKBNR b KQkq -
+QGA: Ericson variation *
+rnbqkb1r/pp2pppp/5n2/2Pp4/3P4/8/PP3PPP/RNBQKBNR b KQkq -
+Caro-Kann: Panov-Botvinnik, Gunderam attack
+rnbqkb1r/pp2pppp/5n2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Queen's gambit accepted *
+rnbqkb1r/pp2pppp/5n2/2Pp4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+QGA: 3.Nf3 *
+rnbqkb1r/pp2pppp/5n2/2Pp4/8/P7/1PP1PPPP/RNBQKBNR b KQkq -
+QGA: Alekhine defense *
+rnbqkb1r/pp2pppp/5n2/2p3N1/4p3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Budapest: Adler variation *
+rnbqkb1r/pp2pppp/5n2/2p5/1PPp4/4PN2/P2P1PPP/RNBQKB1R b KQkq -
+Blumenfeld counter-gambit *
+rnbqkb1r/pp2pppp/5n2/2pP4/4p3/8/PPP2PPP/RNBQKBNR w KQkq -
+QGD: Albin counter-gambit *
+rnbqkb1r/pp2pppp/5n2/2pp4/2P5/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+English: symmetrical, Benoni formation *
+rnbqkb1r/pp2pppp/5n2/2pp4/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+QGD Slav: 3.Nf3 *
+rnbqkb1r/pp2pppp/5n2/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+Neo-Gr\"unfeld defense *
+rnbqkb1r/pp2pppp/5n2/2pp4/5P2/4PN2/PPPP2PP/RNBQKB1R w KQkq -
+Bird's opening: Lasker variation
+rnbqkb1r/pp2pppp/5n2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R b KQkq -
+Queen's Indian defense *
+rnbqkb1r/pp2pppp/5n2/2pp4/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+Queen's pawn game *
+rnbqkb1r/pp2pppp/5n2/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian, 3.Nf3 *
+rnbqkb1r/pp2pppp/5n2/2pp4/8/P3PN2/1PPP1PPP/RNBQKB1R b KQkq -
+Dzindzikhashvili defense *
+rnbqkb1r/pp2pppp/5n2/2ppN3/8/4P3/PPPP1PPP/RNBQKB1R b KQkq -
+D\"ory defense *
+rnbqkb1r/pp2pppp/5n2/3p4/2PP4/2N5/PP3PPP/R1BQKBNR b KQkq -
+Caro-Kann: Panov-Botvinnik attack
+rnbqkb1r/pp2pppp/5n2/3p4/3P4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+QGD Slav: exchange variation *
+rnbqkb1r/pp2pppp/5n2/3p4/3P4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav: exchange variation
+rnbqkb1r/pp2pppp/5n2/8/1pPP4/4PN2/P5PP/RNBQKB1R b KQkq -
+Blumenfeld counter-gambit accepted *
+rnbqkb1r/pp2pppp/8/2pn4/8/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+English: symmetrical, three knights system
+rnbqkb1r/pp2pppp/8/2pn4/8/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+English: symmetrical variation *
+rnbqkb1r/pp3p1p/2p1pnp1/3p4/2PP4/4PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD: Spielmann variation
+rnbqkb1r/pp3p1p/3p1np1/2pP2B1/8/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+Benoni: Uhlmann variation
+rnbqkb1r/pp3p1p/3p1np1/2pP4/4P3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+Benoni: classical with e4 and Nf3
+rnbqkb1r/pp3p1p/3p1np1/2pP4/4PP2/2N5/PP4PP/R1BQKBNR b KQkq -
+Benoni: pawn storm variation
+rnbqkb1r/pp3p1p/3p1np1/2pP4/8/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+Benoni defense
+rnbqkb1r/pp3p1p/3p1np1/2pP4/8/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+Benoni: fianchetto variation
+rnbqkb1r/pp3p1p/3p1np1/2pP4/8/2N5/PP1NPPPP/R1BQKB1R b KQkq -
+Benoni: Nimzovich (knight's tour) variation
+rnbqkb1r/pp3p1p/3p1np1/2pPp3/2P1P3/2N5/PP3PPP/R1BQKBNR w KQkq -
+Czech Benoni: King's Indian system
+rnbqkb1r/pp3ppp/2p1pn2/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: 5.e3
+rnbqkb1r/pp3ppp/2p1pn2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD semi-Slav
+rnbqkb1r/pp3ppp/2p1pn2/3p4/2PP4/4PN2/PP1N1PPP/R1BQKB1R b KQkq -
+QGD Slav
+rnbqkb1r/pp3ppp/2p1pn2/6B1/2pP4/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+QGD semi-Slav: 5.Bg5 dc
+rnbqkb1r/pp3ppp/2p1pn2/6B1/2pPP3/2N2N2/PP3PPP/R2QKB1R b KQkq -
+QGD semi-Slav: Botvinnik system (anti-Meran)
+rnbqkb1r/pp3ppp/2p1pn2/8/P1pP4/2N2N2/1P2PPPP/R1BQKB1R w KQkq -
+QGD Slav: Soultanb\'eieff variation
+rnbqkb1r/pp3ppp/2p2n2/3Pp3/4P3/8/PP1P1PPP/RNBQKBNR w KQkq -
+Sicilian: Andreaschek gambit *
+rnbqkb1r/pp3ppp/2p2n2/3Pp3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Scotch: G\"oring gambit *
+rnbqkb1r/pp3ppp/2p2n2/3Pp3/8/3P4/PP2PPPP/RNBQKBNR w KQkq -
+Sicilian: Tartakower variation *
+rnbqkb1r/pp3ppp/2p2n2/3p2B1/3P4/2N5/PP2PPPP/R2QKBNR w KQkq -
+QGD: exchange, positional line, 5...c6
+rnbqkb1r/pp3ppp/2p2n2/3p2B1/3P4/2N5/PPQ1PPPP/R3KBNR b KQkq -
+QGD: exchange, positional line, 6.Qc2
+rnbqkb1r/pp3ppp/2p2n2/3p4/2PPp3/1Q2P3/PP1B1PPP/RN2KBNR b KQkq -
+French: advance, Wade variation *
+rnbqkb1r/pp3ppp/2p2n2/3p4/2PPp3/2N1P3/PP1B1PPP/R2QKBNR b KQkq -
+French: advance, Euwe variation *
+rnbqkb1r/pp3ppp/2p2n2/3p4/2PPp3/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+French: advance, Paulsen attack *
+rnbqkb1r/pp3ppp/2p2n2/3pp3/8/3P2P1/PPP1PPBP/RNBQK1NR w KQkq -
+Robatsch defense: Geller's system *
+rnbqkb1r/pp3ppp/2p2n2/4N3/2BpP3/2N5/PPPP1PPP/R1BQK2R b KQkq -
+Ponziani: Fraser defense *
+rnbqkb1r/pp3ppp/2p2n2/4p3/3pPP2/2NP4/PPP3PP/R1BQKBNR w KQkq -
+Ponziani counter-gambit, Schmidt attack *
+rnbqkb1r/pp3ppp/2p2p2/8/2BP4/8/PPP2PPP/R1BQK1NR b KQkq -
+Caro-Kann: Forg\'acs variation
+rnbqkb1r/pp3ppp/2p2p2/8/3P4/8/PPP2PPP/R1BQKBNR w KQkq -
+Caro-Kann: Tartakower (Nimzovich) variation
+rnbqkb1r/pp3ppp/3p1n2/1B2p3/3NP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Sicilian: Venice attack
+rnbqkb1r/pp3ppp/3p1n2/1B2p3/3NP3/5P2/PPP3PP/RNBQK2R b KQkq -
+Sicilian: Prins variation, Venice attack
+rnbqkb1r/pp3ppp/3p1n2/2pP4/4P3/2N5/PP3PPP/R1BQKBNR b KQkq -
+Benoni: 6.e4
+rnbqkb1r/pp3ppp/3ppn2/1B6/3NP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Sicilian: Scheveningen, Vitoli\'n\'s variation
+rnbqkb1r/pp3ppp/3ppn2/8/2BNP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Sicilian: Sozin attack
+rnbqkb1r/pp3ppp/3ppn2/8/3NP1P1/2N5/PPP2P1P/R1BQKB1R b KQkq -
+Sicilian: Scheveningen, Keres attack
+rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N3P1/PPP2P1P/R1BQKB1R b KQkq -
+Sicilian: Scheveningen, fianchetto variation
+rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+Sicilian: Scheveningen, 6.Be2
+rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Scheveningen variation
+rnbqkb1r/pp3ppp/3ppn2/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+Sicilian: Scheveningen, 6.f4
+rnbqkb1r/pp3ppp/4p3/2pn4/3P4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+QGD: Semi-Tarrasch with e3
+rnbqkb1r/pp3ppp/4pn2/2Pp2B1/8/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+QGA, Janowsky-Larsen variation *
+rnbqkb1r/pp3ppp/4pn2/2Pp4/1P6/P7/2P1PPPP/RNBQKBNR b KQkq -
+QGA: Haberditz variation *
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/4BN2/PPP1PPPP/RN1QKB1R b KQkq -
+QGA, Flohr variation *
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+QGA: 4...e6 *
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+QGA, 4.e3 *
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+QGA, Smyslov variation *
+rnbqkb1r/pp3ppp/4pn2/2p5/2BP4/4PN2/PP3PPP/RNBQ1RK1 b kq -
+QGA: classical variation, 6.O-O
+rnbqkb1r/pp3ppp/4pn2/2p5/2BP4/4PN2/PP3PPP/RNBQK2R w KQkq -
+QGA: classical variation
+rnbqkb1r/pp3ppp/4pn2/2pP2B1/3P4/2N5/PP2PPPP/R2QKBNR b KQkq -
+QGD: Semi-Tarrasch
+rnbqkb1r/pp3ppp/4pn2/2pP4/3P4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+QGD: Semi-Tarrasch, 5.cd
+rnbqkb1r/pp3ppp/4pn2/2pp2B1/2PP4/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+QGD: Semi-Tarrasch defense, Pillsbury variation
+rnbqkb1r/pp3ppp/4pn2/2pp2B1/2PP4/2N5/PP2PPPP/R2QKBNR w KQkq -
+QGD: Been-Koomen variation
+rnbqkb1r/pp3ppp/4pn2/2pp4/2P5/1P2PN2/PB1P1PPP/RN1QKB1R b KQkq -
+English: Wimpey system
+rnbqkb1r/pp3ppp/4pn2/2pp4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD: Semi-Tarrasch defense
+rnbqkb1r/pp3ppp/4pn2/2pp4/3P1B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+QGD Slav: 4.e3 Bf5 *
+rnbqkb1r/pp3ppp/4pn2/2pp4/3P4/1P1BPN2/P1P2PPP/RNBQK2R b KQkq -
+Queen's pawn game, Rubinstein (Colle-Zukertort) variation
+rnbqkb1r/pp3ppp/4pn2/2pp4/3P4/1P2PN2/P1PN1PPP/R1BQKB1R b KQkq -
+Queen's pawn game, Zukertort variation
+rnbqkb1r/pp3ppp/4pn2/2pp4/3P4/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav: 4.e3 *
+rnbqkb1r/pp3ppp/4pn2/2pp4/3P4/2PBPN2/PP3PPP/RNBQK2R b KQkq -
+Colle system
+rnbqkb1r/pp3ppp/4pn2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+Queen's Indian: 4.e3 *
+rnbqkb1r/pp3ppp/4pn2/3p2B1/2PQ4/2N2N2/PP2PPPP/R3KB1R b KQkq -
+QGD: Semi-Tarrasch, Primitive Pillsbury variation
+rnbqkb1r/pp3ppp/4pn2/3p4/2PP4/2N5/PP3PPP/R1BQKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik attack, 5...e6
+rnbqkb1r/pp3ppp/4pn2/8/2Bp4/4PN2/PP3PPP/RNBQ1RK1 w kq -
+QGA: classical, Steinitz variation
+rnbqkb1r/pp3ppp/5n2/2Ppp3/8/P7/1PP1PPPP/RNBQKBNR w KQkq -
+QGA: Alekhine defense, Borisenko-Furman variation *
+rnbqkb1r/pp3ppp/5n2/2p3B1/3pp3/1N1P4/PPP1PPPP/RN1QKB1R w KQkq -
+Alekhine's defense: modern, Vitolins attack *
+rnbqkb1r/pp3ppp/5n2/2pp2B1/3Np3/3P4/PPP1PPPP/RN1QKB1R w KQkq -
+Alekhine's defense: modern, Alekhine variation *
+rnbqkb1r/pp3ppp/5n2/2ppp1B1/8/3P2P1/PPP1PPBP/RN1QK1NR b KQkq -
+Robatsch defense: Rossolimo variation *
+rnbqkb1r/pp3ppp/8/2pnp3/8/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+Sicilian: accelerated fianchetto, Mar\'oczy bind *
+rnbqkb1r/pp3ppp/8/2pnp3/8/2N3P1/PP1PPPBP/R1BQK1NR b KQkq -
+Sicilian: accelerated fianchetto, Mar\'oczy bind, 5...Bg7 *
+rnbqkb1r/pp3ppp/8/2pnp3/8/P3P3/1P1P1PPP/RNBQKBNR w KQkq -
+Sicilian: Kan, Mar\'oczy bind (R\'eti variation) *
+rnbqkb1r/pp4pp/2p1p3/3p1p2/2PPn3/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: stonewall defense
+rnbqkb1r/pp4pp/2p1p3/3p1p2/2PPn3/3BPN2/PP1N1PPP/R1BQK2R w KQkq -
+QGD: Stonewall variation
+rnbqkb1r/pp4pp/5n2/3p2B1/2p5/1NN1P3/PPP1P1PP/R2QKB1R w KQkq -
+Alekhine's defense: four pawns attack, Ilyin-Genevsky variation *
+rnbqkb1r/ppn1pppp/8/2p5/8/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: symmetrical, Rubinstein system
+rnbqkb1r/ppp1p1pp/5n2/3p4/8/3B3N/PPP2PPP/RNBQK2R w KQkq -
+Bird: From gambit, Lipke variation *
+rnbqkb1r/ppp1pp1p/1n1p2p1/4P3/2PP1P2/8/PP4PP/RNBQKBNR w KQkq -
+Alekhine's defense: four pawns attack, fianchetto variation
+rnbqkb1r/ppp1pp1p/1n1p4/4P1p1/2PP1P2/8/PP4PP/RNBQKBNR w KQkq -
+Alekhine's defense: four pawns attack, Planinc variation
+rnbqkb1r/ppp1pp1p/1n4p1/8/8/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: Anglo-Gr\"unfeld, Czech defense
+rnbqkb1r/ppp1pp1p/3p1np1/6B1/3PP3/2N5/PPP2PPP/R2QKBNR b KQkq -
+Pirc: Byrne variation
+rnbqkb1r/ppp1pp1p/3p1np1/8/2BPP3/2N5/PPP2PPP/R1BQK1NR b KQkq -
+Pirc: Holmov system
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+Pirc: classical (two knights) system
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PP3/2N3P1/PPP2P1P/R1BQKBNR b KQkq -
+Pirc: Sveshnikov system
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PP3/2N5/PPP1BPPP/R1BQK1NR b KQkq -
+Pirc defense
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Pirc defense
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PPP2/2N5/PPP3PP/R1BQKBNR b KQkq -
+Pirc: Austrian attack
+rnbqkb1r/ppp1pp1p/3p2p1/3nP3/3P4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Alekhine's defense: modern, fianchetto variation
+rnbqkb1r/ppp1pp1p/5np1/3P4/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+Scandinavian: Richter variation
+rnbqkb1r/ppp1pp1p/5np1/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+Gr\"unfeld: Stockholm variation
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP1B2/2N5/PP2PPPP/R2QKBNR b KQkq -
+Gr\"unfeld: 4.Bf4
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP2P1/2N5/PP2PP1P/R1BQKBNR b KQkq -
+Gr\"unfeld: Spike gambit
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/1QN5/PP2PPPP/R1B1KBNR b KQkq -
+Gr\"unfeld: Russian variation
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+Gr\"unfeld: Three knights variation
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Gr\"unfeld defense
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Neo-Gr\"unfeld defense
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/5P2/PP2P1PP/RNBQKBNR w KQkq -
+Neo-Gr\"unfeld defense
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/6P1/PP2PP1P/RNBQKBNR w KQkq -
+Neo-Gr\"unfeld (Kemeri) defense
+rnbqkb1r/ppp1pp1p/5np1/3p4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian: fianchetto without c4 *
+rnbqkb1r/ppp1pp1p/5np1/8/2pP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGA, Smyslov variation
+rnbqkb1r/ppp1pp1p/6p1/3n4/3P4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Gr\"unfeld: exchange variation
+rnbqkb1r/ppp1pp1p/6p1/8/8/2n3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: Anglo-Gr\"unfeld, Smyslov defense
+rnbqkb1r/ppp1pppp/1n1P4/8/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+Alekhine's defense: exchange variation
+rnbqkb1r/ppp1pppp/1n1p4/4P3/2PP1P2/8/PP4PP/RNBQKBNR b KQkq -
+Alekhine's defense: four pawns attack
+rnbqkb1r/ppp1pppp/1n1p4/4P3/3P4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Alekhine's defense: modern, Schmid variation
+rnbqkb1r/ppp1pppp/3p1n2/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Old Indian defense
+rnbqkb1r/ppp1pppp/3p1n2/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+R\'eti: old Indian attack *
+rnbqkb1r/ppp1pppp/3p1n2/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Pirc defense
+rnbqkb1r/ppp1pppp/3p4/3nP3/2BP4/8/PPP2PPP/RNBQK1NR b KQkq -
+Alekhine's defense: Balogh variation
+rnbqkb1r/ppp1pppp/3p4/3nP3/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+Alekhine's defense
+rnbqkb1r/ppp1pppp/3p4/3nP3/3P4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Alekhine's defense: modern variation
+rnbqkb1r/ppp1pppp/3p4/3nP3/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+Alekhine's defense
+rnbqkb1r/ppp1pppp/5n2/2P5/3p4/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+Hawk (Habichd) defense *
+rnbqkb1r/ppp1pppp/5n2/3P4/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+Scandinavian defense
+rnbqkb1r/ppp1pppp/5n2/3P4/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+Scandinavian defense
+rnbqkb1r/ppp1pppp/5n2/3p2B1/3P4/2N5/PPP1PPPP/R2QKBNR b KQkq -
+Richter-Veresov attack
+rnbqkb1r/ppp1pppp/5n2/3p2B1/3P4/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+Torre attack (Tartakower variation)
+rnbqkb1r/ppp1pppp/5n2/3p2B1/8/3P4/PPP1PPPP/RN1QKBNR b KQkq -
+Old Indian: Tartakower (Wade) variation *
+rnbqkb1r/ppp1pppp/5n2/3p4/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English: Anglo-Gr\"unfeld defense
+rnbqkb1r/ppp1pppp/5n2/3p4/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+Queen's pawn game, Krause variation *
+rnbqkb1r/ppp1pppp/5n2/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QGD: Marshall defense
+rnbqkb1r/ppp1pppp/5n2/3p4/3P1B2/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+Queen's bishop game
+rnbqkb1r/ppp1pppp/5n2/3p4/3P2P1/5P2/PPP1P2P/RNBQKBNR b KQkq -
+Gedult attack
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/2N5/PPP1PPPP/R1BQKBNR b KQkq -
+Queen's pawn game, Chigorin variation *
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/3BP3/PPP2PPP/RNBQK1NR b KQkq -
+Queen's pawn: stonewall attack
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+Queen's pawn game
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Queen's pawn game *
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's pawn game
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn game *
+rnbqkb1r/ppp1pppp/5n2/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+Blackmar-Diemer gambit
+rnbqkb1r/ppp1pppp/5n2/3p4/3PP3/5P2/PPP3PP/RNBQKBNR b KQkq -
+Blackmar-Diemer gambit
+rnbqkb1r/ppp1pppp/5n2/3p4/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Alekhine's defense: Scandinavian variation
+rnbqkb1r/ppp1pppp/5n2/3p4/8/1P3N2/P1PPPPPP/RNBQKB1R b KQkq -
+Queen's Indian defense *
+rnbqkb1r/ppp1pppp/5n2/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Queen's pawn game *
+rnbqkb1r/ppp1pppp/5n2/3p4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+King's Indian: East Indian defense *
+rnbqkb1r/ppp1pppp/5n2/3pN3/8/8/PPPPPPPP/RNBQKB1R b KQkq -
+D\"ory defense *
+rnbqkb1r/ppp1pppp/5n2/8/2Pp4/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+Old Benoni defense *
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+QGA, 4.Nc3
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+QGA, 4.e3
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Queen's gambit accepted
+rnbqkb1r/ppp1pppp/5n2/8/Q1pP4/5N2/PP2PPPP/RNB1KB1R b KQkq -
+QGA: Mannheim variation
+rnbqkb1r/ppp1pppp/8/3n4/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+Scandinavian: Marshall variation
+rnbqkb1r/ppp1pppp/8/3n4/8/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+English: Anglo-Gr\"unfeld defense
+rnbqkb1r/ppp1pppp/8/3np3/3P4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Alekhine's defense: modern, Larsen variation
+rnbqkb1r/ppp1pppp/8/8/1nPP4/8/PP3PPP/RNBQKBNR w KQkq -
+Scandinavian: Kiel variation
+rnbqkb1r/ppp2Npp/3p1n2/8/4P3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Petrov: Cochrane gambit
+rnbqkb1r/ppp2p1p/5n2/3p4/4PpNP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Berlin defense, Rivi\`ere variation
+rnbqkb1r/ppp2p1p/5n2/3pN3/3PPBpP/8/PPP3P1/RN1QKB1R b KQkq -
+KGA: Kieseritsky, Brentano defense
+rnbqkb1r/ppp2p1p/8/3pN3/3PnBpP/8/PPPN2P1/R2QKB1R b KQkq -
+KGA: Kieseritsky, Brentano defense, Caro variation
+rnbqkb1r/ppp2pp1/4pn1p/3p2B1/2PP4/5N2/PP2PPPP/RN1QKB1R w KQkq -
+QGD: Capablanca-Duras variation
+rnbqkb1r/ppp2pp1/5n1p/3p2B1/3Np3/3P4/PPP1PPPP/RN1QKB1R w KQkq -
+Alekhine's defense: modern, Panov variation *
+rnbqkb1r/ppp2ppp/1n6/1B2p3/8/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Scotch: Romanishin variation *
+rnbqkb1r/ppp2ppp/1n6/4p3/2B5/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Scotch: Potter variation *
+rnbqkb1r/ppp2ppp/3p1n2/4N3/8/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: French attack *
+rnbqkb1r/ppp2ppp/3p1n2/4P3/4P3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: Nimzovich variation
+rnbqkb1r/ppp2ppp/3p1n2/4p1N1/3PP3/8/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: Nimzovich, Locock variation
+rnbqkb1r/ppp2ppp/3p1n2/4p3/2BPP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+Philidor: Nimzovich, Klein variation
+rnbqkb1r/ppp2ppp/3p1n2/4p3/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+Old Indian: Ukrainian variation, 4.Nf3
+rnbqkb1r/ppp2ppp/3p1n2/4p3/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Old Indian: Ukrainian variation
+rnbqkb1r/ppp2ppp/3p1n2/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Nimzovich (Jaenisch) variation
+rnbqkb1r/ppp2ppp/3p1n2/4p3/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+R\'eti: Lisitsin gambit deferred *
+rnbqkb1r/ppp2ppp/3p1n2/8/2N1P3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Petrov: Paulsen attack
+rnbqkb1r/ppp2ppp/3p1n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: exchange variation
+rnbqkb1r/ppp2ppp/3p1n2/8/3P4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: classical attack, close variation
+rnbqkb1r/ppp2ppp/3p4/3QP3/4n3/5N2/PPP2PPP/RNB1KB1R b KQkq -
+Philidor: Nimzovich, Rellstab variation
+rnbqkb1r/ppp2ppp/3p4/4P3/2P1P1n1/8/PP3PPP/RNBQKBNR w KQkq -
+Budapest: Alekhine variation, Balogh gambit
+rnbqkb1r/ppp2ppp/3p4/4P3/4n3/5N2/PPPN1PPP/R1BQKB1R b KQkq -
+Philidor: Nimzovich, Sokolsky variation
+rnbqkb1r/ppp2ppp/3p4/8/2P1n3/5N2/PP1P1PPP/RNBQKB1R b KQkq -
+Petrov: Kaufmann attack
+rnbqkb1r/ppp2ppp/3p4/8/3Pn3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Petrov: classical attack
+rnbqkb1r/ppp2ppp/3p4/8/4n3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Petrov: Nimzovich attack
+rnbqkb1r/ppp2ppp/3p4/8/4n3/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+Petrov: French attack
+rnbqkb1r/ppp2ppp/3p4/8/4n3/5N2/PPPPQPPP/RNB1KB1R b KQkq -
+Petrov: Cozio (Lasker) attack
+rnbqkb1r/ppp2ppp/3pp3/2PnP3/2B5/2N5/PP1P1PPP/R1BQK1NR w KQkq -
+Alekhine's defense: two pawns' attack, Mikenas variation
+rnbqkb1r/ppp2ppp/4n3/3pP3/8/3P1Q2/PPP3PP/RNB1KBNR w KQkq -
+Latvian: Nimzovich variation *
+rnbqkb1r/ppp2ppp/4pn2/3P4/2P5/8/PP1P1PPP/RNBQKBNR w KQkq -
+Scandinavian: Icelandic gambit
+rnbqkb1r/ppp2ppp/4pn2/3P4/3P4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+QGD: exchange variation
+rnbqkb1r/ppp2ppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+QGD: 4.Bg5
+rnbqkb1r/ppp2ppp/4pn2/3p2B1/2PP4/5N2/PP2PPPP/RN1QKB1R b KQkq -
+QGD
+rnbqkb1r/ppp2ppp/4pn2/3p4/2P5/5NP1/PP1PPP1P/RNBQKB1R w KQkq -
+English: Neo-Catalan
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP1B2/2N5/PP2PPPP/R2QKBNR b KQkq -
+QGD: Harrwitz attack
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+QGD: 4.Nf3
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: 3...Nf6
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/6P1/PP2PPBP/RNBQK1NR b KQkq -
+Catalan: closed
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/3BPN2/PPP2PPP/RNBQK2R b KQkq -
+Queen's pawn game
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+Queen's pawn game *
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+Queen's pawn game
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's pawn game *
+rnbqkb1r/ppp2ppp/4pn2/3p4/3PP3/2N1B3/PPP2PPP/R2QKBNR b KQkq -
+French: Henneberger variation
+rnbqkb1r/ppp2ppp/4pn2/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+French defense
+rnbqkb1r/ppp2ppp/4pn2/3p4/3PP3/2NB4/PPP2PPP/R1BQK1NR b KQkq -
+French: Swiss variation
+rnbqkb1r/ppp2ppp/4pn2/3p4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+French: Tarrasch, closed variation
+rnbqkb1r/ppp2ppp/4pn2/3p4/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+Queen's pawn: Yusupov-Rubinstein system *
+rnbqkb1r/ppp2ppp/4pn2/3pP3/2P5/2N5/PP1P1PPP/R1BQKBNR b KQkq -
+English: Mikenas-Carls, Flohr variation
+rnbqkb1r/ppp2ppp/4pn2/3pP3/3P4/2N5/PPP2PPP/R1BQKBNR b KQkq -
+French: Steinitz variation
+rnbqkb1r/ppp2ppp/4pn2/6B1/3Pp3/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: Burn variation
+rnbqkb1r/ppp2ppp/4pn2/8/2p5/5NP1/PP1PPPBP/RNBQK2R w KQkq -
+English: Neo-Catalan accepted
+rnbqkb1r/ppp2ppp/4pn2/8/2pP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGA: 4...e6
+rnbqkb1r/ppp2ppp/4pn2/8/2pP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+Catalan: open, 5.Nf3
+rnbqkb1r/ppp2ppp/4pn2/8/3P4/2N2N2/PPP3PP/R1BQKB1R w KQkq -
+Blackmar-Diemer: Euwe defense
+rnbqkb1r/ppp2ppp/4pn2/8/Q1pP4/6P1/PP2PPBP/RNB1K1NR b KQkq -
+Catalan: open, 5.Qa4
+rnbqkb1r/ppp2ppp/5n2/3B4/4Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Morphy variation
+rnbqkb1r/ppp2ppp/5n2/3Np3/4P3/8/PPPP1PPP/R1BQKBNR b KQkq -
+Scotch: Lolli variation *
+rnbqkb1r/ppp2ppp/5n2/3P4/4PP2/8/PPP3PP/RNBQKBNR b KQkq -
+KGD: Falkbeer, 5.de
+rnbqkb1r/ppp2ppp/5n2/3P4/4pP2/2N5/PPPPQ1PP/R1B1KBNR b KQkq -
+KGD: Falkbeer, Rubinstein variation
+rnbqkb1r/ppp2ppp/5n2/3P4/4pP2/3P4/PPP1Q1PP/RNB1KBNR b KQkq -
+KGD: Falkbeer, R\'eti variation
+rnbqkb1r/ppp2ppp/5n2/3P4/4pP2/3P4/PPPN2PP/R1BQKBNR b KQkq -
+KGD: Falkbeer, Keres variation
+rnbqkb1r/ppp2ppp/5n2/3P4/5p2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Abbazia defense, modern variation
+rnbqkb1r/ppp2ppp/5n2/3Pp3/8/3P4/PP2PPPP/RNBQKBNR b KQkq -
+Sicilian *
+rnbqkb1r/ppp2ppp/5n2/3Pp3/8/3P4/PPP2PPP/RNBQKBNR b KQkq -
+Philidor: exchange variation *
+rnbqkb1r/ppp2ppp/5n2/3Pp3/8/4P3/PP1P1PPP/RNBQKBNR b KQkq -
+Sicilian defense *
+rnbqkb1r/ppp2ppp/5n2/3p2B1/3Np3/3P4/PPP1PPPP/RN1QKB1R b KQkq -
+Alekhine's defense: modern variation, 4...Bg4 *
+rnbqkb1r/ppp2ppp/5n2/3p2B1/3P4/2N5/PP2PPPP/R2QKBNR b KQkq -
+QGD: exchange, positional line
+rnbqkb1r/ppp2ppp/5n2/3p2B1/3P4/2N5/PPP2PPP/R2QKBNR b KQkq -
+French: exchange, Svenonius variation
+rnbqkb1r/ppp2ppp/5n2/3p4/2PPp3/4P3/PP3PPP/RNBQKBNR w KQkq -
+French: advance, Nimzovich system *
+rnbqkb1r/ppp2ppp/5n2/3p4/3NP3/8/PPP1PPPP/RNBQKB1R b KQkq -
+Alekhine's defense: modern, Larsen variation *
+rnbqkb1r/ppp2ppp/5n2/3p4/3Np3/3P2P1/PPP1PP1P/RNBQKB1R b KQkq -
+Alekhine's defense: modern, fianchetto variation *
+rnbqkb1r/ppp2ppp/5n2/3p4/3Np3/3P4/PPP1PPPP/RNBQKB1R w KQkq -
+Alekhine's defense: modern variation *
+rnbqkb1r/ppp2ppp/5n2/3p4/4p3/1N1P4/PPP1PPPP/RNBQKB1R b KQkq -
+Alekhine's defense: modern, Schmid variation *
+rnbqkb1r/ppp2ppp/5n2/3p4/8/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+Petrov: classical attack, close variation *
+rnbqkb1r/ppp2ppp/5n2/3pN3/4P3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Petrov: modern attack, Symmetrical variation *
+rnbqkb1r/ppp2ppp/5n2/3pN3/8/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: classical attack *
+rnbqkb1r/ppp2ppp/5n2/3pp3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+English: Bremen, reverse dragon
+rnbqkb1r/ppp2ppp/5n2/3pp3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Sicilian defense *
+rnbqkb1r/ppp2ppp/5n2/3pp3/2P5/3P1N2/PP2PPPP/RNBQKB1R b KQkq -
+Sicilian: Cortlever (Alatortsev) variation *
+rnbqkb1r/ppp2ppp/5n2/3pp3/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+Sicilian: Marshall variation *
+rnbqkb1r/ppp2ppp/5n2/3pp3/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Blackmar-Diemer: Lemberg counter-gambit
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Scotch opening *
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: Nimzovich (Jaenisch) variation *
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/3P4/PPP2PPP/RNBQKBNR w KQkq -
+Philidor's defense *
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/3P4/PPPN1PPP/R1BQKBNR b KQkq -
+Philidor: Hanham variation *
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov: modern (Steinitz) attack *
+rnbqkb1r/ppp2ppp/5n2/3pp3/4PP2/2N5/PPPP2PP/R1BQKBNR w KQkq -
+Vienna gambit
+rnbqkb1r/ppp2ppp/5n2/3pp3/4PP2/2NP4/PPP3PP/R1BQKBNR b KQkq -
+Vienna gambit, Steinitz variation
+rnbqkb1r/ppp2ppp/5n2/3pp3/4PP2/3P4/PPP3PP/RNBQKBNR b KQkq -
+Philidor: Philidor counter-gambit *
+rnbqkb1r/ppp2ppp/5n2/4p2Q/8/2N5/PPPP1PPP/R1B1KBNR w KQkq -
+Scotch: Fraser attack *
+rnbqkb1r/ppp2ppp/5n2/4p3/4p3/3P1N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Nimzovich variation *
+rnbqkb1r/ppp2ppp/8/3P4/4nP2/8/PPP1Q1PP/RNB1KBNR b KQkq -
+KGD: Falkbeer, Charousek gambit
+rnbqkb1r/ppp2ppp/8/3n4/3p4/8/PPP2PPP/RNBQKBNR w KQkq -
+Philidor: Paulsen attack *
+rnbqkb1r/ppp2ppp/8/3np2Q/8/2N5/PPPP1PPP/R1B1KBNR b KQkq -
+Scotch: Pulling counter-attack *
+rnbqkb1r/ppp2ppp/8/3np3/2B5/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Scotch game *
+rnbqkb1r/ppp2ppp/8/3np3/3P4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+Sicilian: Nimzovich variation *
+rnbqkb1r/ppp2ppp/8/3np3/4P3/2N5/PP1P1PPP/R1BQKBNR b KQkq -
+Sicilian: Labourdonnais-L\"owenthal variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/2N1P3/PP1P1PPP/R1BQKBNR b KQkq -
+Sicilian defense *
+rnbqkb1r/ppp2ppp/8/3np3/8/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+Sicilian defense *
+rnbqkb1r/ppp2ppp/8/3np3/8/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Scotch: Schmidt variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Scotch game *
+rnbqkb1r/ppp2ppp/8/3np3/8/2N5/PPQPPPPP/R1B1KBNR b KQkq -
+Sicilian: Flohr variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: exchange variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/3P2P1/PPP2P1P/RNBQKBNR b KQkq -
+Philidor: Larsen variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/3P4/PP2PPPP/RNBQKBNR w KQkq -
+Sicilian *
+rnbqkb1r/ppp2ppp/8/3np3/8/3P4/PPP2PPP/RNBQKBNR w KQkq -
+Philidor: exchange variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+Sicilian: Anderssen variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/P3P3/1P1P1PPP/RNBQKBNR b KQkq -
+Sicilian: Kan variation *
+rnbqkb1r/ppp2ppp/8/3pP3/4n3/2N2Q2/PPPP2PP/R1B1KBNR b KQkq -
+Vienna gambit: Paulsen attack
+rnbqkb1r/ppp2ppp/8/3pP3/4n3/2NP4/PPP3PP/R1BQKBNR b KQkq -
+Vienna gambit
+rnbqkb1r/ppp2ppp/8/3pp3/2B1n3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Boden-Kieseritsky gambit: Lichtenhein defense
+rnbqkb1r/ppp2ppp/8/3pp3/4N3/8/PPPP1PPP/R1BQKBNR w KQkq -
+Irish (Chicago) gambit *
+rnbqkb1r/ppp2ppp/8/3pp3/4P1n1/3P1N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Nimzovich, Locock variation *
+rnbqkb1r/ppp2ppp/8/4P3/3P2n1/4p3/PPP3PP/RNBQKBNR w KQkq -
+Philidor: Philidor counter-gambit, del Rio attack *
+rnbqkb1r/ppp2ppp/8/4p2Q/1n6/2N5/PPPP1PPP/R1B1KBNR w KQkq -
+Scotch: Horwitz attack *
+rnbqkb1r/ppp2ppp/8/4p3/1n2P3/2NP4/PP3PPP/R1BQKBNR b KQkq -
+Sicilian: Labourdonnais-L\"owenthal (Kalashnikov) variation *
+rnbqkb1r/ppp2ppp/8/4p3/1n6/2N1P3/PP1P1PPP/R1BQKBNR w KQkq -
+Sicilian, Sz\'en (`anti-Taimanov') variation *
+rnbqkb1r/ppp2ppp/8/4p3/8/2n3P1/PP1PPP1P/R1BQKBNR w KQkq -
+Sicilian: accelerated fianchetto, exchange variation *
+rnbqkb1r/ppp2ppp/8/8/4p3/2P2N2/P1PP1PPP/R1BQKB1R w KQkq -
+Scotch: Mieses variation *
+rnbqkb1r/ppp3p1/8/3ppPPp/8/7P/PPPP1K2/RNBQ1BNR w kq -
+KGA: Allgaier, Thorold variation *
+rnbqkb1r/ppp3pN/3p3n/5p2/2BpP3/8/PPP2PPP/RNBQK2R b KQkq -
+Philidor: L\'opez counter-gambit, Jaenisch variation
+rnbqkb1r/ppp3pp/5n2/3ppP2/6P1/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: Rosentreter gambit *
+rnbqkb1r/ppp3pp/5p2/3np3/8/3P1N2/PP2PPPP/RNBQKB1R w KQkq -
+Sicilian: Prins (Moscow) variation *
+rnbqkb1r/ppp3pp/8/3pPp2/3Pn3/2N2Q2/PPP3PP/R1B1KBNR b KQkq -
+Vienna gambit: Heyde variation
+rnbqkb1r/ppp3pp/8/3pPp2/4n3/2N2Q2/PPPP2PP/R1B1KBNR w KQkq f6
+Vienna gambit: Bardeleben variation
+rnbqkb1r/ppp3pp/8/3ppPP1/4n3/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: S\o rensen gambit *
+rnbqkb1r/pppn1ppp/4p3/3pP3/3P2Q1/2N5/PPP2PPP/R1B1KBNR b KQkq -
+French: Steinitz, Gledhill attack
+rnbqkb1r/pppnpppp/4P3/3p4/8/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Alekhine's defense: Spielmann variation
+rnbqkb1r/pppp1p1p/5n2/4N3/2B1PppP/8/PPPP2P1/RNBQK2R b KQkq -
+KGA: Kieseritsky, Berlin defense, 6.Bc4
+rnbqkb1r/pppp1p1p/5n2/4N3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Berlin defense
+rnbqkb1r/pppp1p1p/5n2/6N1/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Allgaier, Schlechter defense
+rnbqkb1r/pppp1p1p/5np1/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+English: Bremen system with ...g6
+rnbqkb1r/pppp1p1p/5np1/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Konstantinopolsky opening *
+rnbqkb1r/pppp1ppp/2n5/8/2P1PP2/8/PP4PP/RNBQKBNR w KQkq -
+Budapest: Alekhine, Abonyi variation
+rnbqkb1r/pppp1ppp/4p3/8/2PPn3/5N2/PP2PPPP/RNBQKB1R w KQkq -
+D\"ory defense
+rnbqkb1r/pppp1ppp/4pn2/6B1/2PP4/8/PP2PPPP/RN1QKBNR b KQkq -
+Neo-Indian (Seirawan) attack
+rnbqkb1r/pppp1ppp/4pn2/6B1/3P4/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+Queen's pawn: Torre attack
+rnbqkb1r/pppp1ppp/4pn2/8/2P1P3/2N5/PP1P1PPP/R1BQKBNR b KQkq -
+English: Mikenas-Carls variation
+rnbqkb1r/pppp1ppp/4pn2/8/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English opening
+rnbqkb1r/pppp1ppp/4pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+Queen's pawn game
+rnbqkb1r/pppp1ppp/4pn2/8/2PP4/6P1/PP2PP1P/RNBQKBNR b KQkq -
+Catalan opening
+rnbqkb1r/pppp1ppp/4pn2/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Queen's pawn game
+rnbqkb1r/pppp1ppp/4pn2/8/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+Queen's pawn: Yusupov-Rubinstein system
+rnbqkb1r/pppp1ppp/5n2/4p1B1/8/3P4/PPP1PPPP/RN1QKBNR b KQkq -
+R\'eti: Wade defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Vienna game
+rnbqkb1r/pppp1ppp/5n2/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Petrov: Italian variation
+rnbqkb1r/pppp1ppp/5n2/4p3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Berlin defense
+rnbqkb1r/pppp1ppp/5n2/4p3/2B1PP2/8/PPPP2PP/RNBQK1NR b KQkq -
+Bishop's opening: Greco gambit
+rnbqkb1r/pppp1ppp/5n2/4p3/2BPP3/8/PPP2PPP/RNBQK1NR b KQkq -
+Bishop's opening: Ponziani gambit
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/1P6/P2PPPPP/RNBQKBNR b KQkq -
+Sicilian: Katalimov variation *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+English: Carls' Bremen system
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+Sicilian defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English opening
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/3P4/PP2PPPP/RNBQKBNR b KQkq -
+Sicilian *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/4P3/PP1P1PPP/RNBQKBNR b KQkq -
+Sicilian defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+Sicilian: Nimzovich-Rubinstein variation *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/6P1/PP1PPP1P/RNBQKBNR b KQkq -
+Sicilian: Hungarian variation *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/8/PPQPPPPP/RNB1KBNR b KQkq -
+Sicilian: Quinteros variation *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/P7/1P1PPPPP/RNBQKBNR b KQkq -
+Sicilian: O'Kelly variation *
+rnbqkb1r/pppp1ppp/5n2/4p3/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Budapest defense declined
+rnbqkb1r/pppp1ppp/5n2/4p3/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Tennison (Lemberg, Zukertort) gambit *
+rnbqkb1r/pppp1ppp/5n2/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Petrov: modern (Steinitz) attack
+rnbqkb1r/pppp1ppp/5n2/4p3/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+QP counter-gambit (elephant gambit) *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Petrov three knights game
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+Vienna: Paulsen-Mieses variation
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+King's pawn game *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna: Falkbeer variation
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+Philidor's defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+Petrov's defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov's defense
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5P2/PPPP2PP/RNBQKBNR b KQkq -
+Damiano's defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5Q2/PPPP1PPP/RNB1KBNR b KQkq -
+Greco defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+King's knight opening *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/8/PPPPQPPP/RNB1KBNR b KQkq -
+Gunderam defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/P1N5/1PPP1PPP/R1BQKBNR b KQkq -
+Vienna: Mengarini variation
+rnbqkb1r/pppp1ppp/5n2/4p3/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Vienna gambit
+rnbqkb1r/pppp1ppp/5n2/4p3/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+Latvian counter-gambit *
+rnbqkb1r/pppp1ppp/5n2/4p3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: 2...Nf6
+rnbqkb1r/pppp1ppp/5n2/4p3/5P2/2N5/PPPPP1PP/R1BQKBNR b KQkq -
+KP: Colorado counter *
+rnbqkb1r/pppp1ppp/5n2/4p3/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+R\'eti: Pirc-Lisitsin gambit *
+rnbqkb1r/pppp1ppp/5n2/4p3/8/2N5/PPPPPPPP/R1BQKBNR w KQkq -
+KP: Nimzovich defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/Q1P5/8/PP1PPPPP/RNB1KBNR b KQkq -
+Sicilian: Stiletto (Althouse) variation *
+rnbqkb1r/pppp1ppp/5n2/8/2B1Pp2/2N5/PPPP2PP/R1BQK1NR b KQkq -
+KGA: bishop's gambit, Bogolyubov variation
+rnbqkb1r/pppp1ppp/5n2/8/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Cozio (Morphy) defense
+rnbqkb1r/pppp1ppp/5n2/8/2BpP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+Bishop's opening/Petrov: Urusov gambit
+rnbqkb1r/pppp1ppp/5n2/8/3pP3/3B4/PPP2PPP/RNBQK1NR b KQkq -
+QP counter-gambit: Maroczy gambit *
+rnbqkb1r/pppp1ppp/5n2/8/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Schallop defense
+rnbqkb1r/pppp1ppp/8/2n1p3/8/3P1N2/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: Paulsen attack *
+rnbqkb1r/pppp1ppp/8/4N3/4n3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Petrov: Damiano variation *
+rnbqkb1r/pppp1ppp/8/4N3/4n3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov: Damiano variation
+rnbqkb1r/pppp1ppp/8/4P3/2P1P1n1/8/PP3PPP/RNBQKBNR b KQkq -
+Budapest: Alekhine variation
+rnbqkb1r/pppp1ppp/8/4P3/2P1n3/8/PP2PPPP/RNBQKBNR w KQkq -
+Budapest: Fajarowicz variation
+rnbqkb1r/pppp1ppp/8/4P3/2P1n3/8/PPQ1PPPP/RNB1KBNR b KQkq -
+Budapest: Fajarowicz, Steiner variation
+rnbqkb1r/pppp1ppp/8/4P3/2P2Bn1/8/PP2PPPP/RN1QKBNR b KQkq -
+Budapest: Rubinstein variation
+rnbqkb1r/pppp1ppp/8/4P3/2P3n1/5N2/PP2PPPP/RNBQKB1R b KQkq -
+Budapest: Adler variation
+rnbqkb1r/pppp1ppp/8/4P3/2P3n1/8/PP2PPPP/RNBQKBNR w KQkq -
+Budapest defense
+rnbqkb1r/pppp1ppp/8/4P3/3Qn3/5N2/PPP2PPP/RNB1KB1R b KQkq -
+Petrov: modern attack, main line
+rnbqkb1r/pppp1ppp/8/4P3/3pn3/5N2/PPP1QPPP/RNB1KB1R b KQkq -
+Petrov: modern attack, Steinitz variation
+rnbqkb1r/pppp1ppp/8/4p3/2B1n3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Boden-Kieseritsky gambit
+rnbqkb1r/pppp1ppp/8/4p3/2B1n3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Vienna game
+rnbqkb1r/pppp1ppp/8/4p3/3Pn3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: modern attack, Symmetrical variation
+rnbqkb1r/pppp1ppp/8/4p3/4nP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Latvian: Fraser defense *
+rnbqkb1r/pppp1ppp/8/4p3/8/3P1N2/PPP2nPP/RNBQKB1R w KQkq -
+Petrov: Cochrane gambit *
+rnbqkb1r/pppp2p1/5n2/4pP1p/6P1/8/PPPP1P1P/RNBQKBNR w KQkq -
+King's knight's gambit *
+rnbqkb1r/pppp2p1/8/4pPPp/3Pn3/8/PPP2P1P/RNBQKBNR b KQkq -
+KGA: Kieseritsky, Brentano (Campbell) defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n2P/8/PPPP1P2/RNBQKBNR b KQkq -
+KGA: Kieseritsky, long whip (Stockwhip, classical) defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n3/2N5/PPPP1P1P/R1BQKBNR b KQkq -
+KGA: Kieseritsky, Neumann defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n3/3P4/PPP2P1P/RNBQKBNR b KQkq -
+KGA: Kieseritsky, Kolisch defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n3/5N2/PPPP1P1P/RNBQKB1R b KQkq -
+KGA: Kieseritsky, Berlin defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n3/8/PPPP1PBP/RNBQK1NR b KQkq -
+KGA: Kieseritsky, Paulsen defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n3/8/PPPPBP1P/RNBQK1NR b KQkq -
+KGA: Kieseritsky, Polerio defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n3/8/PPPPQP1P/RNB1KBNR b KQkq -
+KGA: Kieseritsky, Salvio (Rosenthal) defense *
+rnbqkb1r/pppp2p1/8/4pPPp/6n1/5N2/PPPP1P1P/RNBQKB1R b KQkq -
+KGA: Allgaier, Schlechter defense *
+rnbqkb1r/pppp2p1/8/4pPPp/6n1/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: Allgaier gambit *
+rnbqkb1r/pppp2p1/8/4pPnp/3P4/5N2/PPP2P1P/RNBQKB1R b KQkq -
+KGA: Kieseritsky, Berlin defense, Rivi\`ere variation *
+rnbqkb1r/pppp2pp/4pn2/5p2/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+Bird's opening: Lasker variation *
+rnbqkb1r/pppp2pp/4pn2/5p2/2PP4/6P1/PP2PPBP/RNBQK1NR b KQkq -
+Dutch defense
+rnbqkb1r/pppp2pp/4pn2/5p2/3P4/6PN/PPP1PPBP/RNBQK2R b KQkq -
+Dutch defense, Blackburne variation
+rnbqkb1r/pppp2pp/5n2/4N3/2B1p3/8/PPPP1PPP/RNBQK2R w KQkq -
+Latvian: corkscrew counter-gambit
+rnbqkb1r/pppp2pp/5n2/4p3/2B1p3/3P4/PPP2PPP/RNBQK1NR w KQkq -
+KGD: classical, Soldatenkov variation *
+rnbqkb1r/pppp2pp/5n2/4pP2/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+KGA: Abbazia defense (classical defense, modern defense[!]) *
+rnbqkb1r/pppp2pp/5n2/4pP2/5P2/8/PPPP2PP/RNBQKBNR b KQkq -
+KGA: Gianutio counter-gambit *
+rnbqkb1r/pppp2pp/5n2/4pP2/8/3P4/PPP2PPP/RNBQKBNR b KQkq -
+KGA: Fischer defense *
+rnbqkb1r/pppp2pp/5n2/4pP2/8/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+KGA: Schallop defense *
+rnbqkb1r/pppp2pp/5n2/4pP2/8/7P/PPPP1PP1/RNBQKBNR b KQkq -
+KGA: Becker defense *
+rnbqkb1r/pppp2pp/5n2/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+King's knight's gambit *
+rnbqkb1r/pppp2pp/5n2/4pP2/8/8/PPPPBPPP/RNBQK1NR b KQkq -
+KGA: Cunningham defense *
+rnbqkb1r/pppp2pp/5n2/4pP2/8/8/PPPPNPPP/RNBQKB1R b KQkq -
+KGA: Bonsch-Osmolovsky variation *
+rnbqkb1r/pppp2pp/5n2/4pp2/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+KGD: Falkbeer, Tartakower variation *
+rnbqkb1r/pppp2pp/5n2/5P2/3p4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+KGA: Abbazia defense, modern variation *
+rnbqkb1r/ppppnppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: Keres variation (2.Ne2) *
+rnbqkb1r/ppppnppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Alapin's opening *
+rnbqkb1r/ppppnppp/8/8/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Steinitz defense
+rnbqkb1r/ppppnppp/8/8/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Bonsch-Osmolovsky variation
+rnbqkb1r/ppppp1pp/5n2/5p2/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+Dutch with c4 & Nc3
+rnbqkb1r/ppppp1pp/5n2/5p2/2PP4/6P1/PP2PP1P/RNBQKBNR b KQkq -
+Dutch with c4 & g3
+rnbqkb1r/ppppp1pp/5n2/5p2/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Dutch defense
+rnbqkb1r/ppppp1pp/5n2/5p2/3P2P1/2N5/PPP1PP1P/R1BQKBNR b KQkq -
+Dutch, Spielmann gambit
+rnbqkb1r/ppppp1pp/5n2/5p2/4P3/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+R\'eti: Lisitsin gambit deferred
+rnbqkb1r/ppppp1pp/5n2/6B1/3Pp3/2N5/PPP2PPP/R2QKBNR b KQkq -
+Dutch: Staunton gambit, Staunton's line
+rnbqkb1r/ppppp1pp/5n2/8/3Pp1P1/2N5/PPP2P1P/R1BQKBNR b KQkq -
+Dutch: Staunton gambit, Tartakower variation
+rnbqkb1r/ppppp1pp/5n2/8/4pPP1/2N5/PPPP3P/R1BQKBNR b KQkq -
+Bird's opening, Swiss gambit
+rnbqkb1r/ppppp1pp/5n2/8/6P1/3B4/PPP2P1P/RNBQK1NR b KQkq -
+Bird: From gambit, Lasker variation *
+rnbqkb1r/ppppp2p/5np1/5p2/2PP4/6P1/PP2PP1P/RNBQKBNR w KQkq -
+Dutch: Leningrad variation
+rnbqkb1r/ppppp2p/5np1/5p2/3P4/6P1/PPP1PPBP/RNBQK1NR w KQkq -
+Dutch defense
+rnbqkb1r/ppppp2p/5np1/6B1/3Pp2P/2N5/PPP2PP1/R2QKBNR b KQkq -
+Dutch: Staunton gambit, Alekhine variation
+rnbqkb1r/ppppp2p/5np1/6B1/3Pp3/2N2P2/PPP3PP/R2QKBNR b KQkq -
+Dutch: Staunton gambit, Lasker variation
+rnbqkb1r/ppppp2p/5ppn/8/2PPP3/8/PP3PPP/RNBQKBNR w KQkq -
+Hippopotamus defense
+rnbqkb1r/ppppp2p/6pn/5p2/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Dutch defense: Bladel variation
+rnbqkb1r/pppppp1p/5np1/3P4/2P5/8/PP2PPPP/RNBQKBNR b KQkq -
+King's Indian: Anti-Gr\"unfeld
+rnbqkb1r/pppppp1p/5np1/6B1/3P4/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+King's Indian: Torre attack
+rnbqkb1r/pppppp1p/5np1/8/1P6/5N2/P1PPPPPP/RNBQKB1R b KQkq -
+R\'eti: King's Indian attack, Spassky's variation *
+rnbqkb1r/pppppp1p/5np1/8/1P6/5NP1/P1PPPP1P/RNBQKB1R b KQkq -
+R\'eti: King's Indian attack, R\'eti-Smyslov variation
+rnbqkb1r/pppppp1p/5np1/8/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+King's Indian defense, 3.Nc3
+rnbqkb1r/pppppp1p/5np1/8/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+King's Indian, 3.Nf3
+rnbqkb1r/pppppp1p/5np1/8/2PP4/6P1/PP2PP1P/RNBQKBNR b KQkq -
+King's Indian: 3.g3
+rnbqkb1r/pppppp1p/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+R\'eti: King's Indian attack (with ...c5) *
+rnbqkb1r/pppppp1p/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+King's Indian defense
+rnbqkb1r/pppppp1p/5np1/8/2PP4/8/PPQ1PPPP/RNB1KBNR b KQkq -
+Queen's pawn: Mengarini attack
+rnbqkb1r/pppppp1p/5np1/8/3P1B2/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+King's Indian: London system
+rnbqkb1r/pppppp1p/5np1/8/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+King's Indian: East Indian defense
+rnbqkb1r/pppppp1p/5np1/8/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+King's Indian: fianchetto without c4
+rnbqkb1r/pppppp1p/5np1/8/3P4/6P1/PPP1PP1P/RNBQKBNR b KQkq -
+R\'eti: King's Indian attack *
+rnbqkb1r/pppppp1p/5np1/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+R\'eti: King's Indian attack (Barcza system) *
+rnbqkb1r/pppppp1p/5np1/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Benko's opening: reversed Alekhine *
+rnbqkb1r/pppppp1p/5np1/8/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+R\'eti: King's Indian attack *
+rnbqkb1r/pppppp1p/5np1/8/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+R\'eti: King's Indian attack
+rnbqkb1r/ppppppnp/6p1/4P3/3P2P1/8/PPP2P1P/RNBQKBNR w KQkq -
+Norwegian defense
+rnbqkb1r/pppppppp/1n6/2P1P3/8/8/PP1P1PPP/RNBQKBNR b KQkq -
+Alekhine's defense: two pawns' (Lasker's) attack
+rnbqkb1r/pppppppp/1n6/4P3/2P5/1P6/P2P1PPP/RNBQKBNR b KQkq -
+Alekhine's defense: Steiner variation
+rnbqkb1r/pppppppp/5n2/6B1/3P4/8/PPP1PPPP/RN1QKBNR b KQkq -
+Trompovsky attack (Ruth, Opo\v censk\'y opening)
+rnbqkb1r/pppppppp/5n2/8/1PP5/8/P2PPPPP/RNBQKBNR b KQkq -
+English orang-utan
+rnbqkb1r/pppppppp/5n2/8/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+Alekhine's defense: Krejcik variation
+rnbqkb1r/pppppppp/5n2/8/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+English opening
+rnbqkb1r/pppppppp/5n2/8/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+English opening
+rnbqkb1r/pppppppp/5n2/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English, 1...Nf6 (Anglo-Indian defense)
+rnbqkb1r/pppppppp/5n2/8/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+Queen's pawn game
+rnbqkb1r/pppppppp/5n2/8/3P1B2/8/PPP1PPPP/RN1QKBNR b KQkq -
+Queen's pawn: London system
+rnbqkb1r/pppppppp/5n2/8/3P1P2/8/PPP1P1PP/RNBQKBNR b KQkq -
+Canard opening
+rnbqkb1r/pppppppp/5n2/8/3P2P1/8/PPP1PP1P/RNBQKBNR b KQkq -
+Queen's pawn: Bronstein gambit
+rnbqkb1r/pppppppp/5n2/8/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Queen's pawn game
+rnbqkb1r/pppppppp/5n2/8/3P4/5P2/PPP1P1PP/RNBQKBNR b KQkq -
+Paleface attack
+rnbqkb1r/pppppppp/5n2/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+R\'eti opening *
+rnbqkb1r/pppppppp/5n2/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn game
+rnbqkb1r/pppppppp/5n2/8/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+Alekhine's defense: Mar\'oczy variation
+rnbqkb1r/pppppppp/5n2/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Alekhine's defense
+rnbqkb1r/pppppppp/5n2/8/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+R\'eti v Dutch *
+rnbqkb1r/pppppppp/5n2/8/6P1/8/PPPPPP1P/RNBQKBNR b KQkq -
+R\'eti: Herrstr\"om gambit *
+rnbqkb1r/pppppppp/5n2/8/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: Indian variation
+rnbqkb1r/pppppppp/5n2/8/8/3P4/PPP1PPPP/RNBQKBNR b KQkq -
+R\'eti opening *
+rnbqkb1r/pppppppp/5n2/8/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+R\'eti opening *
+rnbqkb1r/pppppppp/5n2/8/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+R\'eti opening
+rnbqkb1r/pppppppp/5n2/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+R\'eti opening *
+rnbqkb1r/pppppppp/7n/8/1P6/8/P1PPPPPP/RNBQKBNR w KQkq -
+Polish: T\"ubingen variation
+rnbqkb1r/pppppppp/7n/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Amar (Paris) opening *
+rnbqkb1r/pppppppp/8/3nP3/2P5/8/PP1P1PPP/RNBQKBNR b KQkq -
+Alekhine's defense
+rnbqkb1r/pppppppp/8/3nP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+Alekhine's defense
+rnbqkb1r/pppppppp/8/3nP3/8/1P6/P1PP1PPP/RNBQKBNR b KQkq -
+Alekhine's defense: Welling variation
+rnbqkb1r/pppppppp/8/3nP3/8/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Alekhine's defense: S\"amisch attack
+rnbqkb1r/pppppppp/8/3nP3/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+Alekhine's defense
+rnbqkb1r/pppppppp/8/4P3/4n3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Alekhine's defense: Mokele Mbembe (B\"ucker) variation
+rnbqkb1r/pppppppp/8/8/3Pn3/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+D\"ory defense
+rnbqkbnr/1p1p1p1p/p3p1p1/8/3NP3/3B4/PPP2PPP/RNBQK2R w KQkq -
+Sicilian: Kan, Swiss cheese variation
+rnbqkbnr/1p1p1ppp/p3p3/8/2PNP3/8/PP3PPP/RNBQKB1R b KQkq -
+Sicilian: Kan, Mar\'oczy bind (R\'eti variation)
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Sicilian: Kan, 5.Nc3
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/3B4/PPP2PPP/RNBQK2R b KQkq -
+Sicilian: Kan, 5.Bd3
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Kan variation
+rnbqkbnr/1p1ppppp/p7/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian: O'Kelly variation
+rnbqkbnr/1pp1pppp/p7/8/2pP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+QGA: Alekhine defense
+rnbqkbnr/1pp1pppp/p7/8/2pPP3/5N2/PP3PPP/RNBQKB1R b KQkq -
+QGA: Alekhine defense, Borisenko-Furman variation
+rnbqkbnr/1pp2ppp/p3p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: Janowski variation
+rnbqkbnr/1ppp1ppp/p3p3/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+St. George defense
+rnbqkbnr/1ppp1ppp/p7/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: Mengarini's opening *
+rnbqkbnr/1pppppp1/8/p6p/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Crab opening *
+rnbqkbnr/1pppppp1/p6p/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Global opening *
+rnbqkbnr/1ppppppp/8/p7/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Corn stalk defense
+rnbqkbnr/1ppppppp/8/p7/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Ware (Meadow Hay) opening *
+rnbqkbnr/1ppppppp/p7/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+St. George (Baker) defense
+rnbqkbnr/1ppppppp/p7/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Anderssen's opening *
+rnbqkbnr/2p1pppp/p7/1p6/2pP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGA: Haberditz variation
+rnbqkbnr/2pp1ppp/P7/4p3/8/8/PP1PPPPP/RNBQKBNR b KQkq -
+Sicilian: wing gambit, Carlsbad variation *
+rnbqkbnr/2pp1ppp/p7/1P2p3/8/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: wing gambit, Marshall variation *
+rnbqkbnr/p1p1pppp/8/1p6/2pP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+QGA: Ericson variation
+rnbqkbnr/p1p2ppp/1p2p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: Alapin variation
+rnbqkbnr/p1pp1ppp/1p2p3/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Queen's pawn: Keres defense
+rnbqkbnr/p1pp1ppp/1p6/4p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French: R\'eti (Spielmann) variation *
+rnbqkbnr/p1pp1ppp/1p6/8/3Np3/8/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Welling variation *
+rnbqkbnr/p1pp1ppp/8/1p2p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: wing gambit *
+rnbqkbnr/p1pp1ppp/8/1p6/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Bryan counter-gambit
+rnbqkbnr/p1pp2pp/1p6/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Orsini gambit *
+rnbqkbnr/p1pppppp/1p6/8/1P6/8/P1PPPPPP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack: Polish variation *
+rnbqkbnr/p1pppppp/1p6/8/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack: English variation *
+rnbqkbnr/p1pppppp/1p6/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack: classical variation *
+rnbqkbnr/p1pppppp/1p6/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn: English defense
+rnbqkbnr/p1pppppp/1p6/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack: modern variation *
+rnbqkbnr/p1pppppp/1p6/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Owen defense
+rnbqkbnr/p1pppppp/1p6/8/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack: Dutch variation *
+rnbqkbnr/p1pppppp/1p6/8/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack: symmetrical variation *
+rnbqkbnr/p1pppppp/1p6/8/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: symmetrical variation
+rnbqkbnr/p1pppppp/1p6/8/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+Nimzovich-Larsen attack: Indian variation *
+rnbqkbnr/p1pppppp/1p6/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack *
+rnbqkbnr/p1pppppp/8/1p6/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English: Jaenisch gambit
+rnbqkbnr/p1pppppp/8/1p6/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Polish defense
+rnbqkbnr/p1pppppp/8/1p6/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: Polish variation
+rnbqkbnr/p1pppppp/8/1p6/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+Polish: Outflank variation *
+rnbqkbnr/p1pppppp/8/1p6/8/7N/PPPPPPPP/RNBQKB1R b KQkq -
+Polish: T\"ubingen variation *
+rnbqkbnr/p1pppppp/8/1p6/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Polish (Sokolsky) opening *
+rnbqkbnr/p2p1ppp/1p6/2p5/4p3/1N6/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Steiner variation *
+rnbqkbnr/p2p1ppp/8/1Pp1p3/8/8/PP1PPPPP/RNBQKBNR w KQkq c6
+Sicilian: wing gambit, Santasiere variation *
+rnbqkbnr/p2p1ppp/8/1pp5/2BpP3/5N2/PPP2PPP/RNBQK2R w KQkq -
+Center game, Kieseritsky variation
+rnbqkbnr/p2ppppp/1p6/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian: Katalimov variation
+rnbqkbnr/p2ppppp/8/1pp5/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+English orang-utan *
+rnbqkbnr/p3pppp/2p5/1p1p4/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Caro-Kann: Gurgenidze counter-attack
+rnbqkbnr/p4ppp/2p5/3pp3/8/2N5/PPPPPPPP/R1BQKBNR w KQkq -
+KP: Nimzovich defense, Wheeler gambit *
+rnbqkbnr/p4ppp/8/1pP5/N2p4/8/PP2PPPP/R1BQKBNR w KQkq b6
+QGD: Tarrasch defense, Tarrasch gambit
+rnbqkbnr/pp1p1ppp/2p5/4p3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Philidor counter-attack
+rnbqkbnr/pp1p1ppp/2p5/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: Alapin's variation (2.c3) *
+rnbqkbnr/pp1p1ppp/2p5/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: Lopez opening *
+rnbqkbnr/pp1p1ppp/2p5/8/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Ruy L\'opez defense
+rnbqkbnr/pp1p1ppp/4p3/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian defense
+rnbqkbnr/pp1p1ppp/4p3/2pP4/4P3/8/PPP2PPP/RNBQKBNR b KQkq -
+Old Benoni: Franco-Benoni defense
+rnbqkbnr/pp1p1ppp/4p3/8/3pP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian defense
+rnbqkbnr/pp1p1ppp/8/2p1p3/3P4/2P5/PP2PPPP/RNBQKBNR b KQkq -
+Caro-Kann: anti-anti-Caro-Kann defense *
+rnbqkbnr/pp1p1ppp/8/2p1p3/4P3/6P1/PPPP1P1P/RNBQKBNR b KQkq -
+English: Adorjan defense *
+rnbqkbnr/pp1p1ppp/8/2p1p3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: Mafia defense
+rnbqkbnr/pp1p1ppp/8/2p1p3/8/2P5/PP1PPPPP/RNBQKBNR w KQkq -
+Caro-Kann: anti-Caro-Kann defense *
+rnbqkbnr/pp1p1ppp/8/2p1p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French defense, Steiner variation *
+rnbqkbnr/pp1p1ppp/8/2p5/3Np3/8/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense *
+rnbqkbnr/pp1p1ppp/8/2p5/3p4/2P2N2/PP2PPPP/RNBQKB1R b KQkq -
+Scandinavian gambit *
+rnbqkbnr/pp1p1ppp/8/2p5/3p4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+Scandinavian: Icelandic gambit *
+rnbqkbnr/pp1p1ppp/8/2pPp3/8/8/PPP1PPPP/RNBQKBNR w KQkq e6
+Old Benoni defense
+rnbqkbnr/pp1p1ppp/8/4p3/3pP3/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+Sicilian: Andreaschek gambit
+rnbqkbnr/pp1p1ppp/8/8/2p1p3/1N6/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: two pawns' (Lasker's) attack *
+rnbqkbnr/pp1pp1pp/8/2p2p2/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Mujannah opening *
+rnbqkbnr/pp1pp1pp/8/2pP1p2/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+Old Benoni: Mujannah formation
+rnbqkbnr/pp1ppp1p/6p1/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian: Hungarian variation
+rnbqkbnr/pp1ppppp/2p5/8/1P6/8/P1PPPPPP/RNBQKBNR w KQkq -
+Polish: Outflank variation
+rnbqkbnr/pp1ppppp/2p5/8/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+Caro-Kann: Hillbilly attack
+rnbqkbnr/pp1ppppp/2p5/8/2P1P3/8/PP1P1PPP/RNBQKBNR b KQkq -
+Caro-Kann: anti-Caro-Kann defense
+rnbqkbnr/pp1ppppp/2p5/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English: Caro-Kann defensive system
+rnbqkbnr/pp1ppppp/2p5/8/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+Caro-Kann defense
+rnbqkbnr/pp1ppppp/2p5/8/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Caro-Kann defense
+rnbqkbnr/pp1ppppp/2p5/8/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+Caro-Kann: closed (Breyer) variation
+rnbqkbnr/pp1ppppp/2p5/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Caro-Kann defense
+rnbqkbnr/pp1ppppp/2p5/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Saragossa opening *
+rnbqkbnr/pp1ppppp/8/2p5/1P2P3/8/P1PP1PPP/RNBQKBNR b KQkq -
+Sicilian: wing gambit
+rnbqkbnr/pp1ppppp/8/2p5/1P6/8/P1PPPPPP/RNBQKBNR b KQkq -
+English: Jaenisch gambit *
+rnbqkbnr/pp1ppppp/8/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+English: symmetrical variation
+rnbqkbnr/pp1ppppp/8/2p5/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+English: symmetrical variation *
+rnbqkbnr/pp1ppppp/8/2p5/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English: symmetrical variation
+rnbqkbnr/pp1ppppp/8/2p5/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Old Benoni defense
+rnbqkbnr/pp1ppppp/8/2p5/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+Sicilian: Smith-Morra gambit
+rnbqkbnr/pp1ppppp/8/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Sicilian: closed
+rnbqkbnr/pp1ppppp/8/2p5/4P3/2P5/PP1P1PPP/RNBQKBNR b KQkq -
+Sicilian: Alapin's variation (2.c3)
+rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+Sicilian defense
+rnbqkbnr/pp1ppppp/8/2p5/4P3/6P1/PPPP1P1P/RNBQKBNR b KQkq -
+Sicilian: Steinitz variation
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+English opening *
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Sicilian defense
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPPNPPP/RNBQKB1R b KQkq -
+Sicilian: Keres variation (2.Ne2)
+rnbqkbnr/pp1ppppp/8/2p5/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+Sicilian: Grand Prix attack
+rnbqkbnr/pp1ppppp/8/2p5/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+English: Anglo-Dutch defense *
+rnbqkbnr/pp1ppppp/8/2p5/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: English variation
+rnbqkbnr/pp1ppppp/8/2p5/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+English: Caro-Kann defensive system *
+rnbqkbnr/pp1ppppp/8/2p5/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+English opening *
+rnbqkbnr/pp1ppppp/8/2p5/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+English, 1...Nf6 (Anglo-Indian defense) *
+rnbqkbnr/pp1ppppp/8/2p5/8/6P1/PPPPPP1P/RNBQKBNR b KQkq -
+English opening *
+rnbqkbnr/pp1ppppp/8/2p5/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+English opening *
+rnbqkbnr/pp1ppppp/8/8/1p2P3/P7/2PP1PPP/RNBQKBNR b KQkq -
+Sicilian: wing gambit, Marshall variation
+rnbqkbnr/pp1ppppp/8/8/1pP1P3/8/P2P1PPP/RNBQKBNR b KQkq c3
+Sicilian: wing gambit, Santasiere variation
+rnbqkbnr/pp1ppppp/8/8/3pP3/2P5/PP3PPP/RNBQKBNR b KQkq -
+Sicilian: Smith-Morra gambit
+rnbqkbnr/pp1ppppp/8/8/4P3/p7/2PP1PPP/RNBQKBNR w KQkq -
+Sicilian: wing gambit, Carlsbad variation
+rnbqkbnr/pp2p1pp/5p2/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+Neo-Gr\"unfeld defense *
+rnbqkbnr/pp2pp1p/2p3p1/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Caro-Kann: Gurgenidze system
+rnbqkbnr/pp2pp1p/3p2p1/2pP4/8/2N5/PPP1PPPP/R1BQKBNR w KQkq -
+Old Benoni: Schmid's system
+rnbqkbnr/pp2pp1p/6p1/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+Neo-Gr\"unfeld (Kemeri) defense *
+rnbqkbnr/pp2pp1p/6p1/2pp4/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Dutch with c4 & g3 *
+rnbqkbnr/pp2pp1p/6p1/2pp4/5P2/5NP1/PPPPP2P/RNBQKB1R b KQkq -
+Dutch: Leningrad variation *
+rnbqkbnr/pp2pp1p/6p1/2pp4/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+Catalan opening *
+rnbqkbnr/pp2pp1p/6p1/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian: 3.g3 *
+rnbqkbnr/pp2pppp/2p5/3P4/3P4/8/PP2PPPP/RNBQKBNR b KQkq -
+QGD Slav defense: exchange variation
+rnbqkbnr/pp2pppp/2p5/3P4/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+Caro-Kann: exchange variation
+rnbqkbnr/pp2pppp/2p5/3p2P1/8/8/PPPPPPBP/RNBQK1NR b KQkq -
+Grob: spike attack
+rnbqkbnr/pp2pppp/2p5/3p4/2P1P3/8/PP1P1PPP/RNBQKBNR w KQkq -
+Caro-Kann: anti-anti-Caro-Kann defense
+rnbqkbnr/pp2pppp/2p5/3p4/2P5/1P3N2/P2PPPPP/RNBQKB1R b KQkq -
+English: Caro-Kann defensive system
+rnbqkbnr/pp2pppp/2p5/3p4/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+QGD Slav: 3.Nf3
+rnbqkbnr/pp2pppp/2p5/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QGD Slav defense
+rnbqkbnr/pp2pppp/2p5/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+Caro-Kann defense
+rnbqkbnr/pp2pppp/2p5/3p4/3PP3/5P2/PPP3PP/RNBQKBNR b KQkq -
+Caro-Kann: Tartakower (fantasy) variation
+rnbqkbnr/pp2pppp/2p5/3p4/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Caro-Kann defense
+rnbqkbnr/pp2pppp/2p5/3p4/3PP3/8/PPPN1PPP/R1BQKBNR b KQkq -
+Caro-Kann: 3.Nd2
+rnbqkbnr/pp2pppp/2p5/3p4/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Caro-Kann: two knights variation
+rnbqkbnr/pp2pppp/2p5/3p4/4P3/2N2Q2/PPPP1PPP/R1B1KBNR b KQkq -
+Caro-Kann: Goldman (Spielmann) variation
+rnbqkbnr/pp2pppp/2p5/3pP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+Caro-Kann: advance variation
+rnbqkbnr/pp2pppp/2p5/8/2pPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+QGD Slav defense, Alekhine variation
+rnbqkbnr/pp2pppp/2p5/8/3PN3/8/PPP2PPP/R1BQKBNR b KQkq -
+Caro-Kann defense
+rnbqkbnr/pp2pppp/2p5/8/3Pp3/2N2P2/PPP3PP/R1BQKBNR b KQkq -
+Caro-Kann: Rasa-Studier gambit
+rnbqkbnr/pp2pppp/3p4/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Sicilian: Canal-Sokolsky (Nimzovich-Rossolimo, Moscow) attack
+rnbqkbnr/pp2pppp/3p4/2p5/1P2P3/5N2/P1PP1PPP/RNBQKB1R b KQkq -
+Sicilian: wing gambit deferred
+rnbqkbnr/pp2pppp/3p4/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian
+rnbqkbnr/pp2pppp/3p4/2pP4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+Old Benoni defense
+rnbqkbnr/pp2pppp/3p4/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+Sicilian
+rnbqkbnr/pp2pppp/3p4/8/3QP3/5N2/PPP2PPP/RNB1KB1R b KQkq -
+Sicilian, Chekhover variation
+rnbqkbnr/pp2pppp/3p4/8/3pP3/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+Sicilian: Tartakower variation
+rnbqkbnr/pp2pppp/3p4/8/3pP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian
+rnbqkbnr/pp2pppp/8/1Bpp4/8/4P3/PPPP1PPP/RNBQK1NR b KQkq -
+Queen's pawn: Franco-Indian (Keres) defense *
+rnbqkbnr/pp2pppp/8/2Pp4/8/8/PPP1PPPP/RNBQKBNR b KQkq -
+Queen's gambit accepted *
+rnbqkbnr/pp2pppp/8/2p1N3/2Pp4/8/PP1PPPPP/RNBQKB1R b KQkq -
+Vulture defense *
+rnbqkbnr/pp2pppp/8/2p1N3/4p3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Budapest: Fajarowicz variation *
+rnbqkbnr/pp2pppp/8/2p3N1/4p3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Budapest defense *
+rnbqkbnr/pp2pppp/8/2p5/1P1p4/5NP1/P1PPPP1P/RNBQKB1R b KQkq -
+King's Indian: Danube gambit *
+rnbqkbnr/pp2pppp/8/2p5/1PPp4/5N2/P2PPPPP/RNBQKB1R b KQkq -
+Benk\"o gambit *
+rnbqkbnr/pp2pppp/8/2p5/2Pp4/3P1N2/PP2PPPP/RNBQKB1R b KQkq -
+Benoni defense, Hromodka system *
+rnbqkbnr/pp2pppp/8/2p5/2Pp4/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+Benoni defense *
+rnbqkbnr/pp2pppp/8/2p5/2PpP3/5N2/PP1P1PPP/RNBQKB1R b KQkq e3
+Czech Benoni defense *
+rnbqkbnr/pp2pppp/8/2p5/3p4/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian: Anti-Gr\"unfeld *
+rnbqkbnr/pp2pppp/8/2pp4/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+Benoni defense *
+rnbqkbnr/pp2pppp/8/2pp4/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+QGD: symmetrical (Austrian) defense *
+rnbqkbnr/pp2pppp/8/2pp4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QGD: symmetrical (Austrian) defense
+rnbqkbnr/pp2pppp/8/2pp4/3P1B2/8/PPP1PPPP/RN1QKBNR b KQkq -
+QGD: Grau (Sahovic) defense *
+rnbqkbnr/pp2pppp/8/2pp4/3P1B2/8/PPP1PPPP/RN1QKBNR w KQkq -
+Queen's pawn, Mason variation, Steinitz counter-gambit
+rnbqkbnr/pp2pppp/8/2pp4/3P4/2N5/PPP1PPPP/R1BQKBNR b KQkq -
+QGD: Chigorin defense *
+rnbqkbnr/pp2pppp/8/2pp4/3P4/2P5/PP2PPPP/RNBQKBNR b KQkq -
+QGD Slav defense *
+rnbqkbnr/pp2pppp/8/2pp4/3P4/4P3/PPP2PPP/RNBQKBNR b KQkq -
+Queen's gambit declined *
+rnbqkbnr/pp2pppp/8/2pp4/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+QGD: Marshall defense *
+rnbqkbnr/pp2pppp/8/2pp4/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's pawn game, Krause variation
+rnbqkbnr/pp2pppp/8/2pp4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's gambit declined *
+rnbqkbnr/pp2pppp/8/2pp4/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+QGD: Albin counter-gambit *
+rnbqkbnr/pp2pppp/8/2pp4/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+Budapest defense declined *
+rnbqkbnr/pp2pppp/8/2pp4/5P2/4P3/PPPP2PP/RNBQKBNR b KQkq -
+Dutch defense *
+rnbqkbnr/pp2pppp/8/2pp4/5P2/5N2/PPPPP1PP/RNBQKB1R b KQkq -
+Dutch defense *
+rnbqkbnr/pp2pppp/8/2pp4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch defense *
+rnbqkbnr/pp2pppp/8/2pp4/8/1P2P3/P1PP1PPP/RNBQKBNR b KQkq -
+Queen's pawn: Keres defense *
+rnbqkbnr/pp2pppp/8/2pp4/8/1P3N2/P1PPPPPP/RNBQKB1R b KQkq -
+Queen's Indian accelerated *
+rnbqkbnr/pp2pppp/8/2pp4/8/2N2N2/PPPPPPPP/R1BQKB1R b KQkq -
+Kevitz-Trajkovich defense *
+rnbqkbnr/pp2pppp/8/2pp4/8/3P1N2/PPP1PPPP/RNBQKB1R b KQkq -
+Old Indian defense *
+rnbqkbnr/pp2pppp/8/2pp4/8/3P4/PPP1PPPP/RNBQKBNR w KQkq -
+Old Indian defense *
+rnbqkbnr/pp2pppp/8/2pp4/8/4PN2/PPPP1PPP/RNBQKB1R b KQkq -
+Queen's pawn game *
+rnbqkbnr/pp2pppp/8/2pp4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Queen's pawn game *
+rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+King's Indian defense *
+rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+R\'eti: King's Indian attack (with ...c5)
+rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPPBP/RNBQK2R b KQkq -
+R\'eti: King's Indian attack
+rnbqkbnr/pp2pppp/8/3p4/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+Caro-Kann: Panov-Botvinnik attack
+rnbqkbnr/pp2pppp/8/3p4/3p4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+QGD Slav defense: exchange variation *
+rnbqkbnr/pp2pppp/8/8/1pPp4/P4N2/3PPPPP/RNBQKB1R b KQkq -
+Benk\"o gambit half accepted *
+rnbqkbnr/pp2pppp/8/8/2Pp4/p4N2/3PPPPP/RNBQKB1R w KQkq -
+Benk\"o gambit accepted *
+rnbqkbnr/pp3ppp/2p1p3/3p4/2P5/5NP1/PP1PPP1P/RNBQKB1R w KQkq -
+English: Kurajica defense
+rnbqkbnr/pp3ppp/2p1p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: semi-Slav
+rnbqkbnr/pp3ppp/2p1p3/3p4/2PPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+QGD: semi-Slav, Marshall gambit
+rnbqkbnr/pp3ppp/2p1p3/8/2pP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD: semi-Slav, Noteboom variation
+rnbqkbnr/pp3ppp/2p5/3B4/4Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Anderssen variation
+rnbqkbnr/pp3ppp/2p5/3Pp3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+Danish gambit: S\o rensen defense *
+rnbqkbnr/pp3ppp/2p5/3Pp3/5P2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: Nimzovich counter-gambit
+rnbqkbnr/pp3ppp/2p5/3Pp3/8/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: Smith-Morra gambit *
+rnbqkbnr/pp3ppp/2p5/3Pp3/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+Danish gambit *
+rnbqkbnr/pp3ppp/2p5/3p4/2PPp3/2N1P3/PP3PPP/R1BQKBNR b KQkq -
+French: advance variation *
+rnbqkbnr/pp3ppp/2p5/3p4/2PPp3/4P3/PP3PPP/RNBQKBNR w KQkq -
+French: advance variation *
+rnbqkbnr/pp3ppp/2p5/3pp3/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD Slav: Winawer counter-gambit
+rnbqkbnr/pp3ppp/2pp4/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+English, Keres variation
+rnbqkbnr/pp3ppp/3p4/2pPp3/4P3/8/PPP2PPP/RNBQKBNR w KQkq -
+Semi-Benoni (`blockade variation')
+rnbqkbnr/pp3ppp/4p3/2PpP3/8/8/PPP2PPP/RNBQKBNR b KQkq -
+French: advance, Steinitz variation
+rnbqkbnr/pp3ppp/4p3/2pp4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: Tarrasch defense
+rnbqkbnr/pp3ppp/4p3/2pp4/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+French: Marshall variation
+rnbqkbnr/pp3ppp/4p3/2pp4/3PP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Marshall variation
+rnbqkbnr/pp3ppp/4p3/2pp4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+French: Tarrasch, open variation
+rnbqkbnr/pp3ppp/4p3/2pp4/4P3/2N3P1/PPPP1P1P/R1BQKBNR w KQkq -
+Sicilian: closed, Korchnoi variation
+rnbqkbnr/pp3ppp/4p3/2ppP3/1P6/5N2/P1PP1PPP/RNBQKB1R b KQkq -
+French: Wing gambit
+rnbqkbnr/pp3ppp/4p3/2ppP3/3P2Q1/8/PPP2PPP/RNB1KBNR b KQkq -
+French: advance, Nimzovich variation
+rnbqkbnr/pp3ppp/4p3/2ppP3/3P4/2P5/PP3PPP/RNBQKBNR b KQkq -
+French: advance variation
+rnbqkbnr/pp3ppp/4p3/2ppP3/3P4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+French: advance, Nimzovich system
+rnbqkbnr/pp3ppp/4p3/3P4/3p4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: Tarrasch, von Hennig-Schara gambit
+rnbqkbnr/pp3ppp/4p3/8/2Bp4/5N2/PPPN1PPP/R1BQK2R w KQkq -
+French: Tarrasch, Eliskases variation
+rnbqkbnr/pp3ppp/8/1Npp4/8/8/PPP1PPPP/RNBQKB1R b KQkq -
+Scandinavian: Kiel variation *
+rnbqkbnr/pp3ppp/8/2Ppp3/5P2/8/PPP1P1PP/RNBQKBNR b KQkq -
+QGA: Schwartz defense *
+rnbqkbnr/pp3ppp/8/2Ppp3/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+QGA: 3.e4 *
+rnbqkbnr/pp3ppp/8/2p1p1N1/4p3/3P4/PPP2PPP/RNBQKB1R b KQkq -
+Budapest: Alekhine variation, Balogh gambit *
+rnbqkbnr/pp3ppp/8/2p1p1N1/4p3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Budapest: Alekhine variation *
+rnbqkbnr/pp3ppp/8/2pp4/3Np3/3P4/PPP1PPPP/RNBQKB1R w KQkq -
+Alekhine's defense *
+rnbqkbnr/pp3ppp/8/2pp4/3P4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+QGD: Tarrasch defense
+rnbqkbnr/pp3ppp/8/2pp4/3P4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: Tarrasch defense, 4.cd ed
+rnbqkbnr/pp3ppp/8/2pp4/3P4/8/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik attack *
+rnbqkbnr/pp3ppp/8/2pp4/3P4/8/PPPN1PPP/R1BQKBNR w KQkq -
+French: Tarrasch, open, 4.ed ed
+rnbqkbnr/pp3ppp/8/2pp4/3PP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+QGD: Tarrasch defense, Marshall gambit
+rnbqkbnr/pp3ppp/8/2pp4/8/1N1p4/PPP1PPPP/RNBQKB1R w KQkq -
+Alekhine's defense: exchange variation *
+rnbqkbnr/pp3ppp/8/2ppp3/5P2/4P3/PPPP2PP/RNBQKBNR w KQkq -
+Dutch: Staunton gambit deferred *
+rnbqkbnr/pp3ppp/8/2ppp3/8/5PPN/PPPPP2P/RNBQKB1R b KQkq -
+Hippopotamus defense *
+rnbqkbnr/pp3ppp/8/3p4/2pP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Caro-Kann: Panov-Botvinnik, Gunderam attack *
+rnbqkbnr/pp4pp/8/2p1pp2/8/2N5/PPPP1PPP/RNBQKB1R b KQkq -
+Budapest: Alekhine, Abonyi variation *
+rnbqkbnr/pp4pp/8/2pp1p2/4p1P1/1N1P4/PPP1PP1P/RNBQKB1R b KQkq -
+Alekhine's defense: four pawns attack, Planinc variation *
+rnbqkbnr/pp4pp/8/2pp1p2/4p3/1N1P2P1/PPP1PP1P/RNBQKB1R b KQkq -
+Alekhine's defense: four pawns attack, fianchetto variation *
+rnbqkbnr/pp4pp/8/2pp1p2/4p3/1N1P4/PPP1PPPP/RNBQKB1R w KQkq -
+Alekhine's defense: four pawns attack *
+rnbqkbnr/pp4pp/8/2pp1p2/4pB2/1N1P4/PPP1PPPP/RN1QKB1R b KQkq -
+Alekhine's defense: four pawns attack, Trifunovi\'c variation *
+rnbqkbnr/pp4pp/8/2pp4/4p3/1NN5/PPP1PPPP/R1BQKB1R b KQkq -
+Alekhine's defense: four pawns attack, 6...Nc6 *
+rnbqkbnr/ppp1p1pp/3p4/5p2/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+(Dutch:) Balogh defense
+rnbqkbnr/ppp1p1pp/5p2/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Paleface attack *
+rnbqkbnr/ppp1p1pp/8/3p1p2/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Canard opening *
+rnbqkbnr/ppp1p1pp/8/5p2/2pPP3/8/PP3PPP/RNBQKBNR w KQkq -
+QGA: Schwartz defense
+rnbqkbnr/ppp1p2p/5p2/3p2p1/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Gedult attack *
+rnbqkbnr/ppp1pp1p/6p1/3p4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch defense *
+rnbqkbnr/ppp1pp1p/6p1/3p4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+R\'eti: King's Indian attack
+rnbqkbnr/ppp1pp1p/8/3p2p1/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch, Krejcik gambit *
+rnbqkbnr/ppp1pp1p/8/3p2p1/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Queen's pawn: Bronstein gambit *
+rnbqkbnr/ppp1ppp1/7p/3p4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch, Korchnoi attack *
+rnbqkbnr/ppp1pppp/3p4/8/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+Old Indian defense
+rnbqkbnr/ppp1pppp/3p4/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's Pawn
+rnbqkbnr/ppp1pppp/3p4/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+Mieses opening *
+rnbqkbnr/ppp1pppp/3p4/8/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+R\'eti opening
+rnbqkbnr/ppp1pppp/3p4/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Mieses opening *
+rnbqkbnr/ppp1pppp/8/3p2B1/3P4/8/PPP1PPPP/RN1QKBNR b KQkq -
+Levitsky attack (Queen's bishop attack)
+rnbqkbnr/ppp1pppp/8/3p4/1P6/5N2/P1PPPPPP/RNBQKB1R b KQkq -
+Santasiere's folly
+rnbqkbnr/ppp1pppp/8/3p4/1P6/8/P1PPPPPP/RNBQKBNR b KQkq -
+Polish defense *
+rnbqkbnr/ppp1pppp/8/3p4/2P2P2/8/PP1PP1PP/RNBQKBNR b KQkq -
+Mujannah opening
+rnbqkbnr/ppp1pppp/8/3p4/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+R\'eti opening
+rnbqkbnr/ppp1pppp/8/3p4/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+Old Benoni defense *
+rnbqkbnr/ppp1pppp/8/3p4/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+Queen's gambit declined
+rnbqkbnr/ppp1pppp/8/3p4/3P1B2/8/PPP1PPPP/RN1QKBNR b KQkq -
+Queen's pawn, Mason variation
+rnbqkbnr/ppp1pppp/8/3p4/3P4/2N5/PPP1PPPP/R1BQKBNR b KQkq -
+Queen's pawn: Chigorin variation
+rnbqkbnr/ppp1pppp/8/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Queen's pawn game
+rnbqkbnr/ppp1pppp/8/3p4/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+Queen's pawn game *
+rnbqkbnr/ppp1pppp/8/3p4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn game
+rnbqkbnr/ppp1pppp/8/3p4/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+Blackmar gambit
+rnbqkbnr/ppp1pppp/8/3p4/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+Tennison (Lemberg, Zukertort) gambit
+rnbqkbnr/ppp1pppp/8/3p4/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+Queen's pawn: Charlick (Englund) gambit *
+rnbqkbnr/ppp1pppp/8/3p4/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Scandinavian (center counter) defense
+rnbqkbnr/ppp1pppp/8/3p4/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+Bird's opening: Williams gambit
+rnbqkbnr/ppp1pppp/8/3p4/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+Dutch *
+rnbqkbnr/ppp1pppp/8/3p4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Bird's opening
+rnbqkbnr/ppp1pppp/8/3p4/8/1P3N2/P1PPPPPP/RNBQKB1R b KQkq -
+R\'eti: Nimzovich-Larsen attack
+rnbqkbnr/ppp1pppp/8/3p4/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+Queen's pawn: English defense *
+rnbqkbnr/ppp1pppp/8/3p4/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: classical variation
+rnbqkbnr/ppp1pppp/8/3p4/8/2N5/PPPPPPPP/R1BQKBNR b KQkq -
+Queen's pawn: Lundin (Kevitz-Mikenas) defense *
+rnbqkbnr/ppp1pppp/8/3p4/8/3P1N2/PPP1PPPP/RNBQKB1R b KQkq -
+R\'eti: old Indian attack
+rnbqkbnr/ppp1pppp/8/3p4/8/3P4/PPP1PPPP/RNBQKBNR b KQkq -
+Queen's Pawn *
+rnbqkbnr/ppp1pppp/8/3p4/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+Queen's pawn *
+rnbqkbnr/ppp1pppp/8/3p4/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+Queen's pawn game *
+rnbqkbnr/ppp1pppp/8/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+R\'eti opening
+rnbqkbnr/ppp1pppp/8/3p4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+R\'eti: King's Indian attack (Barcza system)
+rnbqkbnr/ppp1pppp/8/3p4/8/6P1/PPPPPP1P/RNBQKBNR b KQkq -
+Modern defense *
+rnbqkbnr/ppp1pppp/8/3p4/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Queen's pawn *
+rnbqkbnr/ppp1pppp/8/8/2Pp1P2/8/PP1PP1PP/RNBQKBNR b KQkq -
+Old Benoni: Mujannah formation *
+rnbqkbnr/ppp1pppp/8/8/2Pp4/3P4/PP2PPPP/RNBQKBNR b KQkq -
+Old Benoni defense *
+rnbqkbnr/ppp1pppp/8/8/2Pp4/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+Old Benoni defense *
+rnbqkbnr/ppp1pppp/8/8/2Pp4/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+R\'eti: advance variation
+rnbqkbnr/ppp1pppp/8/8/2PpP3/8/PP1P1PPP/RNBQKBNR b KQkq e3
+Old Benoni defense *
+rnbqkbnr/ppp1pppp/8/8/2p5/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+R\'eti accepted
+rnbqkbnr/ppp1pppp/8/8/2pP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+QGA: 3.Nf3
+rnbqkbnr/ppp1pppp/8/8/2pP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Queen's gambit accepted
+rnbqkbnr/ppp1pppp/8/8/2pPP3/8/PP3PPP/RNBQKBNR b KQkq -
+QGA: 3.e4
+rnbqkbnr/ppp2p1p/3p2p1/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Larsen variation
+rnbqkbnr/ppp2p1p/3p4/4N3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Kolisch defense
+rnbqkbnr/ppp2p1p/8/3p2p1/4p3/6P1/PPPPPPNP/RNBQKB1R b KQkq -
+Norwegian defense *
+rnbqkbnr/ppp2p1p/8/3p4/2B1Ppp1/5N2/PPPP2PP/RNBQ1RK1 w kq -
+KGA: Muzio gambit, Brentano defense
+rnbqkbnr/ppp2p1p/8/3pN3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Brentano (Campbell) defense
+rnbqkbnr/ppp2ppp/3p4/4p3/2P5/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+English opening
+rnbqkbnr/ppp2ppp/3p4/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Philidor's defense
+rnbqkbnr/ppp2ppp/3p4/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Philidor's defense
+rnbqkbnr/ppp2ppp/3p4/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: Indian opening *
+rnbqkbnr/ppp2ppp/3p4/4p3/8/2P5/PP1PPPPP/RNBQKBNR w KQkq -
+Caro-Kann: closed (Breyer) variation *
+rnbqkbnr/ppp2ppp/3p4/4p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French: King's Indian attack *
+rnbqkbnr/ppp2ppp/3p4/4p3/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Mar\'oczy variation *
+rnbqkbnr/ppp2ppp/3p4/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: exchange variation
+rnbqkbnr/ppp2ppp/3p4/8/3pP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: exchange variation
+rnbqkbnr/ppp2ppp/3p4/8/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Fischer defense
+rnbqkbnr/ppp2ppp/3pp3/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Lengfellner system
+rnbqkbnr/ppp2ppp/4p3/3P4/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+French: exchange variation
+rnbqkbnr/ppp2ppp/4p3/3p4/2P5/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+English opening: Agincourt variation
+rnbqkbnr/ppp2ppp/4p3/3p4/2P5/5NP1/PP1PPP1P/RNBQKB1R b KQkq -
+English opening: Agincourt variation
+rnbqkbnr/ppp2ppp/4p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+QGD: 3.Nc3
+rnbqkbnr/ppp2ppp/4p3/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Queen's gambit declined
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+French: Paulsen variation
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/3B4/PPP2PPP/RNBQK1NR b KQkq -
+French: Schlechter variation
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/4B3/PPP2PPP/RN1QKBNR b KQkq -
+French: Alapin variation
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+French defense
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/8/PPPN1PPP/R1BQKBNR b KQkq -
+French: Tarrasch
+rnbqkbnr/ppp2ppp/4p3/3p4/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+French: Two knights variation
+rnbqkbnr/ppp2ppp/4p3/3p4/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+French: Pelikan variation
+rnbqkbnr/ppp2ppp/4p3/3pP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+French: advance variation
+rnbqkbnr/ppp2ppp/4p3/8/3Pp3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+French: Rubinstein variation
+rnbqkbnr/ppp2ppp/8/1B1P4/4pP2/8/PPPP2PP/RNBQK1NR b KQkq -
+KGD: Falkbeer, Nimzovich variation
+rnbqkbnr/ppp2ppp/8/3P4/3N4/8/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: Paulsen attack
+rnbqkbnr/ppp2ppp/8/3P4/4pP2/3P4/PPP3PP/RNBQKBNR b KQkq -
+KGD: Falkbeer, 4.d3
+rnbqkbnr/ppp2ppp/8/3P4/4pP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: Falkbeer, 3...e4
+rnbqkbnr/ppp2ppp/8/3Pp3/5P2/8/PPPP2PP/RNBQKBNR b KQkq -
+KGD: Falkbeer counter-gambit
+rnbqkbnr/ppp2ppp/8/3Pp3/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+Center game *
+rnbqkbnr/ppp2ppp/8/3p4/1P1Np3/8/P1PPPPPP/RNBQKB1R b KQkq -
+Alekhine's defense: O'Sullivan gambit *
+rnbqkbnr/ppp2ppp/8/3p4/2B1P3/8/PB3PPP/RN1QK1NR w KQkq -
+Danish gambit: Schlechter defense
+rnbqkbnr/ppp2ppp/8/3p4/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Bledow variation
+rnbqkbnr/ppp2ppp/8/3p4/3N4/8/PPP1PPPP/RNBQKB1R b KQkq -
+Scandinavian: Marshall variation *
+rnbqkbnr/ppp2ppp/8/3p4/3Np3/3P4/PPP1PPPP/RNBQKB1R b KQkq -
+Alekhine's defense *
+rnbqkbnr/ppp2ppp/8/3p4/3Np3/8/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense *
+rnbqkbnr/ppp2ppp/8/3p4/3Pp3/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: advance variation *
+rnbqkbnr/ppp2ppp/8/3p4/3Pp3/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: advance variation *
+rnbqkbnr/ppp2ppp/8/3p4/3p4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: exchange variation *
+rnbqkbnr/ppp2ppp/8/3p4/3p4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: exchange variation *
+rnbqkbnr/ppp2ppp/8/3p4/3p4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Scandinavian defense *
+rnbqkbnr/ppp2ppp/8/3p4/3p4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+Scandinavian: Richter variation *
+rnbqkbnr/ppp2ppp/8/3p4/3pP3/2P5/PP3PPP/RNBQKBNR w KQkq -
+Danish gambit: S\o rensen defense
+rnbqkbnr/ppp2ppp/8/3p4/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Abbazia defense (classical defense, modern defense[!])
+rnbqkbnr/ppp2ppp/8/3pP3/8/8/PPPPP1PP/RNBQKBNR b KQkq -
+Dutch: Staunton gambit *
+rnbqkbnr/ppp2ppp/8/3pp3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: Smith-Morra gambit *
+rnbqkbnr/ppp2ppp/8/3pp3/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QGD: Albin counter-gambit
+rnbqkbnr/ppp2ppp/8/3pp3/3P4/2P5/PP2PPPP/RNBQKBNR b KQkq -
+Caro-Kann defense *
+rnbqkbnr/ppp2ppp/8/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR b KQkq -
+French defense *
+rnbqkbnr/ppp2ppp/8/3pp3/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Blackmar gambit *
+rnbqkbnr/ppp2ppp/8/3pp3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+QP counter-gambit (elephant gambit)
+rnbqkbnr/ppp2ppp/8/3pp3/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+KGD: Falkbeer, Milner-Barry variation
+rnbqkbnr/ppp2ppp/8/3pp3/4PP2/5N2/PPPP2PP/RNBQKB1R b KQkq -
+KGD: Falkbeer, Tartakower variation
+rnbqkbnr/ppp2ppp/8/3pp3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: Falkbeer counter-gambit
+rnbqkbnr/ppp2ppp/8/3pp3/5P2/3P4/PPP1P1PP/RNBQKBNR b KQkq -
+(Dutch:) Balogh defense *
+rnbqkbnr/ppp2ppp/8/3pp3/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch: Staunton gambit *
+rnbqkbnr/ppp2ppp/8/3pp3/8/2N2P2/PPPPP1PP/R1BQKBNR b KQkq -
+KP: Neo-Mongoloid defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/2N5/PPPPPPPP/R1BQKBNR w KQkq -
+KP: Nimzovich defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/2P2N2/PP1PPPPP/RNBQKB1R b KQkq -
+Caro-Masi defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/2P5/PP1PPPPP/RNBQKBNR w KQkq -
+Caro-Kann defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/3P1N2/PPP1PPPP/RNBQKB1R b KQkq -
+Pirc defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/3PP3/PPP2PPP/RNBQKBNR b KQkq -
+Lengfellner system *
+rnbqkbnr/ppp2ppp/8/3pp3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/5P2/PPPPPKPP/RNBQ1BNR b kq -
+Fried fox defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/6P1/PPPPPPBP/RNBQK1NR b KQkq -
+Robatsch (modern) defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/BP6/P1PPPPPP/RN1QKBNR b KQkq -
+Guatemala defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/P3P3/1PPP1PPP/RNBQKBNR b KQkq -
+St. George defense *
+rnbqkbnr/ppp2ppp/8/4P3/2Pp4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+QGD: Albin counter-gambit
+rnbqkbnr/ppp2ppp/8/4p3/2Pp4/4P3/PP1P1PPP/RNBQKBNR w KQkq -
+Old Benoni: Franco-Benoni defense *
+rnbqkbnr/ppp2ppp/8/4p3/2PpP3/3P4/PP3PPP/RNBQKBNR b KQkq -
+Semi-Benoni (`blockade variation') *
+rnbqkbnr/ppp2ppp/8/8/2pPp3/4P3/PP3PPP/RNBQKBNR w KQkq -
+French: advance, Steinitz variation *
+rnbqkbnr/ppp3pp/3p4/4Pp2/3p4/8/PPP2PPP/RNBQKBNR w KQkq -
+KGD: Falkbeer, 4.d3 *
+rnbqkbnr/ppp3pp/3p4/4pp2/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Philidor: L\'opez counter-gambit
+rnbqkbnr/ppp3pp/3p4/4pp2/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+Philidor: Philidor counter-gambit, Zukertort variation
+rnbqkbnr/ppp3pp/3p4/4pp2/3PP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Philidor counter-gambit
+rnbqkbnr/ppp3pp/4P3/3p2N1/4p3/8/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: Philidor counter-gambit, del Rio attack
+rnbqkbnr/ppp3pp/4p3/3p1p2/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+French: Tarrasch, Haberditz variation
+rnbqkbnr/ppp3pp/5p2/3pp3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: Tartakower (fantasy) variation *
+rnbqkbnr/ppp3pp/5p2/3pp3/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Blackmar-Diemer gambit *
+rnbqkbnr/ppp3pp/8/3Ppp2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+Halasz gambit *
+rnbqkbnr/ppp3pp/8/3pN3/2B1p3/8/PPPP1PPP/RNBQK2R w KQkq -
+Latvian: Polerio variation
+rnbqkbnr/ppp3pp/8/3ppP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Villemson (Steinitz) gambit *
+rnbqkbnr/ppp3pp/8/3ppp2/8/6P1/PPPPPPBP/RNBQK1NR w KQkq -
+Robatsch defense: three pawns attack *
+rnbqkbnr/ppp3pp/8/4pp2/3p4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+KGD: Falkbeer, 5.de *
+rnbqkbnr/pppp1B1p/8/8/4Ppp1/5N2/PPPP2PP/RNBQK2R b KQkq -
+KGA: Lolli gambit (wild Muzio gambit)
+rnbqkbnr/pppp1p1p/6p1/4p3/2P1P3/8/PP1P1PPP/RNBQKBNR w KQkq -
+English: Adorjan defense
+rnbqkbnr/pppp1p1p/6p1/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: Steinitz variation *
+rnbqkbnr/pppp1p1p/8/4N3/2B1Ppp1/8/PPPP2PP/RNBQK2R b KQkq -
+KGA: Salvio gambit
+rnbqkbnr/pppp1p1p/8/4N3/3PPpp1/8/PPP3PP/RNBQKB1R b KQkq -
+KGA: S\o rensen gambit
+rnbqkbnr/pppp1p1p/8/6N1/4PppP/8/PPPP2P1/RNBQKB1R b KQkq -
+KGA: Allgaier gambit
+rnbqkbnr/pppp1p1p/8/6p1/2B1Pp2/5N2/PPPP2PP/RNBQK2R b KQkq -
+KGA: King's knight's gambit
+rnbqkbnr/pppp1p1p/8/6p1/3PPp2/5N2/PPP3PP/RNBQKB1R b KQkq -
+KGA: Rosentreter gambit
+rnbqkbnr/pppp1p1p/8/6p1/4Pp1P/5N2/PPPP2P1/RNBQKB1R b KQkq -
+King's knight's gambit
+rnbqkbnr/pppp1p1p/8/6p1/4Pp2/2N2N2/PPPP2PP/R1BQKB1R b KQkq -
+KGA: Quaade gambit
+rnbqkbnr/pppp1p1p/8/8/2B1Ppp1/2N2N2/PPPP2PP/R1BQK2R b KQkq -
+KGA: MacDonnell gambit
+rnbqkbnr/pppp1p1p/8/8/2B1Ppp1/5N2/PPPP2PP/RNBQ1RK1 b kq -
+KGA: Muzio gambit
+rnbqkbnr/pppp1p1p/8/8/2BPPpp1/5N2/PPP3PP/RNBQK2R b KQkq -
+KGA: Ghulam Kassim gambit
+rnbqkbnr/pppp1p2/8/4N2p/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, long whip (Stockwhip, classical) defense
+rnbqkbnr/pppp1pp1/7p/8/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Becker defense
+rnbqkbnr/pppp1ppp/4p3/4P3/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+French: Steinitz attack
+rnbqkbnr/pppp1ppp/4p3/8/2P1P3/8/PP1P1PPP/RNBQKBNR b KQkq -
+French defense, Steiner variation
+rnbqkbnr/pppp1ppp/4p3/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English opening
+rnbqkbnr/pppp1ppp/4p3/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn
+rnbqkbnr/pppp1ppp/4p3/8/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+French defense
+rnbqkbnr/pppp1ppp/4p3/8/4P3/1P6/P1PP1PPP/RNBQKBNR b KQkq -
+French: R\'eti (Spielmann) variation
+rnbqkbnr/pppp1ppp/4p3/8/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+French defense
+rnbqkbnr/pppp1ppp/4p3/8/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+French: King's Indian attack
+rnbqkbnr/pppp1ppp/4p3/8/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+French defense
+rnbqkbnr/pppp1ppp/4p3/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+French defense
+rnbqkbnr/pppp1ppp/4p3/8/4P3/8/PPPPQPPP/RNB1KBNR b KQkq -
+French: Chigorin variation
+rnbqkbnr/pppp1ppp/4p3/8/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+French: Labourdonnais variation
+rnbqkbnr/pppp1ppp/4p3/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Van't Kruijs opening *
+rnbqkbnr/pppp1ppp/8/4N3/4p3/8/PPPPPPPP/RNBQKB1R b KQkq -
+Alekhine's defense: Mokele Mbembe (B\"ucker) variation *
+rnbqkbnr/pppp1ppp/8/4p2Q/4P3/8/PPPP1PPP/RNB1KBNR b KQkq -
+KP: Patzer opening
+rnbqkbnr/pppp1ppp/8/4p3/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+Bishop's opening
+rnbqkbnr/pppp1ppp/8/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+English opening
+rnbqkbnr/pppp1ppp/8/4p3/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+English, Nimzovich variation
+rnbqkbnr/pppp1ppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+Sicilian defense *
+rnbqkbnr/pppp1ppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English opening
+rnbqkbnr/pppp1ppp/8/4p3/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+Scandinavian (center counter) defense *
+rnbqkbnr/pppp1ppp/8/4p3/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn: Charlick (Englund) gambit
+rnbqkbnr/pppp1ppp/8/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Vienna game
+rnbqkbnr/pppp1ppp/8/4p3/4P3/2P5/PP1P1PPP/RNBQKBNR b KQkq -
+KP: Lopez opening
+rnbqkbnr/pppp1ppp/8/4p3/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+KP: Indian opening
+rnbqkbnr/pppp1ppp/8/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+King's knight opening
+rnbqkbnr/pppp1ppp/8/4p3/4P3/5P2/PPPP2PP/RNBQKBNR b KQkq -
+KP: King's head opening
+rnbqkbnr/pppp1ppp/8/4p3/4P3/5Q2/PPPP1PPP/RNB1KBNR b KQkq -
+KP: Napoleon's opening
+rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+King's pawn game *
+rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+King's pawn game
+rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPPNPPP/RNBQKB1R b KQkq -
+Alapin's opening
+rnbqkbnr/pppp1ppp/8/4p3/4P3/P7/1PPP1PPP/RNBQKBNR b KQkq -
+KP: Mengarini's opening
+rnbqkbnr/pppp1ppp/8/4p3/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+King's gambit
+rnbqkbnr/pppp1ppp/8/4p3/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+Fred *
+rnbqkbnr/pppp1ppp/8/4p3/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Bird: From gambit
+rnbqkbnr/pppp1ppp/8/4p3/6P1/8/PPPPPP1P/RNBQKBNR b KQkq -
+Reversed Grob (Borg/Basman defense/macho Grob) *
+rnbqkbnr/pppp1ppp/8/4p3/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+Owen defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: modern variation
+rnbqkbnr/pppp1ppp/8/4p3/8/2N5/PPPPPPPP/R1BQKBNR b KQkq -
+KP: Nimzovich defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/2N5/PPPPPPPP/R1BQKBNR w KQkq -
+Dunst (Sleipner,Heinrichsen) opening
+rnbqkbnr/pppp1ppp/8/4p3/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+Caro-Kann defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/3P4/PPP1PPPP/RNBQKBNR w KQkq -
+Mieses opening
+rnbqkbnr/pppp1ppp/8/4p3/8/3P4/PPPNPPPP/R1BQKBNR b KQkq -
+Valencia opening
+rnbqkbnr/pppp1ppp/8/4p3/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+French defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+Alekhine's defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+Benko's opening: reversed Alekhine
+rnbqkbnr/pppp1ppp/8/4p3/8/5P2/PPPPP1PP/RNBQKBNR b KQkq -
+Barnes defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/5P2/PPPPPKPP/RNBQ1BNR b kq -
+Hammerschlag (Fried fox/Pork chop opening)
+rnbqkbnr/pppp1ppp/8/4p3/8/6P1/PPPPPP1P/RNBQKBNR b KQkq -
+Robatsch (modern) defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/7P/PPPPPPP1/RNBQKBNR b KQkq -
+Carr's defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+King's pawn opening *
+rnbqkbnr/pppp1ppp/8/4p3/8/N7/PPPPPPPP/R1BQKBNR b KQkq -
+Lemming defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/P1N5/1PPPPPPP/R1BQKBNR b KQkq -
+Battambang opening
+rnbqkbnr/pppp1ppp/8/4p3/8/P6P/1PPPPPP1/RNBQKBNR b KQkq -
+Global opening
+rnbqkbnr/pppp1ppp/8/4p3/8/P7/1PPPPPPP/RNBQKBNR b KQkq -
+St. George (Baker) defense *
+rnbqkbnr/pppp1ppp/8/4p3/P6P/8/1PPPPPP1/RNBQKBNR b KQkq -
+Crab opening
+rnbqkbnr/pppp1ppp/8/4p3/P7/8/1PPPPPPP/RNBQKBNR b KQkq -
+Corn stalk defense *
+rnbqkbnr/pppp1ppp/8/8/2B1Pp2/8/PPPP2PP/RNBQK1NR b KQkq -
+KGA: bishop's gambit
+rnbqkbnr/pppp1ppp/8/8/2P1p3/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+English, Nimzovich, Flohr variation
+rnbqkbnr/pppp1ppp/8/8/3Np3/8/PPPPPPPP/RNBQKB1R b KQkq -
+Alekhine's defense *
+rnbqkbnr/pppp1ppp/8/8/3PPp2/8/PPP3PP/RNBQKBNR b KQkq -
+KGA: Villemson (Steinitz) gambit
+rnbqkbnr/pppp1ppp/8/8/3QP3/8/PPP2PPP/RNB1KBNR b KQkq -
+Center game
+rnbqkbnr/pppp1ppp/8/8/3p4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Scandinavian defense *
+rnbqkbnr/pppp1ppp/8/8/3pP3/2P5/PP3PPP/RNBQKBNR b KQkq -
+Danish gambit
+rnbqkbnr/pppp1ppp/8/8/3pP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Center game
+rnbqkbnr/pppp1ppp/8/8/3pPP2/8/PPP3PP/RNBQKBNR b KQkq -
+Halasz gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp1P/8/PPPP2P1/RNBQKBNR b KQkq -
+KGA: Pawn's gambit (Stamma gambit)
+rnbqkbnr/pppp1ppp/8/8/4Pp2/1P6/P1PP2PP/RNBQKBNR b KQkq -
+KGA: Orsini gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+KGA: Keres (Mason-Steinitz) gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/3B4/PPPP2PP/RNBQK1NR b KQkq -
+KGA: Schurig gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/5N2/PPPP2PP/RNBQKB1R b KQkq -
+King's knight's gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/5Q2/PPPP2PP/RNB1KBNR b KQkq -
+KGA: Breyer gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/8/PPPP1KPP/RNBQ1BNR b kq -
+KGA: Tumbleweed gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/8/PPPP2PP/RNBQKBNR w KQkq -
+King's gambit accepted
+rnbqkbnr/pppp1ppp/8/8/4Pp2/8/PPPPB1PP/RNBQK1NR b KQkq -
+KGA: Lesser bishop's (Petroff-Jaenisch-Tartakower) gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/8/PPPPQ1PP/RNB1KBNR b KQkq -
+KGA: Carrera (Basman) gambit
+rnbqkbnr/pppp1ppp/8/8/4p3/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French: Steinitz attack *
+rnbqkbnr/pppp1ppp/8/8/4p3/8/PPPPPPPP/RNBQKBNR b KQkq -
+Alekhine's defense: Brooklyn defense *
+rnbqkbnr/pppp2p1/8/4pP1p/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Pawn's gambit (Stamma gambit) *
+rnbqkbnr/pppp2pp/4p3/5p2/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+Dutch defense, Rubinstein variation
+rnbqkbnr/pppp2pp/4p3/5p2/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Dutch defense
+rnbqkbnr/pppp2pp/4p3/5p2/2PPP3/8/PP3PPP/RNBQKBNR b KQkq -
+Dutch: Staunton gambit deferred
+rnbqkbnr/pppp2pp/4p3/5p2/3P2P1/3Q4/PPP1PP1P/RNB1KBNR b KQkq -
+Dutch, Von Pretzel gambit
+rnbqkbnr/pppp2pp/5p2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Damiano's defense
+rnbqkbnr/pppp2pp/5p2/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: King's head opening *
+rnbqkbnr/pppp2pp/8/4Pp2/3p4/8/PPP2PPP/RNBQKBNR b KQkq -
+KGD: Falkbeer, 3...e4 *
+rnbqkbnr/pppp2pp/8/4pP2/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+King's gambit accepted *
+rnbqkbnr/pppp2pp/8/4pp2/2B1P3/3P4/PPP2PPP/RNBQK1NR b KQkq -
+Bishop's opening: Calabrese counter-gambit, Jaenisch variation
+rnbqkbnr/pppp2pp/8/4pp2/2B1P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Latvian gambit, 3.Bc4
+rnbqkbnr/pppp2pp/8/4pp2/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+KGD: classical variation *
+rnbqkbnr/pppp2pp/8/4pp2/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Calabrese counter-gambit
+rnbqkbnr/pppp2pp/8/4pp2/2P1P3/8/PP1P1PPP/RNBQKBNR b KQkq -
+KGD: Mafia defense *
+rnbqkbnr/pppp2pp/8/4pp2/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: Grand Prix attack *
+rnbqkbnr/pppp2pp/8/4pp2/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Bird's opening: Williams gambit *
+rnbqkbnr/pppp2pp/8/4pp2/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+KGD: Falkbeer counter-gambit *
+rnbqkbnr/pppp2pp/8/4pp2/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+KGD: 2...Nf6 *
+rnbqkbnr/pppp2pp/8/4pp2/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Latvian counter-gambit
+rnbqkbnr/pppp2pp/8/4pp2/4P3/5Q2/PPPP1PPP/RNB1KBNR b KQkq -
+KGD: Norwalde variation *
+rnbqkbnr/pppp2pp/8/4pp2/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+King's gambit *
+rnbqkbnr/pppp2pp/8/4pp2/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French: Labourdonnais variation *
+rnbqkbnr/pppp2pp/8/5p2/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, L\'opez-Gianutio counter-gambit
+rnbqkbnr/pppp2pp/8/5p2/3pP3/2P5/PP3PPP/RNBQKBNR b KQkq -
+KGD: Nimzovich counter-gambit *
+rnbqkbnr/pppp2pp/8/5p2/3pP3/8/PPP2PPP/RNBQKBNR w KQkq -
+KGD: Falkbeer counter-gambit *
+rnbqkbnr/pppp2pp/8/5p2/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Gianutio counter-gambit
+rnbqkbnr/pppp3p/6p1/4pp2/4P3/8/PPPPQPPP/RNB1KBNR b KQkq -
+KGD: Keene's defense *
+rnbqkbnr/ppppp1pp/5p2/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Barnes defense
+rnbqkbnr/ppppp1pp/5p2/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Gedult's opening *
+rnbqkbnr/ppppp1pp/8/5p2/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English: Anglo-Dutch defense
+rnbqkbnr/ppppp1pp/8/5p2/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+Dutch defense
+rnbqkbnr/ppppp1pp/8/5p2/3P2P1/8/PPP1PP1P/RNBQKBNR b KQkq -
+Dutch, Krejcik gambit
+rnbqkbnr/ppppp1pp/8/5p2/3P4/3Q4/PPP1PPPP/RNB1KBNR b KQkq -
+Dutch, Manhattan (Alapin, Ulvestad) variation
+rnbqkbnr/ppppp1pp/8/5p2/3P4/6P1/PPP1PP1P/RNBQKBNR b KQkq -
+Dutch defense
+rnbqkbnr/ppppp1pp/8/5p2/3P4/7P/PPP1PPP1/RNBQKBNR b KQkq -
+Dutch, Korchnoi attack
+rnbqkbnr/ppppp1pp/8/5p2/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+Bird's opening *
+rnbqkbnr/ppppp1pp/8/5p2/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Dutch
+rnbqkbnr/ppppp1pp/8/5p2/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+Dutch: Staunton gambit
+rnbqkbnr/ppppp1pp/8/5p2/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+R\'eti: Pirc-Lisitsin gambit
+rnbqkbnr/ppppp1pp/8/5p2/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+Bird: From gambit *
+rnbqkbnr/ppppp1pp/8/5p2/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Fred
+rnbqkbnr/ppppp1pp/8/5p2/6P1/8/PPPPPP1P/RNBQKBNR b KQkq -
+Bird: Hobbs gambit *
+rnbqkbnr/ppppp1pp/8/5p2/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: Dutch variation
+rnbqkbnr/ppppp1pp/8/5p2/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+R\'eti v Dutch
+rnbqkbnr/ppppp1pp/8/5p2/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Bird's opening *
+rnbqkbnr/ppppp1pp/8/5pB1/3P4/8/PPP1PPPP/RN1QKBNR b KQkq -
+Dutch, 2.Bg5 variation
+rnbqkbnr/ppppp1pp/8/8/3Pp3/8/PPP2PPP/RNBQKBNR w KQkq -
+Dutch: Staunton gambit
+rnbqkbnr/pppppp1p/6p1/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English opening
+rnbqkbnr/pppppp1p/6p1/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Modern defense
+rnbqkbnr/pppppp1p/6p1/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Robatsch (modern) defense
+rnbqkbnr/pppppp1p/6p1/8/7P/8/PPPPPPP1/RNBQKBNR b KQkq -
+Lasker simul special *
+rnbqkbnr/pppppp1p/6p1/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Benko's opening *
+rnbqkbnr/pppppp1p/8/6p1/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Reversed Grob (Borg/Basman defense/macho Grob)
+rnbqkbnr/pppppp1p/8/6p1/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Bird: Hobbs gambit
+rnbqkbnr/pppppp1p/8/6p1/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+R\'eti: Herrstr\"om gambit
+rnbqkbnr/pppppp1p/8/6p1/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Grob's attack *
+rnbqkbnr/ppppppp1/7p/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Carr's defense
+rnbqkbnr/ppppppp1/7p/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Clemenz (Mead's, Basman's or de Klerk's) opening *
+rnbqkbnr/ppppppp1/8/7p/8/6P1/PPPPPP1P/RNBQKBNR w KQkq -
+Lasker simul special
+rnbqkbnr/ppppppp1/8/7p/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Anti-Borg (Desprez) opening *
+rnbqkbnr/pppppppp/8/4P3/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+Alekhine's defense: Brooklyn defense
+rnbqkbnr/pppppppp/8/8/1P6/8/P1PPPPPP/RNBQKBNR b KQkq -
+Polish (Sokolsky) opening
+rnbqkbnr/pppppppp/8/8/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+English opening
+rnbqkbnr/pppppppp/8/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+Queen's pawn
+rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+King's pawn opening
+rnbqkbnr/pppppppp/8/8/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+Bird's opening
+rnbqkbnr/pppppppp/8/8/6P1/8/PPPPPP1P/RNBQKBNR b KQkq -
+Grob's attack
+rnbqkbnr/pppppppp/8/8/7P/8/PPPPPPP1/RNBQKBNR b KQkq -
+Anti-Borg (Desprez) opening
+rnbqkbnr/pppppppp/8/8/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack
+rnbqkbnr/pppppppp/8/8/8/2N5/PPPPPPPP/R1BQKBNR b KQkq -
+Dunst (Sleipner, Heinrichsen) opening
+rnbqkbnr/pppppppp/8/8/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+Saragossa opening
+rnbqkbnr/pppppppp/8/8/8/3P4/PPP1PPPP/RNBQKBNR b KQkq -
+Mieses opening
+rnbqkbnr/pppppppp/8/8/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+Van't Kruijs opening
+rnbqkbnr/pppppppp/8/8/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+R\'eti opening
+rnbqkbnr/pppppppp/8/8/8/5P2/PPPPP1PP/RNBQKBNR b KQkq -
+Gedult's opening
+rnbqkbnr/pppppppp/8/8/8/6P1/PPPPPP1P/RNBQKBNR b KQkq -
+Benko's opening
+rnbqkbnr/pppppppp/8/8/8/7N/PPPPPPPP/RNBQKB1R b KQkq -
+Amar (Paris) opening
+rnbqkbnr/pppppppp/8/8/8/7P/PPPPPPP1/RNBQKBNR b KQkq -
+Clemenz (Mead's, Basman's or de Klerk's) opening
+rnbqkbnr/pppppppp/8/8/8/N7/PPPPPPPP/R1BQKBNR b KQkq -
+Durkin's attack
+rnbqkbnr/pppppppp/8/8/8/P7/1PPPPPPP/RNBQKBNR b KQkq -
+Anderssen's opening
+rnbqkbnr/pppppppp/8/8/P7/8/1PPPPPPP/RNBQKBNR b KQkq -
+Ware (Meadow Hay) opening
+rnbqkr2/pppp1pQp/8/2b1P3/3P4/5N2/PPP3PP/RNB1KB1n b KQq -
+Latvian: Behting variation *
+rnbqkr2/ppppbp1p/5N2/4Q3/8/8/PPPP1nPP/R1B1KBNR b KQq -
+Blackburne shilling gambit *
+rnbqr1k1/1p1p1ppp/pbp2n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, Suetin variation *
+rnbqr1k1/1p3pp1/2p2n1p/p1bpp3/4P3/PBNP1N2/1PP1QPPP/R1B1K2R w KQ -
+Giuoco Piano: Tarrasch variation *
+rnbqr1k1/1pb2ppp/2p2n2/p2pp3/NPP1P3/P2P1N2/2Q1BPPP/R1B1K2R w KQ -
+Ruy Lopez: closed, Balla variation *
+rnbqr1k1/1ppp1ppp/1b3n2/p3p3/1P2P3/P1N2N2/2PPBPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, anti-Marshall 8.a4 *
+rnbqr1k1/p1pp1ppp/5n2/1p2p3/1bP1P3/2N3P1/PP1P1PBP/R1BQK1NR w KQ -
+Sicilian: Nimzovich-Rossolimo attack, Gurgenidze variation *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N1P/2P1BPP1/R1BQ1RK1 b - -
+Ruy Lopez: closed, Smyslov defense *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N2/1BP1BPPP/R2Q1RK1 b - -
+Ruy Lopez: closed, Flohr-Zaitsev system (Lenzerheide variation) *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, 9.h3 *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP4/2PNBPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed, Ragozin-Petrosian (`Keres') variation *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NPBN2/2P1BPPP/R2Q1RK1 b - -
+Ruy Lopez: closed, Kholmov variation *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P2P1N2/2P1BPPP/RNBQ1RK1 b - -
+Ruy Lopez: closed, Breyer defense *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/PP2P3/2NP1N2/2P1BPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed, Keres (9...a5) variation *
+rnbqr1k1/pp1p1ppp/1bp2n2/4P3/1P1p4/P1N2N2/2P1BPPP/R1BQ1RK1 b - -
+Ruy Lopez: Marshall, Herman Steiner variation *
+rnbqr1k1/pp1p1ppp/1bp2n2/4p3/1P1PP3/P1N2N2/2P1BPPP/R1BQ1RK1 b - -
+Ruy Lopez: Marshall counter-attack *
+rnbqr1k1/pp1p1ppp/1bp2n2/4p3/1P2P3/P1N2N2/2PPBPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, 8.c3 *
+rnbqr1k1/pp1p1ppp/1bp2n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed (with ...d6) *
+rnbqr1k1/pp3p1p/1bp3pQ/3p4/1P1N4/P1PB4/5PPP/R1B2RK1 b - -
+Ruy Lopez: Marshall, main line, 14...Qh3 *
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+Benoni: classical, 9...Re8
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4P3/2N5/PP1NBPPP/R1BQ1RK1 b - -
+Benoni: classical, 9...Re8, 10.Nd2
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4PP2/2N2N2/PP2B1PP/R1BQK2R w KQ -
+Benoni: four pawns attack, main line
+rnbqr1k1/pp3pp1/1bp2n1p/3pp3/1P2P3/P2P1N2/2P1BPPP/RNBQ1RK1 w - -
+Ruy Lopez: closed, Breyer, 10.d4 *
+rnbqr1k1/pp3pp1/1bp2n1p/3pp3/1P2P3/P2P1N2/2PNBPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed, Breyer, Borisenko variation *
+rnbqr1k1/pp3pp1/1bp4p/3pp2n/1P2P3/P2P1N2/2PNBPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, Breyer, Simagin variation *
+rnbqr1k1/pp3ppB/3b1n2/3pN1B1/3p1P2/8/PPP3PP/RN1Q1RK1 b - -
+Petrov: classical attack, Marshall trap *
+rnbqr1k1/pp3ppp/1bp2n2/3pp1B1/1P2P3/P1NP1N2/2P1BPPP/R2Q1RK1 b - -
+Ruy Lopez: closed, Bogolyubov variation *
+rnbqr1k1/pp3ppp/1bp2n2/3pp3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, 9.d4 *
+rnbqr1k1/pp3ppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P1BPPP/R2QK2R w KQ -
+Ruy Lopez: open, 9...Be7, 10.Re1 *
+rnbqr1k1/pp3ppp/1bp5/3nN3/1P1PN3/P3B3/2P1BPPP/R2Q1RK1 b - -
+Ruy Lopez: open, Breslau variation *
+rnbqr1k1/pp3ppp/1bpp1n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, Pilnik variation *
+rnbqr1k1/pp3ppp/3b1n2/2ppN1B1/3P1P2/2N5/PPP1B1PP/R2QK2R w KQ -
+Petrov: classical attack, Krause variation *
+rnbqr1k1/pp3ppp/3b1n2/2ppN1BB/3P1P2/2N5/PPP3PP/R2QK2R b KQ -
+Petrov: classical attack, Mar\'oczy variation *
+rnbqr1k1/ppb2pp1/2p2n1p/3pp3/1PP1P3/P1NP1N2/4BPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed, Borisenko defense *
+rnbqr1k1/ppb2pp1/2p2n1p/3pp3/NP2P3/P1PP1N2/2Q1BPPP/R1B2RK1 b - -
+Ruy Lopez: closed, Rossolimo defense *
+rnbqr1k1/ppb2pp1/2p2n1p/3pp3/NPP1P3/P2P1N2/2Q1BPPP/R1B2RK1 b - -
+Ruy Lopez: closed, Chigorin defense *
+rnbqr1k1/ppb2pp1/2p2n1p/3pp3/NPP1P3/P2P4/3NBPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed, Keres (...Nd7) defense *
+rnbqr1k1/ppbp1pp1/2p2n1p/4p3/NP2P3/P2P1N2/2P1BPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed (9...Na5) *
+rnbqr1k1/ppbp1pp1/2p2n1p/4p3/NPP1P3/P2P1N2/4BPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed (10...c5) *
+rnbqr1k1/ppbp1ppp/2p2n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, Lutikov variation *
+rnbqr1k1/ppp2ppp/1b3n2/3pp3/1P2P3/P1NP1N2/2P1BPPP/R1BQK2R w KQ -
+Ruy Lopez: closed, 7...d6, 8.d4 *
+rnbqr1k1/ppp2ppp/3b1n2/3pN3/3P4/2N5/PPP1BPPP/R1BQK2R w KQ -
+Petrov: classical attack, Chigorin variation *
+rnbqr1k1/ppp2ppp/5n2/2PP4/2B5/2N1B3/PPP2PpP/R2QK2R w KQ -
+two knights: Max Lange attack, Schlechter variation *
+rnbqr1k1/ppp2ppp/8/2PP4/2B3n1/2N1BpP1/PPP2P1P/R2QK2R b KQ -
+two knights: Max Lange attack, Loman defense *
+rnbqr1k1/pppp1ppp/1b3n2/4p3/1P2P3/P1N2N2/1BPPBPPP/R2QK2R b KQ -
+Ruy Lopez: Trajkovi\'c counter-attack *
+rnbqr1k1/pppp1ppp/1b3n2/4p3/1P2P3/P1N2N2/2PPBPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed, 7...O-O *
+rnbqr1k1/pppp1ppp/1b3n2/4p3/1P2P3/P1N2N2/2PPBPPP/R1BQK2R w KQ -
+Ruy Lopez: closed *
+rnbqr1k1/pppp1ppp/5n2/b3p3/4P3/P1NP1N2/1PP1BPPP/R1BQK2R b KQ -
+Ruy Lopez: closed, Averbach variation *
+rnbr2k1/1pq1ppbp/5np1/p1pp4/3P4/1PP1PN2/P2NBPPP/R1BQ1RK1 w - -
+Catalan: closed, Zagoryansky variation *
+rnbr2k1/pp2qppp/5n2/2b1N3/3Pp3/P1N1B3/2PQBPPP/R4RK1 b - -
+Ruy Lopez: open, Howell attack, Ekstr\"om variation *
+rnq1kb1r/pp3ppp/4pn2/3p1b2/3P4/NQ2PN2/PP1B1PPP/R3KB1R b KQkq -
+QGD Slav: Landau variation
--- /dev/null
+1q3rk1/pp3ppp/2r1pn2/2bp4/4P3/2P5/PP1NQPPP/R1B2RK1 w - -
+QGD: Orthodox defense, classical, 13.d1b1 (Mar\'oczy) *
+1r2kb1r/p1pq2pp/Q1n5/3npp2/6b1/P2PPN2/1P3PPP/RNB1KB1R b KQk -
+Sicilian: Najdorf, Poisoned pawn variation *
+1rb2rk1/pp3ppp/5q2/3P4/1n6/2P1Q3/PP3PPP/RN2KB1R w KQ -
+Scotch: Gottschall variation
+1rbq1rk1/1pp1ppbp/p1np1np1/8/2PPP3/2N1BP2/PP1QN1PP/R3KB1R w KQ -
+King's Indian: S\"amisch, Panno main line
+1rbq1rk1/ppp1ppbp/2np1np1/8/2PPP3/2N1BP2/PP2N1PP/R2QKB1R w KQ -
+King's Indian: S\"amisch, Ruban variation
+1rbqk1nr/pp1pppbp/2n3p1/2p5/4P3/2N3P1/PPPP1PBP/R1BQK1NR w KQk -
+English: closed, 5.Rb1 *
+1rbqk1nr/pp1pppbp/2n3p1/2p5/4P3/2N3PN/PPPP1PBP/R1BQK2R b KQk -
+English: closed, 5.Rb1 Taimanov variation *
+1rbqkb1r/p4ppp/2p2n2/nB2p1N1/8/5Q2/PPPP1PPP/RNB1K2R w KQk -
+two knights defense: Colman variation
+2bqkbnr/r4ppp/p1npp3/1p6/4P3/1BN2N2/PP2QPPP/R1B2RK1 w k -
+Sicilian: Smith-Morra gambit, Chicago defense
+2kr1b1r/ppp3pp/2n2q2/3npp2/6b1/P2PPN2/1PQNBPPP/R1B1K2R b KQ -
+Sicilian: Najdorf, 7...Be7 main line *
+2kr1b1r/ppp3pp/2n5/3qpp2/6b1/3PPN2/PP2BPPP/R1BQ1RK1 w - -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 defense, 9...Nxd4 *
+2kr1b1r/pppq1ppp/2n5/3np3/6b1/P1NPPN2/1P1B1PPP/R2QKB1R b KQ -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 defense, 8...Bd7 *
+2kr1b1r/pppq2pp/2n1bp2/3np3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+Sicilian: dragon, Yugoslav attack, Rauser variation *
+2kr1b1r/pppq2pp/2n2n2/2Pp1p2/3Pp3/2N1P3/PP1NQPPP/R1B2RK1 b - -
+French: classical, St\a hlberg variation *
+2kr1b1r/pppq2pp/2n2n2/4pp2/1P6/P1NPPb2/3BBPPP/R2QK2R w KQ -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 defense, 11.Bxf6 *
+2kr1b1r/pppq2pp/2n5/3Npp2/6b1/3PPN2/PP2BPPP/R1BQ1RK1 b - -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 defense, 9...Nxd4 *
+2kr1b1r/pppq2pp/2n5/3npp2/4P1b1/2NP1N2/PP2BPPP/R1BQ1RK1 b - -
+Sicilian: Richter-Rauzer, Rauzer attack, Geller variation *
+2kr1b1r/pppq2pp/2n5/3npp2/6b1/2NPPN2/PP2BPPP/R1BQ1RK1 w - -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 defense, 9.f4 *
+2kr1b1r/pppq2pp/2n5/3npp2/6b1/P1NPPN2/1P1BBPPP/R2QK2R b KQ -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 defense, 9...Be7 *
+2kr3r/pp2bppp/2nqbn2/3pp1B1/8/1NN3P1/PPP1PPBP/R2Q1RK1 w - -
+Gr\"unfeld: Russian, Keres variation *
+2kr3r/ppp2ppp/1bn1bPq1/6N1/2ppNPP1/8/PPP4P/R1BQR1K1 w - -
+two knights: Max Lange attack, Berger variation
+2kr3r/pppb1ppp/2n1q2n/1Bb1p3/8/2NP1N2/PPP2PPP/R1BQR1K1 w - -
+Center game: Kupreichik variation *
+2kr3r/pppq2p1/1bn1bp2/3np2p/Q7/2NP1NP1/PP1BPPBP/R1R3K1 w - -
+Sicilian: dragon, Yugoslav attack, 12.h4 *
+2kr3r/pppq2pp/2n1bp2/2bnp3/8/2NP1NP1/PP1BPPBP/R2Q1RK1 w - -
+Sicilian: dragon, Yugoslav attack, 10.O-O-O *
+2kr3r/pppqbppp/1nn1p3/4Pb2/2PP4/2N1BN2/PP2B1PP/R2Q1RK1 w - -
+Alekhine's defense: four pawns attack, Tartakower variation
+2kr3r/pppqbppp/2n1b3/3np3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+Sicilian: dragon, classical, Grigoriev variation *
+2kr3r/ppq1nppp/2nbp3/3p4/3P2b1/5N2/PPP1BPPP/R1BQRNK1 w - -
+QGD: exchange, chameleon variation *
+2krr3/pppq1ppp/1bn5/3n4/QPN1p1b1/P2PPN2/1B3PPP/R3KB1R w KQ -
+Sicilian: Najdorf, Ivkov variation *
+2r1kb1r/1pq2ppp/p1n1pn2/2pp4/3P2b1/P1P1PN2/1P1NBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Rubinstein attack, Gr\"unfeld variation *
+2r1kb1r/ppq2ppp/2n1pn2/2pp4/3P2b1/2P1PN2/PP1NBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Rubinstein attack (with Rc1) *
+2r1kb1r/ppq2ppp/2n1pn2/2pp4/3P2b1/P1P1PN2/1P1NBPPP/R1BQ1RK1 b k -
+QGD: Orthodox defense, Rubinstein attack, Karlsbad variation *
+2r1kb1r/ppq2ppp/2n1pn2/2ppN3/3P2b1/2P1P3/PP1NBPPP/R1BQ1RK1 b k -
+QGD: Orthodox defense, Rubinstein attack, Wolf variation *
+2r1kb1r/ppq2ppp/2n1pn2/3p4/3p2b1/P1P1PN2/1P1NBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Rubinstein attack, main line *
+2rq1rk1/pp2ppbp/2n2np1/2Pp4/3P2b1/2N1BN2/PP2BPPP/R2Q1RK1 b - -
+QGD: Tarrasch, Bogolyubov variation *
+2rq1rk1/pp2ppbp/2n2np1/3p4/2PP2b1/1PN1BN2/P3BPPP/R2Q1RK1 b - -
+QGD: Tarrasch, Stoltz variation *
+2rq1rk1/pp3ppp/2n1pn2/2bp4/3N4/2P1P3/PP1NQPPP/R1B2RK1 w - -
+QGD: Orthodox defense, Bd3 line, 11.O-O *
+2rq1rk1/pp3ppp/2n1pn2/2bp4/8/2P1PB1P/PP1N1PP1/R1BQ1RK1 w - -
+QGD: Petrosian variation *
+2rqk2r/pp3pp1/2n1pn2/2bp3p/3N2b1/2P1P3/PP1NBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Bd3 line, Janowski variation *
+2rqk2r/pp3ppp/2n1pn2/2bp4/1P4b1/2P1PN2/P2NBPPP/R1BQ1RK1 b k -
+QGD: Orthodox defense, Bd3 line, fianchetto variation *
+2rqk2r/pp3ppp/2n1pn2/2bp4/3N2b1/2P1P3/PP1NBPPP/R1BQ1RK1 b k -
+QGD: Orthodox defense, Bd3 line, Capablanca freeing maneuver *
+2rqk2r/pp3ppp/2n1pn2/2bp4/3N4/2P1P3/PP1NQPPP/R1B2RK1 b k -
+QGD: Orthodox defense, Bd3 line *
+2rqk2r/pp3ppp/2n1pn2/3p4/1b1P2b1/1P3N2/P1PNBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Capablanca variation *
+2rqk2r/pp3ppp/2nbpn2/2pp4/3P2b1/2P1PN2/PP1NBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Bd3 line *
+2rqk2r/pp3ppp/2nbpn2/3p4/3P2b1/1P3N2/P1PNBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Pillsbury attack *
+2rqk2r/pp3ppp/4pn2/2bpn3/3N4/2P1P3/PP1NQPPP/R1B2RK1 w k -
+QGD: Orthodox defense, Bd3 line, Alekhine variation *
+2rqkb1r/pp1bpppp/2n2n2/2pp4/Q2P4/2P1PN2/PP1N1PPP/R1B1KB1R w KQk -
+QGD: Rochlin variation *
+2rqkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/2P1PN2/PP1NBPPP/R1BQ1RK1 b k -
+QGD: Orthodox defense *
+2rqkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, 7.Rc1 *
+2rqkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/P3PN2/1PPNBPPP/R1BQ1RK1 b k -
+QGD: Orthodox defense, Swiss (Henneberger) variation *
+2rqkb1r/pp3ppp/2n1pn2/3p4/3p2b1/P3PN2/1PPNBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Swiss, Karlsbad variation *
+2rqkb1r/pp3ppp/4pn2/3p4/3P4/1P2B2P/P1P1QPP1/RN3RK1 b k -
+QGD: Tartakower variation *
+2rqkbnr/pp3ppp/2n1p3/2p2b2/2pP4/4BNP1/PP2PPBP/RN1Q1RK1 b k -
+Gr\"unfeld: Gr\"unfeld gambit, Botvinnik variation *
+2rqkbnr/pp3ppp/2n1p3/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w k -
+Gr\"unfeld: Gr\"unfeld gambit, Capablanca variation *
+2rqkbnr/pp3ppp/2n1p3/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQ1RK1 w k -
+QGD: Anti-neo-orthodox variation *
+3q1rk1/pp3ppp/2r1p3/2b5/4Q3/2P5/PP3PPP/R1B2RK1 b - -
+QGD: Orthodox defense, classical, 13.de *
+3q1rk1/pp3ppp/2r1pn2/2bp4/4P3/2P5/PP1NQPPP/R1B2RK1 b - -
+QGD: Orthodox defense, classical variation *
+4rrk1/pppb2pp/2np1q2/2b2P2/4Q3/2N4B/PPPPNP1P/R1B1K2R w KQ -
+KGA: Muzio gambit, Paulsen variation *
+5rk1/5ppp/p1pbr3/1p1n3q/P2P2b1/1BPQB1P1/1P1N1P1P/R3R1K1 w - -
+Ruy Lopez: Marshall, main line, Spassky variation
+5rk1/ppq2ppp/2r1pn2/2bp4/4P3/2P5/PP1NQPPP/R1B2RK1 w - -
+QGD: Orthodox defense, classical, 13.d1c2 (Vidmar) *
+N1bk1b1r/p2pq2p/1pnn2p1/3Qpp2/8/1B6/PPPP1PPP/R1B1K1NR w KQ -
+Vienna: `Frankenstein-Dracula' variation
+N1bk3r/pp1p1ppp/2n2n2/8/1b6/P4B1q/1PPN1P1P/R1BQK2R b KQ -
+Scotch: Berger variation
+r1b1k1nr/ppp2ppp/1bn5/3p4/4P2q/2NN4/PPPP1PPP/R1BQKB1R w KQkq -
+Vienna: Adams' gambit *
+r1b1k1nr/ppp2ppp/2n5/q3P3/1b6/2N2N2/PPPB1PPP/R2QKB1R b KQkq -
+Scandinavian: Anderssen counter-attack orthodox attack
+r1b1k1nr/pppp1ppp/1b6/8/3qPP2/1PNN2P1/P2PQ2P/n1BK1B1R b kq -
+Vienna: `Frankenstein-Dracula' variation *
+r1b1k1nr/pppp1ppp/1b6/nP2N1q1/2B1P3/8/P1PP1PPP/RNBQK2R w KQkq -
+Evans gambit declined, Hirschbach variation
+r1b1k1nr/pppp1ppp/1bn5/8/4P2q/3N4/PPPPBPPP/RNBQK2R b KQkq -
+Vienna game *
+r1b1k1nr/pppp1ppp/2n2q2/1Nb5/4P3/4B3/PPP2PPP/RN1QKB1R b KQkq -
+Scotch: Blumenfeld attack
+r1b1k1nr/pppp1ppp/2n5/1N6/1b2P2q/8/PPPB1PPP/RN1QKB1R b KQkq -
+Scotch game
+r1b1k1nr/ppppqppp/1bn5/4p1B1/2BPP3/2P2N2/PP3PPP/RN1QK2R b KQkq -
+Giuoco Piano: Mestel variation
+r1b1k1nr/ppppqppp/1bn5/4p3/2BPP3/2P2N2/PP3PPP/RNBQK2R w KQkq -
+Giuoco Piano: center-holding variation
+r1b1k1nr/ppppqppp/2n5/1Bb1p3/4P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Ruy Lopez: classical defense, Boden variation
+r1b1k1nr/ppppqppp/2n5/2b1p3/2B1P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Giuoco Piano: close variation
+r1b1k1nr/pppq1ppp/1b6/n3N3/2B1P3/BQP5/P4PPP/RN3RK1 b kq -
+Evans gambit: Levenfish variation
+r1b1k2r/1pp1qppp/pbnp1n2/4p3/P1BPP3/2P2N1P/1P3PP1/RNBQR1K1 b kq -
+Giuoco Piano: Tarrasch variation
+r1b1k2r/1pp2ppp/p1n5/2bpq3/3NP3/2P1K3/PPN3PP/R1BQ1B1R b kq -
+two knights defense: Fegatello attack, Leonhardt variation *
+r1b1k2r/1pq1bppp/p1nppn2/8/P2NPP2/2N5/1PP1B1PP/R1BQ1R1K b kq -
+Sicilian: Scheveningen, classical, Mar\'oczy system
+r1b1k2r/1pqnbppp/p2ppn2/6B1/3NPP2/2N2Q2/PPP3PP/2KR1B1R w kq -
+Sicilian: Najdorf, 7...Be7 main line
+r1b1k2r/2q1bppp/p2p1n2/npp1p3/P2PP3/2P2N2/1PB2PPP/RNBQR1K1 b kq -
+Ruy Lopez: closed, Balla variation
+r1b1k2r/p1q2pp1/2pb1n1p/n3N3/3Pp3/8/PPPBBPPP/RN1QK2R b KQkq -
+two knights defense: Knorre variation
+r1b1k2r/pp1n1ppp/2p1pn2/q2p2B1/1bPP4/2N1P3/PPQN1PPP/R3KB1R b KQkq -
+QGD: Cambridge Springs defense, Bogolyubov variation
+r1b1k2r/pp3ppp/1qn1p3/2bp4/6n1/5NP1/PPPNPPBP/R1BQ1RK1 w kq -
+Gr\"unfeld: Pachman variation *
+r1b1k2r/pp3ppp/3b1q2/3P4/1P2n3/4PN2/5PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: Meran, Stahlberg variation *
+r1b1k2r/ppp1qppp/5n2/4p1B1/2BnP3/2N5/PPP3PP/R2Q1RK1 b kq -
+Giuoco piano: Holzhausen attack
+r1b1k2r/ppp2ppp/2N5/1B1pP3/4n2q/8/PPP2bPP/RNBQ1K1R w kq -
+Two knights defense, Keidanz variation
+r1b1k2r/ppp3p1/2np1q1p/2b1pP2/2B5/2NP1N2/PPP2PPP/R2QK2R b KQkq -
+KGD: classical, Svenonius variation *
+r1b1k2r/pppp1ppp/1bn5/8/4n2q/2NN4/PPPPBPPP/R1BQK2R w KQkq -
+Vienna: Alekhine variation *
+r1b1k2r/pppp1ppp/2n2q2/2b5/3NP3/4K3/PPP1N1PP/R1BQ1B1R b kq -
+two knights defense: Fegatello attack, Polerio defense *
+r1b1k2r/ppppnp1p/2n4b/4q3/2B2p2/2NP1Q2/PPPB2PP/4RRK1 b kq -
+KGA: Muzio gambit, Paulsen variation
+r1b1k2r/ppppnppp/2n2q2/1Bb5/3NP3/2P1B3/PP3PPP/RN1QK2R b KQkq -
+Scotch: Paulsen attack
+r1b1k2r/ppppnppp/2n2q2/2b5/3NP3/2P1B3/PP1Q1PPP/RN2KB1R b KQkq -
+Scotch: Blackburne attack
+r1b1k2r/ppppnppp/2n2q2/2b5/4P3/2P1B3/PPN2PPP/RN1QKB1R b KQkq -
+Scotch: Meitner variation
+r1b1k2r/ppppnppp/2n3q1/b3P3/2B5/1QN2N2/P4PPP/R1BR2K1 b kq -
+Evans gambit: compromised defense, Potter variation
+r1b1k2r/ppppnppp/2n3q1/b3P3/2B5/BQN2N2/P4PPP/R4RK1 b kq -
+Evans gambit: compromised defense, Paulsen variation
+r1b1kb1r/1pp3pp/p1n2n2/5pq1/2BPp3/2N1PP2/PP1N2PP/R1BQ1RK1 b kq -
+French: Steinitz, Brodsky-Jones variation *
+r1b1kb1r/1pq2ppp/p1nppn2/8/3NPP2/2N1B3/PPP1B1PP/R2Q1RK1 b kq -
+Sicilian: Scheveningen, classical
+r1b1kb1r/1pq2ppp/p1nppn2/8/3NPP2/2N5/PPP1B1PP/R1BQ1RK1 w kq -
+Sicilian: Scheveningen, classical variation with ...Qc7 and ...Nc6
+r1b1kb1r/2p1nppp/p1p5/3P4/3Pp3/4P3/PPQ1NP1q/RNB1K1R1 w Qkq -
+French: Winawer, advance, poisoned pawn, Konstantinopolsky variation *
+r1b1kb1r/p1q2pp1/2p2n1p/n3N3/4p3/8/PPPPBPPP/RNBQK2R w KQkq -
+two knights defense: G\"oring variation
+r1b1kb1r/p1q2ppp/2p2n2/n3p1N1/8/3B1Q2/PPPP1PPP/RNB1K2R b KQkq -
+two knights defense: Paoli variation
+r1b1kb1r/pp1n1ppp/2p1p3/q2n2B1/3P4/2N1PN2/PP3PPP/R2QKB1R w KQkq -
+QGD: Cambridge Springs defense, Yugoslav variation
+r1b1kb1r/pp1n1ppp/2p1pB2/q2p4/2PP4/2N1PN2/PP3PPP/R2QKB1R b KQkq -
+QGD: Cambridge Springs defense, Capablanca variation
+r1b1kb1r/pp1n1ppp/2p1pn2/q2P2B1/3P4/2N1PN2/PP3PPP/R2QKB1R b KQkq -
+QGD: Cambridge Springs defense, 7.cd
+r1b1kb1r/pp1n1ppp/2p1pn2/q2p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQkq -
+QGD: Cambridge Springs defense
+r1b1kb1r/pp1n1ppp/2p1pn2/q2p4/2PP4/2N2N2/PP1BPPPP/2RQKB1R b Kkq -
+QGD: Rochlin variation
+r1b1kb1r/pp1n1ppp/2p1pn2/q5B1/2pP4/2N1P3/PP1N1PPP/R2QKB1R w KQkq -
+QGD: Cambridge Springs defense, Rubinstein variation
+r1b1kb1r/pp1p1ppp/1qn1pn2/8/2PN4/2N3P1/PP2PP1P/R1BQKB1R w KQkq -
+English: symmetrical, Geller variation
+r1b1kb1r/pp1p1ppp/4pn2/1Bp5/3nPq2/2N2N2/PPPP1PPP/R1BQR1K1 w kq -
+English: four knights, Stean variation *
+r1b1kb1r/pp2pppp/1qn2n2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: Russian variation *
+r1b1kb1r/pp2pppp/1qn2n2/3p2B1/2PP4/2N5/PP3PPP/R2QKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik, Reifir (Spielmann) variation
+r1b1kb1r/pp2pppp/1qnp1n2/8/2BNP3/2N5/PPP2PPP/R1BQK2R w KQkq -
+Sicilian: Sozin, Benk\"o variation
+r1b1kb1r/pp2pppp/2n2n2/q1pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: Flohr variation *
+r1b1kb1r/pp2pppp/2n2n2/q2p2B1/2PP4/2N5/PP3PPP/R2QKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik, Czerniak variation
+r1b1kb1r/pp3ppp/1qn1pn2/2pp4/3P4/4PNP1/PPP2PBP/RNBQ1RK1 b kq -
+Gr\"unfeld: Botvinnik variation *
+r1b1kb1r/pp3ppp/1qn1pn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Gr\"unfeld with e3 & Qb3 *
+r1b1kb1r/pp3ppp/2n2n2/2qpp1B1/8/5NP1/PPP1PPBP/RN1Q1RK1 b kq -
+Gr\"unfeld: Russian, Smyslov variation *
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/1P3NP1/P1P1PPBP/RNBQ1RK1 b kq -
+Gr\"unfeld: Russian, Levenfish variation *
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/2N2NP1/PPP1PPBP/R1BQ1RK1 b kq -
+Gr\"unfeld: Russian, Byrne (Simagin) variation *
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/2P2NP1/PP2PPBP/RNBQ1RK1 b kq -
+Gr\"unfeld: Russian, Szabo (Boleslavsky) variation *
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Gr\"unfeld: Russian variation with e4 *
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/N4NP1/PPP1PPBP/R1BQ1RK1 b kq -
+Gr\"unfeld: Russian, Prins variation *
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/P4NP1/1PP1PPBP/RNBQ1RK1 b kq -
+Gr\"unfeld: Russian, Alekhine (Hungarian) variation *
+r1b1kb1r/pp3ppp/2n5/2pqp3/8/3P1NP1/PP2PP1P/R1BQKB1R b KQkq -
+Sicilian: accelerated fianchetto, Gurgenidze variation *
+r1b1kb1r/ppppq1pp/2n2n2/3Q4/8/5N2/PPP1PPPP/RNB1KB1R w KQkq -
+Queen's pawn: Englund gambit
+r1b1kb1r/ppppq1pp/2n2n2/4N1B1/3Pp3/8/PPP2PPP/RN1QKB1R w KQkq -
+Vienna gambit: Kaufmann variation *
+r1b1kb1r/ppppqppp/5n2/1B2N3/3nPP2/2N5/PPPP2PP/R1BQK2R b KQkq -
+Four knights: Rubinstein counter-gambit, Bogolyubov variation
+r1b1kb1r/ppq1pppp/2n2n2/1Bpp4/8/2NPPN2/PPP2PPP/R1BQK2R b KQkq -
+Nimzo-Indian: classical, Milner-Barry (Zurich) variation *
+r1b1kb1r/ppq2ppp/2n1pn2/2pp4/3P4/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: Stoltz variation *
+r1b1kb1r/ppqp1ppp/2B1pn2/2p5/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+English: four knights, Romanishin variation *
+r1b1kbnr/1p2pppp/p1q5/2pp4/1P6/4PN2/P1PP1PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: classical, Adorjan gambit *
+r1b1kbnr/1p2pppp/p1q5/2pp4/3P4/2N1PN2/PPP2PPP/R1BQK2R b KQkq -
+Nimzo-Indian: classical, Botvinnik variation *
+r1b1kbnr/1p2pppp/p1q5/2ppN3/3P4/4P3/PPP2PPP/RNBQK2R b KQkq -
+Nimzo-Indian: classical, Noa variation, main line *
+r1b1kbnr/1pp2ppp/p1pq4/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: exchange, Bronstein variation
+r1b1kbnr/1pq1pppp/p1n5/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R w KQkq -
+Nimzo-Indian: classical, Noa variation, 5.a3 *
+r1b1kbnr/1pq1pppp/p7/2ppN3/3P4/4P3/PPP2PPP/RNBQK2R w KQkq -
+Nimzo-Indian: classical, Noa variation, main line, 7.Qc2 *
+r1b1kbnr/1pq2ppp/p3p3/2ppN3/3PP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Nimzo-Indian: classical, San Remo variation *
+r1b1kbnr/1pqp1ppp/p1n1p3/8/3NP3/2N1B3/PPP1BPPP/R2QK2R b KQkq -
+Sicilian: Taimanov variation
+r1b1kbnr/2p2ppp/p1p5/3p2q1/2PPp3/4P3/PP2NPPP/RNBQK2R w KQkq -
+French: Winawer, advance, poisoned pawn variation *
+r1b1kbnr/p1p2ppp/2p5/3pN1q1/3Pp3/4P2P/PPP2PP1/RNBQ1K1R w kq -
+French: MacCutcheon, Duras variation *
+r1b1kbnr/p1pp1ppp/1pn5/8/3PPp1q/2N5/PPP1K1PP/R1BQ1BNR w kq -
+Vienna: Steinitz gambit, Fraser-Minckwitz variation
+r1b1kbnr/pp1qpppp/2np4/1B6/3QP3/5N2/PPP2PPP/RNB1K2R w KQkq -
+Sicilian: Chekhover, Zaitsev variation
+r1b1kbnr/pp2pppp/1qn5/1Bp5/2p5/2N1PN2/PP1P1PPP/R1BQK2R b KQkq -
+Nimzo-Indian: Spielmann, 4...c5, 5.dc Nc6 *
+r1b1kbnr/pp2pppp/1qn5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: Spielmann variation *
+r1b1kbnr/pp2pppp/1qn5/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Gr\"unfeld: Russian variation *
+r1b1kbnr/pp2pppp/2nq4/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: Mikenas attack *
+r1b1kbnr/pp3ppp/1qn1p3/2ppP3/3P4/2PB1N2/PP3PPP/RNBQK2R b KQkq -
+French: advance, Milner-Barry gambit
+r1b1kbnr/ppp1pppp/2n5/3q4/3P4/2N5/PPP2PPP/R1BQKBNR b KQkq -
+KP: Nimzovich defense, Marshall gambit
+r1b1kbnr/ppp1pppp/2n5/7q/8/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Novosibirsk opening *
+r1b1kbnr/ppp1qppp/2n5/4P3/2Pp4/5N2/PP1NPPPP/R1BQKB1R w KQkq -
+QGD: Albin counter-gambit, Balogh variation
+r1b1kbnr/ppp2ppp/2n5/1B1p2q1/2PPp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+French: Winawer, advance, Russian variation *
+r1b1kbnr/ppp2ppp/2n5/3p2q1/3Pp3/4P3/PPPN1PPP/RNBQKB1R w KQkq -
+French: Steinitz, Gledhill attack *
+r1b1kbnr/ppp2ppp/2n5/3p4/3PPp1q/2N5/PPP1K1PP/R1BQ1BNR w kq -
+Vienna: Steinitz gambit, Zukertort defense
+r1b1kbnr/ppp3pp/2n2q2/3pN3/3PpP2/8/PPP3PP/RNBQKB1R w KQkq -
+Vienna gambit: Heyde variation *
+r1b1kbnr/ppp3pp/2n5/5pq1/2BPp3/4P3/PP1N1PPP/RNBQK2R w KQkq -
+French: Steinitz, Bradford attack *
+r1b1kbnr/pppnq2p/8/4Npp1/3Q1P2/8/PPP3PP/RNB1KB1R w KQkq -
+KGD: Falkbeer, Charousek variation *
+r1b1kbnr/pppp1Npp/8/8/4q3/5n2/PPPPBP1P/RNBQKR2 w Qkq -
+Blackburne shilling gambit
+r1b1kbnr/pppp1p1p/2n5/4N3/2B1Pppq/8/PPPP2PP/RNBQ1K1R w kq -
+KGA: Herzfeld gambit
+r1b1kbnr/pppp1p1p/5q2/4n3/2B1PQ2/2N5/PPPP2PP/R1B2RK1 w kq -
+Vienna: Hamppe-Muzio, Dubois variation
+r1b1kbnr/pppp1ppp/2n2q2/4p3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: Goldman (Spielmann) variation *
+r1b1kbnr/pppp1ppp/2n5/1B2p1q1/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Vienna: Zhuravlev countergambit *
+r1b1kbnr/pppp1ppp/2n5/1N6/4P2q/8/PPP2PPP/RNBQKB1R b KQkq -
+Scotch: Horwitz attack
+r1b1kbnr/pppp1ppp/2n5/8/2B1Pp1q/8/PPPP2PP/RNBQ1KNR w kq -
+KGA: bishop's gambit, Boden defense
+r1b1kbnr/pppp1ppp/2n5/8/3NP2q/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Scotch: Steinitz variation
+r1b1kbnr/pppp1ppp/2n5/8/3NP2q/8/PPP2PPP/RNBQKB1R w KQkq -
+Scotch: Pulling counter-attack
+r1b1kbnr/pppp1ppp/2n5/8/4P2q/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Scotch: Fraser attack
+r1b1kbnr/pppp2pp/2n2q2/4N3/3Pp3/8/PPP2PPP/RNBQKB1R w KQkq -
+Vienna gambit: Paulsen attack *
+r1b1kbnr/pppp2pp/2n2q2/4N3/3PpP2/8/PPP3PP/RNBQKB1R b KQkq f3
+Vienna gambit: Bardeleben variation *
+r1b1kbnr/ppppq1pp/2n5/4Pp2/3p4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+KGD: Falkbeer, Rubinstein variation *
+r1b1kbnr/ppppqppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Vinogradov variation
+r1b1kbnr/ppq1pppp/2n5/1B1p4/3P4/5N2/PPP2PPP/RNBQK2R b KQkq -
+Nimzo-Indian: classical, Noa variation, 5.cd ed *
+r1b1kbnr/ppq1pppp/2n5/1Bp5/2p5/4PN2/PP1P1PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: classical, Pir\'c variation *
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+Nimzo-Indian: classical, 4...c5 *
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R b KQkq -
+Nimzo-Indian: classical, Noa variation *
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/8/2N1PN2/PPPP1PPP/R1BQK2R b KQkq -
+Nimzo-Indian: classical, 4...Nc6 *
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: classical variation *
+r1b1kbnr/ppqp1ppp/2n1p3/8/3NP3/2N1B3/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: Taimanov variation
+r1b1kbnr/ppqp1ppp/2n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Taimanov (Bastrikov) variation
+r1b1kbnr/ppqppppp/2n5/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Flohr variation
+r1b2knr/pppp3p/2n2qP1/2b1p2Q/6P1/8/PPPP1PBP/RNB1K1NR w KQ -
+KGA: bishop's gambit, Fraser variation *
+r1b2rk1/1p2qp1p/2n1pn2/pBbpN1p1/5B2/2P1P3/PP3PPP/RN1Q1RK1 w - -
+QGD Slav: Dutch, S\"amisch variation *
+r1b2rk1/1p2qppp/2n1pn2/pBbp4/5B2/2P1PN2/PP3PPP/RN1Q1RK1 w - -
+QGD Slav: Dutch variation, main line *
+r1b2rk1/1pp1qppp/2n2n2/p1bPp3/8/2PP1N2/PP1NBPPP/R1BQ1RK1 b - -
+Philidor: Nimzovich, Sozin variation *
+r1b2rk1/1pq1bppp/p1nppn2/8/3NPP2/2N1B3/PPP1B1PP/R3QRK1 w - -
+Sicilian: Scheveningen, classical main line
+r1b2rk1/2q1bppp/p1np1n2/1pP1p3/4P3/2P2N1P/PPBN1PP1/R1BQR1K1 b - -
+Ruy Lopez: closed, Chigorin, Rauzer attack
+r1b2rk1/2q1bppp/p1np1n2/1pp1p3/3PP3/2P2N1P/PPBN1PP1/R1BQR1K1 w - -
+Ruy Lopez: closed, Chigorin, 12...Nc6
+r1b2rk1/2q1bppp/p1pp1n2/np2p3/3PP3/2P2N1P/PPB2PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Rossolimo defense
+r1b2rk1/2q1bppp/p2p1n2/np2p3/3PP3/5N1P/PPBN1PP1/R1BQR1K1 b - -
+Ruy Lopez: closed, Chigorin, 12...c5d4
+r1b2rk1/2q1bppp/p2p1n2/npp1p3/3PP3/2P2N1P/PPB2PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Chigorin defense
+r1b2rk1/5ppp/p1pb4/1p1n4/3P4/1BP3Pq/PP3P1P/RNBQR1K1 w - -
+Ruy Lopez: Marshall, main line, 14...Qh3
+r1b2rk1/p1q2ppp/2n2n2/3pp3/N7/1B1P4/PPPB1bPP/R2Q1KNR w - -
+Evans gambit: Fraser-Mortimer attack *
+r1b2rk1/p4ppp/1qB2n2/2bp4/3P4/2N5/PPP2PPP/R1BQK2R b KQ -
+Giuoco Piano: Bernstein variation *
+r1b2rk1/p4ppp/2n2n2/q1bpp1B1/8/1BNP4/PPP2PPP/R2QK1NR w KQ -
+Evans gambit: Fraser attack *
+r1b2rk1/pp1n1ppp/2p1pn2/q2p4/1bPP3B/2N1P3/PPQN1PPP/R3KB1R b KQ -
+QGD: Cambridge Springs defense, Argentine variation
+r1b2rk1/pp1nqppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P1BPPP/R2Q1RK1 w - -
+Ruy Lopez: open, Malkin variation *
+r1b2rk1/pp1nqppp/2n1p3/3pP3/2pP1P2/2N2N2/PPPQ2PP/2KR1B1R w - -
+French: classical, St\a hlberg variation
+r1b2rk1/pp1nqppp/2p1p3/3n4/2BP4/2N1PN2/PP3PPP/2RQ1RK1 b - -
+QGD: Orthodox defense, Bd3 line, 11.O-O
+r1b2rk1/pp1nqppp/2p1p3/3n4/2BP4/2N1PN2/PP3PPP/2RQK2R w K -
+QGD: Orthodox defense, Bd3 line
+r1b2rk1/pp1nqppp/2p1p3/3n4/2BPN3/4PN2/PP3PPP/2RQK2R b K -
+QGD: Orthodox defense, Bd3 line, Alekhine variation
+r1b2rk1/pp1nqppp/2p5/4p3/2BP4/2R1PN2/PP3PPP/1Q3RK1 b - -
+QGD: Orthodox defense, classical, 13.d1b1 (Mar\'oczy)
+r1b2rk1/pp1nqppp/2p5/4p3/2BP4/2R1PN2/PP3PPP/3Q1RK1 w - -
+QGD: Orthodox defense, classical variation
+r1b2rk1/pp1nqppp/2p5/4p3/2BP4/2R1PN2/PPQ2PPP/5RK1 b - -
+QGD: Orthodox defense, classical, 13.d1c2 (Vidmar)
+r1b2rk1/pp2nppp/2pq1n2/3pp1B1/1b2P2N/1BNP4/PPP2PPP/R2Q1RK1 w - -
+Four knights: symmetrical, Blake variation
+r1b2rk1/pp2ppbp/1qnp1np1/4P3/3N1P2/2N1B3/PPP1B1PP/R2Q1RK1 b - -
+Sicilian: dragon, classical, Zollner gambit
+r1b2rk1/pp2ppbp/2nq1np1/2pp4/3P4/2P1PN2/PP1NBPPP/R1BQ1RK1 w - -
+Catalan: closed, Botvinnik variation *
+r1b2rk1/pp2ppbp/2q2np1/2pp4/8/1P2P3/PBPPBPPP/RN1Q1RK1 w - -
+Queen's Indian: old main line, 9.Qxc3 *
+r1b2rk1/pp2qppp/1bn2n2/4p3/1P6/P1NPP3/R4PPP/2BQKBNR b K -
+Sicilian: Smith-Morra gambit, Chicago defense *
+r1b2rk1/pp2qppp/2n1pn2/2bp4/2P1P3/2NB1N2/PP2QPPP/R1B2RK1 b - -
+QGD: Semi-Tarrasch, Levenfish variation
+r1b2rk1/pp2qppp/2nb1n2/2p1p3/2BP4/2N1PN2/PP2QPPP/R1B2RK1 w - -
+QGD: Semi-Tarrasch, Levenfish variation *
+r1b2rk1/pp3ppp/2p5/4q3/2B5/2R1P3/PP3PPP/3Q1RK1 w - -
+QGD: Orthodox defense, classical, 13.de
+r1b2rk1/ppp1qppp/2n2n2/1B1pp3/1b2P3/3P1N2/PPP1NPPP/R1BQ1RK1 w - -
+Four knights: Alatortsev variation
+r1b2rk1/ppp1qppp/2np1n2/1B2p1B1/4P3/2PP1N2/P1P2PPP/R2Q1RK1 w - -
+Four knights: symmetrical, Metger unpin
+r1b2rk1/pppp2pp/2n5/2b1pq2/4N3/5Q2/PPPP1P1P/R1B1KBNR b KQ -
+Vienna: Hamppe-Muzio, Dubois variation *
+r1b2rk1/ppq1ppbp/2n2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 w - -
+Dutch: Ilyin-Genevsky variation with Qc2 *
+r1b2rk1/ppqnppbp/5np1/2pp4/3P4/2P1PN2/PP1NBPPP/R1BQ1RK1 w - -
+Catalan: closed, main line *
+r1b3nr/ppppkBpp/1b6/nP2N1qQ/4P3/8/P1PP1PPP/RNB1K2R b KQ -
+Evans gambit declined, V\'asquez variation
+r1b3r1/ppp2k1p/1b6/nP2B1q1/3PP3/8/P1PN1PPP/R2QK2R b KQ -
+Evans gambit declined, Pavlov variation
+r1bB1rk1/pp3ppp/8/4p3/3nn3/3P4/PPP1KbPP/R2Q1BNR w - -
+Scotch: Sea-cadet mate *
+r1bk1bnr/2p2ppp/p1p5/3P4/3Pp3/4P3/PPQ1NP1q/RNB1K1R1 w Q -
+French: Winawer, advance, poisoned pawn, Euwe-Gligori\'c variation *
+r1bk2nr/pppp1Qpp/1b6/nP2q3/2B1P3/8/PBPP1PPP/RN2K2R b KQ -
+Evans gambit declined, Hicken variation
+r1bk2nr/pppp1ppp/2n3q1/1N6/8/8/PPPNBPPP/R2Q1RK1 w - -
+Scotch: Rosenthal variation
+r1bk2nr/ppppq1pp/2n5/2b1PP1Q/8/8/PPPP2PP/RNBK1BNR b - -
+KGA: L\'opez-Gianutio counter-gambit, Hein variation *
+r1bnk2r/ppppnppp/5q2/1Bb5/3NP3/2P1B3/PP3PPP/RN1QK2R w KQkq -
+Scotch: Paulsen, Gunsberg defense
+r1bq1b1r/ppn3pp/2p1k3/3np3/2BPQ3/P1N5/1PP2PPP/R1B1K2R w KQ -
+two knights defense: Fegatello attack, Leonhardt variation
+r1bq1b1r/ppp1n1pp/4k3/3np3/2B5/2N2Q2/PPPP1PPP/R1B1K2R w KQ -
+two knights defense: Fegatello attack, Polerio defense
+r1bq1b1r/ppp2kp1/2n5/1B1p1PPp/3Qn3/5N2/PPP2P1P/RNB1K2R w KQ -
+KGA: Kieseritsky, Brentano defense, Kaplanek variation *
+r1bq1bnr/ppp1k1pp/2n5/3ppP1Q/3P4/2N5/PPP2PPP/R1B1KBNR b KQ -
+Vienna: Steinitz gambit, Zukertort defense *
+r1bq1bnr/ppp1k1pp/2n5/3ppP1Q/8/1PN5/P1PP1PPP/R1B1KBNR b KQ -
+Vienna: Steinitz gambit, Fraser-Minckwitz variation *
+r1bq1k1r/2p2ppp/p4n2/1pbPR1N1/3n4/1B6/PPPP1PPP/RNBQ2K1 w - -
+Ruy Lopez: Rabinovich variation
+r1bq1k1r/pp2nppp/2n5/4p3/2Pp4/3P1NP1/4PP1P/RN1QKB1R w KQ -
+Benk\"o gambit: Ne2 variation *
+r1bq1knr/pp3p1p/2n3p1/4p3/2Pp4/3P1NP1/4PP1P/RN1QKB1R w KQ -
+Benk\"o gambit *
+r1bq1knr/ppp3pp/2n5/2bp1P1Q/4p1P1/3P4/PPP2PBP/RNB1K1NR w KQ -
+KGA: bishop's gambit, Grimm attack *
+r1bq1knr/ppp3pp/2n5/2bppP1Q/6P1/8/PPPPNPBP/RNB1K2R b KQ -
+KGA: bishop's gambit, classical defense *
+r1bq1knr/ppp4p/2n3p1/2bppP1Q/6P1/8/PPPPNPBP/RNB1K2R w KQ -
+KGA: bishop's gambit, McDonnell attack *
+r1bq1knr/pppp3p/2n3p1/2b1pP1Q/6P1/8/PPPP1PBP/RNB1K1NR w KQ -
+KGA: bishop's gambit, McDonnell attack *
+r1bq1r1k/1pp1b1pp/2n5/p2npp2/8/P1NPPN2/1PQ1BPPP/R1B1K2R w KQ -
+Sicilian: Scheveningen, classical, Mar\'oczy system *
+r1bq1rk1/1p1n1pbp/2pp1np1/p3p3/2PPP3/2N2N2/PP3PPP/R1BQRBK1 w - -
+King's Indian: orthodox, 7...Nbd7, main line
+r1bq1rk1/1p1nbppp/p1p1pn2/3P2B1/3P4/2N1PN2/PPQ2PPP/2R1KB1R b K -
+QGD: Orthodox defense, Rubinstein attack, main line
+r1bq1rk1/1p1nbppp/p1p1pn2/3p2B1/2PP4/2N1PN2/PPQ2PPP/2R1KB1R w K -
+QGD: Orthodox defense, Rubinstein attack, Karlsbad variation
+r1bq1rk1/1p1nbppp/p1p1pn2/3p2B1/2PP4/P1N1PN2/1PQ2PPP/2R1KB1R b K -
+QGD: Orthodox defense, Rubinstein attack, Gr\"unfeld variation
+r1bq1rk1/1p1nppbp/2n3p1/p7/2Pp4/P2P1NP1/1P1N1PBP/R1BQR1K1 b - -
+Benoni: fianchetto, 11...Re8 *
+r1bq1rk1/1p2bppp/2n2n2/p3p1B1/2Pp4/P2P1NP1/1P3PBP/RN1Q1RK1 b - -
+Benoni: classical with ...a6 and 10...Bg4 *
+r1bq1rk1/1p2bppp/2n2n2/p3p3/2Pp4/P2P1NP1/1P3PBP/RNBQ1RK1 w - -
+Benoni: classical, 9...a6, 10.a4 *
+r1bq1rk1/1p2ppbp/2np1np1/p7/2BNP3/2N1BP2/PPPQ2PP/R3K2R w KQ -
+Sicilian: dragon, Yugoslav attack, Byrne variation
+r1bq1rk1/1p2ppbp/2np1np1/p7/4P3/1NN1B3/PPP1BPPP/R2Q1RK1 w - -
+Sicilian: dragon, classical, Alekhine variation
+r1bq1rk1/1p3ppp/2n1pn2/pBbp4/5B2/2P1PN2/PP3PPP/RN1QK2R w KQ -
+QGD Slav: Dutch variation *
+r1bq1rk1/1p3ppp/p1n1pn2/1BbP4/8/2N1PN2/PP3PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, main line with 8...dc and 9...cd *
+r1bq1rk1/1pp1ppbp/p1np1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, Panno variation
+r1bq1rk1/1pp1ppbp/p1np1np1/8/2PPP3/2N1BP2/PP2N1PP/R2QKB1R w KQ -
+King's Indian: S\"amisch, Panno formation
+r1bq1rk1/1pp2ppp/1bn5/p2PN3/1P1P4/P7/2P2PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, Berger variation *
+r1bq1rk1/1ppnbppp/p3pn2/3P2B1/3P4/2N1PN2/PP3PPP/2RQKB1R b K -
+QGD: Orthodox defense, Swiss, Karlsbad variation
+r1bq1rk1/1ppnbppp/p3pn2/3p2B1/2PP4/2N1PN2/PP3PPP/2RQKB1R w K -
+QGD: Orthodox defense, Swiss (Henneberger) variation
+r1bq1rk1/2p1bpp1/p1np1n1p/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Smyslov defense
+r1bq1rk1/2p1bppp/2np1n2/pp2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Keres (9...a5) variation
+r1bq1rk1/2p1bppp/p1n2n2/1p1P4/4p3/1BP2N2/PP1P1PPP/RNBQR1K1 w - -
+Ruy Lopez: Marshall, Herman Steiner variation
+r1bq1rk1/2p1bppp/p1n2n2/1p1pp3/4P3/1BP2N2/PP1P1PPP/RNBQR1K1 w - -
+Ruy Lopez: Marshall counter-attack
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/3PP3/1BP2N2/PP3PPP/RNBQR1K1 b - -
+Ruy Lopez: closed, 9.d4
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 b - -
+Ruy Lopez: closed, 9.h3
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/1BP2N2/PP1P1PPP/RNBQR1K1 w - -
+Ruy Lopez: closed (with ...d6)
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/1BPP1N2/PP3PPP/RNBQR1K1 b - -
+Ruy Lopez: closed, Pilnik variation
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/2P2N2/PPBP1PPP/RNBQR1K1 b - -
+Ruy Lopez: closed, Lutikov variation
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/PBP2N2/1P1P1PPP/RNBQR1K1 b - -
+Ruy Lopez: closed, Suetin variation
+r1bq1rk1/2p1bppp/p2p1n2/np2p3/4P3/2P2N1P/PPBP1PP1/RNBQR1K1 b - -
+Ruy Lopez: closed (9...Na5)
+r1bq1rk1/2pnbppp/p1np4/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Ragozin-Petrosian (`Keres') variation
+r1bq1rk1/2pnbppp/p2p1n2/1p2p3/3PP2N/1BP4P/PP3PP1/RNBQR1K1 b - -
+Ruy Lopez: closed, Breyer, Simagin variation
+r1bq1rk1/2pnbppp/p2p1n2/1p2p3/3PP3/1BP2N1P/PP3PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Breyer, Borisenko variation
+r1bq1rk1/2ppbppp/p1n2n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQR1K1 w - -
+Ruy Lopez: closed, 7...O-O
+r1bq1rk1/2ppbppp/p1n2n2/1p2p3/4P3/1B3N2/PPPPQPPP/RNB2RK1 w - -
+Ruy Lopez: Worrall attack, sharp line
+r1bq1rk1/2ppbppp/p1n2n2/1p2p3/4P3/1BP2N2/PP1P1PPP/RNBQR1K1 b - -
+Ruy Lopez: closed, 8.c3
+r1bq1rk1/2ppbppp/p1n2n2/1p2p3/P3P3/1B3N2/1PPP1PPP/RNBQR1K1 b - -
+Ruy Lopez: closed, anti-Marshall 8.a4
+r1bq1rk1/3nbppp/p2p4/npp1p3/3PP3/2P2N1P/PPB2PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Keres (...Nd7) defense
+r1bq1rk1/4bppp/p1np1n2/1pp1p3/3PP3/2P2N1P/PPB2PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Borisenko defense
+r1bq1rk1/4bppp/p1p5/1p1nR3/3P4/1BP5/PP3PPP/RNBQ2K1 b - -
+Ruy Lopez: Marshall, main line, 12.d2d4
+r1bq1rk1/4bppp/p1p5/1p1nR3/8/1BP5/PP1P1PPP/RNBQ2K1 w - -
+Ruy Lopez: Marshall counter-attack, 11...c6
+r1bq1rk1/4bppp/p2p1n2/npp1p3/4P3/2P2N1P/PPBP1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed (10...c5)
+r1bq1rk1/4bppp/ppnppn2/8/2P1P3/N1N5/PP2BPPP/R1BQ1RK1 w - -
+Sicilian, Sz\'en, hedgehog variation
+r1bq1rk1/5ppp/p1p1pn2/2bp4/2P5/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, main line *
+r1bq1rk1/5ppp/p1pbpn2/2pp4/2PP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, main line with 8...Bxc3 *
+r1bq1rk1/5ppp/p2b4/1p1p4/3P4/2P1R3/PP3PPP/RNBQ2K1 b - -
+Ruy Lopez: Marshall, Kevitz variation
+r1bq1rk1/p1p2ppp/2pp1n2/4p3/1b1PP3/2N2N2/PPP2PPP/R1BQ1RK1 b - -
+Four knights: Svenonius variation *
+r1bq1rk1/p1pnbppp/1p3n2/1B1p2B1/3P4/2N1PN2/PP3PPP/2RQK2R b K -
+QGD: Orthodox defense, Capablanca variation
+r1bq1rk1/p1pnbppp/1p3n2/3p2B1/3P4/2NBPN2/PP3PPP/2RQK2R b K -
+QGD: Orthodox defense, Pillsbury attack
+r1bq1rk1/p1ppbppp/8/2p1P3/3B4/2N5/PPP1QPPP/R3R1K1 w - -
+Ruy Lopez: Berlin defense, Rio de Janeiro variation
+r1bq1rk1/p2nbppp/1pp1pn2/3p4/P1PP4/5NP1/1PQ1PPBP/RNBR2K1 b - -
+Catalan: closed, Zagoryansky variation
+r1bq1rk1/p2nbppp/2p1pn2/1p4B1/2BP4/2N1PN2/PP3PPP/2RQK2R w K -
+QGD: Orthodox defense, Bd3 line, fianchetto variation
+r1bq1rk1/p2pppbp/1pn2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w - -
+English: symmetrical, main line with b3 *
+r1bq1rk1/p3bppp/2n2n2/1pp1p3/3pP3/3P1NP1/PPP1NPBP/R1BQ1RK1 w - -
+King's Indian: orthodox, Aronin-Taimanov, bayonet attack *
+r1bq1rk1/p3nppp/2p5/2bpp3/8/1P4P1/P1PQPPBP/RNB2RK1 b - -
+Gr\"unfeld: exchange, Larsen variation *
+r1bq1rk1/p3ppbp/1pn2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 w - -
+Dutch: Ilyin-Genevsky variation with b3 *
+r1bq1rk1/p4ppp/2n2n2/2bpp1B1/8/1BNP4/PPP2PPP/R2QK1NR b KQ -
+Evans gambit *
+r1bq1rk1/p4ppp/2n2n2/2bpp3/8/1BNP4/PPP2PPP/R1BQK1NR w KQ -
+Evans gambit: Morphy attack *
+r1bq1rk1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N2NPP/PP3PB1/R1BQ1RK1 b - -
+King's Indian: fianchetto, classical main line
+r1bq1rk1/pp1n1pbp/3p1np1/2pP4/8/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+Benoni: fianchetto, 9...Nbd7
+r1bq1rk1/pp1n1pp1/2p1pb1p/8/2BP4/2N1PN2/PP3PPP/2RQ1RK1 b - -
+QGD: Petrosian variation
+r1bq1rk1/pp1n1ppp/1bp2n2/4N3/1PBPp3/P1N1B3/2P2PPP/R2QK2R w KQ -
+Ruy Lopez: open, St. Petersburg variation *
+r1bq1rk1/pp1n1ppp/1bp5/3P4/1PN1p1n1/P1N1B3/2P2PPP/R2QKB1R w KQ -
+Ruy Lopez: open, Bernstein variation, Karpov gambit *
+r1bq1rk1/pp1n1ppp/4pn2/2p5/1bBP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, Gligori\'c system, Bronstein variation
+r1bq1rk1/pp1n1ppp/4pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, Gligori\'c system with 7...Nbd7
+r1bq1rk1/pp1n2pp/2n1pp2/2bpP3/5PQ1/P1N2N2/1PP3PP/R1B1KB1R w KQ -
+French: Steinitz, Brodsky-Jones variation
+r1bq1rk1/pp1nb1pp/2n2p2/4p3/2Pp4/N2P1NP1/PP3PBP/R1BQR1K1 w - -
+Benoni: classical, 11.f3 *
+r1bq1rk1/pp1nbppp/2n5/4p3/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 w - -
+Benoni: classical, 9...Re8, 10.Nd2 *
+r1bq1rk1/pp1nbppp/2n5/4p3/2Pp4/N2P1NP1/PP3PBP/R1BQR1K1 b - -
+Benoni: classical with ...Re8 and ...Na6 *
+r1bq1rk1/pp1nbppp/2p1p3/3n2B1/2BP3P/2N1PN2/PP3PP1/2RQK2R b K -
+QGD: Orthodox defense, Bd3 line, Janowski variation
+r1bq1rk1/pp1nbppp/2p1p3/3n2B1/2BP4/2N1PN2/PP3PPP/2RQK2R w K -
+QGD: Orthodox defense, Bd3 line, Capablanca freeing maneuver
+r1bq1rk1/pp1nbppp/2p1p3/3p2B1/2PPn3/2N1PN2/PPQ2PPP/2R1KB1R w K -
+QGD: Orthodox defense, Rubinstein attack, Wolf variation
+r1bq1rk1/pp1nbppp/2p1pn2/3p2B1/2PP4/2N1PN2/PP3PPP/2RQKB1R w K -
+QGD: Orthodox defense
+r1bq1rk1/pp1nbppp/2p1pn2/3p2B1/2PP4/2N1PN2/PPQ2PPP/2R1KB1R b K -
+QGD: Orthodox defense, Rubinstein attack (with Rc1)
+r1bq1rk1/pp1nbppp/2p1pn2/3p2B1/2PP4/2NBPN2/PP3PPP/2RQK2R b K -
+QGD: Orthodox defense, Bd3 line
+r1bq1rk1/pp1nbppp/2p1pn2/3p4/2PP4/1P3NP1/P1Q1PPBP/RNB2RK1 b - -
+Catalan: closed, Qc2 & b3
+r1bq1rk1/pp1nbppp/2p1pn2/3p4/2PP4/2NQ1NP1/PP2PPBP/R1B2RK1 b - -
+Catalan: closed, Botvinnik variation
+r1bq1rk1/pp1nbppp/2p1pn2/3p4/2PP4/5NP1/PPQNPPBP/R1B2RK1 b - -
+Catalan: closed, main line
+r1bq1rk1/pp1nbppp/2p4n/3pp1N1/2BPPP2/2P5/PP4PP/RNBQ1RK1 w - -
+Philidor: Hanham, Berger variation
+r1bq1rk1/pp1nbppp/2pp1n2/8/P1BpP3/2N2N2/1PP1QPPP/R1B2RK1 w - -
+Philidor: Nimzovich, Sozin variation
+r1bq1rk1/pp1nbppp/4pn2/2pP2B1/3P4/2N1PN2/PPQ2PPP/R3KB1R b KQ -
+QGD: Orthodox defense, 7.Qc2 c5, 8.cd (Rubinstein)
+r1bq1rk1/pp1p1ppp/2n1pn2/2p5/2PP4/P1PBP3/5PPP/R1BQK1NR w KQ -
+Nimzo-Indian: S\"amisch, main line
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/1P2PN2/PB1PBPPP/RN1QK2R b KQ -
+English: symmetrical, hedgehog system *
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/1PN2NP1/P2PPPBP/R1BQ1RK1 b - -
+English: symmetrical, main line with b3
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/2NP1NP1/PP2PPBP/R1BQ1RK1 b - -
+English: symmetrical, main line with d3
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+English: symmetrical, main line with d4
+r1bq1rk1/pp1pppbp/2n2np1/8/2PN4/2N1P3/PP2BPPP/R1BQK2R b KQ -
+English: Symmetrical, Keres defense *
+r1bq1rk1/pp2b1pp/2n2n2/2pp4/4pB2/1N2PP2/PPP1B1PP/RN1Q1RK1 b - -
+Alekhine's defense: four pawns attack, Korchnoi variation *
+r1bq1rk1/pp2bppp/2n1pn2/2pp4/4P3/3P1NP1/PPPN1PBP/R1BQR1K1 b - -
+R\'eti: King's Indian attack, French variation
+r1bq1rk1/pp2bppp/2n2n2/2pp2B1/3P4/2N2NP1/PP2PPBP/R2Q1RK1 b - -
+QGD: Tarrasch, Prague variation, 9.Bg5
+r1bq1rk1/pp2bppp/2n2n2/2pp4/3P4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+QGD: Tarrasch, Prague variation, Normal position
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/2NP1NP1/PPP2PBP/R1BQ1RK1 b - -
+King's Indian: orthodox, Aronin-Taimanov variation (Yugoslav attack / Mar del Plata variation) *
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/2PP1NP1/PP3PBP/RNBQ1RK1 b - -
+King's Indian: orthodox, Donner variation *
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 w - -
+King's Indian: orthodox variation *
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 b - -
+King's Indian: orthodox, 7...Nbd7 *
+r1bq1rk1/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 w - -
+Benoni: classical, 9.O-O *
+r1bq1rk1/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 b - -
+Benoni: classical, 9...Re8 *
+r1bq1rk1/pp2bppp/2np1n2/4p1B1/3NPP2/2N5/PPPQ2PP/2KR1B1R w - -
+Sicilian: Richter-Rauzer, Rauzer attack, Geller variation
+r1bq1rk1/pp2bppp/2nppn2/6B1/3NPP2/2N5/PPPQ2PP/2KR1B1R b - -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 defense, 9.f4
+r1bq1rk1/pp2bppp/2nppn2/8/3NPP2/1BN1B3/PPP3PP/R2QK2R b KQ -
+Sicilian: Sozin, Fischer variation
+r1bq1rk1/pp2bppp/2nppn2/8/3NPP2/2N1B3/PPP1B1PP/R2Q1RK1 b - -
+Sicilian: modern Scheveningen, main line
+r1bq1rk1/pp2bppp/3ppn2/6B1/3QPP2/2N5/PPP3PP/2KR1B1R b - -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 defense, 9...Nxd4
+r1bq1rk1/pp2bppp/3ppn2/6B1/3nPP2/2N5/PPPQ2PP/2KR1B1R w - -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 defense, 9...Nxd4
+r1bq1rk1/pp2bppp/n1n5/2p1p3/8/PPNPPN2/4BPPP/R1BQ1RK1 b - -
+Sicilian, Sz\'en, hedgehog variation *
+r1bq1rk1/pp2ppbp/2n2np1/2p5/2Pp4/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, Yugoslav Panno *
+r1bq1rk1/pp2ppbp/2n2np1/2pp2B1/8/2NP1NP1/PPP1PPBP/R2Q1RK1 b - -
+King's Indian: fianchetto, Simagin variation *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w - -
+English: symmetrical, main line with d4 *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 w - -
+King's Indian: fianchetto, Yugoslav, 7.O-O *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/3P1P2/2P1PN2/PP2B1PP/RNBQ1RK1 b - -
+Dutch: stonewall with Nc3 *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/3P1P2/4PN2/PPP1B1PP/RNBQ1RK1 w - -
+Dutch: stonewall with Nc3 *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/4P3/2NP1NP1/PPP2PBP/R1BQ1RK1 b - -
+King's Indian: fianchetto, Uhlmann (Szabo) variation *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 b - -
+King's Indian: fianchetto, classical variation *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5B2/2NP1NP1/PPP1PPBP/R2Q1RK1 b - -
+King's Indian: fianchetto, lesser Simagin (Spassky) variation *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5B2/2PP1NP1/PP2PPBP/RN1Q1RK1 b - -
+King's Indian: fianchetto, Larsen system *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5P2/2NP1NP1/PPP1P1BP/R1BQ1RK1 b - -
+Dutch: Leningrad, main variation with Nc6 *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5P2/2PP1NP1/PP2P1BP/RNBQ1RK1 b - -
+Dutch: Leningrad, main variation with c6 *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 b - -
+Dutch: Ilyin-Genevsky variation *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/1P2PN2/PBPPBPPP/RN1Q1RK1 w - -
+Queen's Indian: old main line, 7.Nc3 *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/P1NP1NP1/1PP1PPBP/R1BQ1RK1 b - -
+King's Indian: fianchetto, Panno variation *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/Q7/2PP1NP1/PP2PPBP/RNB2RK1 b - -
+King's Indian: fianchetto, Kavalek (Bronstein) variation *
+r1bq1rk1/pp2ppbp/2n2np1/3p4/2PN4/6P1/PP2PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O c5, 8.Nc3 *
+r1bq1rk1/pp2ppbp/2n2np1/3p4/2PP4/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+QGD: Tarrasch, Prague variation, Normal position *
+r1bq1rk1/pp2ppbp/2n2np1/8/2Pp4/3P1NP1/PP1N1PBP/R1BQ1RK1 b - -
+Benoni: fianchetto, 9...Nbd7 *
+r1bq1rk1/pp2ppbp/2n3p1/8/2BPP3/4B3/P3NPPP/R2Q1RK1 b - -
+Gr\"unfeld: Spassky variation, main line, 10...cd, 11.cd
+r1bq1rk1/pp2ppbp/2np1np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w - -
+English: symmetrical, main line with d3 *
+r1bq1rk1/pp2ppbp/2np1np1/2pP4/2P5/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+King's Indian: fianchetto, Yugoslav Panno
+r1bq1rk1/pp2ppbp/2np1np1/8/2BNP3/2N1BP2/PPPQ2PP/R3K2R b KQ -
+Sicilian: dragon, Yugoslav attack, 9.Bc4
+r1bq1rk1/pp2ppbp/2np1np1/8/2PNPP2/2N1B3/PP2B1PP/R2QK2R b KQ -
+King's Indian: Four pawns attack, main line
+r1bq1rk1/pp2ppbp/2np1np1/8/3NP3/2N1B3/PPPQBPPP/2KR3R b - -
+Sicilian: dragon, classical, Grigoriev variation
+r1bq1rk1/pp2ppbp/2np1np1/8/3NP3/2N1B3/PPPQBPPP/R4RK1 b - -
+Sicilian: dragon, classical, Richter variation
+r1bq1rk1/pp2ppbp/2np1np1/8/3NP3/2N1BP2/PPPQ2PP/2KR1B1R b - -
+Sicilian: dragon, Yugoslav attack, Rauser variation
+r1bq1rk1/pp2ppbp/2np1np1/8/4P3/1NN1B3/PPP1BPPP/R2Q1RK1 b - -
+Sicilian: dragon, classical, 9.Nb3
+r1bq1rk1/pp2ppbp/5np1/n7/2BP4/2N2N2/PP3PPP/R1BQ1RK1 w - -
+QGD: Tarrasch, R\'eti variation *
+r1bq1rk1/pp3pb1/2n2npp/2ppp3/4P3/2PP1NP1/PP1N1PBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, classical main line *
+r1bq1rk1/pp3pbp/2n2np1/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, classical variation, 8.e4 *
+r1bq1rk1/pp3ppp/2B2n2/2b1N3/3p4/2N5/PPPP1PPP/R1BQK2R w KQ -
+Giuoco Piano: M\"oller (Therkatz) attack *
+r1bq1rk1/pp3ppp/2B2n2/2bpN3/8/2N5/PPPP1PPP/R1BQK2R b KQ -
+Giuoco Piano *
+r1bq1rk1/pp3ppp/2N2n2/1Bbp4/8/2N5/PPPP1PPP/R1BQK2R b KQ -
+Giuoco Piano: Greco variation *
+r1bq1rk1/pp3ppp/2n1pn2/1Bbp4/2P5/4PN2/PP1N1PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, Gligori\'c system, Bronstein variation *
+r1bq1rk1/pp3ppp/2n1pn2/1Bbp4/2P5/4PN2/PP2QPPP/RNB2RK1 b - -
+Nimzo-Indian: 4.e3, Gligori\'c system, Smyslov variation *
+r1bq1rk1/pp3ppp/2n1pn2/1Bbp4/2P5/4PN2/PP3PPP/RNBQ1RK1 w - -
+Nimzo-Indian: 4.e3, Gligori\'c system with 7...dc *
+r1bq1rk1/pp3ppp/2n1pn2/2p5/2BP4/P1P1PN2/5PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, main line
+r1bq1rk1/pp3ppp/2n1pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, main line with 7...Nc6
+r1bq1rk1/pp3ppp/2n1pn2/2pp4/2PP4/P1PBPN2/5PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, main line with 8...Bxc3
+r1bq1rk1/pp3ppp/2n1pn2/8/1bBp4/P1N1PN2/1P3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, main line with 8...dc and 9...cd
+r1bq1rk1/pp3ppp/2n2n2/2bp4/N7/5NP1/PP2PPBP/R1BQ1RK1 b - -
+QGD: Tarrasch, R\'eti variation
+r1bq1rk1/pp3ppp/2nbpn2/1BPp4/8/2N1PN2/PPP2PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, Ragozin variation *
+r1bq1rk1/pp3ppp/2nbpn2/1Bpp4/2PP4/1P2PN2/P4PPP/RNBQ1RK1 b - -
+Nimzo-Indian: 4.e3, Keres variation *
+r1bq1rk1/pp3ppp/2nbpn2/1Bpp4/2PP4/2N1PN2/PP3PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, main line with 7...Nc6 *
+r1bq1rk1/pp3ppp/2nbpn2/1Bpp4/2PP4/4PN2/PP1N1PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, Gligori\'c system with 7...Nbd7 *
+r1bq1rk1/pp3ppp/2nbpn2/2pp2B1/3P4/2P2NP1/PP2PPBP/RN1Q1RK1 b - -
+Gr\"unfeld: Smyslov defense *
+r1bq1rk1/pp3ppp/2nbpn2/2pp4/2PP4/2NBPN2/PP3PPP/R1BQ1RK1 b - -
+QGD: Semi-Tarrasch, symmetrical variation *
+r1bq1rk1/pp3ppp/2nbpn2/2pp4/2PP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+QGD: Semi-Tarrasch, symmetrical variation
+r1bq1rk1/pp3ppp/2nbpn2/2pp4/3P1B2/2P2NP1/PP2PPBP/RN1Q1RK1 b - -
+Gr\"unfeld: Flohr defense *
+r1bq1rk1/pp3ppp/3b4/3P4/1P2n3/4PN2/5PPP/R1BQKB1R w KQ -
+QGD semi-Slav: Meran, Sozin variation *
+r1bq1rk1/pp4bp/2nppnp1/2p5/2P1PPPP/2N5/PP2B3/R1BQK1NR b KQ -
+King's Indian: Six pawns attack
+r1bq1rk1/ppbn1Npp/2p2n2/8/1PBPp3/P1N1B3/2P2PPP/R2Q1RK1 b - -
+Ruy Lopez: open, Dilworth variation *
+r1bq1rk1/ppp1b1pp/2n5/3npp2/8/P1NPPN2/1PQ2PPP/R1B1KB1R b KQ -
+Sicilian: Scheveningen, classical variation with ...Qc7 and ...Nc6 *
+r1bq1rk1/ppp1bppp/2n1pn2/8/3PN3/P5N1/1PP1BPPP/R1BQK2R w KQ -
+French: Winawer, Alekhine gambit, Alatortsev variation
+r1bq1rk1/ppp1bppp/2n5/3np3/8/P2PPN2/1P1N1PPP/R1BQKB1R b KQ -
+Sicilian: Scheveningen, classical, Nd7 system *
+r1bq1rk1/ppp1bppp/2n5/3np3/8/P2PPN2/1PQ2PPP/RNB1KB1R b KQ -
+Sicilian: Scheveningen (Paulsen), classical variation *
+r1bq1rk1/ppp1npbp/3p1np1/3Pp3/1PP1P3/2N2N2/P3BPPP/R1BQ1RK1 b - -
+King's Indian: orthodox, Aronin-Taimanov, bayonet attack
+r1bq1rk1/ppp1npbp/3p1np1/3Pp3/2P1P3/2N5/PP2BPPP/R1BQNRK1 b - -
+King's Indian: orthodox, Aronin-Taimanov, 9.Ne1
+r1bq1rk1/ppp1nppN/3p4/3P4/2B1R3/8/PP3PPP/R2Q2K1 b - -
+Giuoco Piano: Therkatz-Herzog variation
+r1bq1rk1/ppp1nppp/3p1n2/1B2p1B1/1b2P3/2NP1N2/PPP2PPP/R2Q1RK1 w - -
+Four knights: symmetrical, Pillsbury variation
+r1bq1rk1/ppp1nppp/3p1n2/1B2p3/1b1PP3/2N2N2/PPP1QPPP/R1B2RK1 b - -
+Four knights: Alatortsev variation *
+r1bq1rk1/ppp1nppp/3p1n2/1B2p3/1b2P3/2NP1N2/PPP2PPP/R1BQ1RK1 w - -
+Four knights: symmetrical, Mar\'oczy system *
+r1bq1rk1/ppp1p1bp/2np1np1/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+Dutch: Leningrad, main variation with Nc6
+r1bq1rk1/ppp1ppbp/2n2np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Russian, Byrne (Simagin) variation
+r1bq1rk1/ppp1ppbp/2n3p1/8/2BPP3/2P5/P3NPPP/R1BQK2R w KQ -
+Gr\"unfeld: exchange, Simagin's improved variation
+r1bq1rk1/ppp1ppbp/2np1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+King's Indian: fianchetto with ...Nc6
+r1bq1rk1/ppp1ppbp/2np1np1/8/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+King's Indian: S\"amisch, 6...Nc6
+r1bq1rk1/ppp1ppbp/n2p1np1/8/2PPP3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+King's Indian: Kazakh variation
+r1bq1rk1/ppp1ppbp/n4np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Russian, Prins variation
+r1bq1rk1/ppp2pbp/2np1np1/4p3/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, Uhlmann (Szabo) variation
+r1bq1rk1/ppp2pbp/2np1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+King's Indian: orthodox, Aronin-Taimanov variation (Yugoslav attack / Mar del Plata variation)
+r1bq1rk1/ppp2ppp/1b1p1n2/4p3/N3P3/3P1B2/PPP2PPP/R1BQ1RK1 w - -
+Four knights: Rubinstein counter-gambit Mar\'oczy variation
+r1bq1rk1/ppp2ppp/2Bp1n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQ1RK1 b - -
+Four knights *
+r1bq1rk1/ppp2ppp/2n1pn2/8/1bpP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, Ragozin variation
+r1bq1rk1/ppp2ppp/2n2n2/1B1pp3/4P3/2PP1N2/P1P2PPP/R1BQ1RK1 w - -
+Four knights: Svenonius variation
+r1bq1rk1/ppp2ppp/2n2n2/3Pp3/1b6/2NP1N2/PPPB1PPP/R2QKB1R b KQ -
+Ruy Lopez: closed Berlin defense, Wolf variation *
+r1bq1rk1/ppp2ppp/2n2n2/3pp3/1b2P3/2NP1N2/PPPBBPPP/R2QK2R b KQ -
+Ruy Lopez: Berlin defense, hedgehog variation *
+r1bq1rk1/ppp2ppp/2n2n2/3pp3/4P3/2bP1N2/PPPBBPPP/R2QK2R w KQ -
+Ruy Lopez: closed Berlin defense, Showalter variation *
+r1bq1rk1/ppp2ppp/2np1n2/1B2p3/1b2P3/2N2N2/PPPP1PPP/R1BQ1RK1 w - -
+Four knights: double Ruy Lopez *
+r1bq1rk1/ppp2ppp/2np1n2/1B2p3/1b2P3/2NP1N2/PPP2PPP/R1BQ1RK1 b - -
+Four knights: symmetrical variation *
+r1bq1rk1/ppp2ppp/2np1n2/1B2p3/1b2P3/2NP1N2/PPP2PPP/R1BQ1RK1 w - -
+Four knights: symmetrical variation
+r1bq1rk1/ppp2ppp/2np1n2/1B2p3/1b2P3/3P1N2/PPP1NPPP/R1BQ1RK1 b - -
+Four knights: symmetrical, Mar\'oczy system
+r1bq1rk1/ppp2ppp/2np1n2/1B2p3/4P3/2PP1N2/P1P2PPP/R1BQR1K1 b - -
+Four knights: Janowski variation
+r1bq1rk1/ppp2ppp/3p1b2/n3p3/4P3/1B1P1N2/PPP2PPP/R1BQ1RK1 b - -
+Four knights: Rubinstein counter-gambit Mar\'oczy variation *
+r1bq1rk1/ppp3pp/2n2P2/2bp1PB1/8/2p5/PPP2P1P/R2QKBNR w KQ -
+Vienna: Pierce gambit, Rushmere attack *
+r1bq1rk1/ppp3pp/2n5/1B1p1p2/1b2p3/2N2N2/PPPP1PPP/R1BQ1RK1 b - -
+Four knights: Bardeleben variation *
+r1bq1rk1/pppn1pb1/3p3p/3Pp1pn/2P1P2P/2N2NB1/PP2BPP1/R2QK2R b KQ -
+King's Indian: Petrosian system, Keres variation
+r1bq1rk1/pppn1pbp/3p1np1/3Pp3/2P1P3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+King's Indian: Petrosian system, main line
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, classical variation
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+King's Indian: orthodox, 7...Nbd7
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQR1K1 b - -
+King's Indian: orthodox, 7...Nbd7, 8.Re1
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2NP1/PP3PBP/R1BQ1RK1 b - -
+King's Indian: fianchetto, classical variation, 8.e4
+r1bq1rk1/pppn1ppp/1b3n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R w KQ -
+Ruy Lopez: open, Bernstein variation *
+r1bq1rk1/pppnbBpp/3p1n2/4p1N1/3PP3/2N5/PPP2PPP/R1BQK2R b KQ -
+Philidor: Nimzovich, L\"arobok variation
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/1QN1PN2/PP3PPP/R3KB1R b KQ -
+QGD: Orthodox defense, Rauzer variation
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/2RQKB1R b K -
+QGD: Orthodox defense, 7.Rc1
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QGD: Orthodox defense
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PPQ2PPP/R3KB1R b KQ -
+QGD: Orthodox defense, Rubinstein variation
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2NBPN2/PP3PPP/R2QK2R b KQ -
+QGD: Orthodox defense, Botvinnik variation
+r1bq1rk1/pppnbppp/4pn2/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Catalan: closed, 6...Nbd7
+r1bq1rk1/pppnbppp/4pn2/3p4/2PP4/5NP1/PPQ1PPBP/RNB2RK1 b - -
+Catalan: closed, 7.Qc2
+r1bq1rk1/pppnn1bp/3p2p1/3Ppp2/2P1P1P1/2N2P2/PP2B2P/R1BQNRK1 b - -
+King's Indian: orthodox, Aronin-Taimanov, Benk\"o attack
+r1bq1rk1/pppnn1bp/3p2p1/3Ppp2/2P1P3/2N2P2/PP2B1PP/R1BQNRK1 w - -
+King's Indian: orthodox, Aronin-Taimanov, main line
+r1bq1rk1/pppnppbp/3p1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+King's Indian: fianchetto with ...Nd7
+r1bq1rk1/pppnppbp/5np1/6N1/2BP4/1QN1P3/PP3PPP/R1B1K2R b KQ -
+Gr\"unfeld: Pachman variation
+r1bq1rk1/pppp1ppp/1bn2n2/1B2p3/3PP3/2P2N2/PP3PPP/RNBQ1RK1 w - -
+Ruy Lopez: classical defense, Benelux variation
+r1bq1rk1/pppp1ppp/2B2n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQ1RK1 b - -
+Four knights: Nimzovich (Paulsen) variation
+r1bq1rk1/pppp1ppp/2n2n2/1B2P3/1b1P1P2/2N5/PPP3PP/R1BQ1RK1 w - -
+Four knights: Bardeleben variation
+r1bq1rk1/pppp1ppp/2n2n2/1B2p3/1b2P3/2NP1N2/PPP2PPP/R1BQ1RK1 b - -
+Four knights: double Ruy Lopez
+r1bq1rk1/pppp1ppp/2n2n2/1B2p3/4P3/2b2N2/PPPP1PPP/R1BQ1RK1 w - -
+Four knights: Nimzovich (Paulsen) variation *
+r1bq1rk1/pppp1ppp/2n2n2/1B2p3/4P3/2bP1N2/PPP2PPP/R1BQ1RK1 w - -
+Four knights
+r1bq1rk1/pppp1ppp/2n2n2/3Np3/1b2P3/5N2/PPPP1PPP/R1BQKB1R w KQ -
+Four knights: Rubinstein counter-gambit, Henneberger variation *
+r1bq1rk1/pppp1ppp/2n2n2/b3N3/2BPP3/2P5/P4PPP/RNBQ1RK1 b - -
+Evans gambit: Richardson attack
+r1bq1rk1/pppp1ppp/2n2n2/b3N3/4P3/P1N5/1PPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, Knorre variation *
+r1bq1rk1/pppp1ppp/2n5/1B1P4/1b2p3/5N2/PPPP1PPP/R1BQ1RK1 w - -
+Four knights: Gunsberg counter-attack
+r1bq1rk1/pppp1ppp/2n5/3Np3/1bB1n3/5N2/PPPP1PPP/R1BQ1RK1 b - -
+Four knights: Marshall variation *
+r1bq1rk1/pppp1ppp/5n2/1B2P3/1b1p4/2N5/PPPP1PPP/R1BQ1RK1 b - -
+Four knights: Gunsberg counter-attack *
+r1bq1rk1/pppp1ppp/5n2/1Bb1N3/3nP3/2N5/PPPP1PPP/R1BQ1RK1 w - -
+Four knights: Marshall variation
+r1bq1rk1/pppp1ppp/5n2/4n1N1/1bB5/8/PB3PPP/RN1Q1RK1 w - -
+Scotch gambit: Hanneken variation
+r1bq1rk1/pppp2pp/2n2n2/2b1pPP1/8/2N5/PPPP1P1P/R1BQKBNR w KQ -
+Vienna: Hamppe-Muzio gambit *
+r1bq2k1/pp3p1p/5n2/2b1r1p1/3p4/3P1B2/PPP1NPPP/R1BQK2R w KQ -
+Giuoco Piano: M\"oller, bayonet attack *
+r1bq3r/pp3pkp/2n2np1/4p3/2Pp4/3P1NP1/4PPBP/RN1Q1RK1 w - -
+Benk\"o gambit: main line *
+r1bq3r/ppp2k1p/2n3p1/2Qp4/3pP3/8/PPP2PPP/RNB1K2R w KQ -
+Scotch gambit: Cochrane-Shumov defense
+r1bq3r/ppp3pp/5k2/3pN3/1n1Pn3/1Q3P2/PP4PP/RN2K2R b KQ -
+Giuoco Piano: Krause variation
+r1bqk1nr/1ppp1ppp/p1n5/2b1p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Classical defense deferred
+r1bqk1nr/1ppp1ppp/p1n5/4p3/Bb2P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Alapin's defense deferred
+r1bqk1nr/1ppp1ppp/pbn5/4p3/PPB1P3/2N2N2/2PP1PPP/R1BQK2R b KQkq -
+Evans gambit declined, Showalter variation
+r1bqk1nr/2pp1ppp/p1n5/1pb1p3/4P3/1B3N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Graz variation
+r1bqk1nr/5ppp/p1pbp3/2pp4/2P5/2N1PN2/PP1P1PPP/R1BQ1RK1 b kq -
+Nimzo-Indian: S\"amisch, main line *
+r1bqk1nr/5ppp/p1pbp3/2pp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 w kq -
+Nimzo-Indian: 4.e3, Botvinnik system *
+r1bqk1nr/p1pp1ppp/2n5/bp2p3/2BPP3/2P2N2/P4PPP/RNBQK2R w KQkq -
+Evans gambit: Leonhardt variation
+r1bqk1nr/p4ppp/2p5/2bpp3/8/6P1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: exchange, classical variation *
+r1bqk1nr/pp1n1ppp/2pb4/3p4/2PPp3/1P2P3/P2N1PPP/RNBQKB1R b KQkq -
+French: Tarrasch, Botvinnik variation *
+r1bqk1nr/pp1n1ppp/2pb4/3p4/2PPp3/2N1P3/PP1N1PPP/R1BQKB1R b KQkq -
+French: Tarrasch, closed variation *
+r1bqk1nr/pp1nbppp/2pp4/4P3/2B1P3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Philidor: Hanham, Steiner variation
+r1bqk1nr/pp1p1pbp/2n1p1p1/2p2P2/2B1P3/2N2N2/PPPP2PP/R1BQK2R b KQkq -
+Sicilian: Grand Prix attack, Schofman variation
+r1bqk1nr/pp1p1pbp/2n1p1p1/2p5/2P1P3/2N3P1/PP1P1PBP/R1BQK1NR b KQkq -
+English: symmetrical, Botvinnik system reversed *
+r1bqk1nr/pp1p1pbp/2n3p1/1Bp1p3/1P2P3/5N2/P1PP1PPP/RNBQR1K1 b kq -
+Sicilian: Nimzovich-Rossolimo attack, Gurgenidze variation
+r1bqk1nr/pp1p1pbp/2n3p1/2p1p3/2P5/2N1P1P1/PP1P1PBP/R1BQK1NR w KQkq -
+English: symmetrical, Botvinnik system reversed
+r1bqk1nr/pp1p1pbp/2n3p1/2p1p3/2P5/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+English: symmetrical, Botvinnik system reversed
+r1bqk1nr/pp1p1pbp/2n3p1/2p1p3/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: symmetrical, Botvinnik system *
+r1bqk1nr/pp1p1pbp/4p1p1/2p5/3nP3/3PB1P1/PPP1NPBP/R2QK1NR b KQkq -
+Sicilian: closed, Smyslov variation
+r1bqk1nr/pp1p1ppp/2n5/2b5/2pNp3/3PP3/PPP2PPP/RNBQKB1R b KQkq -
+Alekhine's defense: two pawns' attack, Mikenas variation *
+r1bqk1nr/pp1pppbp/2N3p1/8/8/6P1/PPP1PP1P/RNBQKB1R b KQkq -
+English: Anglo-Gr\"unfeld, Smyslov defense *
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P1P3/2N3P1/PP1P1PBP/R1BQK1NR b KQkq -
+English: symmetrical, Botvinnik system
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+English: symmetrical variation
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR b KQkq -
+English: ultra-symmetrical variation *
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: ultra-symmetrical variation
+r1bqk1nr/pp1pppbp/2n3p1/2p5/4P3/2N3P1/PPPP1PBP/R1BQK1NR b KQkq -
+English: closed system *
+r1bqk1nr/pp1pppbp/2n3p1/2p5/4P3/2NPB3/PPP2PPP/R2QKBNR b KQkq -
+English, Tr\"oger defense *
+r1bqk1nr/pp1pppbp/2n3p1/8/2P5/8/PPN1PPPP/RNBQKB1R b KQkq -
+English: symmetrical, Rubinstein system *
+r1bqk1nr/pp1pppbp/2n3p1/8/2PNP3/4B3/PP3PPP/RN1QKB1R b KQkq -
+Sicilian: accelerated fianchetto, Mar\'oczy bind, 6.Be3
+r1bqk1nr/pp1pppbp/2n3p1/8/2PNP3/8/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: accelerated fianchetto, Mar\'oczy bind, 5...Bg7
+r1bqk1nr/pp1pppbp/2n3p1/8/8/1N4P1/PPP1PP1P/RNBQKB1R b KQkq -
+English: Anglo-Gr\"unfeld, Czech defense *
+r1bqk1nr/pp2b1pp/2n5/2pppp2/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+King's Indian: Four pawns attack, 6.Be2 *
+r1bqk1nr/pp2b3/2n5/2p1pppp/2P5/2NPPNP1/PP4BP/R1BQ1RK1 w kq -
+King's Indian: Six pawns attack *
+r1bqk1nr/pp2bppp/2n5/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: 5.Be2 *
+r1bqk1nr/pp2ppbp/2n3p1/2pp4/5P2/2PP1N2/PPQ1P1PP/RNB1KB1R b KQkq -
+Dutch: Hort-Antoshin system *
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2N3P1/PPPP1PBP/R1BQK1NR w KQkq -
+English: closed system (without ...d6) *
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NP2P1/PPP2PBP/R1BQK1NR b KQkq -
+English: closed system *
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NP2P1/PPP2PBP/R1BQK1NR w KQkq -
+Sicilian: closed
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NPB1P1/PPP2PBP/R2QK1NR b KQkq -
+Sicilian: closed, 6.Be3
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4PP2/2NP2P1/PPP3BP/R1BQK1NR b KQkq -
+Sicilian: closed, 6.f4
+r1bqk1nr/pp3pbp/2np2p1/2p1p3/4P3/2NP2P1/PPP1NPBP/R1BQK2R w KQkq -
+Sicilian: closed, 6.Ne2 e5 (Botvinnik)
+r1bqk1nr/pp3pbp/2np2p1/2p1p3/4P3/2NP2P1/PPP2PBP/R1BQK1NR w KQkq -
+English: Botvinnik system *
+r1bqk1nr/pp3pbp/2np2p1/2p1p3/4PP2/2NP2P1/PPP3BP/R1BQK1NR w KQkq -
+Sicilian: closed, 6.f4 e5 (Botvinnik)
+r1bqk1nr/pp3ppp/2nbp3/1Bpp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: 4.e3 O-O, 5.Bd3 d5 *
+r1bqk1nr/pp3ppp/2nbp3/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+Nimzo-Indian: 4.e3 O-O, 5.Bd3 *
+r1bqk1nr/pp3ppp/2nbp3/2pp4/4P3/3P1N2/PPPN1PPP/R1BQKB1R w KQkq -
+Old Indian: Dus-Khotimirsky variation *
+r1bqk1nr/pp3ppp/8/1Pb1p3/1nPp4/3P1N2/4PPPP/RNBQKB1R w KQkq -
+Benk\"o gambit: Nescaf\'e Frapp\'e attack *
+r1bqk1nr/pp4pp/2n5/4pp2/1bPp4/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+Benoni: Taimanov variation *
+r1bqk1nr/ppp1bp1p/2n5/3pp1p1/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+Pirc: Chinese variation *
+r1bqk1nr/ppp1bpp1/2n5/3pp2p/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+Pirc: bayonet (Mariotti) attack *
+r1bqk1nr/ppp1bppp/2n5/3pp3/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Pirc defense *
+r1bqk1nr/ppp1ppbp/2np2p1/8/2PPP3/2N5/PP3PPP/R1BQKBNR w KQkq -
+Modern defense: Averbakh system, Kotov variation
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P1P3/2NP2P1/PP3PBP/R1BQK1NR b KQkq -
+English: Botvinnik system
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR b KQkq -
+Sicilian: closed *
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR w KQkq -
+English: closed system
+r1bqk1nr/ppp2ppp/1b1p4/n2P4/2B1P3/5N2/PB3PPP/RN1Q1RK1 b kq -
+Evans gambit: Ulvestad variation
+r1bqk1nr/ppp2ppp/1b1p4/n5B1/2BPP3/2N2N2/P4PPP/R2Q1RK1 b kq -
+Evans gambit: G\"oring attack
+r1bqk1nr/ppp2ppp/1bnp4/4p3/2BPP3/2P2N2/P4PPP/RNBQ1RK1 w kq -
+Evans gambit: Lasker defense
+r1bqk1nr/ppp2ppp/1bnp4/8/2BPP3/2N2N2/P4PPP/R1BQ1RK1 b kq -
+Evans gambit: Morphy attack
+r1bqk1nr/ppp2ppp/1bnp4/8/2BPP3/5N2/P4PPP/RNBQ1RK1 w kq -
+Evans gambit: normal variation
+r1bqk1nr/ppp2ppp/1bnp4/8/2BPP3/5N2/PP3PPP/RNBQK2R w KQkq -
+Giuoco Piano: LaBourdonnais variation
+r1bqk1nr/ppp2ppp/2n1p3/8/3Pp3/P1N5/1PP2PPP/R1BQKB1R w KQkq -
+French: Winawer, Alekhine gambit, Kan variation
+r1bqk1nr/ppp2ppp/2n5/2bpp3/1PB1P3/5N2/P1PP1PPP/RNBQK2R w KQkq -
+Evans counter-gambit
+r1bqk1nr/ppp2ppp/2n5/2bpp3/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Pirc: Holmov system *
+r1bqk1nr/ppp2ppp/2nb4/3pp3/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+French: Swiss variation *
+r1bqk1nr/ppp2ppp/2np4/b3p1B1/2BPP3/2P2N2/P4PPP/RN1QK2R b KQkq -
+Evans gambit: Sokolsky variation
+r1bqk1nr/ppp2ppp/2np4/b3p3/2B1P3/2P2N2/P2P1PPP/RNBQ1RK1 w kq -
+Evans gambit
+r1bqk1nr/ppp2ppp/2np4/b3p3/2BPP3/1QP2N2/P4PPP/RNB1K2R b KQkq -
+Evans gambit: Tartakower attack
+r1bqk1nr/ppp2ppp/2np4/b3p3/2BPP3/2P2N2/P4PPP/RNBQK2R w KQkq -
+Evans gambit
+r1bqk1nr/ppp2ppp/2np4/b7/2BpP3/1QP2N2/P4PPP/RNB2RK1 b kq -
+Evans gambit: Waller attack
+r1bqk1nr/ppp2ppp/3b4/3pn3/8/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+Caro-Kann: Alekhine gambit *
+r1bqk1nr/ppp2ppp/8/2bp4/8/2P2P2/PP3PPP/RNBQKB1R w KQkq -
+Caro-Kann: Forg\'acs variation *
+r1bqk1nr/ppp3bp/2np2p1/4pp2/2P1P3/2NP2P1/PP3PBP/R1BQK1NR b KQkq -
+Sicilian: closed, 6.f4 e5 (Botvinnik) *
+r1bqk1nr/ppp3bp/2np2p1/4pp2/2P5/2NP2P1/PP2PPBP/R1BQK1NR w KQkq -
+Sicilian: closed, 6.f4 *
+r1bqk1nr/ppp3pp/1b1p1p2/n7/2BPP3/2N1BN2/P4PPP/R2Q1RK1 b kq -
+Evans gambit: Steinitz variation
+r1bqk1nr/ppp3pp/2n5/2bppp2/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+Pirc: Austrian attack, Ljubojevi\'c variation *
+r1bqk1nr/pppn1ppp/3p4/2b1p3/4PP2/2N2N2/PPPP2PP/R1BQKB1R w KQkq -
+KGD: classical, Hanham variation
+r1bqk1nr/pppp1Bpp/2n5/2b1p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Giuoco Piano: Jerome gambit
+r1bqk1nr/pppp1pbp/2n3p1/4p3/2P5/2N3P1/PP1PPPBP/1RBQK1NR b Kkq -
+English: closed, 5.Rb1
+r1bqk1nr/pppp1pbp/2n3p1/4p3/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: closed system
+r1bqk1nr/pppp1pbp/2n3p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR b KQkq -
+English: closed system (without ...d6)
+r1bqk1nr/pppp1ppp/1bn5/1B2p3/4P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Ruy Lopez: classical defense, Charousek variation
+r1bqk1nr/pppp1ppp/1bn5/4p3/1PB1P3/5N2/PBPP1PPP/RN1QK2R b KQkq -
+Evans gambit declined, Cordel variation
+r1bqk1nr/pppp1ppp/1bn5/4p3/PPB1P3/5N2/2PP1PPP/RNBQK2R b KQkq -
+Evans gambit declined, 5.a4
+r1bqk1nr/pppp1ppp/2n5/1B2p3/1b2P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Alapin's defense
+r1bqk1nr/pppp1ppp/2n5/1Bb1p3/4P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+Ruy Lopez: classical defense, 4.c3
+r1bqk1nr/pppp1ppp/2n5/1Bb1p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: classical (Cordel) defense
+r1bqk1nr/pppp1ppp/2n5/2b1N3/4P3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Vienna game *
+r1bqk1nr/pppp1ppp/2n5/2b1p3/1PB1P3/5N2/P1PP1PPP/RNBQK2R b KQkq -
+Evans gambit declined
+r1bqk1nr/pppp1ppp/2n5/2b1p3/2B1P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+Giuoco Piano
+r1bqk1nr/pppp1ppp/2n5/2b1p3/2B1P3/3P1N2/PPP2PPP/RNBQK2R b KQkq -
+Giuoco Pianissimo
+r1bqk1nr/pppp1ppp/2n5/2b1p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Giuoco Piano
+r1bqk1nr/pppp1ppp/2n5/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Vienna game *
+r1bqk1nr/pppp1ppp/2n5/2b1p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Vienna game *
+r1bqk1nr/pppp1ppp/2n5/2b3N1/2BpP3/8/PPP2PPP/RNBQK2R b KQkq -
+Scotch gambit
+r1bqk1nr/pppp1ppp/2n5/2b5/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Scotch game
+r1bqk1nr/pppp1ppp/2n5/2b5/4P3/1N6/PPP2PPP/RNBQKB1R b KQkq -
+Scotch: Potter variation
+r1bqk1nr/pppp1ppp/2n5/4p3/1bB1P3/5N2/P1PP1PPP/RNBQK2R w KQkq -
+Evans gambit
+r1bqk1nr/pppp1ppp/2n5/8/1b2P3/1N6/PPP2PPP/RNBQKB1R w KQkq -
+Scotch: Romanishin variation
+r1bqk1nr/pppp1ppp/2n5/8/1b2P3/2N2N2/PP3PPP/R1BQKB1R w KQkq -
+Scotch: G\"oring gambit
+r1bqk1nr/pppp1ppp/2n5/8/1bB1P3/2P2N2/P4PPP/RNBQK2R b KQkq -
+Scotch gambit
+r1bqk1nr/pppp1ppp/2n5/8/1bBpP3/5N2/PPP2PPP/RNBQK2R w KQkq -
+Scotch gambit
+r1bqk1nr/pppp1ppp/2n5/b3P3/2B5/2P2N2/P4PPP/RNBQK2R b KQkq -
+Scotch gambit: Cochrane variation
+r1bqk1nr/pppp1ppp/2n5/b3p3/2B1P3/2P2N2/P2P1PPP/RNBQ1RK1 b kq -
+Evans gambit
+r1bqk1nr/pppp1ppp/2n5/b3p3/2B1P3/2P2N2/P2P1PPP/RNBQK2R w KQkq -
+Evans gambit
+r1bqk1nr/pppp1ppp/2n5/b7/2B1P3/2p2N2/P4PPP/RNBQ1RK1 w kq -
+Evans gambit: compromised defense
+r1bqk1nr/pppp1ppp/2nb4/4p3/2B1P3/2P2N2/P2P1PPP/RNBQK2R w KQkq -
+Evans gambit: Stone-Ware variation
+r1bqk1nr/pppp1ppp/8/1Bb1p3/1P1nP3/5N2/P1PP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: classical defense, Zaitsev variation
+r1bqk1nr/pppp2pp/2n5/1Bb1pp2/4P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Cordel gambit
+r1bqk1nr/pppp2pp/2n5/1Bb2P2/4p3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+KGA: bishop's gambit, Paulsen attack *
+r1bqk1nr/pppp2pp/2n5/2b1p1N1/2B1Pp2/3P4/PPP2PPP/RNBQK2R w KQkq -
+Giuoco Pianissimo: Dubois variation
+r1bqk1nr/pppp2pp/2n5/2b1pP2/8/2P2N2/PP1P1PPP/RNBQKB1R b KQkq -
+KGA: bishop's gambit, Jaenisch variation *
+r1bqk1nr/pppp2pp/2n5/2b1pP2/8/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+KGA: bishop's gambit, Bogolyubov variation *
+r1bqk1nr/ppppbppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Lucena defense
+r1bqk1nr/ppppbppp/2n5/4p3/2B1P3/2P2N2/P2P1PPP/RNBQK2R w KQkq -
+Evans gambit: 5...Be7
+r1bqk1nr/ppppbppp/2n5/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Hungarian defense
+r1bqk1nr/ppppbppp/2n5/4p3/4P3/2P2N2/PP1P1PPP/RNBQKB1R w KQkq -
+Ponziani: Romanishin variation
+r1bqk1nr/ppppbppp/2n5/8/2BpP3/5N2/PPP2PPP/RNBQK2R w KQkq -
+Scotch gambit: Benima defense
+r1bqk1nr/ppppbppp/2n5/8/4P3/2P1Q3/PP3PPP/RNB1KBNR w KQkq -
+Center game: Charousek variation
+r1bqk1nr/ppppbppp/8/n3p3/2BPP3/2P2N2/P4PPP/RNBQK2R w KQkq -
+Evans gambit: Cordel variation
+r1bqk2r/1p1p1ppp/p1n1pn2/8/1bPNP3/2N5/PPB2PPP/R1BQK2R b KQkq -
+Sicilian: Kan, Mar\'oczy bind - Bronstein variation
+r1bqk2r/1pp1bppp/p1np1n2/4p3/B3P3/5N2/PPPP1PPP/RNBQR1K1 w kq -
+Ruy Lopez: closed, Averbach variation
+r1bqk2r/1pp1bppp/p5n1/3pn3/8/2N1PN2/PPP1BPPP/R1BQ1RK1 b kq -
+French: Winawer, Alekhine gambit, Alatortsev variation *
+r1bqk2r/1ppn1p1p/p4b1Q/1B6/8/2N2N2/PP1P1PPP/n1BK3R w kq -
+Scotch: Berger variation *
+r1bqk2r/1ppp1ppp/p1n2n2/2b1p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: M\"oller defense
+r1bqk2r/1pppbppp/p1B2n2/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: Exchange variation doubly deferred (DERLD)
+r1bqk2r/1pppbppp/p1n2n2/4p3/B2PP3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: closed, center attack
+r1bqk2r/1pppbppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: closed defense
+r1bqk2r/1pppbppp/p1n2n2/4p3/B3P3/5N2/PPPPQPPP/RNB2RK1 b kq -
+Ruy Lopez: Worrall attack
+r1bqk2r/1pppbppp/p1n5/4P3/B2pn3/2P2N2/PP3PPP/RNBQ1RK1 b kq -
+Ruy Lopez: closed, Basque gambit (North Spanish variation)
+r1bqk2r/2p1bppp/p1np1n2/1p2p3/3PP3/1B3N2/PPP2PPP/RNBQR1K1 b kq -
+Ruy Lopez: closed, 7...d6, 8.d4
+r1bqk2r/2p1bppp/p1np1n2/1p2p3/4P3/1B3N2/PPPPQPPP/RNB2RK1 w kq -
+Ruy Lopez: Worrall attack, solid line
+r1bqk2r/2pp1ppp/2n2n2/ppb1p3/4P3/PBN5/1PPP1PPP/R1BQK1NR w KQkq -
+Evans gambit declined, Showalter variation *
+r1bqk2r/2ppbppp/p1n2n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQR1K1 b kq -
+Ruy Lopez: closed
+r1bqk2r/2ppbppp/p1n2n2/1p2p3/P3P3/1B3N2/1PPP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: Wing attack
+r1bqk2r/4bppp/p2p1n2/1pp5/3QP3/1B6/PPP2PPP/RNB1R1K1 w kq -
+Ruy Lopez: Noah's ark trap
+r1bqk2r/4nppp/p1pb4/2ppp3/2P5/1PN1P3/P2P1PPP/R1BQNRK1 b kq -
+Nimzo-Indian: S\"amisch, Capablanca variation *
+r1bqk2r/5ppp/p1n1pn2/1pb1P3/2B5/5N2/PP2QPPP/RNB2RK1 b kq -
+QGA: classical, Furman variation
+r1bqk2r/p1ppbppp/2p5/4Pn2/8/5N2/PPP1QPPP/RNB2RK1 w kq -
+Ruy Lopez: Berlin defense, Cordel variation
+r1bqk2r/p3nppp/2p5/2bpp3/2P5/6P1/PP2PPBP/RNBQ1RK1 b kq -
+Gr\"unfeld: exchange, Spassky variation *
+r1bqk2r/p3nppp/2p5/2bpp3/8/1P4P1/P1P1PPBP/RNBQ1RK1 b kq -
+Gr\"unfeld: exchange, Simagin's lesser variation *
+r1bqk2r/p3nppp/2p5/2bpp3/8/2N3P1/PPP1PPBP/R1BQ1RK1 b kq -
+Gr\"unfeld: exchange, Simagin's improved variation *
+r1bqk2r/p4ppp/2pbpn2/2pp4/2P5/2NPPN2/PP3PPP/R1BQK2R b KQkq -
+Nimzo-Indian: e3, H\"ubner variation *
+r1bqk2r/pnppbppp/2p5/4P3/2P5/5N2/PP2QPPP/RNB2RK1 b kq -
+Ruy Lopez: Berlin defense, Zukertort variation
+r1bqk2r/pnppbppp/2p5/4P3/3N4/8/PPP1QPPP/RNB2RK1 b kq -
+Ruy Lopez: Berlin defense, Winawer attack
+r1bqk2r/pnppbppp/2p5/4P3/8/1P3N2/P1P1QPPP/RNB2RK1 b kq -
+Ruy Lopez: Berlin defense, Pillsbury variation
+r1bqk2r/pp1n1ppp/2p1pn2/3p4/1bPP4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Romih variation
+r1bqk2r/pp1n1ppp/2pbpn2/3p4/2PP4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Chigorin defense
+r1bqk2r/pp1n1ppp/3bpn2/2pp4/2PP4/4PN2/PP1N1PPP/R1BQKB1R b KQkq -
+QGD Slav: Semmering variation *
+r1bqk2r/pp1n1ppp/3bpn2/2ppN3/3P1P2/2P1P3/PP4PP/RNBQKB1R b KQkq -
+QGD: Stonewall variation *
+r1bqk2r/pp1nbppp/2p1pn2/3p4/2PP4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Bogolyubov variation
+r1bqk2r/pp1nnppp/3b4/3p4/3Pp3/1NN1P3/PP3PPP/R1BQKB1R b KQkq -
+French: Tarrasch, Leningrad variation *
+r1bqk2r/pp1nnppp/3b4/3p4/3Pp3/2N1P3/PP1N1PPP/R1BQKB1R w KQkq -
+French: Tarrasch, closed variation, main line *
+r1bqk2r/pp1p1ppp/2n1p3/2P5/1bP5/1QN2N2/PP1nPPPP/R3KB1R w KQkq -
+Nimzo-Indian: Spielmann, Karlsbad variation
+r1bqk2r/pp1p1ppp/2n1p3/2n5/1bP5/1QN2N2/PP1BPPPP/R3KB1R w KQkq -
+Nimzo-Indian: Spielmann, San Remo variation
+r1bqk2r/pp1p1ppp/2n1pn2/2P5/1bP5/1QN5/PP2PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: Spielmann, 4...c5, 5.dc Nc6
+r1bqk2r/pp1p1ppp/2nNpn2/8/1b2P3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Sicilian: Taimanov, American attack
+r1bqk2r/pp1p1ppp/2nb1n2/2p1p3/8/1P2PN2/PBPP1PPP/RN1QKB1R w KQkq -
+English: Queens Indian, Romanishin variation *
+r1bqk2r/pp1p2pp/2n1p3/2n2p2/1bP5/2N2NP1/PPQBPP1P/R3KB1R b KQkq -
+Nimzo-Indian: Spielmann, St\aa hlberg variation
+r1bqk2r/pp1pnpbp/2n1p1p1/2p5/4P3/2NP2PN/PPP2PBP/R1BQK2R b KQkq -
+English: closed, Taimanov variation *
+r1bqk2r/pp1pnpbp/2n1p1p1/2p5/4P3/2NPB1P1/PPP2PBP/R2QK1NR b KQkq -
+English: closed, Hort variation *
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P1P3/2N3P1/PP1P1PBP/R1BQK1NR b KQkq -
+English: symmetrical, Botvinnik system reversed *
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+English: symmetrical variation *
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+English: symmetrical variation
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: symmetrical variation *
+r1bqk2r/pp1pppbp/2n2np1/8/2BNP3/2N1B3/PPP2PPP/R2QK2R b KQkq -
+Sicilian: accelerated fianchetto, modern variation with Bc4
+r1bqk2r/pp1pppbp/2n2np1/8/3NP3/6P1/PPP2PBP/RNBQK2R b KQkq -
+English: Anglo-Gr\"unfeld defense, Korchnoi variation *
+r1bqk2r/pp1pppbp/2n3p1/8/2PNP1n1/2N1B3/PP3PPP/R2QKB1R w KQkq -
+Sicilian: accelerated fianchetto, Breyer variation
+r1bqk2r/pp2b1pp/2n2n2/2p1pp2/2Pp4/3PPNP1/PP3PBP/RNBQ1RK1 w kq -
+King's Indian: Four pawns attack *
+r1bqk2r/pp2b1pp/2n2n2/2p2p2/2PPp3/3P1NP1/PP3PBP/RNBQ1RK1 w kq -
+King's Indian: Four pawns attack, Florentine gambit *
+r1bqk2r/pp2b1pp/2n2n2/2pppp2/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 w kq -
+King's Indian: Four pawns attack, with Be2 and Nf3 *
+r1bqk2r/pp2b1pp/2n2n2/4pp2/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 b kq -
+Benoni: four pawns attack, main line *
+r1bqk2r/pp2bppp/2n1p3/2pn4/8/2N2NP1/PP1PPPBP/R1BQ1RK1 w kq -
+English: Symmetrical, Keres defense
+r1bqk2r/pp2bppp/2n2n2/2p1p3/3pP3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+King's Indian: Petrosian system *
+r1bqk2r/pp2bppp/2n2n2/2p1p3/3pP3/3P1NP1/PPPN1PBP/R1BQ1RK1 b kq -
+King's Indian: Petrosian system, main line *
+r1bqk2r/pp2bppp/2n2n2/2p1p3/4p3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+King's Indian: Andersson variation *
+r1bqk2r/pp2bppp/2n2n2/2p1p3/P2pP3/3P1NP1/1PP2PBP/RNBQ1RK1 b kq -
+King's Indian: Petrosian system, Stein variation *
+r1bqk2r/pp2bppp/2n2n2/2pp4/3P4/2N2NP1/PP2PPBP/R1BQK2R w KQkq -
+QGD: Tarrasch, Prague variation, 7...Be7
+r1bqk2r/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 b kq -
+King's Indian: classical variation *
+r1bqk2r/pp2bppp/2n2n2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+King's Indian: 6.Be2 *
+r1bqk2r/pp2bppp/2n2n2/2ppp3/8/N2P1NP1/PPP1PPBP/R1BQ1RK1 b kq -
+King's Indian: Kazakh variation *
+r1bqk2r/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+Benoni: classical without 9.O-O *
+r1bqk2r/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+Benoni: classical without 9.O-O *
+r1bqk2r/pp2bppp/2nppn2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R w KQkq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7
+r1bqk2r/pp2bppp/2nppn2/8/2BNP3/2N1B3/PPP1QPPP/R3K2R b KQkq -
+Sicilian: Velimirovi\'c attack
+r1bqk2r/pp2bppp/2nppn2/8/3NPP2/2N1BQ2/PPP3PP/R3KB1R b KQkq -
+Sicilian: Scheveningen, Tal variation
+r1bqk2r/pp2npbp/2n3p1/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+King's Indian: Pomar system *
+r1bqk2r/pp2ppbp/2n2np1/2pp4/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+King's Indian: fianchetto, Yugoslav system *
+r1bqk2r/pp2ppbp/2n2np1/2pp4/8/1P2PN2/PBPPBPPP/RN1QK2R w KQkq -
+Queen's Indian: anti-Queen's Indian system *
+r1bqk2r/pp2ppbp/2n2np1/2pp4/8/2NP1NP1/PPP1PPBP/R1BQ1RK1 b kq -
+King's Indian: fianchetto with ...Nc6 *
+r1bqk2r/pp2ppbp/2n2np1/2pp4/8/3P1NP1/PPPNPPBP/R1BQ1RK1 b kq -
+King's Indian: fianchetto with ...Nd7 *
+r1bqk2r/pp2ppbp/2n2np1/3p2B1/2PP4/2N2N2/PP3PPP/R2QKB1R b KQkq -
+QGD: Tarrasch, Wagner variation *
+r1bqk2r/pp2ppbp/2n2np1/3p4/2PP4/2N2N2/PP2BPPP/R1BQK2R b KQkq -
+QGD: Tarrasch, Prague variation, 7...Be7 *
+r1bqk2r/pp2ppbp/2n2np1/8/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+Benoni: fianchetto variation *
+r1bqk2r/pp2ppbp/2np1np1/8/3NP3/2N1B3/PPP1BPPP/R2Q1RK1 b kq -
+Sicilian: dragon, classical, 8.O-O
+r1bqk2r/pp2ppbp/2np1np1/8/3NP3/2N1B3/PPPQBPPP/R3K2R b KQkq -
+Sicilian: dragon, classical, Amsterdam variation
+r1bqk2r/pp2ppbp/2np1np1/8/4P3/1NN1B3/PPP1BPPP/R2QK2R b KQkq -
+Sicilian: dragon, classical, Nottingham variation
+r1bqk2r/pp2ppbp/2np2pn/8/2P1P3/8/PPN1BPPP/RNBQK2R w KQkq -
+Sicilian: accelerated fianchetto, Simagin variation
+r1bqk2r/pp3ppp/2n1pn2/2bp4/1P6/2P1PN2/P2N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Meran variation *
+r1bqk2r/pp3ppp/2n1pn2/2bp4/8/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: 7.Bc4 *
+r1bqk2r/pp3ppp/2n2n2/1Bb1p3/8/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Scotch: G\"oring gambit, Bardeleben variation *
+r1bqk2r/pp3ppp/2n2n2/1Bbpp3/8/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Giuoco Piano: Greco's attack *
+r1bqk2r/pp3ppp/2nb1n2/1P1pp3/8/P1P1PN2/3N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Meran, Pir\'c variation *
+r1bqk2r/pp3ppp/2nb1n2/3p4/1PP1p3/P3PN2/3N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: Meran, old main line *
+r1bqk2r/pp3ppp/2nb1n2/3pp3/1PP5/P3PN2/3N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Meran *
+r1bqk2r/pp3ppp/2nb1n2/4p3/1PPp4/P3PN2/3N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: Meran, Reynolds' variation *
+r1bqk2r/pp3ppp/2nbpn2/1Bpp4/2PP4/4PN2/PP3PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: 4.e3, main line with ...c5 *
+r1bqk2r/pp3ppp/2nbpn2/1Bpp4/3P4/1P2PN2/P1P2PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: 4.e3, main line with ...b6 *
+r1bqk2r/pp3ppp/2nbpn2/1Bpp4/3P4/2P1PN2/PP1N1PPP/R1BQK2R b KQkq -
+QGD semi-Slav: Romih variation *
+r1bqk2r/pp3ppp/2nbpn2/1P1p4/8/2P1PN2/P2N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: neo-Meran (Lundin variation) *
+r1bqk2r/pp3ppp/2nbpn2/2pp4/3P4/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: 6.Bd3 *
+r1bqk2r/pp3ppp/2nbpn2/2pp4/3P4/2P1PN2/PP1NBPPP/R1BQK2R b KQkq -
+QGD semi-Slav: Bogolyubov variation *
+r1bqk2r/pp3ppp/2nbpn2/2pp4/3P4/2PBPN2/PP1N1PPP/R1BQK2R b KQkq -
+QGD semi-Slav: Chigorin defense *
+r1bqk2r/pp3ppp/2nbpn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Gr\"unfeld with e3 & Bd3 *
+r1bqk2r/pp3ppp/2nbpn2/2ppN3/3P1P2/2P1P3/PP4PP/RNBQKB1R b KQkq -
+QGD semi-Slav: stonewall defense *
+r1bqk2r/pp3ppp/2nbpn2/3p4/1P6/2P1PN2/PB1N1PPP/R2QKB1R b KQkq -
+QGD semi-Slav: Meran, Wade variation *
+r1bqk2r/pp3ppp/2nbpn2/3p4/1P6/P1P1PN2/3N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Meran, 8...a6 *
+r1bqk2r/pp3ppp/2nbpn2/3p4/2PN4/2N1P3/PP3PPP/R1BQKB1R w KQkq -
+QGD: Semi-Tarrasch, 7.Bd3 *
+r1bqk2r/pp3ppp/2nppn2/2p5/2PP4/2PBPN2/P4PPP/R1BQK2R w KQkq -
+Nimzo-Indian: e3, H\"ubner variation
+r1bqk2r/pp3ppp/3b1n2/3P2N1/1n2p3/P3P3/3N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Meran, Rabinovich variation *
+r1bqk2r/pp3ppp/3b1n2/3P4/1n2N3/P3PN2/5PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Meran, Sozin variation *
+r1bqk2r/pp3ppp/3b1n2/3P4/1n2p3/P3PN2/3N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: Meran, Blumenfeld variation *
+r1bqk2r/ppb2ppp/2n5/1Bpnp3/8/P1N1PN2/1P1P1PPP/R1BQK2R w KQkq -
+Sicilian: Kan, Mar\'oczy bind - Bronstein variation *
+r1bqk2r/ppp1bpp1/5n1p/3P4/2P1p3/5N2/PPP1QPPP/RNB1K2R w KQkq -
+two knights defense: Mar\'oczy variation
+r1bqk2r/ppp1bppp/1nn5/4p3/4P3/2NP1N2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Boleslavsky variation, 7.Nb3 *
+r1bqk2r/ppp1bppp/2n2n2/3pp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+Pirc: classical system, 5.Be2 *
+r1bqk2r/ppp1bppp/2n5/1B1pp3/3Pn3/5N2/PPP1QPPP/RNB2RK1 w kq -
+Ruy Lopez: Berlin defense, Trifunovi\'c variation
+r1bqk2r/ppp1bppp/2n5/3np3/4P3/2NP1N2/PP3PPP/R1BQKB1R b KQkq -
+Sicilian: Boleslavsky variation *
+r1bqk2r/ppp1bppp/2n5/3np3/8/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+Sicilian: classical *
+r1bqk2r/ppp1bppp/2n5/3np3/8/2NPPN2/PP3PPP/R1BQKB1R b KQkq -
+Sicilian: modern Scheveningen *
+r1bqk2r/ppp1bppp/2n5/3np3/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Scheveningen, 6.Be2 *
+r1bqk2r/ppp1bppp/2n5/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, Opo\v censky variation *
+r1bqk2r/ppp1bppp/2n5/3np3/8/P2PPN2/1P3PPP/RNBQKB1R b KQkq -
+Sicilian: Scheveningen (Paulsen), classical variation *
+r1bqk2r/ppp1bppp/2n5/3p4/2PPn3/3B1N2/PP3PPP/RNBQ1RK1 b kq -
+Petrov: classical attack, Jaenisch variation
+r1bqk2r/ppp1bppp/2n5/3p4/3Pn3/3B1N2/PPP2PPP/RNBQR1K1 b kq -
+Petrov: classical attack, Chigorin variation
+r1bqk2r/ppp1bppp/2n5/4p3/4P3/2nP1N2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Boleslavsky, Louma variation *
+r1bqk2r/ppp1npbp/2np2p1/4p3/2P1P3/2NP2P1/PP3PBP/R1BQK1NR b KQkq -
+Sicilian: closed, 6.Ne2 e5 (Botvinnik) *
+r1bqk2r/ppp1nppp/1b1p4/n2P4/2B1P3/5N2/PB3PPP/RN1Q1RK1 w kq -
+Evans gambit: Paulsen variation
+r1bqk2r/ppp1nppp/3p1b2/3P4/2B1R1P1/5N2/PP3P1P/R1BQ2K1 b kq -
+Giuoco Piano: M\"oller, bayonet attack
+r1bqk2r/ppp2pbp/2np2pn/4p3/2P5/2N1P1P1/PP1PNPBP/R1BQK2R w KQkq -
+English: closed, Taimanov variation
+r1bqk2r/ppp2pp1/5n1p/2bP4/2P1p3/8/PPPNQPPP/RNB1K2R b KQkq -
+two knights defense: Yankovich variation
+r1bqk2r/ppp2ppp/1bn5/3np3/1P6/P2PPN2/5PPP/RNBQKB1R b KQkq -
+Sicilian: Sozin with ...a6 and ...b5 *
+r1bqk2r/ppp2ppp/2n1pn2/3p4/2PP4/P1Q5/1P2PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, Botvinnik variation
+r1bqk2r/ppp2ppp/2n2n2/2bpP3/2Bp4/2P2N2/PP3PPP/RNBQK2R w KQkq d6
+Giuoco Piano
+r1bqk2r/ppp2ppp/2n2n2/2bpp3/4P3/2PP4/PP1N1PPP/R1BQKBNR w KQkq -
+Philidor: Hanham, Schlechter variation *
+r1bqk2r/ppp2ppp/2n2n2/3pp3/4P3/2bP1N2/PPPB1PPP/R2QKB1R w KQkq -
+Ruy Lopez: old Steinitz defense, Nimzovich attack *
+r1bqk2r/ppp2ppp/2n5/1B1pP3/1b1Pn3/5N2/PP3PPP/RNBQK2R w KQkq -
+Giuoco Piano: Anderssen variation
+r1bqk2r/ppp2ppp/2n5/2b5/4p3/2PP1NP1/P3PP1P/R1BQKB1R w KQkq -
+Sicilian: Magnus Smith trap *
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/1QNP1N2/PP2PPPP/R1B1KB1R b KQkq -
+Sicilian: Sozin, Benk\"o variation *
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+Sicilian: Sozin, not Scheveningen *
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/2NPPN2/PP3PPP/R1BQKB1R b KQkq -
+Sicilian: Sozin, Leonhardt variation *
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Sozin attack *
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, Lipnitzky attack *
+r1bqk2r/ppp2ppp/2n5/3np1N1/1bBP4/8/PPP2PPP/RNBQK2R w KQkq -
+two knights defense: Pincus variation
+r1bqk2r/ppp2ppp/2n5/3np3/1b2P3/3P1N2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Venice attack *
+r1bqk2r/ppp2ppp/2n5/3np3/1b6/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Scheveningen, Vitoli\'n\'s variation *
+r1bqk2r/ppp2ppp/2n5/3p4/2BP4/1Qb2N2/P4PPP/R1B2RK1 w kq -
+Giuoco Piano: Bernstein variation
+r1bqk2r/ppp2ppp/2n5/3p4/2BPn3/B1P2N2/P4PPP/R2Q1RK1 b kq -
+Giuoco Piano: Steinitz variation
+r1bqk2r/ppp2ppp/2n5/3pp3/2PPn3/P3P3/1PQ2PPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, San Remo variation
+r1bqk2r/ppp2ppp/2n5/3pp3/4P1n1/3P1N2/PPPNBbPP/R1BQ1RK1 w kq -
+Philidor: Nimzovich, L\"arobok variation *
+r1bqk2r/ppp2ppp/2nb4/1B1np3/4P3/5N2/PP1P1PPP/RNBQK2R b KQkq -
+Sicilian: Pin, Jaffe variation *
+r1bqk2r/ppp2ppp/2np1n2/2b1p1B1/2B1P3/2NP1N2/PPP2PPP/R2QK2R b KQkq -
+Giuoco Pianissimo: Canal variation
+r1bqk2r/ppp2ppp/2np1n2/2b1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Giuoco Pianissimo: Italian four knights variation *
+r1bqk2r/ppp2ppp/2np1n2/4p3/4P3/P1P2P2/1PP3PP/R1BQKBNR w KQkq -
+Ruy Lopez: exchange, Romanovsky variation *
+r1bqk2r/ppp2ppp/2nppn2/8/1bPP4/2N2N2/PPQ1PPPP/R1B1KB1R w KQkq -
+Nimzo-Indian: classical, Milner-Barry (Zurich) variation
+r1bqk2r/ppp2ppp/3p1n2/4p1B1/2BnP3/8/PPP2PPP/RN1Q1RK1 w kq -
+Giuoco piano
+r1bqk2r/ppp3p1/2n5/2bppPPp/4n2P/7B/PPPP1P1R/RNBQK1N1 w Qkq -
+KGA: Kieseritsky, long whip defense, Jaenisch variation *
+r1bqk2r/ppp3pp/2nb1n2/3ppp2/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Pirc: Austrian attack, 6.Bd3 *
+r1bqk2r/pppn1ppp/4pn2/3p2B1/1bPP4/2N1P3/PP3PPP/R2QKBNR w KQkq -
+QGD: Manhattan variation
+r1bqk2r/pppn1ppp/5n2/2bP4/8/4P3/PP3PPP/RNBQKBNR b KQkq -
+French: Tarrasch, Eliskases variation *
+r1bqk2r/pppnbppp/3p1n2/4p3/3P4/2N1PN2/PPP2PPP/R1BQKB1R w KQkq -
+French: Reversed Philidor formation *
+r1bqk2r/pppnbppp/3p1n2/4p3/3PP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Inverted Hanham *
+r1bqk2r/pppp1p2/5n1p/4p1p1/2BnPP1B/8/PPP3PP/RN1Q1RK1 b kq -
+Giuoco piano: Rosentreter variation
+r1bqk2r/pppp1pbp/2n3pn/4p3/2P5/2N3P1/PP1PPPBP/1RBQK1NR w Kkq -
+English: closed, 5.Rb1 Taimanov variation
+r1bqk2r/pppp1pp1/5n1p/4n3/2PN3B/2P5/P3PPPP/R2QKB1R w KQkq -
+English: Nenarokov variation
+r1bqk2r/pppp1ppp/1b5n/nP2N3/2B1P3/8/P1PP1PPP/RNBQK2R w KQkq -
+Evans gambit declined, Lange variation
+r1bqk2r/pppp1ppp/2n1pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+Nimzo-Indian: 4.e3, Taimanov variation
+r1bqk2r/pppp1ppp/2n1pn2/8/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, 4...Nc6
+r1bqk2r/pppp1ppp/2n2n2/1B2p3/1b2P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Four knights: double Ruy Lopez *
+r1bqk2r/pppp1ppp/2n2n2/1B2p3/1b2P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Four knights: double Ruy Lopez
+r1bqk2r/pppp1ppp/2n2n2/1Bb1p3/4P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Four knights: Spanish, classical defense
+r1bqk2r/pppp1ppp/2n2n2/1Bb1p3/4P3/3PBN2/PPP2PPP/RN1QK2R b KQkq -
+Ruy Lopez: Berlin defense, Kaufmann variation
+r1bqk2r/pppp1ppp/2n2n2/1Bb1p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Berlin defense, Beverwijk variation
+r1bqk2r/pppp1ppp/2n2n2/2b1N3/3PP3/8/PPP2PPP/RNBQKB1R b KQkq -
+Boden-Kieseritsky gambit: Lichtenhein defense *
+r1bqk2r/pppp1ppp/2n2n2/2b1N3/4P3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Boden-Kieseritsky gambit *
+r1bqk2r/pppp1ppp/2n2n2/2b1P3/2Bp4/5N2/PPP2PPP/RNBQ1RK1 b kq -
+two knights: Max Lange attack
+r1bqk2r/pppp1ppp/2n2n2/2b1p1N1/2B1P3/8/PPPP1PPP/RNBQK2R w KQkq -
+two knights defense: Wilkes Barre (Traxler) variation
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/1PB1P3/2P2N2/P2P1PPP/RNBQK2R b KQkq -
+Giuoco Piano: Bird's attack
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Giuoco Piano: four knights variation *
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Giuoco Piano: four knights variation
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2B1P3/2NP1N2/PPP2PPP/R1BQK2R b KQkq -
+Giuoco Pianissimo: Italian four knights variation
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2B1P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Giuoco Piano
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2B1P3/3P1N2/PPP2PPP/RNBQK2R w KQkq -
+Giuoco Pianissimo
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2B1PP2/2P5/PP1PQ1PP/RNB1K1NR b KQkq -
+Bishop's opening: Lopez gambit
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2BPP3/2P2N2/PP3PPP/RNBQK2R b KQkq -
+Giuoco Piano
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Italian variation *
+r1bqk2r/pppp1ppp/2n2n2/2b5/2BPP3/5N2/PP3PPP/RNBQK2R b KQkq -
+Giuoco Piano
+r1bqk2r/pppp1ppp/2n2n2/3Np3/1b2P3/5N2/PPPP1PPP/R1BQKB1R b KQkq -
+Four knights: Rubinstein counter-gambit *
+r1bqk2r/pppp1ppp/2n2n2/3Np3/1b2P3/5N2/PPPP1PPP/R1BQKB1R w KQkq -
+Three knights: Schlechter variation
+r1bqk2r/pppp1ppp/2n2n2/4N3/1b1PP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Four knights: Scotch, Krause variation
+r1bqk2r/pppp1ppp/2n2n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Spanish variation *
+r1bqk2r/pppp1ppp/2n2n2/4p3/1b2P3/2N3P1/PPPPNP1P/R1BQKB1R b KQkq -
+Ruy Lopez: Cozio defense, Paulsen variation *
+r1bqk2r/pppp1ppp/2n2n2/4p3/1b2PP2/2N5/PPPP2PP/R1BQKBNR w KQkq -
+Ruy Lopez: Schliemann defense, Berger variation *
+r1bqk2r/pppp1ppp/2n2n2/4p3/1bB1P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Four knights: Spanish, classical defense *
+r1bqk2r/pppp1ppp/2n2n2/4p3/2P5/2b1PN2/PPQP1PPP/R1B1KB1R w KQkq -
+English: four knights, Romanishin variation
+r1bqk2r/pppp1ppp/2n2n2/4p3/4P3/P1P5/1PP2PPP/R1BQKBNR w KQkq -
+Ruy Lopez: exchange, Keres variation *
+r1bqk2r/pppp1ppp/2n2n2/4p3/4P3/P1b2N2/1PPP1PPP/R1BQKB1R w KQkq -
+Four knights: Ranken variation *
+r1bqk2r/pppp1ppp/2n2n2/8/1bB1P3/2N2N2/PP3PPP/R1BQK2R w KQkq -
+Scotch: G\"oring gambit, Bardeleben variation
+r1bqk2r/pppp1ppp/2n2n2/8/1bBPP3/2N2N2/PP3PPP/R1BQK2R b KQkq -
+Giuoco Piano: Greco's attack
+r1bqk2r/pppp1ppp/2n2n2/8/1bBPP3/5N2/PP3PPP/RNBQ1K1R b kq -
+Giuoco Piano: Cracow variation
+r1bqk2r/pppp1ppp/2n2n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R w KQkq -
+Ruy Lopez: four knights (Tarrasch) variation *
+r1bqk2r/pppp1ppp/2n2n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQkq -
+Ruy Lopez: modern Steinitz defense, Three knights variation *
+r1bqk2r/pppp1ppp/2n4n/2b3NQ/2BpP3/8/PPP2PPP/RNB1K2R b KQkq -
+Scotch gambit: Vitzhum attack
+r1bqk2r/pppp1ppp/2n5/2b1P3/2Bp2n1/2P2N2/PP3PPP/RNBQ1RK1 b kq -
+two knights: Max Lange attack, Krause variation
+r1bqk2r/pppp1ppp/2n5/2b1P3/2Bp2n1/5N2/PPP2PPP/RNBQ1RK1 w kq -
+two knights: Max Lange attack, Steinitz variation
+r1bqk2r/pppp1ppp/2n5/2bBP3/8/2p2NK1/PP4PP/RNBQ3R b kq -
+Giuoco Piano: Ghulam Kassim variation
+r1bqk2r/pppp1ppp/2n5/2bPp3/4n3/2P2N2/PP3PPP/RNBQKB1R w KQkq -
+Ponziani: Fraser defense
+r1bqk2r/pppp1ppp/2n5/3P4/2B1n3/2b2N2/PP3PPP/R1BQ1RK1 b kq -
+Giuoco Piano: M\"oller (Therkatz) attack
+r1bqk2r/pppp1ppp/2n5/3np3/1b2P3/5N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Rubinstein counter-gambit, exchange variation *
+r1bqk2r/pppp1ppp/2n5/8/1bBP4/2n2N2/PP3PPP/R1BQ1RK1 w kq -
+Giuoco Piano: Greco variation
+r1bqk2r/pppp1ppp/2n5/8/2BP4/B1b2N2/P4PPP/R2Q1RK1 b kq -
+Giuoco Piano: Aitken variation
+r1bqk2r/pppp1ppp/2n5/8/2BPn3/2b2N2/PP3PPP/R1BQ1RK1 w kq -
+Giuoco Piano
+r1bqk2r/pppp2pp/2n2n2/1Bb1pQ2/4P3/8/PPPP1PPP/RNB1K1NR w KQkq -
+KGD: Norwalde variation, B\"ucker gambit *
+r1bqk2r/pppp2pp/2n2n2/2b1p3/2P2p2/2N1P1P1/PP1P1PBP/R1BQK1NR w KQkq -
+Sicilian: Grand Prix attack, Schofman variation *
+r1bqk2r/pppp2pp/2n2n2/2b1pPP1/8/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: MacDonnell gambit *
+r1bqk2r/pppp2pp/2n5/3Npp2/1b2n3/5N2/PPPPQPPP/R1B1KB1R w KQkq -
+Four knights: Rubinstein counter-gambit, Bogolyubov variation *
+r1bqk2r/ppppbppp/2n2n2/3Np3/4P3/5N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Rubinstein counter-gambit, 5.Be2 *
+r1bqk2r/ppppbppp/2n5/1B2P3/4n3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: Berlin defense, Minckwitz variation
+r1bqk2r/ppppbppp/2n5/1B2p3/3Pn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open Berlin defense, 5...Be7
+r1bqk2r/ppppbppp/2n5/4P3/2Bpn3/2P2N2/PP3PPP/RNBQK2R w KQkq -
+Hungarian defense: Tartakower variation
+r1bqk2r/ppppbppp/2nn4/4N2Q/8/1BN5/PPPP1PPP/R1B1K2R b KQkq -
+Vienna: Alekhine variation
+r1bqk3/ppp3p1/2n5/2bppP2/4n1P1/2PP4/PP3P2/RNBQK1NB w KQq -
+KGA: Greco gambit *
+r1bqkb1r/1p1n1ppp/p2ppn2/8/3NP3/2N5/PPP1BPPP/R1BQ1RK1 w kq -
+Sicilian: Scheveningen, classical, Nd7 system
+r1bqkb1r/1p1ppppp/p1n2n2/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+English: four knights, Marini variation *
+r1bqkb1r/1p2nppp/p1n1p3/2pp4/3P4/3BPN2/PPP2PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: Simagin variation *
+r1bqkb1r/1p2pp1p/2n3p1/p1np4/4PB2/2P2N2/PPQN1PPP/R3KB1R b KQkq -
+QGD Slav: Carlsbad variation *
+r1bqkb1r/1p2pppp/2n2n2/p1Pp2B1/8/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+QGD Slav: Steiner variation *
+r1bqkb1r/1p2pppp/2n2n2/p1Pp4/5B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+QGD Slav: Czech defense *
+r1bqkb1r/1p2pppp/2n2n2/p1Pp4/8/2P1PN2/PP3PPP/RNBQKB1R b KQkq -
+QGD Slav: Soultanb\'eieff variation *
+r1bqkb1r/1p2pppp/2n2n2/p1Pp4/8/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav accepted: Alapin variation *
+r1bqkb1r/1p2pppp/2n5/p1Pp4/4nB2/2P1PN2/PP3PPP/RN1QKB1R b KQkq -
+QGD Slav: Wiesbaden variation *
+r1bqkb1r/1p2pppp/2n5/p1Pp4/4nB2/2P2N2/PP2PPPP/RN1QKB1R w KQkq -
+QGD Slav: Krause attack *
+r1bqkb1r/1p3ppp/2n1pn2/p1Pp4/5B2/2P2N2/PP2PPPP/RN1QKB1R w KQkq -
+QGD Slav: Dutch variation *
+r1bqkb1r/1p3ppp/2n1pn2/p1Pp4/5B2/N1P2N2/PP2PPPP/R2QKB1R b KQkq -
+QGD Slav: Dutch, Lasker variation *
+r1bqkb1r/1p3ppp/2n2n2/p1Ppp1B1/8/N1P2N2/PP2PPPP/R2QKB1R b KQkq -
+QGD Slav: Smyslov variation *
+r1bqkb1r/1p3ppp/p1n1pn2/3p4/2P1P3/N1N5/PP3PPP/R1BQKB1R w KQkq -
+Sicilian, Sz\'en variation, Dely-Kasparov gambit
+r1bqkb1r/1p3ppp/p1nppn2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R w KQkq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6
+r1bqkb1r/1pp1nppp/p1B5/3pP3/8/4P3/PPP2PPP/RNBQK1NR b KQkq -
+French: Winawer, Alekhine gambit *
+r1bqkb1r/1pp2ppp/2P2n2/1p6/3Pp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+French: Winawer, advance, Rauzer variation *
+r1bqkb1r/1pp2ppp/p1n5/3pP3/8/2N1P3/PPP2PPP/R1BQK1NR b KQkq -
+French: Winawer, Alekhine gambit, Kan variation *
+r1bqkb1r/1pp2ppp/p1np1n2/4p3/B1P1P3/3P1N2/PP3PPP/RNBQK2R b KQkq -
+Ruy Lopez: Morphy defense, Duras variation
+r1bqkb1r/1pp2ppp/p1np1n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Steinitz defense deferred (Russian defense)
+r1bqkb1r/1ppn1ppp/p3pn2/8/3P4/6P1/PPQ1PPBP/RNB1K1NR b KQkq -
+Catalan: open, Alekhine variation
+r1bqkb1r/1ppp1ppp/p1B2n2/4p3/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Four knights: Ranken variation
+r1bqkb1r/1ppp1ppp/p1B2n2/4p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Ruy Lopez: Treybal (Bayreuth) variation (exchange var. deferred)
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Gunsberg variation *
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Ruy Lopez: four knights (Tarrasch) variation
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/3P1N2/PPP2PPP/RNBQK2R b KQkq -
+Ruy Lopez: Anderssen variation
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: 5.O-O
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Morphy defense
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/5N2/PPPPQPPP/RNB1K2R b KQkq -
+Ruy Lopez: Wormald (Alapin) attack
+r1bqkb1r/1ppp1ppp/p1n5/1B2p3/3Pn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Berlin defense, Rosenthal variation
+r1bqkb1r/1ppp1ppp/p1n5/4p3/B2Pn3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, 6.d4
+r1bqkb1r/1ppp1ppp/p1n5/4p3/B3n3/2N2N2/PPPP1PPP/R1BQ1RK1 b kq -
+Ruy Lopez: open, Knorre variation
+r1bqkb1r/1ppp1ppp/p1n5/4p3/B3n3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open (Tarrasch) defense
+r1bqkb1r/1ppp1ppp/p1n5/4p3/B3n3/5N2/PPPPQPPP/RNB2RK1 b kq -
+Ruy Lopez: open, Tartakower variation
+r1bqkb1r/1ppp1ppp/p1n5/8/B2pn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, Riga variation
+r1bqkb1r/1pppnppp/p1n5/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Cozio defense deferred
+r1bqkb1r/2p1nppp/p7/1p1pP3/4n3/1B3N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, Zukertort variation
+r1bqkb1r/2p2ppp/p1n5/1p1pP3/4n3/1B3N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, 8.de
+r1bqkb1r/2p2ppp/p1n5/1p1pp3/2PPn3/1B3N2/PP3PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, Harksen gambit
+r1bqkb1r/2p2ppp/p1np1n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: ...b5 & ...d6
+r1bqkb1r/2p2ppp/p1p2n2/3p4/2PPp3/4P3/PP2NPPP/RNBQK2R w KQkq -
+French: Winawer, advance, positional main line *
+r1bqkb1r/2p2ppp/p1pp4/4p3/3Pn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Steinitz defense deferred, Rubinstein variation
+r1bqkb1r/2p2ppp/p7/1p1p4/P2pn3/1BN5/1PP2PPP/R1BQ1RK1 b kq -
+Ruy Lopez: open, Berger variation
+r1bqkb1r/2p2ppp/p7/1p1pp3/P2nn3/1B3N2/1PP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, Schlechter defense
+r1bqkb1r/2p3pp/p1p5/3pPp2/4n3/2N2N2/PPP2PPP/R1BQR1K1 b kq -
+Ruy Lopez: Steinitz defense deferred, Boleslavsky variation
+r1bqkb1r/2pp1ppp/p1n5/1p1Pp3/B3n3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, Richter variation
+r1bqkb1r/2pp1ppp/p1n5/1p2N3/B2Pn3/8/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, Friess attack
+r1bqkb1r/2pp1ppp/p1n5/1p2p3/3Pn3/1B3N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, 7.Bb3
+r1bqkb1r/2pp1ppp/p1n5/1p2p3/B2Pn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, 6.d4 b5
+r1bqkb1r/3n1ppp/p1p1pn2/1p6/3P4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran, 8...a6
+r1bqkb1r/3n1ppp/p1p1pn2/8/1p1PP3/2NB1N2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran, Pir\'c variation
+r1bqkb1r/3n1ppp/p3p3/1N2P3/3p2n1/3B1N2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran, Rabinovich variation
+r1bqkb1r/3n1ppp/p3pn2/1N2P3/3p4/3B1N2/PP3PPP/R1BQK2R b KQkq -
+QGD semi-Slav: Meran, Blumenfeld variation
+r1bqkb1r/3n1ppp/p3pn2/1pp1P3/3P4/2NB1N2/PP3PPP/R1BQK2R b KQkq -
+QGD semi-Slav: Meran, old main line
+r1bqkb1r/3n1ppp/p3pn2/1pp5/3PP3/2NB1N2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran
+r1bqkb1r/3n1ppp/p3pn2/1ppP4/4P3/2NB1N2/PP3PPP/R1BQK2R b KQkq -
+QGD semi-Slav: Meran, Reynolds' variation
+r1bqkb1r/5p1p/p1np4/1p1Npp2/4P3/N7/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Sveshnikov variation
+r1bqkb1r/5ppp/4pn2/1p2N3/3p4/3B1Q2/PP3PPP/R1B1K2R b KQkq -
+QGD semi-Slav: Meran, Stahlberg variation
+r1bqkb1r/5ppp/4pn2/1p2N3/3p4/3B4/PP3PPP/R1BQ1RK1 b kq -
+QGD semi-Slav: Meran, Sozin variation
+r1bqkb1r/5ppp/p1np1n2/1p2p1B1/4P3/N1N5/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Pelikan, Chelyabinsk variation
+r1bqkb1r/5ppp/p3pn2/1N2n3/3p4/3B1N2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran, Sozin variation
+r1bqkb1r/p1p2ppp/2n2n2/1p1Pp1N1/2B5/8/PPPP1PPP/RNBQK2R w KQkq -
+two knights defense: Ulvestad variation
+r1bqkb1r/p1p2ppp/8/1p1np3/3nN3/2P5/PP1P1PPP/RNBQKB1R b KQkq -
+two knights defense: Fritz, Gruber variation
+r1bqkb1r/p1pn1ppp/1p2pn2/3p4/2PP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+Queen's pawn game, Zukertort variation *
+r1bqkb1r/p1pp1ppp/2p2n2/4P3/8/8/PPP2PPP/RNBQKB1R b KQkq -
+Scotch: Mieses variation
+r1bqkb1r/p1pp1ppp/2p2n2/8/4P3/8/PPPN1PPP/R1BQKB1R b KQkq -
+Scotch: Tartakower variation
+r1bqkb1r/p2n1p2/2p1pn2/1p2P1B1/2pP4/2N2Q2/PP3PPP/R3KB1R b KQkq -
+QGD semi-Slav: anti-Meran, Szab\'o variation
+r1bqkb1r/p2n1p2/2p1pn2/1p2P1B1/2pP4/2N3P1/PP3P1P/R2QKB1R b KQkq -
+QGD semi-Slav: anti-Meran, Lilienthal variation
+r1bqkb1r/p2n1ppp/2p1pn2/1p6/2BP4/2N1PN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran variation
+r1bqkb1r/p2n1ppp/2p1pn2/8/1p1P4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: neo-Meran (Lundin variation)
+r1bqkb1r/p3pp1p/2pp1np1/4P3/2B5/2N5/PPP2PPP/R1BQK2R b KQkq -
+Sicilian: Magnus Smith trap
+r1bqkb1r/p4pp1/2p2n1p/n3p1N1/8/8/PPPPBPPP/RNBQK2R w KQkq -
+Two knights defense
+r1bqkb1r/p4pp1/2p2n1p/n3p3/8/7N/PPPPBPPP/RNBQK2R b KQkq -
+two knights defense: Steinitz variation
+r1bqkb1r/p4ppp/2n1pn2/1ppp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Gr\"unfeld: Makogonov variation *
+r1bqkb1r/p4ppp/2p2n2/3pp3/8/6P1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: modern exchange variation *
+r1bqkb1r/p4ppp/2p2n2/n3p1N1/8/8/PPPPBPPP/RNBQK2R b KQkq -
+Two knights defense
+r1bqkb1r/p4ppp/2p2n2/nB2p1N1/8/5Q2/PPPP1PPP/RNB1K2R b KQkq -
+two knights defense: Bogolyubov variation
+r1bqkb1r/p4ppp/5n2/np2p1N1/8/5Q2/PPPP1PPP/RNB1K2R w KQkq -
+two knights defense: Blackburne variation
+r1bqkb1r/pp1n1ppp/2n1p3/2PpP3/5P2/2N5/PPP3PP/R1BQKBNR w KQkq -
+French: Steinitz variation
+r1bqkb1r/pp1n1ppp/2n1p3/2ppP3/3P1P2/2N1BN2/PPP3PP/R2QKB1R b KQkq -
+French: Steinitz, Boleslavsky variation
+r1bqkb1r/pp1n1ppp/2n1p3/2ppP3/3P4/2PB4/PP1N1PPP/R1BQK1NR w KQkq -
+French: Tarrasch, closed variation
+r1bqkb1r/pp1n1ppp/2n1p3/3pP3/3P4/3B4/PP1NNPPP/R1BQK2R b KQkq -
+French: Tarrasch, closed variation, main line
+r1bqkb1r/pp1n1ppp/2p1pn2/3p2B1/2PP4/2N1P3/PP3PPP/R2QKBNR w KQkq -
+QGD: 5...c6
+r1bqkb1r/pp1n1ppp/2p1pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R b KQkq -
+QGD
+r1bqkb1r/pp1n1ppp/2p1pn2/3p2B1/2PP4/4PN2/PP1N1PPP/R2QKB1R b KQkq -
+QGD: Capablanca variation
+r1bqkb1r/pp1n1ppp/2p1pn2/3p2B1/2PP4/P1N1P3/1P3PPP/R2QKBNR b KQkq -
+QGD: Capablanca anti-Cambridge Springs variation
+r1bqkb1r/pp1n1ppp/2p1pn2/3p2B1/2PPP3/2N2N2/PP3PPP/R2QKB1R b KQkq -
+QGD: Alekhine variation
+r1bqkb1r/pp1n1ppp/2p1pn2/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: 5...Nd7
+r1bqkb1r/pp1n1ppp/2p1pn2/3p4/2PP4/2N1PN2/PPQ2PPP/R1B1KB1R b KQkq -
+QGD semi-Slav: Stoltz variation
+r1bqkb1r/pp1n1ppp/2p1pn2/3p4/2PP4/2NBPN2/PP3PPP/R1BQK2R b KQkq -
+QGD semi-Slav: 6.Bd3
+r1bqkb1r/pp1n1ppp/2p1pn2/3p4/2PP4/4PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD Slav
+r1bqkb1r/pp1n1ppp/2p1pn2/3pN3/2PP4/2N1P3/PP3PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Rubinstein (anti-Meran) system
+r1bqkb1r/pp1n1ppp/2p1pn2/8/2BP4/2N1PN2/PP3PPP/R1BQK2R b KQkq -
+QGD semi-Slav: 7.Bc4
+r1bqkb1r/pp1n1ppp/4pn2/2pp4/2PP4/3BPN2/PP1N1PPP/R1BQK2R w KQkq -
+QGD Slav: Semmering variation
+r1bqkb1r/pp1n1ppp/4pn2/2pp4/3P4/2P1PN2/PP1N1PPP/R1BQKB1R b KQkq -
+QGD Slav *
+r1bqkb1r/pp1n1ppp/4pn2/2pp4/3P4/2P1PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD Slav *
+r1bqkb1r/pp1n1ppp/4pn2/2pp4/3P4/2P1PNP1/PP3P1P/RNBQKB1R b KQkq -
+QGD: Spielmann variation *
+r1bqkb1r/pp1npp1p/3p1np1/8/3NPP2/2N5/PPP3PP/R1BQKB1R w KQkq -
+Sicilian: dragon, Levenfish; Flohr variation
+r1bqkb1r/pp1npppp/2n5/8/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+Benoni: Nimzovich (knight's tour) variation *
+r1bqkb1r/pp1npppp/2n5/8/2Pp4/B2P1NP1/4PP1P/RN1QKB1R w KQkq -
+Benk\"o gambit: Nd2 variation *
+r1bqkb1r/pp1npppp/5n2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Bogo-Indian defense, Gr\"unfeld variation *
+r1bqkb1r/pp1npppp/5n2/2pP4/4p3/2N2P2/PPP3PP/R1BQKBNR b KQkq -
+QGD: Albin counter-gambit, Janowski variation *
+r1bqkb1r/pp1npppp/5n2/2pP4/4p3/2N5/PPP1QPPP/R1B1KBNR b KQkq -
+QGD: Albin counter-gambit, Balogh variation *
+r1bqkb1r/pp1npppp/5n2/2pP4/4p3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+QGD: Albin counter-gambit, Alapin variation *
+r1bqkb1r/pp1npppp/5n2/2pp4/3P4/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav: Breyer variation *
+r1bqkb1r/pp1p1Npp/2p1nn2/8/2B1P3/8/PPP2PPP/RNBQ1RK1 b kq -
+Scotch: Cochrane variation
+r1bqkb1r/pp1p1ppp/2n1pn2/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+English: four knights, 4.e3 *
+r1bqkb1r/pp1p1ppp/2n1pn2/8/2PN4/2N5/PP2PPPP/R1BQKB1R w KQkq -
+English: symmetrical variation
+r1bqkb1r/pp1p1ppp/2n2n2/2p1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+English: four knights, Nimzovich variation *
+r1bqkb1r/pp1p1ppp/2n2n2/4p3/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Pelikan (Lasker/Sveshnikov) variation
+r1bqkb1r/pp1p1ppp/2n5/2ppP3/3P4/5N2/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Nimzovich-Rubinstein; Rubinstein counter-gambit
+r1bqkb1r/pp1p1ppp/n1p2n2/8/2PNp3/2N5/PP1PPPPP/R1BQKB1R w KQkq -
+Sicilian: 2.c3, Heidenfeld variation *
+r1bqkb1r/pp1pnppp/2p2n2/1B2N3/4P3/3P4/PPP2PPP/RNBQK2R w KQkq -
+Ruy Lopez: Berlin defense, Mortimer trap
+r1bqkb1r/pp1ppp1p/2n2np1/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+English: four knights, kingside fianchetto *
+r1bqkb1r/pp1ppppp/2n2n2/1Bp5/8/4PN2/PPPP1PPP/RNBQK2R b KQkq -
+English: Nimzo-English opening *
+r1bqkb1r/pp1ppppp/2n2n2/2p3B1/4P3/3P4/PPP2PPP/RN1QKBNR b KQkq -
+English, Smyslov defense *
+r1bqkb1r/pp1ppppp/2n2n2/2p5/2P5/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+English: symmetrical, four knights system *
+r1bqkb1r/pp1ppppp/2n2n2/2p5/2P5/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+English: symmetrical, four knights system
+r1bqkb1r/pp1ppppp/2n2n2/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+English: four knights system *
+r1bqkb1r/pp1ppppp/2n2n2/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+English: three knights system *
+r1bqkb1r/pp1ppppp/2n2n2/2p5/4P3/3P4/PPP2PPP/RNBQKBNR w KQkq -
+English opening *
+r1bqkb1r/pp1ppppp/2n2n2/2p5/8/1P2PN2/P1PP1PPP/RNBQKB1R b KQkq -
+English: Queens Indian formation *
+r1bqkb1r/pp1ppppp/2n2n2/8/2PN4/8/PP2PPPP/RNBQKB1R b KQkq -
+English: symmetrical, three knights system *
+r1bqkb1r/pp1ppppp/2n2n2/8/3N4/8/PPP1PPPP/RNBQKB1R w KQkq -
+English: Anglo-Gr\"unfeld defense *
+r1bqkb1r/pp1ppppp/2n2n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian defense
+r1bqkb1r/pp1ppppp/2n5/2p1P3/1P4n1/5N2/P1PP1PPP/RNBQKB1R b KQkq -
+English: Bellon gambit *
+r1bqkb1r/pp1ppppp/2n5/2pnP3/8/N1P2N2/PP1P1PPP/R1BQKB1R b KQkq -
+Sicilian: 2.c3, Heidenfeld variation
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: 4.e3 c5, 5.Ne2 (Rubinstein, anti-H\"ubner system) *
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/8/1P2PN2/P1PP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: Fischer variation, 5.Ne2 *
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+Nimzo-Indian: Reshevsky variation *
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/8/BP2PN2/P1PP1PPP/RN1QK2R b KQkq -
+Nimzo-Indian: 4.e3, Bronstein (Byrne) variation *
+r1bqkb1r/pp2nppp/2n5/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: Kramer system *
+r1bqkb1r/pp2pp1p/2n2np1/2Pp4/3P4/2N5/PP3PPP/R1BQKBNR b KQkq -
+QGD: Tarrasch, Folkestone (Swedish) variation *
+r1bqkb1r/pp2pp1p/2n2np1/2pp4/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: fianchetto variation *
+r1bqkb1r/pp2pp1p/2n2np1/3p4/2PP4/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+QGD: Tarrasch, Prague variation *
+r1bqkb1r/pp2pp1p/2n2np1/3p4/2PP4/2N5/PP3PPP/R1BQKBNR w KQkq -
+QGD: Tarrasch, Schlechter-Rubinstein system *
+r1bqkb1r/pp2pp1p/2n2np1/8/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+Benoni: fianchetto variation *
+r1bqkb1r/pp2pp1p/2n2np1/8/2Pp4/B2P1NP1/4PP1P/RN1QKB1R w KQkq -
+Benk\"o gambit: fianchetto variation *
+r1bqkb1r/pp2pp1p/2n3p1/2pn4/8/1QN1PN2/PP1P1PPP/R1B1KB1R b KQkq -
+English: symmetrical, Geller variation *
+r1bqkb1r/pp2pp1p/2np1np1/6B1/3NP3/2N5/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Richter-Rauzer, Bondarevsky variation
+r1bqkb1r/pp2pp1p/3p1np1/8/2PQP3/2N5/PP3PPP/R1B1KB1R w KQkq -
+Sicilian: accelerated fianchetto, Gurgenidze variation
+r1bqkb1r/pp2pppp/2n2n2/1Bp1N3/2Pp4/4P3/PP1P1PPP/RNBQK2R b KQkq -
+Nimzo-Indian: three knights, Euwe variation *
+r1bqkb1r/pp2pppp/2n2n2/1Bp5/2Pp4/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: three knights, Korchnoi variation *
+r1bqkb1r/pp2pppp/2n2n2/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R b KQkq -
+QGD: Ragozin variation *
+r1bqkb1r/pp2pppp/2n2n2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: three knights variation *
+r1bqkb1r/pp2pppp/2n2n2/2Pp4/8/2N5/PPP1PPPP/R1BQKBNR w KQkq -
+QGD: Chigorin defense, Janowski variation *
+r1bqkb1r/pp2pppp/2n2n2/2Pp4/8/2P1P3/PP3PPP/RNBQKBNR b KQkq -
+QGD: semi-Slav, Noteboom variation *
+r1bqkb1r/pp2pppp/2n2n2/2Pp4/8/2P2N2/PP2PPPP/RNBQKB1R b KQkq -
+QGD Slav accepted *
+r1bqkb1r/pp2pppp/2n2n2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+QGA, 4.Nc3 *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/2PP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+QGD: Semi-Tarrasch defense *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/1QP2N2/PP2PPPP/RNB1KB1R b KQkq -
+QGD Slav: S\"uchting variation *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/2P1PN2/PP3PPP/RNBQKB1R b KQkq -
+QGD semi-Slav *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav: 4.Nc3 *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/2P2NP1/PP2PP1P/RNBQKB1R b KQkq -
+QGD Slav\Gr\"unfeld: Schlechter variation *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+QGD: 4.Nf3 *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Gr\"unfeld: Three knights variation *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R b KQkq -
+Gr\"unfeld: Three knights variation *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/4P3/3P1N2/PPP2PPP/RNBQKB1R w KQkq -
+Old Indian: Ukrainian variation, 4.Nf3 *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+Queen's Indian: 4.Nc3 *
+r1bqkb1r/pp2pppp/2n2n2/2ppP3/8/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+English: Bradley Beach variation *
+r1bqkb1r/pp2pppp/2n2n2/3p4/2PP4/8/PP3PPP/RNBQKBNR w KQkq -
+QGD: Tarrasch defense *
+r1bqkb1r/pp2pppp/2n2n2/3p4/2Pp4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD: Semi-Tarrasch, 5.cd *
+r1bqkb1r/pp2pppp/2n2n2/3p4/3P1B2/2PB4/PP3PPP/RN1QK1NR b KQkq -
+Caro-Kann: exchange, Rubinstein variation
+r1bqkb1r/pp2pppp/2n2n2/8/2Pp4/3P1NP1/PP3P1P/RNBQKB1R b KQkq -
+Benoni defense *
+r1bqkb1r/pp2pppp/2n5/2pn4/8/2N1PN2/PP1P1PPP/R1BQKB1R b KQkq -
+English: symmetrical variation *
+r1bqkb1r/pp2pppp/2np1n2/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+English: four knights, Capablanca variation *
+r1bqkb1r/pp2pppp/2np1n2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: Richter-Rauzer
+r1bqkb1r/pp2pppp/2np1n2/8/2BNP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Sicilian: Sozin, not Scheveningen
+r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+Sicilian: classical
+r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian
+r1bqkb1r/pp2pppp/5n2/n2P2B1/2p5/2N5/PP3PPP/R2QKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik, Herzog defense
+r1bqkb1r/pp3p1p/2n2np1/2Ppp3/3P4/2N5/PP3PPP/R1BQKBNR w KQkq -
+QGD: Tarrasch, Schlechter-Rubinstein system, Rey Ardid variation *
+r1bqkb1r/pp3ppp/1nn1p3/3pP3/3P4/3B4/PP1NNPPP/R1BQK2R w KQkq -
+French: Tarrasch, Leningrad variation
+r1bqkb1r/pp3ppp/2Np1n2/4p3/4P3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+Sicilian: Boleslavsky, Louma variation
+r1bqkb1r/pp3ppp/2Nppn2/6B1/4P3/2N5/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: Richter-Rauzer, Richter attack
+r1bqkb1r/pp3ppp/2n1p3/2pn4/3P4/2NBPN2/PP3PPP/R1BQK2R b KQkq -
+QGD: Semi-Tarrasch, 7.Bd3
+r1bqkb1r/pp3ppp/2n1p3/2pp4/3Pn3/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: Rubinstein (anti-Meran) system *
+r1bqkb1r/pp3ppp/2n1p3/3p4/3PnB2/4P3/PP1N1PPP/RN1QKB1R b KQkq -
+QGD Slav: Amsterdam variation *
+r1bqkb1r/pp3ppp/2n1pn2/1Bpp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: 4.e3 e8g8, 5.Nf3 d7d5 *
+r1bqkb1r/pp3ppp/2n1pn2/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+Nimzo-Indian: 4.e3 e8g8, 5.Nf3, without ...d5 *
+r1bqkb1r/pp3ppp/2n1pn2/2Pp4/8/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav: 5.e3 (Alekhine variation) *
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/2P1PN2/PP1N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: 5...Nd7 *
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/2P1PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD semi-Slav: 5.e3 *
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: 5.e3 *
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/P1P1PN2/1P3PPP/RNBQKB1R b KQkq -
+QGD semi-Slav: accelerated Meran (Alekhine variation) *
+r1bqkb1r/pp3ppp/2n1pn2/3p2B1/2PP4/2N5/PP3PPP/R2QKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik, normal variation
+r1bqkb1r/pp3ppp/2n1pn2/3p4/2PN4/4P3/PP3PPP/RNBQKB1R w KQkq -
+QGD: Semi-Tarrasch with e3 *
+r1bqkb1r/pp3ppp/2n1pn2/3p4/3P1B2/5N2/PP2PPPP/RN1QKB1R w KQkq -
+QGD Slav: exchange variation *
+r1bqkb1r/pp3ppp/2n2n2/1B2p3/8/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Scotch: G\"oring gambit *
+r1bqkb1r/pp3ppp/2n2n2/2Pp4/1P2p3/2P2N2/P3PPPP/RNBQKB1R w KQkq -
+QGD Slav: Tolush-Geller gambit *
+r1bqkb1r/pp3ppp/2n2n2/2Ppp3/8/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav: Slav gambit *
+r1bqkb1r/pp3ppp/2n2n2/2Ppp3/8/P4N2/1PP1PPPP/RNBQKB1R w KQkq -
+QGA, Bogolyubov variation *
+r1bqkb1r/pp3ppp/2n2n2/2pp4/3P4/2N2NP1/PP2PP1P/R1BQKB1R w KQkq -
+QGD: Tarrasch, Prague variation
+r1bqkb1r/pp3ppp/2n2n2/2ppp3/4P3/3P1N2/PPPN1PPP/R1BQKB1R w KQkq -
+Old Indian: main line *
+r1bqkb1r/pp3ppp/2n2n2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: 5.Nf3 *
+r1bqkb1r/pp3ppp/2n2n2/2ppp3/Q1P5/3P2P1/PP2PPBP/RNB1K1NR b KQkq -
+Pterodactyl defense *
+r1bqkb1r/pp3ppp/2n2n2/4p3/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+Benoni: classical with e4 and Nf3 *
+r1bqkb1r/pp3ppp/2np1n2/4p3/3NP3/2N5/PPP1BPPP/R1BQK2R w KQkq -
+Sicilian: Boleslavsky variation
+r1bqkb1r/pp3ppp/2np1n2/4p3/4P3/1NN5/PPP1BPPP/R1BQK2R b KQkq -
+Sicilian: Boleslavsky variation, 7.Nb3
+r1bqkb1r/pp3ppp/2nppn2/1B4B1/3NP3/2N5/PPP2PPP/R2QK2R b KQkq -
+Sicilian: Richter-Rauzer, Margate (Alekhine) variation
+r1bqkb1r/pp3ppp/2nppn2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Richter-Rauzer, 6...e6
+r1bqkb1r/pp3ppp/2nppn2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R b KQkq -
+Sicilian: Richter-Rauzer, Rauzer attack
+r1bqkb1r/pp3ppp/2nppn2/6B1/3NP3/2NQ4/PPP2PPP/R3KB1R b KQkq -
+Sicilian: Richter-Rauzer, Keres variation
+r1bqkb1r/pp3ppp/2nppn2/6B1/4P3/1NN5/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: Richter-Rauzer, Pod\v ebrady variation
+r1bqkb1r/pp3ppp/2nppn2/8/2BNP3/2N1B3/PPP2PPP/R2QK2R b KQkq -
+Sicilian: Sozin, 7.Be3
+r1bqkb1r/pp3ppp/2nppn2/8/2BNP3/2N5/PPP2PPP/R1BQK2R w KQkq -
+Sicilian: Sozin, Leonhardt variation
+r1bqkb1r/pp3ppp/2nppn2/8/3NP3/2N5/PPP1BPPP/R1BQK2R w KQkq -
+Sicilian: modern Scheveningen
+r1bqkb1r/pp3ppp/n1n5/2p1p3/3P4/P1N1PN2/1P3PPP/R1BQKB1R b KQkq -
+Sicilian, Sz\'en variation, Dely-Kasparov gambit *
+r1bqkb1r/pp4pp/2n2n2/2p1pp2/2Pp4/3P1NP1/PP2PPBP/RNBQ1RK1 w kq -
+King's Indian: Four pawns attack, dynamic line *
+r1bqkb1r/pp4pp/2n2n2/4pp2/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+Benoni: four pawns attack *
+r1bqkb1r/ppp1nppp/2n5/1B1pp3/3P4/4P3/PPP2PPP/RNBQK1NR w KQkq -
+French: Winawer, Alekhine (Mar\'oczy) gambit *
+r1bqkb1r/ppp1pppp/1nn5/4P3/2PP4/4B3/PP4PP/RN1QKBNR b KQkq -
+Alekhine's defense: four pawns attack, 7.Be3
+r1bqkb1r/ppp1pppp/1nn5/4P3/2PP4/8/PP4PP/RNBQKBNR w KQkq -
+Alekhine's defense: four pawns attack, 6...Nc6
+r1bqkb1r/ppp2Npp/2n5/3np3/2B5/8/PPPP1PPP/RNBQK2R b KQkq -
+two knights defense: Fegatello attack
+r1bqkb1r/ppp2p1p/2n3p1/3np3/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Scheveningen, fianchetto variation *
+r1bqkb1r/ppp2p1p/2n3p1/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, Zagreb (fianchetto) variation *
+r1bqkb1r/ppp2p1p/2n5/3np1p1/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Scheveningen, Keres attack *
+r1bqkb1r/ppp2p1p/2n5/3p2p1/Q3nB2/2P2N2/PP2PPPP/RN2KB1R w KQkq -
+Scandinavian defense, Gr\"unfeld variation *
+r1bqkb1r/ppp2pp1/2n2n1p/3p2B1/Q7/5N2/PPP1PPPP/RN2KB1R w KQkq -
+Scandinavian defense, Lasker variation *
+r1bqkb1r/ppp2pp1/2n2n1p/3pp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+Pirc: classical, h3 system *
+r1bqkb1r/ppp2pp1/2n4p/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, Adams attack *
+r1bqkb1r/ppp2pp1/5nn1/3p3p/8/2P3BP/PP1NPPP1/R2QKBNR b KQkq -
+Caro-Kann: classical, 7...Nd7 *
+r1bqkb1r/ppp2pp1/5nn1/3p4/7p/2P3BP/PP1NPPP1/R2QKBNR w KQkq -
+Caro-Kann: classical, Spassky variation *
+r1bqkb1r/ppp2ppp/2Bp1n2/4p3/4P3/3P1N2/PPP2PPP/RNBQK2R b KQkq -
+Ruy Lopez: Berlin defense, Anderssen variation
+r1bqkb1r/ppp2ppp/2n1pn2/3p4/3PP3/5N2/PPPN1PPP/R1BQKB1R w KQkq -
+French: Tarrasch, Guimard main line
+r1bqkb1r/ppp2ppp/2n1pn2/3p4/4P3/3P1N2/PPPNBPPP/R1BQK2R b KQkq -
+French: Reversed Philidor formation
+r1bqkb1r/ppp2ppp/2n2n2/3Pp3/8/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Four knights: Scotch, 4...exd4 *
+r1bqkb1r/ppp2ppp/2n2n2/3p2B1/3P4/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: exchange, Bogolyubov variation
+r1bqkb1r/ppp2ppp/2n2n2/3p2B1/Q3P3/8/PPP2PPP/RN2KBNR b KQkq -
+Scandinavian: Anderssen counter-attack, Collijn variation *
+r1bqkb1r/ppp2ppp/2n2n2/3p4/Q3P3/8/PPP2PPP/RNB1KBNR w KQkq -
+Scandinavian: Anderssen counter-attack, Goteborg system *
+r1bqkb1r/ppp2ppp/2n2n2/3p4/Q4B2/5N2/PPP1PPPP/RN2KB1R b KQkq -
+Scandinavian defense *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Scotch variation *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/4P3/3P1N2/PPPN1PPP/R1BQKB1R b KQkq -
+Philidor: Improved Hanham variation *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/4P3/3P1N2/PPPNBPPP/R1BQK2R b KQkq -
+Inverted Hanham
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/4PP2/3P4/PPP3PP/RNBQKBNR w KQkq -
+Philidor: Philidor counter-gambit, Zukertort variation *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/8/2PP2P1/PP2PPBP/RNBQK1NR b KQkq -
+Robatsch defense: two knights, Suttles variation *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Pirc: classical (two knights) system *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/8/3P1NP1/PPP1PPBP/RNBQK2R b KQkq -
+Pirc: classical (two knights) system *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/8/3P2P1/PPP1PPBP/RNBQK1NR w KQkq -
+Robatsch defense: two knights variation *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/Q3P3/2P2N2/PP1P1PPP/RNB1KB1R w KQkq -
+Ponziani: Leonhardt variation
+r1bqkb1r/ppp2ppp/2n5/1B1n4/4p3/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+Sicilian: Pin, Koch variation *
+r1bqkb1r/ppp2ppp/2n5/1B1np3/8/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+Sicilian: Pin variation (Sicilian counter-attack) *
+r1bqkb1r/ppp2ppp/2n5/1B1pp3/4n3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Four knights: Scotch, Krause variation *
+r1bqkb1r/ppp2ppp/2n5/1B2p3/8/2NnPN2/PP1P1PPP/R1BQK2R w KQkq -
+Sicilian: Taimanov, American attack *
+r1bqkb1r/ppp2ppp/2n5/3np1N1/2BP4/8/PPP2PPP/RNBQK2R b KQkq -
+two knights defense: Lolli attack
+r1bqkb1r/ppp2ppp/2n5/3np2Q/8/2N5/PPPP1PPP/R1B1KBNR w KQkq -
+Scotch: Steinitz variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/4P3/2N2N2/PP1P1PPP/R1BQKB1R b KQkq -
+Sicilian: Pelikan (Lasker/Sveshnikov) variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N1P3/PP1P1PPP/R1BQKBNR w KQkq -
+Sicilian: Taimanov variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N1P3/PPQP1PPP/R1B1KBNR b KQkq -
+Sicilian: Taimanov (Bastrikov) variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+Sicilian: accelerated fianchetto, modern variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2NP1N2/PP2PPPP/R1BQKB1R b KQkq -
+Sicilian *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3P1N2/PP2PPPP/RNBQKB1R w KQkq -
+Sicilian *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3P1NP1/PP2PP1P/RNBQKB1R b KQkq -
+Sicilian: dragon variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3PPN2/PP3PPP/RNBQKB1R b KQkq -
+Sicilian: Scheveningen variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P1N1P3/1P1P1PPP/R1BQKBNR b KQkq -
+Sicilian: Taimanov variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R b KQkq -
+Sicilian: Najdorf *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P3P3/1P1P1PPP/RNBQKBNR w KQkq -
+Sicilian: Kan, 5.Nc3 *
+r1bqkb1r/ppp2ppp/2n5/3p4/2Bpn3/2N2N2/PPP2PPP/R1BQR1K1 b kq -
+two knights defense: Canal variation
+r1bqkb1r/ppp2ppp/2n5/4P3/2BP2n1/4p3/PPP3PP/RNBQK1NR w KQkq -
+Philidor: Philidor counter-gambit, Berger variation *
+r1bqkb1r/ppp2ppp/2np1n2/1B2p3/2P1P3/3P1N2/PP3PPP/RNBQK2R b KQkq -
+Ruy Lopez: Berlin defense, Duras variation
+r1bqkb1r/ppp2ppp/2np1n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Berlin defense, 4.O-O, d6
+r1bqkb1r/ppp2ppp/2np1n2/4p3/2P5/1PN1P3/P2P1PPP/R1BQKBNR w KQkq -
+Amsterdam attack
+r1bqkb1r/ppp2ppp/4pn2/4N3/3P4/8/PPP2PPP/R1BQKB1R b KQkq -
+French: Rubinstein, Capablanca line
+r1bqkb1r/ppp2ppp/5n2/3Pp1N1/2Bn4/8/PPPP1PPP/RNBQK2R w KQkq -
+two knights defense: Fritz variation
+r1bqkb1r/ppp2ppp/5n2/3Pp3/3n4/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Belgrade gambit *
+r1bqkb1r/ppp2ppp/5n2/3Pp3/3n4/2N3P1/PPPP1P1P/R1BQKBNR w KQkq -
+Three knights: Steinitz, Rosenthal variation *
+r1bqkb1r/ppp2ppp/5n2/3p4/2PPp3/2N5/PP1P1PPP/R1BQKB1R b KQkq -
+Sicilian: Nimzovich-Rubinstein; Rubinstein counter-gambit *
+r1bqkb1r/ppp2ppp/5n2/3pn3/8/2B1P3/PPP2PPP/RN1QKBNR b KQkq -
+French: Fort Knox variation *
+r1bqkb1r/ppp2ppp/5n2/n2Pp1N1/2B5/3P4/PPP2PPP/RNBQK2R b KQkq -
+two knights defense: Kieseritsky variation
+r1bqkb1r/ppp2ppp/5n2/n2Pp1N1/2B5/8/PPPP1PPP/RNBQK2R w KQkq -
+two knights defense
+r1bqkb1r/ppp2ppp/5n2/nB1Pp1N1/8/8/PPPP1PPP/RNBQK2R b KQkq -
+Two knights defense
+r1bqkb1r/ppp2ppp/6nn/3p4/8/2P3B1/PP2PPPP/RN1QKBNR w KQkq -
+Caro-Kann: classical, Flohr variation *
+r1bqkb1r/ppp2ppp/8/3p4/4n3/4PN2/PPP2PPP/R1BQKB1R w KQkq -
+French: Rubinstein, Capablanca line *
+r1bqkb1r/ppp3pp/2n2n2/3p1p2/2PPp3/4P3/PP1N1PPP/RNBQKB1R w KQkq -
+French: Steinitz variation *
+r1bqkb1r/ppp3pp/2n2n2/3p1p2/4p3/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Pirc: Austrian attack, 6.e5 *
+r1bqkb1r/ppp3pp/2n2n2/3p4/8/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+Blackmar-Diemer: Euwe defense *
+r1bqkb1r/ppp3pp/2n2n2/3ppP2/6P1/2N5/PPPP1P1P/R1BQKBNR w KQkq -
+Vienna: Pierce gambit *
+r1bqkb1r/ppp3pp/2n2n2/3ppp2/2P5/3P1NP1/PP2PPBP/RNBQK2R b KQkq -
+Pirc: Austrian attack, dragon formation *
+r1bqkb1r/ppp3pp/2n2n2/3ppp2/8/3P1NP1/PPP1PPBP/RNBQ1RK1 b kq -
+Pirc: Austrian attack *
+r1bqkb1r/ppp3pp/2n5/3npp2/8/3P1NP1/PP1NPP1P/R1BQKB1R b KQkq -
+Sicilian: dragon, Levenfish; Flohr variation *
+r1bqkb1r/ppp3pp/2n5/3npp2/8/3P1NP1/PP2PP1P/RNBQKB1R w KQkq -
+Sicilian: dragon, Levenfish variation *
+r1bqkb1r/ppp3pp/2n5/3npp2/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Scheveningen, 6.f4 *
+r1bqkb1r/ppp3pp/2n5/3npp2/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, 6.f4 *
+r1bqkb1r/ppp4p/3p1nN1/8/3np2Q/8/PPP2PPP/RNB1KB1R w KQkq -
+Vienna gambit, Wurzburger trap *
+r1bqkb1r/pppn1ppp/2np4/1B2p3/3PP3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: closed Berlin defense, Chigorin variation
+r1bqkb1r/pppn1ppp/3p1n2/4p3/2PP4/2NBP3/PP3PPP/R1BQK1NR b KQkq -
+Old Indian: Dus-Khotimirsky variation
+r1bqkb1r/pppn1ppp/3p1n2/4p3/2PPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+Old Indian: main line
+r1bqkb1r/pppn1ppp/3p1n2/4p3/3PP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Philidor: Improved Hanham variation
+r1bqkb1r/pppn1ppp/4pn2/3p2B1/2PP4/2N1P3/PP3PPP/R2QKBNR b KQkq -
+QGD
+r1bqkb1r/pppn1ppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR w KQkq -
+QGD: 4.Bg5 Nbd7
+r1bqkb1r/pppn1ppp/4pn2/8/2QP4/6P1/PP2PPBP/RNB1K1NR b KQkq -
+Catalan: open, 5.Qa4 Nbd7, 6.Qxc4
+r1bqkb1r/pppn1ppp/5n2/3p4/2PP4/2N5/PP3PPP/R1BQKBNR b KQkq -
+French: Tarrasch, open variation, main line *
+r1bqkb1r/pppn1ppp/5n2/3p4/3P1B2/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+QGD: exchange, S\"amisch variation
+r1bqkb1r/pppn1ppp/5n2/3pp3/3P4/2N1PN2/PPP2PPP/R1BQKB1R b KQkq -
+French: Tarrasch, Guimard main line *
+r1bqkb1r/pppn1ppp/5n2/4N3/4p3/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Nimzovich, Sokolsky variation *
+r1bqkb1r/pppn1ppp/8/4p3/8/2P2N2/P1PP1PPP/R1BQKB1R w KQkq -
+Scotch: Tartakower variation *
+r1bqkb1r/pppp1ppp/2n1pn2/8/2P1P3/2N5/PP1P1PPP/R1BQKBNR w KQkq -
+English: Mikenas-Carls, Kevitz variation
+r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Four knights: Spanish variation
+r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: Berlin defense, 4.O-O
+r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Berlin defense
+r1bqkb1r/pppp1ppp/2n2n2/1B6/3pP3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: Berlin defense, Nyholm attack
+r1bqkb1r/pppp1ppp/2n2n2/3N4/3pP3/5N2/PPP2PPP/R1BQKB1R b KQkq -
+Four knights: Belgrade gambit
+r1bqkb1r/pppp1ppp/2n2n2/4N3/4P3/2N5/PPPP1PPP/R1BQKB1R b KQkq -
+Four knights: Schultze-M\"uller gambit
+r1bqkb1r/pppp1ppp/2n2n2/4N3/8/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: Nimzovich attack *
+r1bqkb1r/pppp1ppp/2n2n2/4p1B1/3P4/2P5/PP2PPPP/RN1QKBNR b KQkq -
+Caro-Kann: two knights, 3...Bg4 *
+r1bqkb1r/pppp1ppp/2n2n2/4p1N1/2B1P3/8/PPPP1PPP/RNBQK2R b KQkq -
+Two knights defense
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Four knights: Italian variation
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Vienna game
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/3P1N2/PPP2PPP/RNBQK2R b KQkq -
+Two knights defense (Modern bishop's opening)
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Two knights defense
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2BPP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+Two knights defense
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P1P3/2N2N2/PP1P1PPP/R1BQKB1R b KQkq -
+English: four knights, Nimzovich variation
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N1PN2/PP1P1PPP/R1BQKB1R b KQkq -
+English: four knights, 4.e3
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+English: four knights system
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N2NP1/PP1PPP1P/R1BQKB1R b KQkq -
+English: four knights, kingside fianchetto
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2NP1N2/PP2PPPP/R1BQKB1R b KQkq -
+English: four knights, Capablanca variation
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/P1N2N2/1P1PPPPP/R1BQKB1R b KQkq -
+English: four knights, Marini variation
+r1bqkb1r/pppp1ppp/2n2n2/4p3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: two knights variation *
+r1bqkb1r/pppp1ppp/2n2n2/4p3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: Two knights variation *
+r1bqkb1r/pppp1ppp/2n2n2/4p3/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+Four knights: Scotch variation
+r1bqkb1r/pppp1ppp/2n2n2/4p3/3PP3/5N2/PPP1BPPP/RNBQK2R b KQkq -
+Tayler opening
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Four knights game *
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights game
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+Three knights: Steinitz variation *
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Three knights game *
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2P2N2/PP1P1PPP/RNBQKB1R w KQkq -
+Ponziani: Jaenisch counter-attack
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov three knights game *
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R b KQkq -
+Four knights: Gunsberg variation
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Three knights: Winawer defense (Gothic defense) *
+r1bqkb1r/pppp1ppp/2n2n2/6N1/2BpP3/8/PPP2PPP/RNBQK2R b KQkq -
+Two knights defense, Perreux variation
+r1bqkb1r/pppp1ppp/2n2n2/8/2BpP3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Two knights defense
+r1bqkb1r/pppp1ppp/2n2n2/8/2BpP3/5N2/PPP2PPP/RNBQK2R w KQkq -
+Scotch gambit: Dubois-R\'eti defense
+r1bqkb1r/pppp1ppp/2n2n2/8/2PPp3/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+English: Bradley Beach variation
+r1bqkb1r/pppp1ppp/2n2n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Scotch: Schmidt variation
+r1bqkb1r/pppp1ppp/2n2n2/8/3pP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Four knights: Scotch, 4...exd4
+r1bqkb1r/pppp1ppp/2n2n2/8/4P3/4Q3/PPP2PPP/RNB1KBNR w KQkq -
+Center game: Berger variation
+r1bqkb1r/pppp1ppp/2n5/1B2p3/4n3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Berlin defense, open variation
+r1bqkb1r/pppp1ppp/2n5/2n1P3/3N4/8/PPP1QPPP/RNB1KB1R w KQkq -
+Petrov: modern attack, Bardeleben variation
+r1bqkb1r/pppp1ppp/2n5/4p3/4n3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Schultze-M\"uller gambit *
+r1bqkb1r/pppp1ppp/2n5/8/2Bpn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Two knights defense
+r1bqkb1r/pppp1ppp/2nn4/1B2P3/8/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open Berlin defense, l'Hermet variation
+r1bqkb1r/pppp1ppp/2nn4/4p2Q/3P4/1BN5/PPP2PPP/R1B1K1NR b KQkq -
+Vienna: Adams' gambit
+r1bqkb1r/pppp1ppp/2nn4/4p3/B2P4/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open Berlin defense, Showalter variation
+r1bqkb1r/pppp1ppp/5n2/1B2p3/3NP3/2N5/PPPP1PPP/R1BQK2R b KQkq -
+Four knights: Rubinstein counter-gambit, exchange variation
+r1bqkb1r/pppp1ppp/5n2/1B2p3/3nP3/2N2N2/PPPP1PPP/R1BQ1RK1 b kq -
+Four knights: Rubinstein counter-gambit, Henneberger variation
+r1bqkb1r/pppp1ppp/5n2/1B2p3/3nP3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Three knights: Schlechter variation *
+r1bqkb1r/pppp1ppp/5n2/1B2p3/3nP3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Four knights: Rubinstein counter-gambit
+r1bqkb1r/pppp1ppp/5n2/4p3/3nP3/2N2N2/PPPPBPPP/R1BQK2R b KQkq -
+Four knights: Rubinstein counter-gambit, 5.Be2
+r1bqkb1r/pppp2p1/2n5/4pPPp/6n1/2N5/PPPP1P1P/R1BQKBNR w KQkq -
+Vienna: Hamppe-Allgaier gambit *
+r1bqkb1r/pppp2p1/2n5/4pPPp/6n1/2NP4/PPP2P1P/R1BQKBNR b KQkq -
+Vienna: Hamppe-Allgaier gambit, Alapin variation *
+r1bqkb1r/pppp2p1/2n5/4pPPp/8/7P/PPPP1K2/RNBQ1BNR w kq -
+KGA: Allgaier, Blackburne gambit *
+r1bqkb1r/pppp2pp/2n2n2/4N3/3Pp3/8/PPP1BPPP/RNBQK2R b KQkq -
+Vienna gambit: Breyer variation *
+r1bqkb1r/pppp2pp/2n2n2/4pP2/6P1/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: Quaade gambit *
+r1bqkb1r/pppp2pp/2n2n2/4pP2/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna gambit *
+r1bqkb1r/pppp2pp/2n2n2/4pp2/2B1P3/3P4/PPPN1PPP/R1BQK1NR b KQkq -
+KGD: classical, Hanham variation *
+r1bqkb1r/ppppnp1p/2n3p1/1B2p3/4P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Ruy Lopez: Cozio defense, Paulsen variation
+r1bqkb1r/ppppnppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Cozio defense
+r1bqkb1r/ppppnppp/2n5/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Sicilian: chameleon variation *
+r1bqkb1r/ppppnppp/2n5/4p3/4P3/2P2N2/PP1P1PPP/RNBQKB1R w KQkq -
+Ponziani: R\'eti variation
+r1bqkb1r/ppppnppp/5n2/1B2p3/4P3/3P1N2/PPP2PPP/RNBQK2R w KQkq -
+Ruy Lopez: Berlin defense, Mortimer variation
+r1bqkb1r/ppppnppp/8/1B6/3pP3/8/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Bird's defense, Paulsen variation
+r1bqkb1r/pppppppp/2n2n2/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Kevitz-Trajkovich defense
+r1bqkbnr/1p1p1ppp/p1n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Taimanov variation
+r1bqkbnr/1pp2ppp/p1n5/1B1p4/2PPp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+French: Winawer, advance, 5.a3 *
+r1bqkbnr/1pp2ppp/p1np4/4p3/B1P1P3/5N2/PP1P1PPP/RNBQK2R b KQkq -
+Ruy Lopez: modern Steinitz defense, Duras (Keres) variation
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Ruy Lopez: modern Steinitz defense, Three knights variation
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+Ruy Lopez: modern Steinitz defense
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: modern Steinitz defense, 5.O-O
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense
+r1bqkbnr/1pp2ppp/p1p5/4p3/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Ruy Lopez: exchange, Keres variation
+r1bqkbnr/1pp2ppp/p1p5/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: exchange variation, 5.O-O
+r1bqkbnr/1pp3pp/p1np4/4pp2/B3P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense, siesta variation
+r1bqkbnr/1pp3pp/p1p2p2/4p3/4P3/2NP1N2/PPP2PPP/R1BQK2R b KQkq -
+Ruy Lopez: exchange, Romanovsky variation
+r1bqkbnr/1pp3pp/p1p2p2/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: exchange, Gligori\'c variation
+r1bqkbnr/1ppp1p1p/p1n3p1/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: fianchetto defense deferred
+r1bqkbnr/1ppp1ppp/p1B5/4p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Ruy Lopez: exchange variation
+r1bqkbnr/1ppp1ppp/p1n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Vienna: Mengarini variation *
+r1bqkbnr/1ppp1ppp/p1n5/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Ruy Lopez
+r1bqkbnr/1ppp1ppp/p7/4p3/B2nP3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Bird's defense deferred
+r1bqkbnr/1ppp2pp/p1n5/4pp2/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Schliemann defense deferred
+r1bqkbnr/1ppppppp/p1n5/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Battambang opening *
+r1bqkbnr/2p2ppp/2p5/p2p4/2PPp3/4P3/PP2NPPP/RNBQK2R w KQkq -
+French: Winawer, advance, Smyslov variation *
+r1bqkbnr/2p2ppp/p1p5/3p4/2PPp3/4P3/PP2NPPP/RNBQK2R b KQkq -
+French: Winawer, advance, 6...Ne7 *
+r1bqkbnr/2p2ppp/p1p5/3p4/2PPp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+French: Winawer, advance variation *
+r1bqkbnr/2p2ppp/p1p5/3p4/2PPp3/4P3/PPQ2PPP/RNB1K1NR b KQkq -
+French: Winawer, classical variation *
+r1bqkbnr/2p2ppp/p1pp4/4p3/3PP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+Ruy Lopez: modern Steinitz defense, Richter variation
+r1bqkbnr/2p2ppp/p1pp4/4p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense, exchange variation
+r1bqkbnr/2p3pp/p1pp1p2/4p3/3PP3/5N2/PPP2PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense, Alapin variation
+r1bqkbnr/2pp1ppp/p1n5/1p2p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Caro variation
+r1bqkbnr/2pp1ppp/p7/np2p3/4P3/1B3N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Taimanov (chase/wing/accelerated counterthrust) variation
+r1bqkbnr/4p1pp/p1p2p2/3p4/2Pp4/4PN2/PP3PPP/RNBQK2R w KQkq -
+Nimzo-Indian: S\"amisch variation *
+r1bqkbnr/4p1pp/p1p2p2/8/2pN1P2/4P3/PP4PP/RNBQK2R b KQkq -
+Nimzo-Indian: S\"amisch, Romanovsky variation *
+r1bqkbnr/4p1pp/p1p2p2/8/2pN4/4P3/PP3PPP/RNBQK2R w KQkq -
+Nimzo-Indian: S\"amisch, Keres variation *
+r1bqkbnr/4pppp/p1p5/2pp4/8/4PN2/PPPP1PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: S\"amisch variation *
+r1bqkbnr/4pppp/p1p5/2pp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: S\"amisch variation *
+r1bqkbnr/5ppp/p1p1p3/2pp4/2P5/1P2PN2/P2P1PPP/RNBQK2R b KQkq -
+Nimzo-Indian: S\"amisch, O'Kelly variation *
+r1bqkbnr/5ppp/p1p1p3/2pp4/2P5/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: S\"amisch variation *
+r1bqkbnr/5ppp/p1p1p3/2pp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+Nimzo-Indian: S\"amisch variation *
+r1bqkbnr/5ppp/p2p4/1pp5/3QP3/1B6/PPP2PPP/RNB1K2R w KQkq -
+Ruy Lopez: Noah's ark trap
+r1bqkbnr/6pp/p1p1pp2/3p4/2PN4/4P3/PP3PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: S\"amisch, Botvinnik variation *
+r1bqkbnr/p1pp1ppp/2n5/1p6/Q7/8/PPP1PPPP/RNB1KBNR w KQkq -
+Scandinavian, Mieses-Kotr\v c gambit *
+r1bqkbnr/p2p1ppp/1pn1p3/2p5/4P3/2NP1N2/PPP2PPP/R1BQKB1R b KQkq -
+Amsterdam attack *
+r1bqkbnr/p3pppp/2p5/2p5/2Pp1P2/6P1/PP1PP2P/RNBQK1NR b KQkq -
+Beefeater defense *
+r1bqkbnr/pp1n1ppp/2pp4/4p1N1/2BPP3/8/PPP2PPP/RNBQK2R b KQkq -
+Philidor: Hanham, Kmoch variation
+r1bqkbnr/pp1n1ppp/2pp4/4p3/2BPP3/2N2N2/PPP2PPP/R1BQK2R b KQkq -
+Philidor: Hanham, Schlechter variation
+r1bqkbnr/pp1n1ppp/2pp4/4p3/2BPP3/2P2N2/PP3PPP/RNBQK2R b KQkq -
+Philidor: Hanham, Delmar variation
+r1bqkbnr/pp1n1ppp/2pp4/4p3/2BPP3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Philidor: Hanham, Krause variation
+r1bqkbnr/pp1npppp/2p5/8/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+Caro-Kann: Steinitz variation
+r1bqkbnr/pp1p1p1p/2n3p1/2p1p3/2P4P/2NP4/PP2PPP1/R1BQKBNR b KQkq -
+Sicilian: Gloria variation *
+r1bqkbnr/pp1p1ppp/2n1p3/1N6/4P3/8/PPP2PPP/RNBQKB1R b KQkq -
+Sicilian, Sz\'en (`anti-Taimanov') variation
+r1bqkbnr/pp1p1ppp/2n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Sicilian: Taimanov variation
+r1bqkbnr/pp1p1ppp/2n1p3/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian defense
+r1bqkbnr/pp1p1ppp/2n5/2p1p3/2P5/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+English: Mikenas-Carls, Sicilian variation *
+r1bqkbnr/pp1p1ppp/2n5/2p1p3/8/2N1PN2/PPPP1PPP/R1BQKB1R b KQkq -
+English: Mikenas-Carls, Kevitz variation *
+r1bqkbnr/pp1p1ppp/2n5/2p1p3/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+English: Mikenas-Carls variation *
+r1bqkbnr/pp1p1ppp/2n5/2p5/3Pp3/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+English: Mikenas-Carls, Flohr variation *
+r1bqkbnr/pp1p1ppp/2n5/4p3/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Labourdonnais-L\"owenthal variation
+r1bqkbnr/pp1ppp1p/2N3p1/8/4P3/8/PPP2PPP/RNBQKB1R b KQkq -
+Sicilian: accelerated fianchetto, exchange variation
+r1bqkbnr/pp1ppp1p/2n3p1/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+English: Bremen, Smyslov system *
+r1bqkbnr/pp1ppp1p/2n3p1/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Sicilian: Nimzovich-Rossolimo attack (with ...g6, without ...d6)
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English: symmetrical variation *
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/2P5/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+English: symmetrical variation *
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+English: Bremen, reverse dragon *
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/2P2N2/PP1P1PPP/RNBQKB1R b KQkq -
+English: Bremen system, Keres variation *
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/2PP4/PP3PPP/RNBQKBNR b KQkq -
+English, Keres variation *
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+English: Carls' Bremen system *
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/5NP1/PPPP1P1P/RNBQKB1R b KQkq -
+English: Bremen system with ...g6 *
+r1bqkbnr/pp1ppp1p/2n3p1/8/2PNP3/8/PP3PPP/RNBQKB1R b KQkq -
+Sicilian: accelerated fianchetto, Mar\'oczy bind
+r1bqkbnr/pp1ppp1p/2n3p1/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Sicilian: accelerated fianchetto, modern variation
+r1bqkbnr/pp1ppppp/2n5/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Sicilian: Nimzovich-Rossolimo attack (without ...d6)
+r1bqkbnr/pp1ppppp/2n5/1Bp5/4P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+English, Kramnik-Shirov counterattack *
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+English: symmetrical variation
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+English: symmetrical variation *
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English: symmetrical variation
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English: symmetrical variation *
+r1bqkbnr/pp1ppppp/2n5/2p5/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+English: Anglo-Gr\"unfeld defense *
+r1bqkbnr/pp1ppppp/2n5/2p5/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Sicilian defense
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+Sicilian: closed
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+English: Sicilian reversed *
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Sicilian: closed, 2...Nc6
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/2N5/PPPPNPPP/R1BQKB1R b KQkq -
+Sicilian: chameleon variation
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+English opening *
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian defense
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+English opening *
+r1bqkbnr/pp1ppppp/2n5/2p5/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Sicilian: Grand Prix attack
+r1bqkbnr/pp1ppppp/2n5/2p5/8/2NP2P1/PPP1PP1P/R1BQKBNR b KQkq -
+Venezolana opening
+r1bqkbnr/pp1ppppp/2n5/2p5/8/4PN2/PPPP1PPP/RNBQKB1R b KQkq -
+English opening *
+r1bqkbnr/pp1ppppp/2n5/2p5/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+English opening *
+r1bqkbnr/pp1ppppp/2n5/8/7Q/2N5/PPP1PPPP/R1B1KBNR b KQkq -
+Novosibirsk opening
+r1bqkbnr/pp2p1pp/2n2p2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: Kmoch variation *
+r1bqkbnr/pp2pp1p/2n3p1/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: Romanishin-Kasparov (Steiner) system *
+r1bqkbnr/pp2pp1p/2n5/2pp2p1/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Gr\"unfeld: Spike gambit *
+r1bqkbnr/pp2ppp1/2np4/2p4p/2P1P3/2N3P1/PP1P1P1P/R1BQKBNR w KQkq -
+Sicilian: Gloria variation
+r1bqkbnr/pp2pppp/2n5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R b KQkq -
+Nimzo-Indian defense *
+r1bqkbnr/pp2pppp/2n5/2pp4/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+QGD: Tarrasch defense *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/1P2P3/P1P2PPP/RNBQKBNR b KQkq -
+QGD: Alapin variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/2P1P3/PP3PPP/RNBQKBNR b KQkq -
+QGD: semi-Slav *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/4P3/PPP1BPPP/RNBQK1NR b KQkq -
+QGD: Charousek (Petrosian) variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+QGD: 3.Nc3 *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+QGD: 3...Nf6 *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+Gr\"unfeld defense *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/P3P3/1PP2PPP/RNBQKBNR b KQkq -
+QGD: Janowski variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/3PP3/2P5/PP3PPP/RNBQKBNR b KQkq -
+QGD Slav: Winawer counter-gambit *
+r1bqkbnr/pp2pppp/2n5/2pp4/4P3/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+Old Indian: Ukrainian variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/5B2/3P1N2/PPP1PPPP/RN1QKB1R b KQkq -
+Old Indian: Janowski variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/5P2/4P3/PPPP2PP/RNBQKBNR w KQkq -
+Dutch defense, Rubinstein variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Dutch with c4 & Nc3 *
+r1bqkbnr/pp2pppp/2n5/2pp4/5P2/6PN/PPPPP2P/RNBQKB1R b KQkq -
+Dutch defense: Bladel variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/8/3P2P1/PPP1PPBP/RNBQK1NR b KQkq -
+Modern defense *
+r1bqkbnr/pp2pppp/2n5/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian defense, 3.Nc3 *
+r1bqkbnr/pp2pppp/2n5/3P4/3p4/4P3/PP3PPP/RNBQKBNR b KQkq -
+QGD: Tarrasch, von Hennig-Schara gambit *
+r1bqkbnr/pp2pppp/2n5/3p4/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+QGD: Tarrasch defense, 4.cd ed *
+r1bqkbnr/pp2pppp/2n5/3p4/3N4/6P1/PPP1PP1P/RNBQKB1R b KQkq -
+Gr\"unfeld: exchange variation *
+r1bqkbnr/pp2pppp/2n5/3p4/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Nimzovich variation
+r1bqkbnr/pp2pppp/2n5/3p4/3p4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+QGD: exchange variation *
+r1bqkbnr/pp2pppp/2n5/8/1pPp4/P4N2/3PPPPP/RNBQKB1R w KQkq -
+Benk\"o gambit: Zaitsev system *
+r1bqkbnr/pp2pppp/8/n2P4/1Pp5/8/P4PPP/RNBQKBNR b KQkq b3
+QGD: Tarrasch defense, Tarrasch gambit *
+r1bqkbnr/pp3p1p/2n3p1/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian with e4 & g3 *
+r1bqkbnr/pp3pp1/2n4p/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: Makagonov system (5.h3) *
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+Nimzo-Indian: 4.e3 c5 *
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/1P2PN2/P1PP1PPP/RNBQK2R b KQkq -
+Nimzo-Indian: Fischer variation *
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/2N1PN2/PPPP1PPP/R1BQK2R b KQkq -
+Nimzo-Indian: 4.e3, Taimanov variation *
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: 4.e3 O-O *
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: 4.e3 *
+r1bqkbnr/pp3ppp/2n1p3/2ppP3/3P4/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+French: advance, Paulsen attack
+r1bqkbnr/pp3ppp/2n1p3/2ppP3/3P4/2P5/PP3PPP/RNBQKBNR w KQkq -
+French: advance variation
+r1bqkbnr/pp3ppp/2n5/2P1p3/1PPp4/5N2/P3PPPP/RNBQKB1R b KQkq -
+QGA: Linares variation *
+r1bqkbnr/pp3ppp/2n5/2Ppp3/8/2P5/PP2PPPP/RNBQKBNR w KQkq -
+QGD Slav defense, Alekhine variation *
+r1bqkbnr/pp3ppp/2n5/2p1p3/2PpP3/3P1NP1/PP3P1P/RNBQKB1R b KQkq -
+Czech Benoni: King's Indian system *
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+QGD: Tarrasch, Schlechter-Rubinstein system
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+Caro-Kann: Panov-Botvinnik attack, 5...e6 *
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Caro-Kann: Panov-Botvinnik attack *
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/5N2/PPPN1PPP/R1BQKB1R w KQkq -
+French: Tarrasch, open variation, main line
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/5NP1/PP2PP1P/RNBQKB1R b KQkq -
+Caro-Kann: Panov-Botvinnik attack, 5...g6 *
+r1bqkbnr/pp3ppp/2n5/2ppp3/3P4/2P1P3/PP3PPP/RNBQKBNR w KQkq -
+QGD: semi-Slav, Marshall gambit *
+r1bqkbnr/pp3ppp/2n5/2ppp3/5P2/3P2P1/PPP1P1BP/RNBQK1NR b KQkq -
+Modern defense: Averbakh system, Randspringer variation *
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/2NP2P1/PPP1PPBP/R1BQK1NR b KQkq -
+Modern defense: Averbakh system, Kotov variation *
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/3P2P1/PPP1PPBP/RNBQK1NR w KQkq -
+Modern defense: Averbakh system *
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/5NP1/PPPPPPBP/RNBQK2R w KQkq -
+King's Indian: 4.e4 *
+r1bqkbnr/pp3ppp/2n5/3p4/2pP4/2N2NP1/PP2PP1P/R1BQKB1R w KQkq -
+QGD: Tarrasch, Folkestone (Swedish) variation
+r1bqkbnr/pp3ppp/2n5/3p4/2pPP3/2N2NP1/PP3P1P/R1BQKB1R b KQkq -
+QGD: Tarrasch, Schlechter-Rubinstein system, Rey Ardid variation
+r1bqkbnr/pp3ppp/2n5/3pp3/2PP4/8/PP3PPP/RNBQKBNR w KQkq -
+QGD: Tarrasch defense, Marshall gambit *
+r1bqkbnr/pp3ppp/2n5/4p3/2Pp4/3P1N2/PP3PPP/RNBQKB1R w KQkq -
+Benoni: 6.e4 *
+r1bqkbnr/pp3ppp/2n5/4p3/2Pp4/B2P1N2/4PPPP/RN1QKB1R w KQkq -
+Benk\"o gambit: 7.e4 *
+r1bqkbnr/pp3ppp/2np4/1N2p3/4P3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Labourdonnais-L\"owenthal (Kalashnikov) variation
+r1bqkbnr/pp4pp/2n2p2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, 5...O-O *
+r1bqkbnr/pp4pp/2n2p2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: S\"amisch variation *
+r1bqkbnr/pp4pp/2n5/2pppp2/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: Four pawns attack *
+r1bqkbnr/pp4pp/2n5/4pp2/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+Benoni: pawn storm variation *
+r1bqkbnr/pp4pp/2n5/5p2/2Ppp3/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+Benoni: Mikenas variation *
+r1bqkbnr/ppnppppp/2p5/8/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+de Bruycker defense
+r1bqkbnr/ppp1pp1p/2n5/3p2p1/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Dutch, Spielmann gambit *
+r1bqkbnr/ppp1pp1p/2np2p1/8/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Venezolana opening *
+r1bqkbnr/ppp1pppp/2n5/3p2B1/3P4/8/PPP1PPPP/RN1QKBNR b KQkq -
+Queen's pawn: Anti-Veresov *
+r1bqkbnr/ppp1pppp/2n5/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QGD: Chigorin defense
+r1bqkbnr/ppp1pppp/2n5/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's pawn game, Chigorin variation
+r1bqkbnr/ppp1pppp/2n5/3p4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn: Chigorin variation *
+r1bqkbnr/ppp1pppp/2n5/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+KP: Nimzovich defense, Bogolyubov variation
+r1bqkbnr/ppp1pppp/2n5/8/2Pp4/3P2P1/PP2PP1P/RNBQKBNR b KQkq -
+Old Benoni: Schmid's system *
+r1bqkbnr/ppp1pppp/2n5/8/2pP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+QGD: Chigorin defense, Janowski variation
+r1bqkbnr/ppp1pppp/2n5/8/Q1Pp4/5N2/PP1PPPPP/RNB1KB1R b KQkq -
+Woozle defense *
+r1bqkbnr/ppp2p1p/2n3p1/3pp3/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Pirc: Sveshnikov system *
+r1bqkbnr/ppp2p1p/2n5/3pP1p1/8/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Dutch: Staunton gambit, Tartakower variation *
+r1bqkbnr/ppp2p1p/2np4/6N1/4PppP/2N5/PPPP2P1/R1BQKB1R w KQkq -
+Vienna: Hamppe-Allgaier gambit, Alapin variation
+r1bqkbnr/ppp2pp1/6n1/3p3p/8/2P3B1/PP2PPPP/RN1QKBNR w KQkq -
+Caro-Kann: classical, 6.h4 *
+r1bqkbnr/ppp2ppp/2n1p3/3p4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+French: Tarrasch, Guimard variation
+r1bqkbnr/ppp2ppp/2n5/1B1p4/2PPp3/4P3/PP3PPP/RNBQK1NR b KQkq -
+French: Winawer, advance variation *
+r1bqkbnr/ppp2ppp/2n5/1B1p4/3Pp3/4P3/PPP2PPP/RNBQK1NR w KQkq -
+French: Winawer, advance variation *
+r1bqkbnr/ppp2ppp/2n5/1B1p4/3Pp3/4P3/PPPQ1PPP/RNB1K1NR b KQkq -
+French: Winawer, Petrosian variation *
+r1bqkbnr/ppp2ppp/2n5/1B1p4/3Pp3/4PN1P/PPP2PP1/RNBQK2R w KQkq -
+French: MacCutcheon, Dr. Olland (Dutch) variation *
+r1bqkbnr/ppp2ppp/2n5/1B1pp3/3P4/4P3/PPP2PPP/RNBQK1NR b KQkq -
+French: Winawer (Nimzovich) variation *
+r1bqkbnr/ppp2ppp/2n5/3p4/3Pp3/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+French: Steinitz variation *
+r1bqkbnr/ppp2ppp/2n5/3p4/3Q4/2N5/PPP1PPPP/R1B1KBNR w KQkq -
+KP: Nimzovich defense, Marshall gambit *
+r1bqkbnr/ppp2ppp/2n5/3p4/Q3P3/8/PPP2PPP/RNB1KBNR b KQkq -
+Scandinavian: Anderssen counter-attack *
+r1bqkbnr/ppp2ppp/2n5/3pP3/8/4P3/PPP2PPP/RNBQKBNR b KQkq -
+French: Rubinstein variation *
+r1bqkbnr/ppp2ppp/2n5/3pp3/1P1P4/2P5/P3PPPP/RNBQKBNR b KQkq -
+Caro-Kann: Gurgenidze counter-attack *
+r1bqkbnr/ppp2ppp/2n5/3pp3/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+French: Marshall variation *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/2N5/PPP1PPPP/R1BQKBNR w KQkq -
+KP: Nimzovich defense, Bogolyubov variation *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/2P3P1/PP2PP1P/RNBQKBNR b KQkq -
+Caro-Kann: Gurgenidze system *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann defense *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: Paulsen variation *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+French defense *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Blackmar-Diemer gambit *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Blackmar-Diemer: Lemberg counter-gambit *
+r1bqkbnr/ppp2ppp/2n5/3pp3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna: Fyfe gambit *
+r1bqkbnr/ppp2ppp/2n5/3pp3/8/2P5/PPNPPPPP/R1BQKBNR b KQkq -
+de Bruycker defense *
+r1bqkbnr/ppp2ppp/2n5/3pp3/8/2PP1N2/PP2PPPP/RNBQKB1R b KQkq -
+Pirc: Ufimtsev-Pytel variation *
+r1bqkbnr/ppp2ppp/2n5/3pp3/8/3P1NP1/PPP1PP1P/RNBQKB1R b KQkq -
+Pirc defense *
+r1bqkbnr/ppp2ppp/2n5/3pp3/8/3P2P1/PPP1PPBP/RNBQK1NR b KQkq -
+Robatsch (modern) defense *
+r1bqkbnr/ppp2ppp/2n5/3pp3/8/6P1/PPPPPPBP/RNBQK1NR w KQkq -
+Robatsch defense *
+r1bqkbnr/ppp2ppp/2n5/4P3/2Pp4/5N2/PP1NPPPP/R1BQKB1R b KQkq -
+QGD: Albin counter-gambit, Alapin variation
+r1bqkbnr/ppp2ppp/2n5/4P3/2Pp4/5NP1/PP2PP1P/RNBQKB1R b KQkq -
+QGD: Albin counter-gambit, 5.g3
+r1bqkbnr/ppp2ppp/2np4/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: old Steinitz defense
+r1bqkbnr/ppp2ppp/3p4/8/3QP3/3B4/PPP2PPP/RNB1K2R b KQkq -
+Scotch: Ghulam Kassim variation
+r1bqkbnr/ppp2ppp/8/3p4/8/2P2P2/PP2PP1P/RNBQKB1R b KQkq -
+Caro-Kann: Bronstein-Larsen variation *
+r1bqkbnr/ppp2ppp/8/3p4/8/2P2P2/PP3PPP/RNBQKB1R b KQkq -
+Caro-Kann: Tartakower (Nimzovich) variation *
+r1bqkbnr/ppp2ppp/8/3pn3/3Q4/4P3/PPP2PPP/RNB1KBNR b KQkq -
+French: Frere (Becker) variation *
+r1bqkbnr/ppp2ppp/8/3pn3/5B2/2P5/PP2PPPP/RN1QKBNR b KQkq -
+Caro-Kann: classical variation *
+r1bqkbnr/ppp2ppp/8/3pn3/8/2P5/PP1NPPPP/R1BQKBNR b KQkq -
+Caro-Kann: Steinitz variation *
+r1bqkbnr/ppp2ppp/8/3pn3/8/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann defense *
+r1bqkbnr/ppp2ppp/8/3pn3/8/4P3/PPPN1PPP/R1BQKBNR b KQkq -
+French: Rubinstein variation *
+r1bqkbnr/ppp3pp/2n2p2/3pP3/8/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: Rasa-Studier gambit *
+r1bqkbnr/ppp3pp/2n2p2/3pp3/Q3P3/2P2N2/PP1P1PPP/RNB1KB1R w KQkq -
+Ponziani: Steinitz variation
+r1bqkbnr/ppp3pp/2n2p2/4P3/2Pp4/5N2/PP1NPPPP/R1BQKB1R w KQkq -
+QGD: Albin counter-gambit, Janowski variation
+r1bqkbnr/ppp3pp/2n5/3p1p2/3Pp2P/2P3P1/PP2PPB1/RNBQK1NR b KQkq -
+Robatsch defense: Gurgenidze variation *
+r1bqkbnr/ppp3pp/2n5/3ppP2/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna: Steinitz gambit *
+r1bqkbnr/ppp3pp/2n5/3ppp2/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Pirc: Austrian attack *
+r1bqkbnr/ppp3pp/2n5/3ppp2/8/3P2P1/PPP1PPBP/RNBQK1NR w KQkq -
+Robatsch defense: Pseudo-Austrian attack *
+r1bqkbnr/ppp3pp/2n5/5p2/2pPp3/2N1P3/PP1N1PPP/R1BQKB1R b KQkq -
+French: Steinitz variation *
+r1bqkbnr/ppp3pp/2np4/3Ppp2/4P3/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+Ponziani counter-gambit, Schmidt attack
+r1bqkbnr/ppp3pp/2np4/4N3/3Pp3/8/PPP2PPP/RNBQKB1R w KQkq -
+Vienna gambit *
+r1bqkbnr/ppp3pp/2np4/4pp2/3PP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Vienna gambit, Steinitz variation *
+r1bqkbnr/ppp3pp/6n1/3p1p2/8/2P3B1/PP2PPPP/RN1QKBNR w KQkq -
+Caro-Kann: classical, Mar\'oczy attack *
+r1bqkbnr/pppn1ppp/3p4/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Hanham variation
+r1bqkbnr/pppn1ppp/4p3/8/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+French: Rubinstein variation
+r1bqkbnr/pppn1ppp/8/3p4/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+French: Tarrasch, open, 4.ed ed *
+r1bqkbnr/pppn1ppp/8/3pp3/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+French: Tarrasch, open variation *
+r1bqkbnr/pppn1ppp/8/3pp3/3P1P2/4P3/PPP3PP/RNBQKBNR b KQkq -
+French: Tarrasch, Haberditz variation *
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/1QP5/PP2PPPP/RNB1KBNR b KQkq -
+Caro-Kann: Edinburgh variation *
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/2N1P3/PPP2PPP/R1BQKBNR b KQkq -
+French: Tarrasch, Guimard variation *
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: 3.Nd2 *
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: Tarrasch *
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+French: Tarrasch, closed variation *
+r1bqkbnr/pppn2pp/3p4/4Pp2/3p4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+KGD: Falkbeer, Keres variation *
+r1bqkbnr/pppnpppp/3p4/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Valencia opening *
+r1bqkbnr/pppp1p1p/2n3p1/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: fianchetto (Smyslov/Barnes) defense
+r1bqkbnr/pppp1p1p/2n3p1/3N4/3pP3/5N2/PPP2PPP/R1BQKB1R b KQkq -
+Three knights: Steinitz, Rosenthal variation
+r1bqkbnr/pppp1p1p/2n3p1/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Sicilian: closed *
+r1bqkbnr/pppp1p1p/2n3p1/4p3/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+Sicilian: closed, Korchnoi variation *
+r1bqkbnr/pppp1p1p/2n3p1/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Three knights: Steinitz variation
+r1bqkbnr/pppp1p1p/2n3p1/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna: Paulsen variation *
+r1bqkbnr/pppp1p1p/2n3p1/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Vienna: Paulsen-Mieses variation *
+r1bqkbnr/pppp1p1p/2n5/1B2p1p1/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Brentano defense
+r1bqkbnr/pppp1p1p/2n5/4N3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Neumann defense
+r1bqkbnr/pppp1p1p/2n5/6N1/4PppP/2N5/PPPP2P1/R1BQKB1R b KQkq -
+Vienna: Hamppe-Allgaier gambit
+r1bqkbnr/pppp1p1p/2n5/6p1/2B1Pp2/5N2/PPPP2PP/RNBQK2R w KQkq -
+KGA: Blachly gambit
+r1bqkbnr/pppp1p1p/2n5/6p1/3PPp2/2N2N2/PPP3PP/R1BQKB1R b KQkq -
+Vienna: Pierce gambit
+r1bqkbnr/pppp1p1p/2n5/8/2B1Pp2/5Q2/PPPP2PP/RNB2RK1 w kq -
+KGA: Muzio gambit, Holloway defense
+r1bqkbnr/pppp1p1p/2n5/8/2B1Ppp1/2N2N2/PPPP2PP/R1BQ1RK1 b kq -
+Vienna: Hamppe-Muzio gambit
+r1bqkbnr/pppp1ppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Ruy Lopez (Spanish opening)
+r1bqkbnr/pppp1ppp/2n5/1B6/3pP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+Scotch: Relfsson gambit (`MacLopez')
+r1bqkbnr/pppp1ppp/2n5/4p3/2B1P3/2P2N2/P2P1PPP/RNBQK2R w KQkq -
+Evans gambit: Mayet defense
+r1bqkbnr/pppp1ppp/2n5/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+King's pawn game
+r1bqkbnr/pppp1ppp/2n5/4p3/2P1P3/5N2/PP1P1PPP/RNBQKB1R b KQkq -
+Dresden opening
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+English: three knights system
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+Sicilian: closed, 2...Nc6 *
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English: Sicilian reversed
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: closed *
+r1bqkbnr/pppp1ppp/2n5/4p3/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Alekhine's defense: Scandinavian variation *
+r1bqkbnr/pppp1ppp/2n5/4p3/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+Vienna: Fyfe gambit
+r1bqkbnr/pppp1ppp/2n5/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Scotch opening
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Three knights game
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+Vienna: Paulsen variation
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Vienna game, Max Lange defense *
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna game, Max Lange defense
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2P2N2/PP1P1PPP/RNBQKB1R b KQkq -
+Ponziani opening
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+Vienna: Falkbeer variation *
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+King's pawn game
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPPBPPP/RNBQK2R b KQkq -
+Inverted Hungarian
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5NP1/PPPP1P1P/RNBQKB1R b KQkq -
+Konstantinopolsky opening
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Vienna game *
+r1bqkbnr/pppp1ppp/2n5/4p3/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Vienna gambit
+r1bqkbnr/pppp1ppp/2n5/4p3/8/2P5/PP1PPPPP/RNBQKBNR w KQkq -
+Caro-Kann defense *
+r1bqkbnr/pppp1ppp/2n5/4p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French defense *
+r1bqkbnr/pppp1ppp/2n5/8/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Maurian defense
+r1bqkbnr/pppp1ppp/2n5/8/2BpP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+Scotch gambit
+r1bqkbnr/pppp1ppp/2n5/8/2Q1P3/8/PPP2PPP/RNB1KBNR b KQkq -
+Center game: Hall variation
+r1bqkbnr/pppp1ppp/2n5/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+Scotch game
+r1bqkbnr/pppp1ppp/2n5/8/3Np3/8/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: S\"amisch attack *
+r1bqkbnr/pppp1ppp/2n5/8/3P4/4p3/PPPNPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Spielmann variation *
+r1bqkbnr/pppp1ppp/2n5/8/3PPp2/2N5/PPP3PP/R1BQKBNR b KQkq -
+Vienna: Steinitz gambit
+r1bqkbnr/pppp1ppp/2n5/8/3QP3/8/PPP2PPP/RNB1KBNR w KQkq -
+Center game
+r1bqkbnr/pppp1ppp/2n5/8/3pP3/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+Scotch: G\"oring gambit
+r1bqkbnr/pppp1ppp/2n5/8/4P3/4Q3/PPP2PPP/RNB1KBNR b KQkq -
+Center game: Paulsen attack
+r1bqkbnr/pppp1ppp/2n5/8/4Pp2/2N2N2/PPPP2PP/R1BQKB1R b KQkq -
+Vienna gambit
+r1bqkbnr/pppp1ppp/2n5/8/8/3Q4/PPP1PPPP/RNB1KBNR b KQkq -
+Scandinavian: Pytel-Wade variation *
+r1bqkbnr/pppp1ppp/8/1B2p3/3nP3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Bird's defense
+r1bqkbnr/pppp1ppp/8/4n3/3PP3/8/PPP2PPP/RNBQKB1R b KQkq -
+Irish (Chicago) gambit
+r1bqkbnr/pppp1ppp/8/4p3/3nP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Scotch: Lolli variation
+r1bqkbnr/pppp1ppp/8/nB2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Pollock defense
+r1bqkbnr/pppp2pp/2n2p2/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Nuremberg variation
+r1bqkbnr/pppp2pp/2n5/1B2pp2/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Ruy Lopez: Schliemann defense, Berger variation
+r1bqkbnr/pppp2pp/2n5/1B2pp2/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Schliemann defense
+r1bqkbnr/pppp2pp/2n5/4Np2/4P3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Latvian: Fraser defense
+r1bqkbnr/pppp2pp/2n5/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Keres (Mason-Steinitz) gambit *
+r1bqkbnr/pppp2pp/2n5/4pp2/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Rousseau gambit
+r1bqkbnr/pppp2pp/2n5/4pp2/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Sicilian: Grand Prix attack *
+r1bqkbnr/pppp2pp/2n5/4pp2/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: Pelikan variation *
+r1bqkbnr/pppp2pp/2n5/4pp2/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Vienna gambit *
+r1bqkbnr/pppp2pp/2n5/4pp2/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+KGD: Falkbeer, Milner-Barry variation *
+r1bqkbnr/pppp2pp/2n5/4pp2/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Three knights: Winawer defense (Gothic defense)
+r1bqkbnr/pppp2pp/2n5/4pp2/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna gambit *
+r1bqkbnr/pppp2pp/2n5/4pp2/4P3/2P2N2/PP1P1PPP/RNBQKB1R w KQkq -
+Ponziani counter-gambit
+r1bqkbnr/pppp2pp/2n5/4pp2/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Vienna gambit *
+r1bqkbnr/pppp2pp/2n5/5p2/4P3/4Q3/PPP2PPP/RNB1KBNR w KQkq -
+Center game: l'Hermet variation
+r1bqkbnr/pppp3p/2n5/4Ppp1/8/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Bird's opening, Swiss gambit *
+r1bqkbnr/ppppp1pp/2n2p2/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+KP: Neo-Mongoloid defense
+r1bqkbnr/ppppp1pp/2n5/5p2/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+KP: Colorado counter
+r1bqkbnr/pppppppp/2n5/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn: Lundin (Kevitz-Mikenas) defense
+r1bqkbnr/pppppppp/2n5/8/3PP3/2P5/P4PPP/RNBQKBNR b KQkq -
+KP: Nimzovich defense, Wheeler gambit
+r1bqkbnr/pppppppp/2n5/8/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+KP: Nimzovich defense
+r1bqkbnr/pppppppp/2n5/8/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+KP: Nimzovich defense
+r1bqkbnr/pppppppp/2n5/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+Dunst (Sleipner,Heinrichsen) opening *
+r1bqkbnr/pppppppp/2n5/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: Nimzovich defense
+r1bqkbnr/pppppppp/2n5/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Dunst (Sleipner, Heinrichsen) opening *
+r1bqkbnr/pppppppp/n7/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Lemming defense
+r1bqkbnr/pppppppp/n7/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Durkin's attack *
+r1bqnrk1/p2p1ppp/1pn1p3/2p5/2PPP3/P1PB4/4NPPP/R1BQK2R w KQ -
+Nimzo-Indian: S\"amisch, Capablanca variation
+r1bqnrk1/pp2b1pp/2n2p2/2p1p3/3pPP2/3P2P1/PPPNN1BP/R1BQ1RK1 b - -
+King's Indian: orthodox, Aronin-Taimanov, main line *
+r1bqnrk1/pp2b2p/2n2p2/2p1p1p1/3pPP2/3P2P1/PPPNN1BP/R1BQ1RK1 w - -
+King's Indian: orthodox, Aronin-Taimanov, Benk\"o attack *
+r1bqnrk1/pp2bppp/2n5/2p1p3/3pP3/3P1NP1/PPP1NPBP/R1BQ1RK1 w - -
+King's Indian: orthodox, Aronin-Taimanov, 9.Ne1 *
+r1bqr1k1/1p1n1pbp/p2p1np1/2pP4/P7/2N3P1/1P1NPPBP/R1BQ1RK1 w - -
+Benoni: fianchetto, 11...Re8
+r1bqr1k1/p1p2ppp/2pp1n2/4p3/1b2P3/2NP1N2/PPP2PPP/R1BQ1RK1 w - -
+Four knights: Janowski variation *
+r1bqr1k1/pp1n1ppp/2p2n2/b2pp3/4P3/P1NP1N2/1PP1BPPP/R2QBRK1 b - -
+Ruy Lopez: Kecskem\'et variation *
+r1bqr1k1/pp1n1ppp/2pb1n2/3pN1B1/3P1P2/2N5/PPP1B1PP/R2QK2R w KQ -
+Petrov: classical attack, Berger variation *
+r1bqr1k1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+King's Indian: orthodox, 7...Nbd7, 8.Re1 *
+r1bqr1k1/pp2ppbp/2n2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 w - -
+Dutch: Ilyin-Genevsky, Winter variation *
+r1bqr1k1/pp3pbp/n2p1np1/2pP4/4P3/2N2P2/PP1NB1PP/R1BQ1RK1 b - -
+Benoni: classical, 11.f3
+r1bqr1k1/pp3pbp/n2p1np1/2pP4/4P3/2N5/PP1NBPPP/R1BQ1RK1 w - -
+Benoni: classical with ...Re8 and ...Na6
+r1bqr1k1/ppb2pp1/2p1nn1p/3pp3/NPP1P3/P2P1NP1/2QBBP1P/R3R1K1 b - -
+Ruy Lopez: closed, Chigorin, Yugoslav system *
+r1bqr1k1/ppbn1pp1/2p2n1p/3pp3/1PP1P3/P1NP1N2/2Q1BPPP/R1B2RK1 b - -
+Ruy Lopez: closed, Chigorin, 12...Nc6 *
+r1bqr1k1/ppbn1pp1/2p2n1p/3pp3/1PP1P3/P2P1N2/1B1NBPPP/R2Q1RK1 b - -
+Ruy Lopez: closed, Breyer, Gligori\'c variation *
+r1bqr1k1/ppbn1pp1/2p2n1p/4p3/1PPpP1P1/P2P1N2/2Q1BP1P/RNB1K2R b KQ -
+Ruy Lopez: closed, Leonhardt variation *
+r1bqr1k1/ppbn1pp1/2p2n1p/4p3/1Pp1P3/P1NP1N2/2Q1BPPP/R1B2RK1 w - -
+Ruy Lopez: closed, Chigorin, Rauzer attack *
+r1bqr1k1/ppbn1pp1/5n1p/3pp3/NP2P3/P2P1N2/2Q1BPPP/R1B2RK1 w - -
+Ruy Lopez: closed, Chigorin, 12...c5d4 *
+r1bqr1k1/ppp2ppp/2n2n2/2bPN3/3P4/2N5/PPP2PPP/R1BQKB1R w KQ -
+two knights defense: Canal variation *
+r1bqr1k1/ppp2ppp/2n2n2/3pp3/1b2P3/2NP1N2/PPPBBPPP/R2Q1RK1 b - -
+Ruy Lopez: Berlin defense, Tarrasch trap *
+r1bqr1k1/ppp2ppp/2n2n2/4N3/3PpP2/P1P5/2P3PP/R1BQKB1R w KQ -
+Ruy Lopez: Steinitz defense deferred, Boleslavsky variation *
+r1bqr1k1/ppp2ppp/2np1n2/8/1bB1P3/2N1Q2N/PPPB1PPP/2KR3R b - -
+Center game: Kupreichik variation
+r1bqr1k1/ppp2ppp/8/2PPn3/2B2Qn1/2N1Bp2/PPP2PPP/R3K2R w KQ -
+two knights: Max Lange attack, Marshall variation *
+r1bqr1k1/ppp2ppp/8/2PPn3/5Qn1/2N1Bp2/PPP2PPP/R3KB1R b KQ -
+two knights: Max Lange attack, Rubinstein variation *
+r1bqr1k1/ppp2ppp/8/3pn3/3Q4/P1P1B3/1PP2PPP/R3KB1R b KQ -
+Four knights: Spielmann variation *
+r1bqr1k1/ppp4p/8/2PPnpp1/6n1/1BN1BpQ1/PPP2PPP/2KR3R b - -
+two knights: Max Lange attack, Berger variation *
+r1bqr1k1/pppn1pbp/3p1np1/4p3/2PP4/2N1PN2/PP2BPPP/R1BQ1RK1 w - -
+R\'eti: King's Indian attack, French variation *
+r1bqr1k1/pppp1ppp/2n2n2/3NpQ2/1bP5/4PN2/PP1P1PPP/R1B1KB1R b KQ -
+English: four knights, Stean variation
+r1bqrbk1/pp3ppp/2n2n2/2ppp3/P3P3/2PP1NP1/1P1N1PBP/R1BQ1RK1 b - -
+King's Indian: orthodox, 7...Nbd7, main line *
+r1bqrnk1/ppp1bppp/5n2/3p2B1/3P4/2NBP3/PPQ1NPPP/2KR3R b - -
+QGD: exchange, chameleon variation
+r1br2k1/p1q1ppbp/1pn2np1/2pp4/1P1P4/2P1PN2/PB1NBPPP/R2Q1RK1 b - -
+Catalan: closed, Spassky gambit *
+r1br2k1/p3ppbp/1pn2np1/2pq4/8/PP1PPN2/1B1NBPPP/R2QK2R b KQ -
+English: symmetrical, hedgehog, flexible formation *
+r1br2k1/p4ppp/1qn2n2/2b5/B3p3/2N3Q1/PPPPNPPP/R1B1K2R w KQ -
+Evans gambit: compromised defense, Potter variation *
+r1br2k1/pp2qppp/1bn1pn2/3p4/1PP5/P2BPN2/1B1N1PPP/R2QK2R b KQ -
+QGA: classical, Smyslov variation *
+r1br2k1/ppq2ppp/2n1pn2/2P5/1P1p4/P3PN2/1BQ2PPP/R3KB1R b KQ -
+QGA: classical, Flohr variation *
+r1q2rk1/pp2ppbp/2npbnp1/8/4PP2/1NN1B3/PPP1B1PP/R2Q1RK1 w - -
+Sicilian: dragon, classical, R\'eti-Tartakower variation
+r1r3k1/pp1bppbp/2np1np1/q7/3NP2P/1BN1BP2/PPPQ2P1/2KR3R b - -
+Sicilian: dragon, Yugoslav attack, 12.h4
+r2n1rk1/ppp1qppp/3p1n2/1B2p1B1/3PP1b1/2P2N2/P1P2PPP/R2QR1K1 w - -
+Four knights: symmetrical, Capablanca variation
+r2q1bnr/ppp1kBpp/3p4/3NN3/4P3/8/PP3PPP/R1Bb1RK1 b - -
+Scotch: Sea-cadet mate
+r2q1knr/pppb1Bpp/1b1p4/n7/3PP3/2N2N2/P1Q2PPP/R1B2RK1 b - -
+Evans gambit: Fraser-Mortimer attack
+r2q1rk1/1b1nbppp/p2p1n2/1pp1p3/3PP3/2P2N1P/PPBN1PP1/R1BQR1K1 w - -
+Ruy Lopez: closed, Breyer, Gligori\'c variation
+r2q1rk1/1bp1bppp/p1np1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Flohr-Zaitsev system (Lenzerheide variation)
+r2q1rk1/2p1bppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP1NQPPP/R1B2RK1 b - -
+Ruy Lopez: open, Malkin variation
+r2q1rk1/2p1bppp/p1np1n2/1p2p3/3PP1b1/1BP2N2/PP3PPP/RNBQR1K1 w - -
+Ruy Lopez: closed, Bogolyubov variation
+r2q1rk1/2p1bppp/p1npbn2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Kholmov variation
+r2q1rk1/2p1bppp/p3b3/1p1pn3/3Nn3/1BP5/PP3PPP/RNBQR1K1 w - -
+Ruy Lopez: open, Breslau variation
+r2q1rk1/2p2ppp/p1n1b3/1pbpP3/8/2P2N2/PPBN1nPP/R1BQ1RK1 w - -
+Ruy Lopez: open, Dilworth variation
+r2q1rk1/3nbppp/bpp1pn2/p2p4/2PP4/1P3NP1/PBQNPPBP/R4RK1 w - -
+Catalan: closed, Sokolsky variation
+r2q1rk1/p1p2ppp/2pp1n2/4p3/1b2P1b1/2NP1N2/PPP1QPPP/R1B2RK1 b - -
+Four knights: symmetrical, Metger unpin *
+r2q1rk1/p3bppp/1pn1bn2/2pp2B1/3P4/2N2NP1/PP2PPBP/2RQ1RK1 w - -
+QGD: Tarrasch, Stoltz variation
+r2q1rk1/p3n1pp/2p1bp2/3pp1B1/N1P5/6P1/PP2PbBP/R2Q1RK1 w - -
+Gr\"unfeld: exchange, Seville variation *
+r2q1rk1/p3n1pp/3bbp2/3pp3/N7/4B1P1/PP2PPBP/R2Q1RK1 b - -
+Gr\"unfeld: Spassky variation, main line, 13.Bd3 *
+r2q1rk1/p3n1pp/3bbp2/4p3/N2p4/4B1P1/PP2PPBP/R2Q1RK1 w - -
+Gr\"unfeld: exchange, Sokolsky variation *
+r2q1rk1/p3nppp/4b3/2bpp3/8/2N3P1/PP2PPBP/R1BQ1RK1 w - -
+Gr\"unfeld: Spassky variation, main line, 10...cd, 11.cd *
+r2q1rk1/p4ppp/2n1bn2/2bpp3/N7/1B1P1P2/PPP3PP/R1BQK1NR w KQ -
+Evans gambit: Steinitz variation *
+r2q1rk1/p4ppp/2n2n2/2bpp3/N5b1/1B1P4/PPP2PPP/R1BQK1NR w KQ -
+Evans gambit: G\"oring attack *
+r2q1rk1/p4ppp/b1B2n2/2bp4/8/2N5/PPPP1PPP/R1BQK2R w KQ -
+Giuoco Piano: Aitken variation *
+r2q1rk1/p4ppp/b1p2n2/2bpN3/3P4/2N5/PPP2PPP/R1BQK2R w KQ -
+Giuoco Piano: Steinitz variation *
+r2q1rk1/pb1nbppp/2p1pn2/1p1p4/2PP4/1PN2NP1/P1Q1PPBP/R1BR2K1 w - -
+Catalan: closed, Spassky gambit
+r2q1rk1/pp1bbppp/2nppn2/8/4PP2/1NN1B3/PPP1B1PP/R2Q1RK1 b - -
+Sicilian: modern Scheveningen, main line with Nb3
+r2q1rk1/pp1bppbp/2np1np1/8/2BNP3/2N1BP2/PPPQ2PP/2KR3R b - -
+Sicilian: dragon, Yugoslav attack, 10.O-O-O
+r2q1rk1/pp1bppbp/2np1np1/8/2BNP3/2N1BP2/PPPQ2PP/R3K2R w KQ -
+Sicilian: dragon, Yugoslav attack, 9...Bd7
+r2q1rk1/pp2b1pp/2n1bn2/2pp4/4pB2/1NN1P3/PPPQBPPP/2KR3R b - -
+Alekhine's defense: four pawns attack, Tartakower variation *
+r2q1rk1/pp2bpp1/2n2n1p/2pp1b2/5B2/1NNP2P1/PP2PPBP/R2Q1RK1 w - -
+Alekhine's defense: exchange, Karpov variation *
+r2q1rk1/pp2bppp/2n1bn2/3p2B1/2pP4/2N2NP1/PP2PPBP/2RQ1RK1 w - -
+QGD: Tarrasch, Bogolyubov variation
+r2q1rk1/pp2bppp/2npbn2/2p3B1/4P3/2N2N2/PPP1BPPP/R2QR1K1 b - -
+Philidor: Berger variation
+r2q1rk1/pp2pBbp/6p1/n1p5/3PP1b1/2P1BP2/P3N1PP/R2Q1RK1 b - -
+Gr\"unfeld: exchange, Seville variation
+r2q1rk1/pp2ppbp/1nnp2p1/5b2/2PP1B2/2N2N1P/PP2BPP1/R2Q1RK1 b - -
+Alekhine's defense: exchange, Karpov variation
+r2q1rk1/pp2ppbp/2n2np1/3p4/2PP2b1/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+QGD: Tarrasch, Prague variation, 9.Bg5 *
+r2q1rk1/pp2ppbp/3p1np1/n4P2/2b1P3/1NNBB3/PPP3PP/R2Q1RK1 b - -
+Sicilian: dragon, classical, Spielmann variation
+r2q1rk1/pp2ppbp/4b1p1/n2P4/4P3/3BBP2/P3N1PP/R2Q1RK1 b - -
+Gr\"unfeld: exchange, Sokolsky variation
+r2q1rk1/pp2ppbp/4b1p1/n7/3PP3/3BBP2/P3N1PP/R2Q1RK1 w - -
+Gr\"unfeld: Spassky variation, main line, 13.Bd3
+r2q1rk1/pp2ppbp/5np1/n2p1P2/4P3/1NNPB3/PP4PP/R2Q1RK1 w - -
+Sicilian: dragon, classical, Bernard defense
+r2q1rk1/pp4pp/1nnpb3/4p3/N2P1p2/5NP1/PP2PPBP/R2Q1RK1 b - -
+Sicilian: dragon, classical, Bernard defense *
+r2q1rk1/ppp1b1pp/1nn1b3/4pp2/8/2NPBNP1/PP2PPBP/R1Q2RK1 b - -
+Sicilian: dragon, classical, R\'eti-Tartakower variation *
+r2q1rk1/ppp1b1pp/1nn1b3/4pp2/8/2NPPN2/PP1BBPPP/R2Q1RK1 w - -
+Sicilian: modern Scheveningen, main line with Nb3 *
+r2q1rk1/ppp1b1pp/2n1b3/3n1p2/4p3/1QNP1NP1/PP2PPBP/R1B2RK1 w - -
+Sicilian: dragon, classical, Zollner gambit *
+r2q1rk1/ppp1b1pp/2n1b3/3npp2/8/2NPPN2/PP2BPPP/R1BQ1RK1 w - -
+Sicilian: modern Scheveningen, main line *
+r2q1rk1/ppp1b1pp/2n1b3/3npp2/8/P1NPPN2/1PQ2PPP/R1B1KB1R w KQ -
+Sicilian: Scheveningen, classical *
+r2q1rk1/ppp1bppp/1nn1b3/4p3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+Sicilian: dragon, classical, 9.Nb3 *
+r2q1rk1/ppp1bppp/1nn1b3/4p3/P7/2NP1NP1/1P2PPBP/R1BQ1RK1 b - -
+Sicilian: dragon, classical, Alekhine variation *
+r2q1rk1/ppp1bppp/2n1b3/3np3/8/2NP1NP1/PP2PPBP/R1BQK2R w KQ -
+Sicilian: dragon, classical, 8.O-O *
+r2q1rk1/ppp1ppbp/1nn3p1/8/3PP1b1/2NQBN2/PP2BPPP/2KR3R b - -
+Gr\"unfeld: Russian, Keres variation
+r2q1rk1/ppp1ppbp/2np1np1/5b2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, lesser Simagin (Spassky) variation
+r2q1rk1/ppp1ppbp/2np1np1/8/2PP2b1/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, Simagin variation
+r2q1rk1/ppp2ppp/1bnp4/1B2p2n/3PP1b1/2PQ1N2/PP2NPPP/R1B2RK1 b - -
+Four knights: symmetrical, Blake variation *
+r2q1rk1/ppp2ppp/2n2n2/3pp3/1b2P1b1/2NP1N2/PPPBBPPP/R2QK2R w KQ -
+Ruy Lopez: closed Berlin defense, Bernstein variation *
+r2q1rk1/ppp2ppp/2np1n2/1B2p3/1b2P1b1/2NPBN2/PPP2PPP/R2Q1RK1 b - -
+Four knights: symmetrical, Tarrasch variation *
+r2q1rk1/ppp2ppp/2np1n2/1B2p3/1b2P1b1/3P1N2/PPP1NPPP/R1BQ1RK1 b - -
+Four knights: symmetrical, Pillsbury variation *
+r2q1rk1/ppp2ppp/2npbn2/1B2p1B1/1b2P3/2NP1N2/PPP2PPP/R2Q1RK1 w - -
+Four knights: symmetrical, Tarrasch variation
+r2q1rk1/ppp3pp/1nnbb3/2B1p3/N4p2/3P1NP1/PP2PPBP/R2Q1RK1 w - -
+Sicilian: dragon, classical, Spielmann variation *
+r2q1rk1/ppp3pp/2n5/2bNp3/4P1b1/5N2/PPP1QPPP/R1B1K2R w KQ -
+Giuoco piano: Holzhausen attack *
+r2q1rk1/pppbbppp/2np1n2/1B2p3/3PP3/2N2N2/PPP2PPP/R1BQR1K1 w - -
+Ruy Lopez: Berlin defense, Tarrasch trap
+r2q1rk1/pppnbppp/8/8/1n6/2N3Q1/PPPP1PPP/R1BK2NR b - -
+Scotch: Rosenthal variation *
+r2q2k1/pp3ppp/8/2b1r3/3p4/3P4/PPP1NPPn/R1BQ1RK1 w - -
+Giuoco Piano: Therkatz-Herzog variation *
+r2qbrk1/1pp1bppp/p1np1n2/4p3/B2PP3/2P2N2/PP1N1PPP/R1BQR1K1 w - -
+Ruy Lopez: Kecskem\'et variation
+r2qk1nr/pp2bppp/2n1b3/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+King's Indian: Semi-Averbakh system *
+r2qk1nr/pp2bppp/2n5/2p1p3/2Pp2b1/3PPNP1/PP3PBP/RNBQ1RK1 b kq -
+King's Indian: Averbakh, main line *
+r2qk1nr/pp2bppp/2n5/2ppp3/2P3b1/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+King's Indian: Averbakh, 6...c5 *
+r2qk1nr/pp2bppp/2n5/2ppp3/6b1/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+King's Indian: Averbakh system *
+r2qk1nr/pp4pp/2nbbp2/2ppp3/8/P1PP1NP1/1P2PPBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, Byrne variation *
+r2qk1nr/ppp1npbp/3pb1p1/3Np3/2P5/4P1P1/PP1P1PBP/R1BQK1NR w KQkq -
+Sicilian: closed, Smyslov variation *
+r2qk1nr/ppp2pbp/2npb1p1/4p3/2P5/2N1P1P1/PP1PNPBP/R1BQK2R w KQkq -
+English: closed, Hort variation
+r2qk1nr/ppp2pbp/2npb1p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR w KQkq -
+Sicilian: closed, 6.Be3 *
+r2qk1nr/ppp2ppp/1bnp4/8/2BPP1b1/2N2N2/P4PPP/R1BQ1RK1 w kq -
+Evans gambit
+r2qk1nr/ppp2ppp/1bnp4/8/Q1BPP1b1/2N2N2/P4PPP/R1B2RK1 b kq -
+Evans gambit: Fraser attack
+r2qk1nr/ppp2ppp/2nb4/3p4/3Pp3/4P3/PPPNQPPP/RNB1K2R w KQkq -
+French: classical, Tarrasch variation *
+r2qk1nr/ppp2ppp/2np4/2b5/2BpP1b1/2P2N2/PP3PPP/RNBQ1RK1 w kq -
+Scotch gambit: Anderssen (Paulsen, Suhle) counter-attack
+r2qk1nr/ppp2ppp/2np4/b3p3/2BPP1b1/2P2N2/P4PPP/RNBQ1RK1 w kq -
+Evans gambit: Alapin-Steinitz variation
+r2qk1nr/pppb1ppp/2nb4/1B1p4/2PQ4/4P3/PP3PPP/RNB1K1NR w KQkq -
+French: Winawer, Kondratiyev variation *
+r2qk1nr/pppb1ppp/2np4/b3p3/2BPP3/2P2N2/P4PPP/RNBQ1RK1 w kq -
+Evans gambit: Sanders-Alapin variation
+r2qk2r/1b1n1ppp/p2bpn2/1pp5/3P4/1BN1PN2/PP2QPPP/R1BR2K1 w kq -
+QGA: classical, Smyslov variation
+r2qk2r/1b1nbppp/pp1ppn2/8/2PQ4/1PN2NP1/P3PPBP/R1BR2K1 w kq -
+English: symmetrical, hedgehog, flexible formation
+r2qk2r/1bppbppp/p1n2n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQR1K1 w kq -
+Ruy Lopez: Trajkovi\'c counter-attack
+r2qk2r/1p1bbppp/p1nppn2/6B1/3NPP2/2N5/PPPQ2PP/2KR1B1R w kq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 defense, 9...Be7
+r2qk2r/2p1bppp/p1n1b3/1p1pP3/2P1n3/1B3N2/PP2QPPP/RNB2RK1 b kq -
+Ruy Lopez: open, Howell attack, Adam variation
+r2qk2r/2p1bppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP3PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, classical defense
+r2qk2r/2p1bppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP3PPP/RNBQR1K1 b kq -
+Ruy Lopez: open, 9...Be7, 10.Re1
+r2qk2r/2p1bppp/p1np1n2/1p2p3/3PP1b1/1BP2N2/PP2QPPP/RNB1K2R w KQkq -
+Ruy Lopez: Wormald attack, Gr\"unfeld variation
+r2qk2r/2p1nppp/p3b3/1pbpP3/4n3/1BPQ1N2/PP3PPP/RNB2RK1 w kq -
+Ruy Lopez: open, Motzko attack, Nenarokov variation
+r2qk2r/2p2ppp/p1n1b3/1pbpP3/4n3/1BP2N2/PP1N1PPP/R1BQ1RK1 b kq -
+Ruy Lopez: open, St. Petersburg variation
+r2qk2r/2p2ppp/p1n1b3/1pbpP3/4n3/1BP2N2/PP3PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, Italian variation
+r2qk2r/2p2ppp/p1n1b3/1pbpP3/4n3/1BPQ1N2/PP3PPP/RNB2RK1 b kq -
+Ruy Lopez: open, Motzko attack
+r2qk2r/3bbppp/p1nppB2/1p6/4PP2/2N2N2/PPPQ2PP/2KR1B1R b kq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 defense, 11.Bxf6
+r2qk2r/p1pn1ppp/8/3pp3/Np2b1Q1/1B6/PPP2K1P/R1B3R1 w kq -
+Evans gambit declined, Pavlov variation *
+r2qk2r/pp1bppbp/2n2np1/2ppN3/8/1P2P3/PBPPBPPP/RN1QK2R w KQkq -
+Queen's Indian: Opo\v censky variation *
+r2qk2r/pp2b1pp/2n1b3/2pnpp2/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w kq -
+King's Indian: Four pawns attack, main line *
+r2qk2r/pp2bpp1/2n2nb1/2p1p2p/3pP1PN/3P3P/PPPN1PB1/R1BQ1RK1 w kq -
+King's Indian: Petrosian system, Keres variation *
+r2qk2r/pp2bppp/2n1bn2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+King's Indian: Gligori\'c-Taimanov system *
+r2qk2r/pp3ppp/2n1pn2/3p1b2/1b1P1B2/1QN1PN2/PP3PPP/R3KB1R w KQkq -
+QGD Slav: exchange, Trifunovi\'c variation
+r2qk2r/pp3ppp/2nbp3/3p4/3Pn1b1/1P3N2/PBP1BPPP/RN1Q1RK1 w kq -
+QGD: Pillsbury attack *
+r2qk2r/pp3ppp/2nbpn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w kq -
+QGD: Orthodox defense, Botvinnik variation *
+r2qk2r/ppp1b1pp/2n5/3p1p2/2PPn1b1/3B1N2/PP3PPP/RNBQR1K1 b kq -
+Petrov: classical attack, Krause variation
+r2qk2r/ppp1b1pp/2n5/3p1p2/3Pn1b1/2PB1N2/PP1N1PPP/R1BQR1K1 b kq -
+Petrov: classical attack, Berger variation
+r2qk2r/ppp1bppp/1nn1b3/4p3/8/2NP1NP1/PP2PPBP/R1BQK2R w KQkq -
+Sicilian: dragon, classical, Nottingham variation *
+r2qk2r/ppp1bppp/2n1b3/3np3/8/3P1NP1/PP2PPBP/RNBQK2R w KQkq -
+Sicilian: dragon, classical attack *
+r2qk2r/ppp1bppp/2n1b3/3np3/8/P1N1P3/1PQP1PPP/R1B1KBNR w KQkq -
+Sicilian: Taimanov variation *
+r2qk2r/ppp2p1p/2n1bPp1/2b3N1/2pp4/8/PPP2PPP/RNBQR1K1 w kq -
+two knights: Max Lange attack, Loman defense
+r2qk2r/ppp2pPp/2n1b3/2b5/2pp4/5N2/PPP2PPP/RNBQR1K1 b kq -
+two knights: Max Lange attack, Schlechter variation
+r2qk2r/ppp2ppp/2n1b3/2bnp3/8/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+Sicilian: accelerated fianchetto, modern variation with Bc4 *
+r2qk2r/ppp2ppp/2n1b3/2bnp3/8/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Sozin, 7.Be3 *
+r2qk2r/ppp2ppp/2n5/3np3/1b4b1/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Richter-Rauzer, Margate (Alekhine) variation *
+r2qk2r/ppp2ppp/2np1n2/2b1p3/2B1P1b1/2NP1N2/PPP2PPP/R1BQK2R w KQkq -
+Giuoco Pianissimo: Canal variation *
+r2qk2r/ppp2ppp/2np1n2/2b5/2B1Pp2/2NP1Q1P/PPP3P1/R1B1K2R w KQkq -
+KGD: classical, Svenonius variation
+r2qk2r/ppp3pp/1bn1b3/3npp2/8/2NPPN2/PP2BPPP/R1BQ1RK1 w kq -
+Sicilian: Sozin, Fischer variation *
+r2qk2r/ppp3pp/2n5/3p1p2/2PPn1bb/3B1N2/PP3PPP/RNBQR1K1 w kq -
+Petrov: classical attack, Mar\'oczy variation
+r2qk2r/pppbbppp/2Bp1n2/4p3/3PP3/2N2N2/PPP2PPP/R1BQ1RK1 b kq -
+Ruy Lopez: closed Berlin defense, Showalter variation
+r2qk2r/pppbbppp/2np1n2/1B2p1B1/3PP3/2N2N2/PPP2PPP/R2Q1RK1 b kq -
+Ruy Lopez: closed Berlin defense, Bernstein variation
+r2qk2r/pppbbppp/2np1n2/1B2p3/3PP3/2N2N2/PPP2PPP/R1BQ1RK1 w kq -
+Ruy Lopez: Berlin defense, hedgehog variation
+r2qkb1r/1bpp1ppp/p1n2n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Archangelsk (counterthrust) variation
+r2qkb1r/1p1b1ppp/2n1pn2/pBPp4/1P6/1QP1P3/P4PPP/RNB1K1NR b KQkq -
+QGD: semi-Slav, Junge variation *
+r2qkb1r/1p1b1ppp/2n1pn2/pBPp4/1P6/2P1P3/P3QPPP/RNB1K1NR b KQkq -
+QGD: semi-Slav, Koomen variation *
+r2qkb1r/1p1b1ppp/2n1pn2/pBPp4/PP6/2P1P3/5PPP/RNBQK1NR b KQkq -
+QGD: semi-Slav, Abrahams variation *
+r2qkb1r/1p1b1ppp/p1nppn2/6B1/3NP3/2N5/PPPQ1PPP/2KR1B1R w kq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 defense, 8...Bd7
+r2qkb1r/1p3ppp/p1npbn2/4p1B1/4P3/N1N5/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Pelikan, Bird variation
+r2qkb1r/1ppbnppp/p1np4/4p3/B2PP3/2P2N2/PP3PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense, Rubinstein variation
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1B3N2/PPP1QPPP/RNB2RK1 b kq -
+Ruy Lopez: open, Howell attack
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1B3N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, 8...Be6
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1B3N2/PPPN1PPP/R1BQ1RK1 b kq -
+Ruy Lopez: open, Bernstein variation
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP3PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, 9.c3
+r2qkb1r/2p2ppp/p1n1b3/1pn1P1N1/3p4/1BP5/PP1N1PPP/R1BQ1RK1 b kq -
+Ruy Lopez: open, Bernstein variation, Karpov gambit
+r2qkb1r/2p2ppp/p1n1b3/1pnpP3/8/1BP2N2/PP3PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, Berlin variation
+r2qkb1r/2p2ppp/p1pp1n2/4p3/3PP1b1/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Steinitz defense deferred, Lipnitsky variation
+r2qkb1r/p2b1ppp/5n2/1B1pp3/Q7/4P3/PP3PPP/RNB1K2R b KQkq -
+QGD: Semi-Tarrasch, San Sebastian variation *
+r2qkb1r/p3pppp/2p5/2pn3b/4N3/5N1P/PPPP1PP1/R1BQK2R b KQkq -
+English: Nenarokov variation *
+r2qkb1r/p4ppp/2p1pn2/3p4/3p4/4P2P/PPP1QPP1/RNB2RK1 w kq -
+QGD: Lasker defense, main line *
+r2qkb1r/pb1n1ppp/2p1pn2/1p6/3P4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran, Wade variation
+r2qkb1r/pp1b1ppp/2n1pn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Gr\"unfeld: Opo\v censky variation *
+r2qkb1r/pp1bppp1/5n1p/1BpP4/4p3/2N5/PPP1QPPP/R3K1NR b KQkq -
+QGD: Albin counter-gambit, Kr\'enosz variation *
+r2qkb1r/pp1bpppp/2np1n2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Richter-Rauzer, Larsen variation
+r2qkb1r/pp1bpppp/2np1n2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R b KQkq -
+Sicilian: Richter-Rauzer, Larsen variation, 7.Qd2
+r2qkb1r/pp1n1ppp/2n1p3/2Pp4/Q5b1/2P1PN2/PP1N1PPP/R1B1KB1R b KQkq -
+QGD: Cambridge Springs defense, Rubinstein variation *
+r2qkb1r/pp1n1ppp/4pn2/2pp4/3P2b1/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD: Capablanca variation *
+r2qkb1r/pp2n1pp/2n1bp2/2p1p3/3PP3/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, orthodox main line *
+r2qkb1r/pp2n1pp/2n1bp2/2ppp3/4P3/2PP1NP1/PP3PBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, orthodox, 7.Nge2 c6 *
+r2qkb1r/pp2n1pp/2n1bp2/2ppp3/8/2NP1NP1/PPP1PPBP/1RBQ1RK1 b kq -
+King's Indian: S\"amisch, Ruban variation *
+r2qkb1r/pp2n1pp/2n1bp2/2ppp3/8/P1NP1NP1/1PP1PPBP/R1BQ1RK1 b kq -
+King's Indian: S\"amisch, Panno formation *
+r2qkb1r/pp2pppp/2n2n2/1BPp4/6b1/4PN2/PPP2PPP/RNBQK2R b KQkq -
+QGD: Ragozin, Vienna variation *
+r2qkb1r/pp2pppp/2n2n2/1Bpp3b/8/1P2PN1P/PBPP1PP1/RN1QK2R b KQkq -
+Queen's Indian: 4.Nc3, main line *
+r2qkb1r/pp2pppp/2n2n2/2Pp4/6b1/2P1PN2/PP3PPP/RNBQKB1R b KQkq -
+QGD semi-Slav: 5.Bg5 dc *
+r2qkb1r/pp2pppp/2n2n2/2pp1b2/3P4/4PN2/PPP1BPPP/RNBQK2R w KQkq -
+QGD: classical variation (5.Bf4) *
+r2qkb1r/pp2pppp/2n2n2/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: 5.Bf4 *
+r2qkb1r/pp2pppp/2n2n2/2pp4/2PP2b1/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD: Semi-Tarrasch defense, Pillsbury variation *
+r2qkb1r/pp2pppp/2n2n2/2pp4/3P2b1/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: 5.Bg5 *
+r2qkb1r/pp2pppp/2n2n2/2pp4/6b1/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: Smyslov system *
+r2qkb1r/pp2pppp/2n2n2/3p1b2/3P1B2/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+QGD Slav: exchange variation, 6.Bf4 Bf5 *
+r2qkb1r/pp2pppp/2n2n2/3p1b2/3P1B2/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+QGD Slav: exchange variation, 6.Bf4 Bf5
+r2qkb1r/pp2pppp/2n2n2/3p1b2/3P4/5N2/PPPN1PPP/R1BQKB1R w KQkq -
+QGD: exchange, S\"amisch variation *
+r2qkb1r/pp2pppp/2n2n2/8/2Pp2b1/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+Benoni: Uhlmann variation *
+r2qkb1r/pp2pppp/2n2nb1/2pp4/6PN/1P2P2P/PBPP1P2/RN1QKB1R b KQkq -
+Queen's Indian: 4.Nc3, Botvinnik variation *
+r2qkb1r/pp2pppp/n1p2n2/5b2/P1pP4/2N1PN2/1P3PPP/R1BQKB1R w KQkq -
+QGD Slav: Dutch, Lasker variation
+r2qkb1r/pp2pppp/n1p2n2/8/P1pPP1b1/2N2N2/1P3PPP/R1BQKB1R w KQkq -
+QGD Slav: Smyslov variation
+r2qkb1r/pp3p1p/2n3p1/2Pp4/1P2p1b1/2P1PN2/P2N1P2/R1BQKB1R w KQkq -
+QGD semi-Slav: anti-Meran, Lilienthal variation *
+r2qkb1r/pp3ppp/2n1b3/2pnp1N1/8/2N3P1/PP1PPPBP/R1BQK2R b KQkq -
+Sicilian: accelerated fianchetto, Breyer variation *
+r2qkb1r/pp3ppp/2n1bn2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+King's Indian: Larsen variation *
+r2qkb1r/pp3ppp/2n1pn2/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Gr\"unfeld with Bf4 & e3 *
+r2qkb1r/pp3ppp/2n1pn2/2pp3b/3P4/1P2PN1P/P1P1BPP1/RNBQ1RK1 b kq -
+QGD: Tartakower (Makagonov-Bondarevsky) system *
+r2qkb1r/pp3ppp/2n1pn2/2pp3b/3P4/4PN1P/PPP1BPP1/RNBQ1RK1 w kq -
+QGD: Neo-orthodox variation, 7.Bh4 *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN1P/PPP1BPP1/RNBQ1RK1 b kq -
+QGD: Neo-orthodox variation *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQ1RK1 w kq -
+QGD: 6.Nf3 *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 b kq -
+QGD: Orthodox defense *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P4/4Pb1P/PPP1BPP1/RNBQ1RK1 w kq -
+QGD: Neo-orthodox variation, 7.Bxf6 *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/Q2P2b1/2P1PN2/PP1N1PPP/R1B1KB1R b KQkq -
+QGD: Cambridge Springs defense *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/Q2P4/2P1Pb2/PP1N1PPP/R1B1KB1R w KQkq -
+QGD: Cambridge Springs defense, Capablanca variation *
+r2qkb1r/pp3ppp/2n1pn2/2ppN2b/3P4/4P2P/PPP1BPP1/RNBQ1RK1 b kq -
+QGD: Lasker defense *
+r2qkb1r/pp3ppp/2n1pn2/3p3b/3N4/1P2P2P/P1P1BPP1/RNBQ1RK1 b kq -
+QGD: Tartakower (Makagonov-Bondarevsky) system, 8.cd Nxd5 *
+r2qkb1r/pp3ppp/2n1pn2/3p4/Q2N2b1/2P1P3/PP1N1PPP/R1B1KB1R b KQkq -
+QGD: Cambridge Springs defense, Yugoslav variation *
+r2qkb1r/pp3ppp/2n1pn2/3p4/Q2p2b1/2P1PN2/PP1N1PPP/R1B1KB1R w KQkq -
+QGD: Cambridge Springs defense, 7.cd *
+r2qkb1r/pp3ppp/2n2n2/2Ppp3/6b1/2P1PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD semi-Slav: Botvinnik system (anti-Meran) *
+r2qkb1r/pp3ppp/2n2n2/2pp4/3P2b1/2N2NP1/PP2PPBP/R1BQK2R w KQkq -
+QGD: Tarrasch, Wagner variation
+r2qkb1r/pp3ppp/2n2n2/2ppp3/3P2b1/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD: Alekhine variation *
+r2qkb1r/pp3ppp/2n2n2/2ppp3/6b1/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+King's Indian: Zinnowitz variation *
+r2qkb1r/pp3ppp/2n2n2/4p3/2Pp2b1/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+Benoni: classical, 8.Bg5 *
+r2qkb1r/pp3ppp/2n5/2Pp3P/1P2n3/2P1Pp1P/P4P2/RNBQKB1R w KQkq -
+QGD semi-Slav: Ekstrom variation *
+r2qkb1r/pp3ppp/2n5/2Pp3b/1P1Np1n1/2P1P2P/P4P2/RNBQKB1R b KQkq -
+QGD semi-Slav: anti-Meran, Alatortsev system *
+r2qkb1r/pp3ppp/2n5/2Pp3b/1P2p1n1/2P1PN1P/P4P2/RNBQKB1R w KQkq -
+QGD semi-Slav: anti-Meran gambit *
+r2qkb1r/ppp1p1pp/1nn1p3/2P5/3P2b1/5N2/PP4PP/RNBQKB1R b KQkq -
+Alekhine's defense: four pawns attack, Ilyin-Genevsky variation
+r2qkb1r/ppp2ppp/1nn5/4p3/6b1/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Richter-Rauzer, Pod\v ebrady variation *
+r2qkb1r/ppp2ppp/2n1b3/3np3/8/2N1P3/PPQP1PPP/R1B1KBNR w KQkq -
+Sicilian: Taimanov variation *
+r2qkb1r/ppp2ppp/2n1b3/3np3/8/3P1NP1/PP2PP1P/RNBQKB1R w KQkq -
+Sicilian: dragon, 6.Be3 *
+r2qkb1r/ppp2ppp/2n1b3/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, Byrne (English) attack *
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NP1N2/PP1BPPPP/R2QKB1R b KQkq -
+Sicilian: Richter-Rauzer, Larsen variation *
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+Sicilian: Richter-Rauzer *
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NP1NP1/PP2PP1P/R1BQKB1R b KQkq -
+Sicilian: Richter-Rauzer, Bondarevsky variation *
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NPPN2/PP3PPP/R1BQKB1R b KQkq -
+Sicilian: Richter-Rauzer, 6...e6 *
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, 6.Bg5 *
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/P2PPN2/1P3PPP/RNBQKB1R b KQkq -
+Sicilian: Najdorf, 6...e6 *
+r2qkb1r/ppp2ppp/2n5/4p3/6b1/2nPPN2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Richter-Rauzer, Richter attack *
+r2qkb1r/ppp2ppp/n1n5/4p3/1P2P1b1/P1NP1N2/5PPP/R1BQKB1R b KQkq -
+Sicilian: Pelikan, Chelyabinsk variation *
+r2qkb1r/ppp2ppp/n1n5/4p3/4P1b1/P1NPBN2/1P3PPP/R2QKB1R b KQkq -
+Sicilian: Pelikan, Bird variation *
+r2qkb1r/ppp2ppp/n7/4p3/1P1nPP2/P1NP4/5P1P/R1BQKB1R b KQkq -
+Sicilian: Sveshnikov variation *
+r2qkb1r/ppp3pp/2n1bn2/3p1p2/2PPp3/2N1P3/PP1N1PPP/R1BQKB1R w KQkq -
+French: Steinitz, Boleslavsky variation *
+r2qkb1r/ppp3pp/2n1bn2/3ppp2/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Pirc: Austrian attack, 6.Be3 *
+r2qkb1r/ppp3pp/2n1bp2/3np3/8/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+Sicilian: dragon, Yugoslav attack, 7...O-O *
+r2qkb1r/ppp3pp/2n1bp2/3np3/8/3P1NP1/PP2PPBP/RNBQK2R w KQkq -
+Sicilian: dragon, Yugoslav attack *
+r2qkb1r/ppp3pp/2n5/3npp2/1P4b1/P2PPN2/5PPP/RNBQKB1R b KQkq -
+Sicilian: Najdorf, Polugayevsky variation *
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/P2PPN2/1P2BPPP/RNBQK2R b KQkq -
+Sicilian: Najdorf, 7...Be7 *
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/P2PPN2/1P3PPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, 7.f4 *
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/PQ1PPN2/1P3PPP/RNB1KB1R b KQkq -
+Sicilian: Najdorf, 7...Qb6 *
+r2qkb1r/pppb1ppp/2Bp1n2/4p3/3PP3/2N2N2/PPP2PPP/R1BQK2R b KQkq -
+Ruy Lopez: old Steinitz defense, Nimzovich attack
+r2qkb1r/pppb1ppp/2n2n2/1B6/Q3p3/2N5/PPP2PPP/R1B1K1NR w KQkq -
+Scandinavian: Anderssen counter-attack orthodox attack *
+r2qkb1r/pppb1ppp/2np1n2/1B6/3pP3/2N2N2/PPP2PPP/R1BQ1RK1 w kq -
+Ruy Lopez: closed Berlin defense, Wolf variation
+r2qkb1r/pppn2p1/8/3pNbPp/3Pn3/8/PPP2P1P/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Brentano defense, Caro variation *
+r2qkbnr/1p3ppp/p1n1p3/2pp4/3P2b1/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD: Capablanca anti-Cambridge Springs variation *
+r2qkbnr/1pp2pp1/p1p5/4p2p/4P1b1/5N1P/PPPP1PP1/RNBQ1RK1 w kq -
+Ruy Lopez: exchange variation, Alapin gambit
+r2qkbnr/1pp3pp/p1np4/4pb2/B7/2P2N2/PP1P1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: Siesta, Kopayev variation
+r2qkbnr/1ppb1p1p/p1np2p1/4p3/B2PP3/2P2N2/PP3PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense, fianchetto (Bronstein) variation
+r2qkbnr/1ppb1ppp/p1np4/4p3/B3P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense
+r2qkbnr/pp1b1ppp/2n1p3/2ppP3/3P4/2P2N2/PP3PPP/RNBQKB1R w KQkq -
+French: advance, Euwe variation
+r2qkbnr/pp1nppp1/2p3bp/7P/3P4/5NN1/PPP2PP1/R1BQKB1R b KQkq -
+Caro-Kann: classical, Spassky variation
+r2qkbnr/pp1nppp1/2p3bp/8/3P3P/5NN1/PPP2PP1/R1BQKB1R w KQkq -
+Caro-Kann: classical, 7...Nd7
+r2qkbnr/pp2pppp/2n5/1Bp4b/1PPp4/4PN1P/P2P1PP1/RNBQK2R b KQkq -
+Nimzo-Indian: Leningrad, ...b5 gambit *
+r2qkbnr/pp2pppp/2n5/1Bp4b/2Pp4/3PPN1P/PP3PP1/RNBQK2R b KQkq -
+Nimzo-Indian: Leningrad, main line *
+r2qkbnr/pp2pppp/2n5/1Bpp4/6b1/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: Leningrad variation *
+r2qkbnr/pp2pppp/2n5/2pp1b2/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+QGD: Harrwitz attack *
+r2qkbnr/pp2pppp/2n5/2pp1b2/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Gr\"unfeld: 4.Bf4 *
+r2qkbnr/pp2pppp/2n5/2pp4/2PP2b1/4PN2/PP3PPP/RNBQKB1R b KQkq -
+QGD: Been-Koomen variation *
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+QGD: 4.Bg5 Be7 *
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+QGD: 4.Bg5 *
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPPN1PPP/R1BQKB1R b KQkq -
+QGD: 4.Bg5 Nbd7 *
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Gr\"unfeld: Stockholm variation *
+r2qkbnr/pp2pppp/2n5/3p4/2Pp2b1/1Q2PN2/PP3PPP/RNB1KB1R b KQkq -
+QGD: Canal (Venice) variation *
+r2qkbnr/pp2pppp/2n5/3p4/2Pp2b1/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD: Semi-Tarrasch *
+r2qkbnr/pp2pppp/2n5/3p4/3P2b1/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+QGD: exchange, positional line, 5...c6 *
+r2qkbnr/pp2pppp/2n5/3p4/3P2b1/5N2/PPP2PPP/RNBQKB1R w KQkq -
+QGD: exchange, positional line *
+r2qkbnr/pp3ppp/2n1p3/1Bpp4/3P2b1/4PN2/PPPN1PPP/R1BQK2R b KQkq -
+QGD: Manhattan variation *
+r2qkbnr/pp3ppp/2n1p3/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQ1RK1 b kq -
+Gr\"unfeld: Gr\"unfeld gambit *
+r2qkbnr/pp3ppp/2n1p3/2pp4/3P2b1/2P1PN2/PP1N1PPP/R1BQKB1R b KQkq -
+QGD: 5...c6 *
+r2qkbnr/pp3ppp/2n1p3/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQ1RK1 b kq -
+QGD: 4.Bg5 Be7, 5.e3 O-O *
+r2qkbnr/pp3ppp/2n1p3/2pp4/3P2b1/4PN2/PPPN1PPP/R1BQKB1R w KQkq -
+QGD *
+r2qkbnr/pp3ppp/2n1p3/2ppN3/3P2b1/4P3/PPP1BPPP/RNBQK2R b KQkq -
+QGD: Lasker variation *
+r2qkbnr/pp3ppp/2n5/2P5/N2p2b1/5N2/PP2PPPP/R1BQKB1R b KQkq -
+Caro-Kann: Panov-Botvinnik, Herzog defense *
+r2qkbnr/pp3ppp/2n5/2pp4/3P2b1/1QN2N2/PP2PPPP/R1B1KB1R b KQkq -
+Caro-Kann: Panov-Botvinnik, Reifir (Spielmann) variation *
+r2qkbnr/pp3ppp/2n5/2pp4/3P2b1/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+Caro-Kann: Panov-Botvinnik, normal variation *
+r2qkbnr/pp3ppp/2n5/2pp4/Q2P2b1/2N2N2/PP2PPPP/R1B1KB1R b KQkq -
+Caro-Kann: Panov-Botvinnik, Czerniak variation *
+r2qkbnr/pp3ppp/2n5/2ppp3/6b1/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: accelerated Averbakh system *
+r2qkbnr/pp3ppp/4p3/3p4/3Q4/6P1/PPb1PPBP/RNB2RK1 w kq -
+Gr\"unfeld: Gr\"unfeld gambit accepted *
+r2qkbnr/pp3ppp/8/3pn3/8/8/PPP1NPPP/RNBQK2R b KQkq -
+Bishop's opening: Lisitsyn variation
+r2qkbnr/pp4pp/2n1bp2/2p1p3/3pP3/2PP1NP1/PP3PBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, orthodox, 7.d5 c6 *
+r2qkbnr/pp4pp/2n1bp2/2p1p3/3pP3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+King's Indian: S\"amisch, orthodox, 7.d5 *
+r2qkbnr/pp4pp/2n1bp2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, orthodox variation *
+r2qkbnr/pp4pp/2n1bp2/2ppp3/8/1P1P1NP1/P1P1PPBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, double fianchetto variation *
+r2qkbnr/pp4pp/2n1bp2/2ppp3/8/2NP1NP1/PPP1PPBP/R1BQ1RK1 b kq -
+King's Indian: S\"amisch, 6...Nc6 *
+r2qkbnr/ppp1p1pp/2n2p2/3p4/3P1Bb1/5N2/PPP1PPPP/RN1QKB1R w KQkq -
+Richter-Veresov attack, Richter variation *
+r2qkbnr/ppp1pppp/2n5/3p4/3P1B2/5b2/PPP1PPPP/RN1QKB1R w KQkq -
+Richter-Veresov attack, Veresov variation *
+r2qkbnr/ppp1pppp/2n5/3p4/3P2b1/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Richter-Veresov attack *
+r2qkbnr/ppp2p1p/2P5/8/2BP1pb1/2N2p2/PPP3PP/R1BQ1RK1 b kq -
+Vienna: Pierce gambit, Rushmere attack
+r2qkbnr/ppp2pp1/2n5/3p3p/2PPp1b1/4P3/PP1NBPPP/RNBQK2R b KQkq -
+French: Albin-Alekhine-Ch\^atard attack, Breyer variation *
+r2qkbnr/ppp2pp1/2n5/3p3p/3Pp1b1/4P3/PPPNBPPP/RNBQ1RK1 b kq -
+French: Albin-Alekhine-Ch\^atard attack, Spielmann variation *
+r2qkbnr/ppp2pp1/2n5/3p3p/3Pp1b1/4P3/PPPNBPPP/RNBQK2R w KQkq -
+French: Albin-Alekhine-Ch\^atard attack *
+r2qkbnr/ppp2pp1/2n5/3p3p/3Pp1b1/4PP2/PPPNB1PP/RNBQK2R b KQkq -
+French: Albin-Alekhine-Ch\^atard attack, Teichmann variation *
+r2qkbnr/ppp2pp1/2n5/3p3p/3Pp1b1/P3P3/1PPNBPPP/RNBQK2R b KQkq -
+French: Albin-Alekhine-Ch\^atard attack, Mar\'oczy variation *
+r2qkbnr/ppp2pp1/2n5/3pP2p/6b1/5NP1/PPPPP2P/RNBQKB1R w KQkq -
+Dutch: Staunton gambit, Alekhine variation *
+r2qkbnr/ppp2ppp/2n1b3/1B1p4/3Pp3/4PN1P/PPP2PP1/RNBQK2R w KQkq -
+French: MacCutcheon, Janowski variation *
+r2qkbnr/ppp2ppp/2n1b3/3p4/3Pp3/1P2P3/P1P1BPPP/RNBQK1NR b KQkq -
+French: classical, Frankfurt variation *
+r2qkbnr/ppp2ppp/2n1b3/3pp3/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+French: Henneberger variation *
+r2qkbnr/ppp2ppp/2n5/1B1p3b/3Pp3/4PN1P/PPP2PP1/RNBQK2R w KQkq -
+French: MacCutcheon, Bernstein variation *
+r2qkbnr/ppp2ppp/2n5/1B1p4/3P2b1/4Pp1P/PPP2PP1/RNBQK2R w KQkq -
+French: MacCutcheon, Chigorin variation *
+r2qkbnr/ppp2ppp/2n5/1B1p4/3Pp1b1/4PN2/PPP2PPP/RNBQK2R w KQkq -
+French: MacCutcheon, advance variation *
+r2qkbnr/ppp2ppp/2n5/1B1pp3/3P2b1/4PN2/PPP2PPP/RNBQK2R b KQkq -
+French: MacCutcheon variation *
+r2qkbnr/ppp2ppp/2n5/3p4/3P2b1/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+French: exchange, Bogolyubov variation *
+r2qkbnr/ppp2ppp/2n5/3p4/3P2b1/5N2/PPP2PPP/RNBQKB1R w KQkq -
+French: exchange, Svenonius variation *
+r2qkbnr/ppp2ppp/2n5/3p4/3Pp1b1/4P3/PPP1BPPP/RNBQK1NR b KQkq -
+French: classical, Vistaneckis (Nimzovich) variation *
+r2qkbnr/ppp2ppp/2n5/3p4/3Pp3/4P3/PPPNQPPP/RNB1K2R b KQkq -
+French: classical variation *
+r2qkbnr/ppp2ppp/2n5/3pN3/3Pp1b1/4P3/PPP1BPPP/RNBQK2R b KQkq -
+French: classical, Tartakower variation *
+r2qkbnr/ppp2ppp/2n5/3pP3/6b1/1P3N2/P1PPP1PP/RNBQKB1R b KQkq -
+Dutch: Staunton gambit, Nimzovich variation *
+r2qkbnr/ppp2ppp/2n5/3pP3/6b1/2P2N2/PP1PP1PP/RNBQKB1R b KQkq -
+Dutch: Staunton gambit, Chigorin variation *
+r2qkbnr/ppp2ppp/2n5/3pP3/6b1/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+French: Burn variation *
+r2qkbnr/ppp2ppp/2n5/3pP3/6b1/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Dutch: Staunton gambit, Staunton's line *
+r2qkbnr/ppp2ppp/2n5/3pp3/3P2b1/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+French: classical *
+r2qkbnr/ppp2ppp/2n5/3pp3/3P4/4Pb2/PPP1BPPP/RNBQK2R w KQkq -
+French: classical, Anderssen variation *
+r2qkbnr/ppp2ppp/2n5/3pp3/6b1/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Pirc: Byrne variation *
+r2qkbnr/ppp2ppp/2npb3/4p3/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English, Tr\"oger defense
+r2qkbnr/ppp2ppp/8/3p4/1n1Pp3/4P3/PPPNQPPP/RNB1K2R w KQkq -
+French: classical, Alapin variation *
+r2qkbnr/ppp3pp/2n2p2/3pP3/6b1/5NP1/PPPPP2P/RNBQKB1R w KQkq -
+Dutch: Staunton gambit, Lasker variation *
+r2qkbnr/ppp3pp/2n5/3p1p2/3Pp3/4P3/PPPNQPPP/RNB1K2R w KQkq -
+French: classical, Steinitz variation *
+r2qkbnr/pppb1ppp/2B5/3p4/3Pp3/4PN1P/PPP2PP1/RNBQK2R b KQkq -
+French: MacCutcheon, Lasker variation *
+r2qkbnr/pppb1ppp/2n5/1B1p4/2PPp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+French: Winawer, advance, Bogolyubov variation *
+r2qkbnr/pppb1ppp/2n5/1B1p4/3Pp3/4P2P/PPPN1PP1/RNBQK2R b KQkq -
+French: MacCutcheon, Tartakower variation *
+r2qkbnr/pppb1ppp/2n5/1B1pp3/3P4/4P3/PPP2PPP/RNBQK1NR w KQkq -
+French: Winawer, fingerslip variation *
+r2qkbnr/pppb1ppp/2n5/3pp3/Q3P3/2P2N2/PP1P1PPP/RNB1KB1R w KQkq -
+Ponziani: Caro variation
+r2qkbnr/pppb1ppp/2np4/1B2p3/2PPP3/5N2/PP3PPP/RNBQK2R b KQkq -
+Ruy Lopez: old Steinitz defense, semi-Duras variation
+r2qkbnr/pppb2pp/2npP3/1B3p2/3p4/5N2/PPP2PPP/RNBQK2R b KQkq -
+KGD: Falkbeer, Morphy gambit *
+r2qkbnr/pppnpppp/8/3p4/6b1/5NP1/PPPPPPBP/RNBQK2R w KQkq -
+R\'eti: King's Indian attack, Keres variation
+r2qr1k1/p1p2ppp/2p2n2/3pp1B1/1b2P1b1/3P1N2/PPP1QPPP/R2N1RK1 b - -
+Four knights: symmetrical, Capablanca variation *
+r2qr1k1/p1p2ppp/5n2/1p1P3b/Q5P1/2N1Bn1P/PPP1KP2/R4B1R w - -
+two knights defense: Yurdansky attack *
+r2qr1k1/ppp1bppp/2n2n2/4p3/2P3b1/2NPBN2/PP2BPPP/R2Q1RK1 w - -
+Philidor: Berger variation *
+r2r2k1/ppq2ppp/2n1pn2/2bp4/2P5/2N1PN1P/PP1BQPP1/R4RK1 b - -
+QGD: Lasker defense, Russian variation *
+r3k1nr/ppp1qppp/2n5/4P3/1bPp4/5N1P/PP1BPPP1/R2QKB1R w KQkq -
+QGD: Albin counter-gambit, Kr\'enosz variation
+r3k2r/p2q1ppp/5n2/3pp3/1b6/4P3/PP3PPP/RNBQ1RK1 w kq -
+QGD: Semi-Tarrasch, Kmoch variation *
+r3k2r/ppp1qppp/2n1b3/2bnp3/8/2NPPN2/PP2BPPP/R1BQK2R w KQkq -
+Sicilian: Velimirovi\'c attack *
+r3k2r/ppp2ppp/2n1bP2/2b2qN1/2ppN3/8/PPP2PPP/R1BQR1K1 b kq -
+two knights: Max Lange attack, Marshall variation
+r3k2r/pppq2pp/2n1bp2/2bnp3/8/2NP1NP1/PP1BPPBP/R2Q1RK1 b kq -
+Sicilian: dragon, Yugoslav attack, 9...Bd7 *
+r3k2r/pppq2pp/2n1bp2/2bnp3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w kq -
+Sicilian: dragon, Yugoslav attack, 9.Bc4 *
+r3k2r/pppq2pp/2n1bp2/2bnp3/P7/2NP1NP1/1P2PPBP/R1BQ1RK1 b kq -
+Sicilian: dragon, Yugoslav attack, Byrne variation *
+r3k2r/pppqbppp/2n1b3/3np3/8/2NP1NP1/PP2PPBP/R1BQK2R w KQkq -
+Sicilian: dragon, classical, Amsterdam variation *
+r3k2r/ppq1ppbp/2N3p1/2pp4/6n1/1P2P3/PBPP1PPP/RN1Q1RK1 w kq -
+Bogo-Indian defense, Monticelli trap *
+r3kb1r/1b3ppp/p2ppn2/qpn1P1B1/3N4/1BN5/PPPQ1PPP/2KRR3 b kq -
+Sicilian: Najdorf, Ivkov variation
+r3kb1r/1bq2ppp/p3pn2/1p1P4/2p5/2N1PN2/PPQ2PPP/R1BR2K1 w kq -
+QGA: classical, Flohr variation
+r3kb1r/1pp2ppp/p1p1b3/3q4/3PN3/8/PPP2PPP/R1BQR1K1 w kq -
+Four knights: Spielmann variation
+r3kb1r/5ppp/b3pn2/1p1qN1B1/3p4/3B4/PP2QPPP/R4RK1 b kq -
+QGD semi-Slav: Meran, Rellstab attack
+r3kb1r/p4ppp/1qp1pn2/3p4/3P4/3Q3P/PPP2PP1/RNB2RK1 b kq -
+QGD: Lasker defense, Bernstein variation *
+r3kb1r/pp1Npppp/1qn2n2/1Bp5/2p5/2N1P3/PP1P1PPP/R1BQK2R b KQkq -
+Nimzo-Indian: Spielmann, Karlsbad variation *
+r3kb1r/pp1b1ppp/nq2pn2/3p4/3P1B2/4PN2/PP3PPP/RNQ1KB1R w KQkq -
+QGD Slav: Landau variation *
+r3kb1r/pp1bpppp/1qn2n2/1Bp5/2N5/2N1P3/PP1P1PPP/R1BQK2R b KQkq -
+Nimzo-Indian: Spielmann, San Remo variation *
+r3kb1r/pp1qn1pp/2n1bp2/2ppp3/8/P1NP1NP1/1PP1PPBP/1RBQ1RK1 b kq -
+King's Indian: S\"amisch, Panno main line *
+r3kb1r/pp1qpppp/2np1n2/2p5/3PP3/2P2N2/PP3PPP/RNBQ1RK1 b kq -
+Sicilian: Canal-Sokolsky attack, Bronstein gambit
+r3kb1r/pp2pppp/1qn2n2/2pp4/3P4/2P1PQ1P/PP3PP1/RNB1KB1R w KQkq -
+QGD/QGD semi-Slav: Hastings variation *
+r3kb1r/pp2pppp/2n2n2/2pq4/3P2b1/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD: Semi-Tarrasch, Primitive Pillsbury variation *
+r3kb1r/pp2pppp/2n5/q1p5/1n1PP1b1/P4N2/1P3PPP/RNBQKB1R w KQkq -
+QGD: Semi-Tarrasch, Krause variation *
+r3kb1r/pp3ppp/1qn1bn2/3pp1B1/2P5/6P1/PP1NPPBP/RN1Q1RK1 b kq -
+Gr\"unfeld defense: Smyslov, Yugoslav variation *
+r3kb1r/pp3ppp/1qn1bn2/3pp1B1/8/6P1/PPPNPPBP/RN1Q1RK1 w kq -
+Gr\"unfeld defense: Smyslov, main line *
+r3kb1r/pp3ppp/1qn1pn2/1B1p1b2/3P1B2/2N1PN2/PP3PPP/R2QK2R b KQkq -
+QGD Slav: exchange, Trifunovi\'c variation *
+r3kb1r/pp3ppp/1qn1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w kq -
+QGD: Orthodox defense, Rauzer variation *
+r3kb1r/pp3ppp/2n2q2/2Pp4/1P2p1b1/2P1PN2/P2N1P2/R1BQKB1R w KQkq -
+QGD semi-Slav: anti-Meran, Szab\'o variation *
+r3kb1r/ppp1q1pp/2n5/3n4/1P2p1b1/P3PN2/2Q2PPP/RNB1KB1R w KQkq -
+Sicilian: Najdorf, Polugayevsky, Simagin variation *
+r3kb1r/ppp2ppp/2n1bP2/5qN1/2ppN3/8/PPP2PPP/R1BQR1K1 w kq -
+two knights: Max Lange attack, Rubinstein variation
+r3kb1r/ppp2ppp/2nq4/3np3/6b1/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Richter-Rauzer, Keres variation *
+r3kb1r/ppp3pp/2n1bq2/3npp2/8/2NPPN2/PP2BPPP/R1BQK2R w KQkq -
+Sicilian: Scheveningen, Tal variation *
+r3kb1r/ppp3pp/2n2q2/3npp1b/6P1/P2PPN1P/1P2BP2/RNBQK2R b KQkq -
+Sicilian: Najdorf, G\"oteborg (Argentine) variation *
+r3kb1r/ppp3pp/2n2q2/3npp1b/8/P2PPN1P/1PQ1BPP1/RNB1K2R b KQkq -
+Sicilian: Najdorf, Browne variation *
+r3kb1r/ppp3pp/2n2q2/3npp2/6b1/P2PPN2/1PQ1BPPP/RNB1K2R b KQkq -
+Sicilian: Najdorf variation *
+r3kb1r/pppq1ppp/2n1b3/3np3/8/P2PPN2/1P3PPP/RNBQKB1R w KQkq -
+Sicilian: Scheveningen, English variation *
+r3kb1r/pppq1ppp/2n5/3np3/6b1/2NP1N2/PP1BPPPP/R2QKB1R w KQkq -
+Sicilian: Richter-Rauzer, Larsen variation, 7.Qd2 *
+r3kb1r/pppq1ppp/2n5/3np3/6b1/2NPPN2/PP2BPPP/R1BQK2R b KQkq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 *
+r3kb1r/pppq1ppp/2n5/3np3/6b1/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Richter-Rauzer, Rauzer attack *
+r3kb1r/pppq1ppp/2n5/3np3/6b1/P1NPPN2/1P3PPP/R1BQKB1R b KQkq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 *
+r3kb1r/ppq2ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w kq -
+QGD: Orthodox defense, Rubinstein variation *
+r3kb1r/ppq2ppp/2n1pn2/2ppN3/3P4/4P2P/PPP1QPP1/RNB2RK1 w kq -
+QGD: Lasker defense, Teichmann variation *
+r3kb1r/ppq2ppp/2n1pn2/3p4/2Pp2b1/4PN2/PP1NBPPP/R1BQ1RK1 w kq -
+QGD: Orthodox defense, 7.Qc2 c5, 8.cd (Rubinstein) *
+r3kb1r/ppqbpp1p/2n2np1/1Bp5/2N2P2/2N1P3/PP1P2PP/R1BQK2R w KQkq -
+Nimzo-Indian: Spielmann, St\aa hlberg variation *
+r3kb1r/ppqn1ppp/2n1p3/1Bpp3b/Q2P4/2P1PN2/PP1N1PPP/R1B2RK1 w kq -
+QGD: Cambridge Springs defense, Argentine variation *
+r3kb1r/ppqn1ppp/2n1p3/1Bpp4/Q2P2b1/2P1PN2/PP1N1PPP/R1B1K2R w KQkq -
+QGD: Cambridge Springs defense, Bogolyubov variation *
+r3kb1r/ppqn1ppp/2p2n2/4pb2/P1NP4/2N3P1/1P2PP1P/R1BQKB1R w KQkq -
+QGD Slav: Carlsbad variation
+r3kbnr/1ppb1ppp/p1p5/8/3NP3/8/PPP2PPP/RNB1K2R w KQkq -
+Ruy Lopez: exchange, Alekhine variation
+r3kbnr/p1pb1ppp/2p5/3pN1q1/3Pp3/4P1PP/PPP2P2/RNBQK2R b KQkq -
+French: MacCutcheon, Lasker variation, 8...g6 *
+r3kbnr/pp1qpppp/8/2ppP3/2P3b1/6P1/PP2PP1P/RNBQKB1R b KQkq -
+Gr\"unfeld: Lundin variation *
+r3kbnr/ppp2pp1/2n5/1B1p2qP/3P4/4P3/PPP2Pp1/RNBQK1R1 w Qkq -
+French: MacCutcheon, Grigoriev variation *
+r3kbnr/ppp2ppp/2n5/3p2q1/3Pp3/4P3/PPP1BPPP/RNBQK2R w KQkq -
+French: classical, Anderssen-Richter variation *
+r3kbnr/ppp2ppp/2n5/3p2q1/3Pp3/4P3/PPPNQPPP/RNB1K2R w KQkq -
+French: classical, Pollock variation *
+r3kbnr/pppq1ppp/2n1b3/3pp3/8/2PP1NP1/PP2PP1P/RNBQKB1R w KQkq -
+Pirc: 150 attack *
+r3kbnr/pppq1ppp/2n5/1B1p4/Q7/4PP2/PPP2P1P/RNB1K2R b KQkq -
+French: MacCutcheon, Bogolyubov variation *
+r3kbnr/pppq1ppp/2n5/3p4/3Pp3/4P3/PPPNQPPP/RNB1K2R w KQkq -
+French: classical, Rubinstein variation *
+r3kbnr/ppq1pppp/2n5/3p4/3P2b1/2P2N2/PP3PPP/RNBQKB1R w KQkq -
+QGD: exchange, positional line, 6.Qc2 *
+r3qrk1/ppp1b1pp/2n1b3/3npp2/8/P1NPPN2/1PQ1BPPP/R1B2RK1 b - -
+Sicilian: Scheveningen, classical main line *
+r3r1k1/1p1n1p1p/1bpqb1p1/p2p2B1/1P1N3Q/P1PBR3/5PPP/5RK1 b - -
+Ruy Lopez: Marshall, main line, Spassky variation *
+r3r1k1/2qbbp1p/p2p1np1/npp1p3/3PP3/2P1NN1P/PPB2PP1/R1BQR1K1 w - -
+Ruy Lopez: closed, Chigorin, Yugoslav system
+r3r1k1/ppp1qppp/2n5/3b4/2P1p3/8/P1PPBPPP/R1BQ1RK1 b - -
+Ruy Lopez: Berlin defense, Rio de Janeiro variation *
+r4b1r/ppp1kp2/2n1bN1p/q5p1/1P1p3B/5N2/P1P2PPP/R2QR1K1 b - -
+two knights defense: Yurdansky attack
+r4rk1/2pqb1pp/p1n1p3/1p1pP3/4R3/1BP5/PP3PPP/RNBQ2K1 b - -
+Ruy Lopez: open, Tarrasch trap
+r4rk1/2pqbppp/p1n1b3/3pP3/2B1n3/5N2/PP2QPPP/RNBR2K1 w - -
+Ruy Lopez: open, Howell attack, Ekstr\"om variation
+r4rk1/p4ppp/bqn2n2/2b5/B3p3/2N3Q1/PPPPNPPP/R1B1K2R w KQ -
+Evans gambit: compromised defense, Paulsen variation *
+r4rk1/pbqnppbp/1p3np1/2pp4/P2P4/BPP1PN2/3NBPPP/R2Q1RK1 b - -
+Catalan: closed, Sokolsky variation *
+r4rk1/pp1bqpp1/2n1pn1p/2p5/2BP4/2N1PN2/PPQ2PPP/R2R2K1 w - -
+QGD: Lasker defense, Russian variation
+r4rk1/pp2ppbp/3p1np1/q4P2/4P1P1/2N1B3/PPP1Q2P/R4RK1 b - -
+Sicilian: dragon, classical, Stockholm attack
+r4rk1/pp2qppp/3b4/3P4/1P1Qn1b1/B3PN2/5PPP/R3KB1R w KQ -
+QGD semi-Slav: Meran, Rellstab attack *
+r4rk1/ppp1q2p/2n1b3/4p1p1/Q4p2/3P1NP1/PP2PPBP/R4RK1 w - -
+Sicilian: dragon, classical, Stockholm attack *
+r4rk1/ppp3pp/2n1bq2/4pP2/8/5Q2/PPPP1K1P/RNB2BNR w - -
+KGA: Lolli gambit, Young variation *
+r4rk1/pppqbppp/2n1b3/3np3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+Sicilian: dragon, classical, Richter variation *
+r4rk1/ppq1ppbp/2n2np1/2pp4/3P1Pb1/2P1PN2/PP2B1PP/RNB1QRK1 w - -
+Dutch: stonewall: Chekhover variation *
+r5nr/pp2k2p/2n2p2/2N1p2q/3pP3/3P2P1/PPP2PBP/RNB2RK1 b - -
+King's Indian: S\"amisch, orthodox, Bronstein variation *
+rn1q1rk1/1p3pbp/p2p1np1/2pP4/P3P1b1/2N2N2/1P2BPPP/R1BQ1RK1 w - -
+Benoni: classical with ...a6 and 10...Bg4
+rn1q1rk1/4ppbp/3p1np1/2pP4/4P3/2N2NP1/PP3PKP/R1BQ3R b - -
+Benk\"o gambit: main line
+rn1q1rk1/p3ppbp/bp3np1/2pp4/3P1P2/2P1PN2/PP2B1PP/RNBQ1RK1 w - -
+Dutch: stonewall with Ba3 *
+rn1q1rk1/pb1pbppp/1p2pn2/8/2PN4/1P1BP3/PB3PPP/RN1Q1RK1 b - -
+Queen's Indian: Averbakh variation
+rn1q1rk1/pb3ppp/1p1bp3/2pn4/8/1P2PN2/PB1PBPPP/RN1Q1RK1 w - -
+Queen's Indian: Averbakh variation *
+rn1q1rk1/pb3ppp/5n2/2b1p3/N2p4/1B1P4/PPP1NPPP/R1BQK2R b KQ -
+Evans gambit: Paulsen variation *
+rn1q1rk1/pb3ppp/5n2/2b1p3/N2p4/1B1P4/PPP2PPP/R1BQK1NR w KQ -
+Evans gambit: Ulvestad variation *
+rn1q1rk1/pb3ppp/8/1Bb5/4N1n1/5N2/PPPP1PPP/R1BQ1RK1 b - -
+Scotch gambit: Hanneken variation *
+rn1q1rk1/pbp1bppp/1p3n2/3pN1B1/3P4/2NBP3/PP3PPP/R2QK2R b KQ -
+QGD: Pillsbury attack
+rn1q1rk1/pbpp1ppp/1p2p3/6N1/2PP4/2n3P1/PPQ1PPBP/R3K2R b KQ -
+Bogo-Indian defense, Monticelli trap
+rn1q1rk1/pbppbppp/1p2p3/8/2PP4/2Q2NP1/PP2PPBP/R1B2RK1 b - -
+Queen's Indian: old main line, 9.Qxc3
+rn1q1rk1/pbppbppp/1p2pn2/8/2PP4/1P3NP1/P3PPBP/RNBQ1RK1 b - -
+Queen's Indian: Euwe variation
+rn1q1rk1/pbppbppp/1p2pn2/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+Queen's Indian: old main line, 7.Nc3
+rn1q1rk1/pp1nppbp/6p1/2p5/3PP1b1/1QN1BN2/PP3PPP/R3KB1R w KQ -
+Gr\"unfeld defense: Smyslov, Yugoslav variation
+rn1q1rk1/pp2ppbp/2p2np1/3p1b2/2PP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+Gr\"unfeld: Flohr defense
+rn1q1rk1/pp2ppbp/2p2np1/3p4/2PP2b1/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+Gr\"unfeld: Smyslov defense
+rn1q1rk1/pp2ppbp/2pp1np1/5b2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, Larsen system
+rn1q1rk1/pp2ppbp/4bnp1/2Pp4/2P2B2/2N1P3/PP3PPP/2RQKBNR w K -
+Gr\"unfeld: Gr\"unfeld gambit, Botvinnik variation
+rn1q1rk1/pp3ppp/2p1p3/5b2/PbBPn1P1/2N1PN2/1P2QP1P/R1B2RK1 b - -
+QGD Slav: Dutch, S\"amisch variation
+rn1q1rk1/pp3ppp/2p1pn2/5b2/PbBP4/2N1PN2/1P2QPPP/R1B2RK1 b - -
+QGD Slav: Dutch variation, main line
+rn1q1rk1/ppp1b1pp/1n2pp2/4Pb2/2PP4/2N2N2/PP2B1PP/R1BQ1RK1 w - -
+Alekhine's defense: four pawns attack, Korchnoi variation
+rn1q1rk1/ppp1ppbp/5np1/8/2QPP1b1/2N2N2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Russian, Smyslov variation
+rn1q1rk1/ppp2ppp/3b4/3p4/2PPn1b1/3B1N2/PP3PPP/RNBQ1RK1 w - -
+Petrov: classical attack, Tarrasch variation
+rn1q1rk1/ppp2ppp/8/2bNp3/4P1b1/3P1N2/PPP2PPP/R1BQK2R b KQ -
+Giuoco piano *
+rn1q1rk1/ppp2ppp/8/2bP1b2/4nPP1/5N2/PPP1Q2P/RNB1KB1R w KQ -
+KGD: Falkbeer, Tarrasch variation
+rn1q1rk1/ppp3pp/8/2bNpp1b/4P1P1/5N1P/PPPP1P2/R1BQK2R w KQ -
+Giuoco piano: Rosentreter variation *
+rn1q1rk1/ppp3pp/8/3P1p2/3Pn1b1/3B1N2/PP3PPb/RNBQR1K1 w - -
+Petrov: classical attack, Marshall trap
+rn1q1rk1/pppnppbp/6p1/8/3PP1b1/1QN1BN2/PP3PPP/R3KB1R b KQ -
+Gr\"unfeld defense: Smyslov, main line
+rn1qk1nr/pb3ppp/8/2b1p3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+Danish gambit: Schlechter defense *
+rn1qk1nr/pb3ppp/8/2b1p3/8/8/PPPPQPPP/RNB1KBNR b KQkq -
+Danish gambit: Collijn defense *
+rn1qk1nr/pp1bppbp/6p1/2pp4/5P2/4PN2/PPPPB1PP/RNBQK2R b KQkq -
+Dutch-Indian, Alekhine variation *
+rn1qk1nr/pp3ppp/2pb4/3p1b2/3P4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+Caro-Kann: exchange, Rubinstein variation *
+rn1qk1nr/ppp1ppbp/3p2p1/8/2PPP1b1/5N2/PP3PPP/RNBQKB1R w KQkq -
+Robatsch defense: Rossolimo variation
+rn1qk1nr/ppp2ppp/8/2b1p3/Q3P1b1/2P2N2/PP1P2PP/RNB1KB1R b KQkq -
+KGD: classical, Marshall attack
+rn1qk2r/1bpp1ppp/1p2pn2/p7/1bPP4/5NP1/PP1BPPBP/RN1QK2R w KQkq -
+Queen's Indian: Yates variation
+rn1qk2r/p1pp1ppp/bp2pn2/8/1bPP4/2N1P3/PP2NPPP/R1BQKB1R w KQkq -
+Nimzo-Indian: 4.e3, Bronstein (Byrne) variation
+rn1qk2r/p4ppp/2p2n2/2bpp3/B3P1b1/2NP4/PPP2PPP/R1BQK1NR w KQkq -
+Evans gambit: Sokolsky variation *
+rn1qk2r/pb1pbppp/1p2pn2/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w kq -
+English: symmetrical, hedgehog system
+rn1qk2r/pbpp1pp1/1p2pn1p/8/1bPP3B/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+Queen's Indian: 4.Nc3, main line
+rn1qk2r/pbpp1ppp/1p2pn2/8/1bPP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+Queen's Indian: Capablanca variation
+rn1qk2r/pbpp1ppp/5n2/1pb1p3/4P3/1BN5/PPPP1PPP/R1BQK1NR w KQkq -
+Evans gambit declined, Cordel variation *
+rn1qk2r/pbppbppp/1p2p3/8/2PPn3/2N2NP1/PP1BPPBP/R2QK2R b KQkq -
+Queen's Indian: Opo\v censky variation
+rn1qk2r/pbppbppp/1p2pn2/8/2PP4/2N2NP1/PP2PPBP/R1BQK2R b KQkq -
+Queen's Indian: anti-Queen's Indian system
+rn1qk2r/pbppbppp/1p2pn2/8/2PP4/5NP1/PP1BPPBP/RN1QK2R w KQkq -
+Queen's Indian: Riumin variation
+rn1qk2r/pbppbppp/1p2pn2/8/2PP4/5NP1/PP2PPBP/RNBQ1RK1 b kq -
+Queen's Indian: old main line, 6.O-O
+rn1qk2r/pbppbppp/1p2pn2/8/2PP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+Queen's Indian: 5.Bg2 Be7
+rn1qk2r/pp1bppbp/5np1/1Bpp4/P7/1P2PN2/1BPP1PPP/RN1QK2R b KQkq -
+Queen's Indian: Yates variation *
+rn1qk2r/pp1bppbp/5np1/2pp4/8/1P2PN2/PBPPBPPP/RN1QK2R b KQkq -
+Queen's Indian: Riumin variation *
+rn1qk2r/pp3ppp/2p1b3/3np3/1bB5/2N2Q2/PPPPNPPP/R1B1K2R w KQkq -
+Scotch: Paulsen attack *
+rn1qk2r/pp3ppp/2p1b3/3np3/1bB5/5Q2/PPPPNPPP/R1BNK2R b KQkq -
+Scotch: Paulsen, Gunsberg defense *
+rn1qk2r/pp3ppp/2p1pn2/5b2/PbBP4/2N1PN2/1P3PPP/R1BQ1RK1 b kq -
+QGD Slav: Dutch variation
+rn1qk2r/pp3ppp/2p2n2/2bpp3/4P1b1/1BN5/PPPPQPPP/R1B1K1NR w KQkq -
+Giuoco Piano: Mestel variation *
+rn1qk2r/ppp2ppp/3pbn2/4p3/1bB1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Ruy Lopez: Berlin defense, Kaufmann variation *
+rn1qk2r/ppp2ppp/8/2bP1b2/4nP2/5N2/PPP1Q1PP/RNB1KB1R w KQkq -
+KGD: Falkbeer, main line, 7...Bf5
+rn1qk2r/ppp3p1/8/2bpP1Pp/4b3/7P/PPP3K1/RNBQ1BNR w kq -
+KGA: Allgaier, Cook variation *
+rn1qk2r/pppbbppp/8/3pP3/N3n3/2PB1N1P/P1Q2PP1/R1B1K2R w KQkq -
+two knights defense: Knorre variation *
+rn1qkb1r/1b3ppp/p3pn2/1pp5/3P4/1B2PN2/PP2QPPP/RNB2RK1 w kq -
+QGA: classical, 8...Bb7
+rn1qkb1r/4pp1p/3p1np1/2pP4/4P3/2N3P1/PP3P1P/R1BQ1KNR b kq -
+Benk\"o gambit
+rn1qkb1r/4pp1p/3p1np1/2pP4/4P3/2N5/PP2NPPP/R1BQ1K1R b kq -
+Benk\"o gambit: Ne2 variation
+rn1qkb1r/4pp1p/b2p1np1/2pP4/8/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+Benk\"o gambit: fianchetto variation
+rn1qkb1r/4pp1p/b2p1np1/2pP4/8/2N5/PP1NPPPP/R1BQKB1R b KQkq -
+Benk\"o gambit: Nd2 variation
+rn1qkb1r/4pppp/b2p1n2/2pP4/4P3/2N5/PP3PPP/R1BQKBNR b KQkq -
+Benk\"o gambit: 7.e4
+rn1qkb1r/p1pp1ppp/bp2pn2/8/2PP4/5NP1/PP2PP1P/RNBQKB1R w KQkq -
+Queen's Indian: Nimzovich variation (exaggerated fianchetto)
+rn1qkb1r/pb1p1ppp/1p2pn2/2p5/2PP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+English: Wimpey system *
+rn1qkb1r/pb1p1ppp/1p3n2/2pp2N1/2P5/6P1/PP2PPBP/RNBQK2R b KQkq -
+Queen's Indian: B\"urger variation
+rn1qkb1r/pb1p1ppp/1p3n2/2pp4/2P4N/6P1/PP2PPBP/RNBQK2R b KQkq -
+Queen's Indian: Rubinstein variation
+rn1qkb1r/pb1ppppp/1p3n2/2p3B1/3P4/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+English: Capablanca's variation *
+rn1qkb1r/pb1ppppp/1p3n2/2p5/3P1B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+English: New York (London) defensive system *
+rn1qkb1r/pb1ppppp/1p3n2/2p5/3P4/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+English: Caro-Kann defensive system *
+rn1qkb1r/pb1ppppp/1p3n2/2p5/3P4/2P2NP1/PP2PP1P/RNBQKB1R b KQkq -
+English: Bled variation *
+rn1qkb1r/pb1ppppp/1p3n2/2p5/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Queen's Indian: Marienbad system
+rn1qkb1r/pb1ppppp/1p3n2/8/2PQ4/5NP1/PP2PPBP/RNB1K2R b KQkq -
+Queen's Indian: Marienbad system, Berg variation
+rn1qkb1r/pbpp1p2/1p2p2p/6pn/2PP4/2N2NB1/PP2PPPP/R2QKB1R w KQkq -
+Queen's Indian: 4.Nc3, Botvinnik variation
+rn1qkb1r/pbpp1ppp/1p2pn2/8/2P1P3/2NB1N2/PP1P1PPP/R1BQK2R b KQkq -
+English: Queens Indian, Romanishin variation
+rn1qkb1r/pbpp1ppp/1p2pn2/8/2PP4/5NP1/PP2PP1P/RNBQKB1R w KQkq -
+Queen's Indian: 4.g3 Bb7
+rn1qkb1r/pp1bpppp/5n2/1Bpp4/8/4PN2/PPPPQPPP/RNB1K2R b KQkq -
+Bogo-Indian defense, Nimzovich variation *
+rn1qkb1r/pp1n1ppp/4p3/3pNb2/3P4/2N1P3/PP3PPP/R1BQKB1R w KQkq -
+QGD Slav: Amsterdam variation
+rn1qkb1r/pp2pppp/2p2n2/3p1b2/2P5/1P3N2/PB1PPPPP/RN1QKB1R w KQkq -
+English: New York (London) defensive system
+rn1qkb1r/pp2pppp/2p2n2/3p1b2/2P5/1P3NP1/P2PPP1P/RNBQKB1R w KQkq -
+English: London defensive system
+rn1qkb1r/pp2pppp/2p2n2/3p1b2/2PP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD Slav: 4.e3 Bf5
+rn1qkb1r/pp2pppp/2p2n2/3p4/2P3b1/1P3N2/PB1PPPPP/RN1QKB1R w KQkq -
+English: Capablanca's variation
+rn1qkb1r/pp2pppp/2p2n2/3p4/2P3b1/1P3NP1/P2PPP1P/RNBQKB1R w KQkq -
+English: Torre defensive system
+rn1qkb1r/pp2pppp/2p2n2/3p4/6b1/5NP1/PPPPPPBP/RNBQ1RK1 w kq -
+R\'eti: King's Indian attack, Yugoslav variation
+rn1qkb1r/pp2pppp/2p2n2/4Nb2/P1pP4/2N5/1P2PPPP/R1BQKB1R b KQkq -
+QGD Slav: Krause attack
+rn1qkb1r/pp2pppp/2p2n2/5b2/P1pP4/2N1PN2/1P3PPP/R1BQKB1R b KQkq -
+QGD Slav: Dutch variation
+rn1qkb1r/pp2pppp/2p2n2/5b2/P1pP4/2N2N2/1P2PPPP/R1BQKB1R w KQkq -
+QGD Slav: Czech defense
+rn1qkb1r/pp2pppp/2p2n2/8/P1pP2b1/2N2N2/1P2PPPP/R1BQKB1R w KQkq -
+QGD Slav: Steiner variation
+rn1qkb1r/pp2pppp/2pp4/3nP3/3P2b1/5N2/PPP1BPPP/RNBQK2R w KQkq -
+Alekhine's defense: modern, Flohr variation
+rn1qkb1r/pp2pppp/5n2/1Bpp4/3P2b1/4PN2/PPP2PPP/RNBQK2R b KQkq -
+QGD: Vienna variation *
+rn1qkb1r/pp2pppp/5n2/2p5/1PPp2b1/4PN2/P2P1PPP/RNBQKB1R w KQkq -
+Blumenfeld counter-gambit, Dus-Chotimursky variation *
+rn1qkb1r/pp2pppp/5n2/2pp1b2/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+Queen's Indian: Miles variation *
+rn1qkb1r/pp2pppp/5n2/2pp4/3P2b1/4PN1P/PPP2PP1/RNBQKB1R b KQkq -
+QGD: Capablanca-Duras variation *
+rn1qkb1r/pp2pppp/5n2/2pp4/3P2b1/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+QGD *
+rn1qkb1r/pp2pppp/5n2/3p1b2/3P4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+QGD Slav: exchange variation
+rn1qkb1r/pp2pppp/5n2/8/1PPp2b1/5N1P/P2P1PP1/RNBQKB1R b KQkq -
+Blumenfeld counter-gambit, Spielmann variation *
+rn1qkb1r/pp3ppp/2p1pn2/4Nb2/P1pP4/2N5/1P2PPPP/R1BQKB1R w KQkq -
+QGD Slav: Wiesbaden variation
+rn1qkb1r/pp3ppp/4b3/2pnp3/8/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+Sicilian: accelerated fianchetto, Mar\'oczy bind, 6.Be3 *
+rn1qkb1r/ppn2ppp/2p1b3/4p3/2B5/2N2Q2/PPPPNPPP/R1B1K2R w KQkq -
+Scotch: Meitner variation *
+rn1qkb1r/ppp1pppp/1n1p4/3PP3/2P3b1/5N2/PP3PPP/RNBQKB1R b KQkq -
+Alekhine's defense: modern, Vitolins attack
+rn1qkb1r/ppp1pppp/1n1p4/4Pb2/2PP1P2/8/PP4PP/RNBQKBNR w KQkq -
+Alekhine's defense: four pawns attack, Trifunovi\'c variation
+rn1qkb1r/ppp1pppp/3p1n2/5b2/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Old Indian: Janowski variation
+rn1qkb1r/ppp1pppp/3p4/3nP3/2PP2b1/5N2/PP3PPP/RNBQKB1R b KQkq -
+Alekhine's defense: modern, Alekhine variation
+rn1qkb1r/ppp1pppp/3p4/3nP3/3P2b1/5N1P/PPP2PP1/RNBQKB1R b KQkq -
+Alekhine's defense: modern, Panov variation
+rn1qkb1r/ppp1pppp/3p4/3nP3/3P2b1/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Alekhine's defense: modern variation, 4...Bg4
+rn1qkb1r/ppp1pppp/4bn2/8/2pP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGA, Flohr variation
+rn1qkb1r/ppp1pppp/5B2/3p1b2/3P4/2N5/PPP1PPPP/R2QKBNR b KQkq -
+Richter-Veresov attack, Veresov variation
+rn1qkb1r/ppp1pppp/5n2/3p1b2/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's bishop game *
+rn1qkb1r/ppp1pppp/5n2/3p1b2/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian: London system *
+rn1qkb1r/ppp1pppp/5n2/3p1bB1/3P4/2N2P2/PPP1P1PP/R2QKBNR b KQkq -
+Richter-Veresov attack, Richter variation
+rn1qkb1r/ppp1pppp/5n2/3p4/3P2b1/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Torre attack (Tartakower variation) *
+rn1qkb1r/ppp1pppp/5n2/3p4/6b1/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+Queen's pawn: Torre attack *
+rn1qkb1r/ppp1pppp/5n2/3p4/6b1/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian: Torre attack *
+rn1qkb1r/ppp1pppp/5n2/8/2pP2b1/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGA, Janowsky-Larsen variation
+rn1qkb1r/ppp2ppp/4b3/4p3/1nB5/2N2Q2/PPPP1PPP/R1B1K1NR w KQkq -
+Scotch: Blumenfeld attack *
+rn1qkb1r/ppp2ppp/5n2/3pp3/2P3b1/4PN2/PP1P1PPP/RNBQKB1R w KQkq -
+Queen's pawn: Torre attack, Wagner gambit *
+rn1qkb1r/ppp2ppp/8/3pP3/4n1b1/2N2N2/PPPPQ1PP/R1B1KB1R b KQkq -
+Vienna gambit: Kaufmann variation
+rn1qkb1r/ppp3p1/8/3ppbPp/3Pn3/5N2/PPP2P1P/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Brentano defense *
+rn1qkb1r/pppb1ppp/8/1B2p2Q/1n6/2N5/PPPP1PPP/R1B1K1NR w KQkq -
+Scotch game *
+rn1qkbnr/1bpp1ppp/p7/1P6/3Q4/8/PP2PPPP/RNB1KBNR w KQkq -
+Sicilian: wing gambit, Marienbad variation *
+rn1qkbnr/1pp2ppp/p3p3/3P4/2B3b1/4PN2/PP3PPP/RNBQK2R b KQkq -
+QGA: Alekhine defense, Alatortsev variation
+rn1qkbnr/p1pppppp/bp6/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Guatemala defense
+rn1qkbnr/pp1b1ppp/4P3/1Bp5/4p3/8/PPP2PPP/RNBQK1NR b KQkq -
+QGD: Albin counter-gambit, Lasker trap *
+rn1qkbnr/pp1bpppp/3p4/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Sicilian: Canal-Sokolsky attack, 3...Bd7
+rn1qkbnr/pp2pppp/2p3b1/8/3P1P2/6N1/PPP3PP/R1BQKBNR b KQkq -
+Caro-Kann: classical, Mar\'oczy attack
+rn1qkbnr/pp2pppp/2p3b1/8/3P3P/6N1/PPP2PP1/R1BQKBNR b KQkq -
+Caro-Kann: classical, 6.h4
+rn1qkbnr/pp2pppp/2p3b1/8/3P4/6NN/PPP2PPP/R1BQKB1R b KQkq -
+Caro-Kann: classical, Flohr variation
+rn1qkbnr/pp2pppp/2p5/3p4/2P3b1/1P3N2/P2PPPPP/RNBQKB1R w KQkq -
+English: Caro-Kann defensive system, Bogolyubov variation
+rn1qkbnr/pp2pppp/2p5/3p4/4P1b1/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Caro-Kann: two knights, 3...Bg4
+rn1qkbnr/pp2pppp/2p5/5b2/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+Caro-Kann: classical variation
+rn1qkbnr/pp2pppp/8/2p2bN1/4p3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Budapest: Rubinstein variation *
+rn1qkbnr/pp2pppp/8/2pp4/6b1/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+Neo-Indian (Seirawan) attack *
+rn1qkbnr/pp3ppp/2p1p3/3pPb2/3P4/2P5/PP2BPPP/RNBQK1NR b KQkq -
+Caro-Kann: advance, Short variation
+rn1qkbnr/pp4pp/4b3/2pp4/4p3/1NN5/PPP1PPPP/R1BQKB1R w KQkq -
+Alekhine's defense: four pawns attack, 7.Be3 *
+rn1qkbnr/ppp1pppp/3p4/8/3P2b1/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Old Indian: Tartakower (Wade) variation
+rn1qkbnr/ppp1pppp/3p4/8/4P1b1/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+R\'eti: Wade defense
+rn1qkbnr/ppp1pppp/4b3/8/2p5/4PN2/PP1P1PPP/RNBQKB1R w KQkq -
+R\'eti accepted: Keres variation
+rn1qkbnr/ppp1pppp/8/3p1b2/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+Queen's pawn, Mason variation, Steinitz counter-gambit *
+rn1qkbnr/ppp1pppp/8/3p1b2/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QGD: Grau (Sahovic) defense
+rn1qkbnr/ppp1pppp/8/3p1b2/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn, Mason variation *
+rn1qkbnr/ppp1pppp/8/3p1b2/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Queen's pawn: London system *
+rn1qkbnr/ppp1pppp/8/3p4/2P3b1/8/PP1PPPBP/RNBQK1NR b KQkq -
+Grob: Fritz gambit
+rn1qkbnr/ppp1pppp/8/3p4/3P2b1/2N5/PPP1PPPP/R1BQKBNR w KQkq -
+Queen's pawn: Anti-Veresov
+rn1qkbnr/ppp1pppp/8/3p4/3P2b1/8/PPP1PPPP/RNBQKBNR w KQkq -
+Levitsky attack (Queen's bishop attack) *
+rn1qkbnr/ppp1pppp/8/3p4/5Pb1/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch, 2.Bg5 variation *
+rn1qkbnr/ppp1pppp/8/3p4/6b1/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Trompovsky attack (Ruth, Opo\v censk\'y opening) *
+rn1qkbnr/ppp1pppp/8/8/2Pp2b1/8/PP1PPPBP/RNBQK1NR w KQkq -
+Grob: Romford counter-gambit
+rn1qkbnr/ppp2ppp/2b1p3/8/3PN3/5N2/PPP2PPP/R1BQKB1R w KQkq -
+French: Fort Knox variation
+rn1qkbnr/ppp2ppp/3p4/4p3/2P3b1/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+English, Smyslov defense
+rn1qkbnr/ppp2ppp/4b3/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: Alapin variation *
+rn1qkbnr/ppp2ppp/8/3p4/5p2/6PB/PPPPP2P/RNBQK2R w KQkq -
+Amar gambit
+rn1qkbnr/pppb1ppp/3p4/8/3QP3/5N2/PPP2PPP/RNB1KB1R w KQkq -
+Philidor: Boden variation
+rn2k2r/pbpp1ppp/8/2b1p3/Np2Q3/1B6/PPPP1qPP/R1BK2NR w kq -
+Evans gambit declined, Hicken variation *
+rn2k2r/pp4pp/1q3p2/1N1pN3/3Pn3/5K2/PPP3PP/R1BQ3R w kq -
+Giuoco Piano: Krause variation *
+rn2kb1r/pp1q1ppp/2p1b3/3np3/2B5/2N2Q2/PPPPNPPP/R1B1K2R w KQkq -
+Scotch: Blackburne attack *
+rn2kb1r/pp2pppp/2p2n2/q3Nb2/3P2P1/2N5/PPP2P1P/R1BQKB1R b KQkq -
+Scandinavian defense, Gr\"unfeld variation
+rn2kb1r/pp3ppp/2p1q3/1N6/3p4/5Q2/PP3PPP/1RB2RK1 b kq -
+Scotch: Gottschall variation *
+rn2kb1r/ppp1pppp/5n2/q4b2/3P4/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Scandinavian defense
+rn2kb1r/ppp1pppp/5n2/q7/3P2b1/2N2N1P/PPP2PP1/R1BQKB1R b KQkq -
+Scandinavian defense, Lasker variation
+rn2kbnr/pp1b1ppp/1q2p3/2ppP3/3P4/2P2N2/PP3PPP/RNBQKB1R w KQkq -
+French: advance, Wade variation
+rn2kbnr/pp1qpppp/3p4/2p5/2P1P3/5N2/PP1P1PPP/RNBQK2R b KQkq -
+Sicilian: Canal-Sokolsky attack, Sokolsky variation
+rn2kbnr/ppp2ppp/8/q3p3/3P2b1/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Scandinavian: Anderssen counter-attack, Collijn variation
+rn3rk1/p1p1qpp1/1p2b2p/3p4/3P4/4PN2/PP3PPP/2RQKB1R w K -
+QGD: Tartakower variation
+rn3rk1/p4ppp/bqp5/2b1p3/N3n3/1B6/PPPQ1PPP/R1B1K1NR w KQ -
+Evans gambit: Levenfish variation *
+rnb1k1nr/p3qppp/2p1p3/1p6/PbpP4/2N1PN2/1P1B1PPP/R2QKB1R w KQkq -
+QGD: semi-Slav, Koomen variation
+rnb1k1nr/p4ppp/1qp1p3/1p6/PbpP4/2N1PN2/1P1B1PPP/R2QKB1R w KQkq -
+QGD: semi-Slav, Junge variation
+rnb1k1nr/pp1pq1pp/2p5/2b1pp2/2B1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Bishop's opening: Lopez gambit *
+rnb1k1nr/pp2ppbp/3p2p1/q1p5/2PPP3/2N2N2/PP3PPP/R1BQKB1R w KQkq -
+Pterodactyl defense
+rnb1k1nr/pp2ppbp/6p1/2qp4/8/4PN2/PPPN1PPP/R1BQKB1R w KQkq -
+Catalan: open, 5.Qa4 Nbd7, 6.Qxc4 *
+rnb1k1nr/pp2ppbp/6p1/q1Pp4/8/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+Catalan: open, 5.Qa4 *
+rnb1k1nr/pp3ppp/2p5/2PP4/2B4q/5p2/PPP2PPP/RNBQ1RK1 b kq -
+Bishop's opening: Pratt variation *
+rnb1k1nr/pp3ppp/4p3/2pq4/1b1P4/2NB4/PPPB1PPP/R2QK1NR b KQkq -
+French: Winawer, Kondratiyev variation
+rnb1k1nr/ppp2pbp/3p4/4P1p1/2BP1p1q/2N5/PPP3PP/R1BQ1KNR b kq -
+KGA: bishop's gambit, Grimm attack
+rnb1k1nr/ppp2ppp/3b4/3B4/4Pp1q/8/PPPP2PP/RNBQ1KNR w kq -
+KGA: bishop's gambit, Bor\'en-Svenonius variation
+rnb1k1nr/pppp1pbp/8/6p1/2B1P2q/2N2Qp1/PPPP3P/R1B2KNR b kq -
+KGA: bishop's gambit, Fraser variation
+rnb1k1nr/pppp1pbp/8/6p1/2B1Pp1q/2N3P1/PPPP3P/R1BQ1KNR b kq -
+KGA: bishop's gambit, McDonnell attack
+rnb1k1nr/pppp1ppp/8/2b1p1q1/2B1P3/2P5/PP1P1PPP/RNBQK1NR w KQkq -
+Bishop's opening: del Rio variation
+rnb1k1nr/pppp1ppp/8/2b5/2B1Pp1q/8/PPPP2PP/RNBQ1KNR w kq -
+KGA: bishop's gambit, Greco variation
+rnb1k1nr/pppp1ppp/8/4p3/1bB1Pq2/2N2N2/PPPP2PP/R1BQK2R b KQkq -
+KGD: Norwalde variation, B\"ucker gambit
+rnb1k1nr/ppppqppp/1b1P4/4p3/2B1P3/2P2N2/PP3PPP/RNBQK2R b KQkq -
+Giuoco Piano: Eisinger variation
+rnb1k1nr/pppq1ppp/4p3/3pP3/1b1P4/2N5/PPP2PPP/R1BQKBNR w KQkq -
+French: Winawer, Petrosian variation
+rnb1k1nr/ppq1ppbp/6p1/3p4/8/P3PN2/1PPN1PPP/R1BQKB1R w KQkq -
+Catalan: open, Alekhine variation *
+rnb1k1nr/ppq2ppp/4p3/2ppP3/3P4/P1P5/2P2PPP/R1BQKBNR w KQkq -
+French: Winawer, classical variation
+rnb1k1r1/ppq1np1Q/4p3/3pP3/3p4/P1P5/2P1NPPP/R1B1KB1R b KQq -
+French: Winawer, advance, poisoned pawn, Konstantinopolsky variation
+rnb1k1r1/ppq1np1Q/4p3/3pP3/3p4/P1P5/2P2PPP/R1BK1BNR b q -
+French: Winawer, advance, poisoned pawn, Euwe-Gligori\'c variation
+rnb1k2r/1pq1bpp1/p2ppn1p/8/3NPP1B/2N2Q2/PPP3PP/R3KB1R w KQkq -
+Sicilian: Najdorf, Browne variation
+rnb1k2r/1pq1bppp/p2ppn2/6B1/3NPP2/2N2Q2/PPP3PP/R3KB1R w KQkq -
+Sicilian: Najdorf variation
+rnb1k2r/2q1bp1p/p2p1n2/1ppPp1p1/4P3/2P2N1P/PPBN1PP1/R1BQR1K1 w kq -
+Ruy Lopez: closed, Leonhardt variation
+rnb1k2r/p1pp1ppp/8/4p3/Np2n1Qq/1B6/PPPPKbPP/R1B3NR w kq -
+Evans gambit declined, V\'asquez variation *
+rnb1k2r/p4ppp/1qp2n2/2bpp3/B3P3/2NP4/PPP2PPP/R1BQK1NR w KQkq -
+Evans gambit: Tartakower attack *
+rnb1k2r/pp2ppbp/5np1/2pq4/8/1P3N2/PB1PPPPP/RN1QKB1R w KQkq -
+Queen's Indian: Marienbad system, Berg variation *
+rnb1k2r/pp2qppp/1bp2n2/3pp1B1/1P2P3/P1NP1N2/2P1BPPP/R2QK2R b KQkq -
+Ruy Lopez: Wormald attack, Gr\"unfeld variation *
+rnb1k2r/pp3ppp/4p3/q7/1b1PP3/5N2/P2B1PPP/R2QKB1R w KQkq -
+QGD: Semi-Tarrasch, San Sebastian variation
+rnb1k2r/ppp1qppp/5n2/2p1P3/3p4/5N1P/PPP1BPP1/R1BQK2R b KQkq -
+two knights defense: Mar\'oczy variation *
+rnb1k2r/ppp1qppp/5n2/3P4/1bBp4/2P2N2/PP3PPP/RNBQK2R w KQkq -
+Bishop's opening: Urusov gambit, Panov variation
+rnb1k2r/ppp2p1p/4pp2/q7/1b1P4/2N5/PPPQ1PPP/R3KBNR w KQkq -
+French: MacCutcheon, Bogolyubov variation
+rnb1k2r/ppp2p1p/5n2/3qN3/1b1P1ppP/2N5/PPP2KP1/R1BQ1B1R b kq -
+KGA: Kieseritsky, Brentano defense, Kaplanek variation
+rnb1k2r/ppp2ppp/1b6/3qp3/1PP5/P2P4/5PPP/R1BQKBNR b KQkq -
+Ruy Lopez: Noah's ark trap *
+rnb1k2r/ppp2ppp/3b4/3qp3/8/3P4/PPP2PPP/R1BQKBNR w KQkq -
+Scotch: Ghulam Kassim variation *
+rnb1k2r/ppp2ppp/5n2/3qp3/1b6/2NP4/PP1QPPPP/R1B1KBNR b KQkq -
+Sicilian: Chekhover, Zaitsev variation *
+rnb1k2r/ppp2ppp/8/2bPp3/2B3nq/2N4N/PPPP1PPP/R1BQK2R w KQkq -
+Scotch gambit: Vitzhum attack *
+rnb1k2r/ppp2ppp/8/3Pp3/2qP4/2N3P1/PPP2K1P/R1BQ3R b kq -
+Scotch gambit: Cochrane-Shumov defense *
+rnb1k2r/ppp2ppp/8/3np3/8/P1P5/1PPB1PPP/R3KBNR b KQkq -
+Ruy Lopez: exchange, Alekhine variation *
+rnb1k2r/ppp2ppp/8/3q4/4nP2/8/PPPNQbPP/RNBK1B1R b kq -
+KGD: Falkbeer, Alapin variation
+rnb1k2r/ppp3p1/3q1n2/2bppP1p/6P1/3P3P/PPP2PB1/RNBQK1NR w KQkq -
+KGA: Philidor gambit, Schultz variation *
+rnb1k2r/pppnqppp/4p3/1N1pP3/3P4/8/PPP2PPP/R2QKBNR b KQkq -
+French: classical, Alapin variation
+rnb1k2r/pppnqppp/4p3/3pP3/3P1P2/2N5/PPP3PP/R2QKBNR b KQkq -
+French: classical, Steinitz variation
+rnb1k2r/pppnqppp/4p3/3pP3/3P2Q1/2N5/PPP2PPP/R3KBNR b KQkq -
+French: classical, Pollock variation
+rnb1k2r/pppnqppp/4p3/3pP3/3P4/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: classical variation
+rnb1k2r/pppnqppp/4p3/3pP3/3P4/2N5/PPPQ1PPP/R3KBNR b KQkq -
+French: classical, Rubinstein variation
+rnb1k2r/pppnqppp/4p3/3pP3/3P4/2NB4/PPP2PPP/R2QK1NR b KQkq -
+French: classical, Tarrasch variation
+rnb1k2r/pppnqppp/8/2p1P3/2Bp4/5N1P/PPP2PP1/R1BQK2R w KQkq -
+two knights defense: Yankovich variation *
+rnb1k2r/pppp1ppp/3b1q2/8/N3P1n1/2P2N2/P1Q2PPP/R1B1KB1R w KQkq -
+two knights defense: Paoli variation *
+rnb1k2r/pppp1ppp/5q2/8/NP2P1n1/5N2/P4PPP/R1BQKB1R b KQkq -
+two knights defense: Blackburne variation *
+rnb1k2r/pppp1ppp/5q2/8/Nb2P1n1/2P2N2/P4PPP/1RBQKB1R b Kkq -
+two knights defense: Colman variation *
+rnb1k2r/pppp1ppp/5q2/8/Nb2P1n1/2P2N2/P4PPP/R1BQKB1R w KQkq -
+two knights defense: Bogolyubov variation *
+rnb1k2r/ppppnpbp/8/6p1/2BPPp1q/2N3P1/PPP4P/R1BQ1KNR b kq -
+KGA: bishop's gambit, McDonnell attack
+rnb1k2r/ppppnpbp/8/6p1/2BPPp1q/2N5/PPP3PP/R1BQ1KNR w kq -
+KGA: bishop's gambit, classical defense
+rnb1k2r/ppppqppp/4pn2/8/1bPP4/5N2/PP1BPPPP/RN1QKB1R w KQkq -
+Bogo-Indian defense, Nimzovich variation
+rnb1k2r/ppppqppp/5n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R w KQkq -
+Ruy Lopez: Wormald (Alapin) attack *
+rnb1kb1N/ppp3pp/5n2/3p4/2B1p3/8/PPPP1PqP/RNBQKR2 w Qkq -
+Latvian: Behting variation
+rnb1kb1r/1p3ppp/p2ppn2/6B1/3NPP2/q1N5/P1PQ2PP/1R2KB1R w Kkq -
+Sicilian: Najdorf, Poisoned pawn variation
+rnb1kb1r/1p3ppp/pq1ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+Sicilian: Najdorf, 7...Qb6
+rnb1kb1r/1pq2ppp/p2ppn2/8/3NP3/2N5/PPP1BPPP/R1BQ1RK1 w kq -
+Sicilian: Scheveningen (Paulsen), classical variation
+rnb1kb1r/2q2ppp/p3pn2/1p2P1B1/3N4/2N5/PPP1Q1PP/R3KB1R b KQkq -
+Sicilian: Najdorf, Polugayevsky, Simagin variation
+rnb1kb1r/pp1p1ppp/2p2n2/q3p3/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+Ponziani: Leonhardt variation *
+rnb1kb1r/pp1p1ppp/2p2n2/q3p3/3PP3/2N2P2/PPP3PP/R1BQKBNR b KQkq -
+Ponziani: Steinitz variation *
+rnb1kb1r/pp1p1ppp/2p2n2/q3p3/3PP3/2N5/PPPB1PPP/R2QKBNR b KQkq -
+Ponziani: Caro variation *
+rnb1kb1r/pp1p2pp/2p2n2/q3p1B1/2B1P3/8/PPP2PPP/RN1QK1NR w KQkq -
+KGD: classical, Marshall attack *
+rnb1kb1r/pp1ppppp/5n2/q1pP4/8/2N5/PPP1PPPP/R1BQKBNR w KQkq -
+Woozle defense
+rnb1kb1r/pp2pppp/1qp2n2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD Slav: S\"uchting variation
+rnb1kb1r/pp2pppp/5n2/q1Pp4/8/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+QGA: Mannheim variation *
+rnb1kb1r/pp3pp1/2p1pq1p/3p4/2PP4/1QN2N2/PP2PPPP/R3KB1R b KQkq -
+QGD/QGD semi-Slav: Hastings variation
+rnb1kb1r/pp3ppp/1q2pn2/2pP2B1/3P4/2N5/PP2PPPP/R2QKBNR w KQkq -
+QGD: Canal (Venice) variation
+rnb1kb1r/ppp1pppp/5n2/8/3q4/2N2N2/PPPPQ1PP/R1B1KB1R b KQkq -
+Queen's pawn: Englund gambit *
+rnb1kb1r/ppp1q1pp/5n2/4Np2/2Bp1B2/8/PPP2PPP/RN1QK2R b KQkq -
+KGD: Falkbeer, main line, 7...Bf5 *
+rnb1kb1r/ppp1q2p/5n2/4Npp1/2Bp1B2/8/PPP2PPP/RN1Q1RK1 b kq -
+KGD: Falkbeer, Tarrasch variation *
+rnb1kb1r/ppp1qppp/5n2/3PN3/4p3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov: modern attack, Steinitz variation *
+rnb1kb1r/ppp1qppp/8/3n4/2N1p3/2N5/PPPP1PPP/R1BQKB1R b KQkq -
+Petrov: modern attack, Bardeleben variation *
+rnb1kb1r/ppp2p1p/3p3n/4N3/2BPPppq/8/PPP3PP/RNBQ1K1R w kq -
+KGA: Salvio gambit, Anderssen counter-attack
+rnb1kb1r/ppp2ppp/5n2/3qN3/4p3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov: modern attack, main line *
+rnb1kb1r/ppp2ppp/5n2/3qp3/8/3P4/PP2PPPP/RNBQKBNR w KQkq -
+Sicilian, Chekhover variation *
+rnb1kb1r/ppp2ppp/5n2/3qp3/8/3P4/PPPB1PPP/RN1QKBNR b KQkq -
+Philidor: Boden variation *
+rnb1kb1r/ppp2ppp/5n2/4N3/3qp3/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Nimzovich, Rellstab variation *
+rnb1kb1r/ppp2ppp/8/3NP2q/8/3P1Nn1/PPP4P/R1BQKB1R b KQkq -
+Vienna gambit, Wurzburger trap
+rnb1kb1r/ppp3pp/8/3q1p2/4nPP1/8/PPPNQ2P/R1B1KBNR b KQkq -
+KGD: Falkbeer, Charousek variation
+rnb1kb1r/pppp1p1p/7n/4N3/2BPP1pq/5p2/PPP3PP/RNBQ1K1R w kq -
+KGA: Silberschmidt gambit
+rnb1kb1r/pppp2p1/8/4pq1p/8/3B1N1P/PPPP1K2/RNBQ3R b kq -
+KGA: Allgaier, Horny defense *
+rnb1kb1r/ppppqppp/5n2/4N3/8/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: Cozio (Lasker) attack *
+rnb1kb1r/ppq1p1pp/2pp1n2/5p2/2PP4/2N3P1/PP2PPBP/R1BQK1NR w KQkq -
+Dutch: Hort-Antoshin system
+rnb1kbnr/p1pp1ppp/8/1p6/2B1Pp1q/8/PPPP2PP/RNBQ1KNR w kq -
+KGA: bishop's gambit, Bryan counter-gambit
+rnb1kbnr/pp1ppppp/8/q1p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian: Stiletto (Althouse) variation
+rnb1kbnr/pp2pppp/1qp5/3p4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+Caro-Kann: Edinburgh variation
+rnb1kbnr/pp2pppp/8/3q4/1p6/P7/1BPP1PPP/RN1QKBNR b KQkq -
+Sicilian: wing gambit, Marienbad variation
+rnb1kbnr/pp3ppp/2p1q3/4p3/8/2N5/PPPPBPPP/R1BQK1NR b KQkq -
+Center game: Charousek variation *
+rnb1kbnr/ppp1pp1p/3q4/3p2p1/5P2/4P3/PPPP2PP/RNBQKBNR w KQkq -
+Dutch, Von Pretzel gambit *
+rnb1kbnr/ppp1pppp/3q4/3p4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch, Manhattan (Alapin, Ulvestad) variation *
+rnb1kbnr/ppp1pppp/3q4/8/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Scandinavian: Pytel-Wade variation
+rnb1kbnr/ppp1pppp/8/q7/1P6/2N5/P1PP1PPP/R1BQKBNR b KQkq -
+Scandinavian, Mieses-Kotr\v c gambit
+rnb1kbnr/ppp1q1pp/3p4/4Pp2/3p4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+KGD: Falkbeer, R\'eti variation *
+rnb1kbnr/ppp1q1pp/8/4Np2/3p4/8/PPP2PPP/RNBQKB1R w KQkq -
+KGD: Falkbeer, Charousek gambit *
+rnb1kbnr/ppp2p1p/8/3B2p1/4Pp1q/6P1/PPPP3P/RNBQ1KNR b kq -
+KGA: bishop's gambit, Chigorin's attack (Gifford variation)
+rnb1kbnr/ppp2ppp/4p3/3q4/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+French: Frere (Becker) variation
+rnb1kbnr/ppp2ppp/4q3/4p3/5P2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Center game: l'Hermet variation *
+rnb1kbnr/ppp2ppp/4q3/4p3/8/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Center game: Berger variation *
+rnb1kbnr/ppp2ppp/4q3/4p3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Center game: Paulsen attack *
+rnb1kbnr/ppp2ppp/8/2q1p3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Center game: Hall variation *
+rnb1kbnr/ppp2ppp/8/3p2q1/2PPp3/4P3/PP3PPP/RNBQKBNR w KQkq -
+French: advance, Nimzovich variation *
+rnb1kbnr/ppp2ppp/8/3qp3/8/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Center game *
+rnb1kbnr/ppp2ppp/8/3qp3/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+Center game *
+rnb1kbnr/ppp2ppp/8/q3p3/3P4/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+Scandinavian: Anderssen counter-attack, Goteborg system
+rnb1kbnr/ppp2ppp/8/q3p3/3P4/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Scandinavian: Anderssen counter-attack
+rnb1kbnr/ppp3pp/3p1q2/8/3Pp3/4N3/PPP2PPP/RNBQKB1R b KQkq -
+Latvian: Nimzovich variation
+rnb1kbnr/pppp1B1p/8/4q3/5p2/5Q2/PPPP2PP/RNB2RK1 b kq -
+KGA: double Muzio gambit
+rnb1kbnr/pppp1p1p/8/4N3/2B1P1pq/5p2/PPPP2PP/RNBQ1K1R w kq -
+KGA: Cochrane gambit
+rnb1kbnr/pppp1p1p/8/6p1/2B1Pp1q/5Q2/PPPP2PP/RNB2KNR b kq -
+KGA: bishop's gambit, classical defense, Cozio attack
+rnb1kbnr/pppp1p1p/8/6p1/2B1Pp1q/8/PPPP2PP/RNBQ1KNR w kq -
+KGA: bishop's gambit, classical defense
+rnb1kbnr/pppp1ppp/5q2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Greco defense
+rnb1kbnr/pppp1ppp/5q2/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: Napoleon's opening *
+rnb1kbnr/pppp1ppp/5q2/4p3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: Norwalde variation
+rnb1kbnr/pppp1ppp/8/4p3/4P2q/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: Patzer opening *
+rnb1kbnr/pppp2pp/5q2/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Breyer gambit *
+rnb1kbnr/ppppq1pp/8/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Carrera (Basman) gambit *
+rnb1kbnr/ppppq2p/8/4Np2/2BPPppP/8/PPP3P1/RNBQK2R b KQkq -
+KGA: Kieseritsky, Salvio defense, Cozio variation
+rnb1kbnr/ppppqp1p/8/4N3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Salvio (Rosenthal) defense
+rnb1kbnr/ppppqp1p/8/8/2B1Pp2/5Q2/PPPP2PP/RNB2RK1 w kq -
+KGA: Muzio gambit, From defense
+rnb1kbnr/ppppqp1p/8/8/2B1Ppp1/5N2/PPPP2PP/RNBQ1RK1 w kq -
+KGA: Muzio gambit, Kling and Horwitz counter-attack
+rnb1kbnr/ppppqppp/8/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Gunderam defense
+rnb1kbnr/ppppqppp/8/4p3/4PP2/6P1/PPPP3P/RNBQKBNR w KQkq -
+KGD: Keene's defense
+rnb1kbnr/ppppqppp/8/4p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French: Chigorin variation *
+rnb1kbnr/ppppqppp/8/8/2B1P3/8/PB3PPP/RN1QK1NR w KQkq -
+Danish gambit: Collijn defense
+rnb1kbnr/ppq1pppp/8/2p1N3/4p3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Budapest: Fajarowicz, Steiner variation *
+rnb1kbnr/ppq1pppp/8/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+Queen's pawn: Mengarini attack *
+rnb1kbnr/ppqppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian: Quinteros variation
+rnb1qrk1/pp2b1pp/2p1pn2/3p1pB1/2PP4/2N2NP1/PPQ1PPBP/R4RK1 b - -
+Dutch: stonewall: Chekhover variation
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/1PN2NP1/P3PPBP/R1BQ1RK1 b - -
+Dutch: Ilyin-Genevsky variation with b3
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+Dutch: Ilyin-Genevsky variation
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/2N2NP1/PP2PPBP/R1BQR1K1 b - -
+Dutch: Ilyin-Genevsky, Winter variation
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/2N2NP1/PPQ1PPBP/R1B2RK1 b - -
+Dutch: Ilyin-Genevsky variation with Qc2
+rnb1r1k1/ppp2ppp/1b6/3qp3/1PP5/P2P1N2/4BPPP/R1BQK2R b KQ -
+Ruy Lopez: Noah's ark trap *
+rnb2bnr/pppp1k1p/5q2/8/4Pp2/2N1BQ2/PPP3PP/R4RK1 b - -
+KGA: Lolli gambit, Young variation
+rnb2knr/pppp2pp/5q2/2b1pP1Q/6P1/8/PPPP1P1P/RNB1KBNR w KQ -
+KGA: bishop's gambit, classical defense, Cozio attack *
+rnb2rk1/p1p1qppp/1p3n2/8/4p3/2P5/PNPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Berlin defense, Pillsbury variation *
+rnb2rk1/p1pqppbp/1p4p1/8/2BPP3/2P5/P3NPPP/R1BQ1RK1 w - -
+Gr\"unfeld: exchange, Larsen variation
+rnb2rk1/p1q1ppbp/1p3np1/2pp4/3P4/2P1PN2/PP1NBPPP/R1BQ1RK1 w - -
+Catalan: closed, Qc2 & b3 *
+rnb2rk1/p4ppp/1qp2n2/2bPp3/B7/2NP4/PPP2PPP/R1BQK1NR w KQ -
+Evans gambit: Waller attack *
+rnb2rk1/pp2ppbp/2pp1np1/q7/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, Kavalek (Bronstein) variation
+rnb2rk1/pp2qppp/1b2pn2/3p4/1PP5/P3PN2/1B3PPP/RN1QKB1R b KQ -
+QGA: classical, 8...Bb7 *
+rnb2rk1/pp2qppp/1b3n2/2p1N3/1P1Pp3/P1N1B3/2P1BPPP/R2QK2R w KQ -
+Ruy Lopez: open, Howell attack, Adam variation *
+rnb2rk1/pp2qppp/4pn2/2bp4/1PP5/P3PN2/5PPP/RNBQKB1R b KQ -
+QGA: classical, 7...b5 *
+rnb2rk1/pp2qppp/4pn2/2bp4/2P5/P3PN2/1P3PPP/RNBQKB1R w KQ -
+QGA: classical, 7.Qe2 *
+rnb2rk1/pp2qppp/4pn2/2p5/1bBP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, Gligori\'c system, Smyslov variation
+rnb2rk1/pp2qppp/5n2/2b5/1PB1p3/P1N1PN2/5PPP/R1BQK2R w KQ -
+QGA: classical, Furman variation *
+rnb2rk1/pp2qppp/5n2/2p5/4p3/2P5/PNPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Berlin defense, Zukertort variation *
+rnb2rk1/pp3ppp/1bpq1n2/4N3/1PBPp3/P1N1B3/2P2PPP/R2QK2R w KQ -
+Ruy Lopez: open, Motzko attack *
+rnb2rk1/pp3ppp/1bpq1n2/4N3/1PBPp3/P3B3/2P1NPPP/R2QK2R b KQ -
+Ruy Lopez: open, Motzko attack, Nenarokov variation *
+rnb2rk1/ppB1ppbp/6p1/3q4/3P4/4P3/PP3PPP/R2QKBNR b KQ -
+Gr\"unfeld: Gr\"unfeld gambit accepted
+rnb2rk1/ppp1qpp1/4p2p/3P4/3P4/2P1PN2/P4PPP/R2QKB1R b KQ -
+QGD: Lasker defense, main line
+rnb2rk1/ppp1qpp1/4p2p/3p4/2PPn3/2N1PN2/PPQ2PPP/R3KB1R b KQ -
+QGD: Lasker defense, Teichmann variation
+rnb2rk1/ppp1qppp/1b3n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R w KQ -
+Ruy Lopez: open, Howell attack *
+rnb2rk1/ppp1qppp/5n2/3pN3/1b1PP3/2N5/PPP1BPPP/R1BQK2R b KQ -
+Ruy Lopez: Berlin defense, Trifunovi\'c variation *
+rnb2rk1/ppp1qppp/5n2/8/4pN2/2P5/P1PPBPPP/R1BQK2R b KQ -
+Ruy Lopez: Berlin defense, Cordel variation *
+rnb2rk1/ppp1qppp/8/3n4/4p3/2P5/PNPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Berlin defense, Winawer attack *
+rnb2rk1/ppp2pbp/3p2p1/3Pp3/2n1P2Q/2N2P2/PP2K2P/R5NR w - -
+King's Indian: S\"amisch, orthodox, Bronstein variation
+rnb2rk1/ppp2pp1/3q3p/3p4/3P4/1QP1PN2/P4PPP/R3KB1R w KQ -
+QGD: Lasker defense, Bernstein variation
+rnb2rk1/pppp2pp/5q2/2b1pP2/8/2N5/PPPP1P1P/R1BQKBNR b KQ -
+KGA: Muzio gambit, Holloway defense *
+rnb2rk1/pppp2pp/5q2/2b1pP2/8/8/PPPPQP1P/RNB1KBNR b KQ -
+KGA: Muzio gambit, From defense *
+rnb2rk1/pppp2pp/5q2/5P2/4Q3/8/PPPP1b1P/RNB1KBNR w KQ -
+KGA: double Muzio gambit *
+rnb2rk1/ppppqppp/1b3n2/4p3/1P2P3/P1N2N2/2PPBPPP/R1BQ1RK1 b - -
+Ruy Lopez: Worrall attack, sharp line *
+rnb2rk1/ppppqppp/1b3n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQK2R b KQ -
+Ruy Lopez: Worrall attack, solid line *
+rnb2rk1/ppppqppp/5n2/b3N3/4P3/P1N5/1PPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, Tartakower variation *
+rnb2rk1/ppppqppp/5n2/b3p3/4P3/P1N2N2/1PPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Worrall attack *
+rnb2rk1/ppq1ppbp/5np1/2pp4/3P4/4PN2/PPPNBPPP/R1BQ1RK1 w - -
+Catalan: closed, 7.Qc2 *
+rnbk1b1r/pppnqBpp/8/4Np2/3Q4/8/PPP2PPP/RNB1K2R w KQ -
+KGD: Falkbeer, Alapin variation *
+rnbk1bnr/pppp2pp/8/8/2B1pp1q/2N5/PPPPQ1PP/R1BK2NR w - -
+KGA: L\'opez-Gianutio counter-gambit, Hein variation
+rnbq1bnr/ppp3k1/7p/3B4/3PPppP/8/PPP3P1/RNBQK2R b KQ -
+KGA: Allgaier, Urusov attack
+rnbq1bnr/ppp3k1/7p/4B3/2BPp1pP/8/PPP3P1/RN1QK2R b KQ -
+KGA: Allgaier, Cook variation
+rnbq1bnr/pppp1k2/7p/8/2B1PppP/8/PPPP2P1/RNBQK2R b KQ -
+KGA: Allgaier, Walker attack
+rnbq1bnr/pppp1k2/7p/8/3PPppP/8/PPP3P1/RNBQKB1R b KQ -
+KGA: Allgaier, Thorold variation
+rnbq1bnr/pppp1k2/7p/8/4PppP/2N5/PPPP2P1/R1BQKB1R b KQ -
+KGA: Allgaier, Blackburne gambit
+rnbq1bnr/pppp1kpp/8/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQ -
+KGA: Tumbleweed gambit *
+rnbq1bnr/pppppkpp/5p2/8/3PP3/8/PPP2PPP/RNBQKBNR w KQ -
+Fried fox defense
+rnbq1bnr/pppppkpp/5p2/8/4P3/8/PPPP1PPP/RNBQKBNR w KQ -
+Hammerschlag (Fried fox/Pork chop opening) *
+rnbq1k1r/pp3ppp/5n2/1Bbpp3/8/2N2N2/PPPP1PPP/R1BQK2R w KQ -
+Giuoco Piano: Cracow variation *
+rnbq1k1r/ppp2Bpp/8/4N2Q/1b1Pp3/2n5/PPP2PPP/R1B1K2R b KQ -
+Two knights defense, Keidanz variation *
+rnbq1k1r/ppp2pp1/4p2p/3pP3/3Pn1Q1/2P5/P1P2PPP/R1B1KBNR b KQ -
+French: MacCutcheon, Duras variation
+rnbq1k1r/ppp3pp/5P2/2bpp1PQ/4n3/7N/PPPP1P1P/RNB1KB1R b KQ -
+KGA: Silberschmidt gambit *
+rnbq1k1r/ppp3pp/8/2bppPPQ/4n3/3P3N/PPP2P1P/RNB1KB1R b KQ -
+KGA: Salvio gambit, Anderssen counter-attack *
+rnbq1k1r/pppp2pp/5P2/2b1p1PQ/4n3/8/PPPP1P1P/RNB1KBNR b KQ -
+KGA: Cochrane gambit *
+rnbq1k1r/pppp2pp/8/2b1pPPQ/4n3/2N5/PPPP1P1P/R1B1KBNR b KQ -
+KGA: Herzfeld gambit *
+rnbq1knr/pppp2pp/8/2b1pP1Q/1P6/8/P1PP1PPP/RNB1KBNR b KQ -
+KGA: bishop's gambit, Bryan counter-gambit *
+rnbq1knr/pppp2pp/8/2b1pP1Q/2B5/8/PPPP1PPP/RNB1K1NR b KQ -
+KGA: bishop's gambit, Greco variation *
+rnbq1knr/pppp2pp/8/2b1pP1Q/6P1/8/PPPP1P1P/RNB1KBNR b KQ -
+KGA: bishop's gambit, classical defense *
+rnbq1knr/pppp2pp/8/2b1pP1Q/8/2N5/PPPP1PPP/R1B1KBNR b KQ -
+KGA: bishop's gambit, Boden defense *
+rnbq1knr/pppp2pp/8/4pP1Q/3b4/3B4/PPP2PPP/RNB1K1NR b KQ -
+KGA: bishop's gambit, Bor\'en-Svenonius variation *
+rnbq1knr/pppp3p/6p1/4pP1Q/3b2P1/8/PPP2P1P/RNB1KBNR w KQ -
+KGA: bishop's gambit, Chigorin's attack (Gifford variation) *
+rnbq1r1k/p1p4P/5n2/2bpp2B/8/8/PPPP1PPP/RNBQK1NR w KQ -
+Bishop's opening: Four pawns' gambit *
+rnbq1r1k/pppp3P/5n2/2b1p2B/8/8/PPPP1PPP/RNBQK1NR w KQ -
+KGA: Cunningham, three pawns gambit *
+rnbq1rk1/1p2ppbp/p1pp1np1/8/2PPP3/2NBBP2/PP4PP/R2QK1NR w KQ -
+King's Indian: S\"amisch, Byrne variation
+rnbq1rk1/1p3pbp/p2p1np1/2pP4/P3P3/2N2N2/1P2BPPP/R1BQ1RK1 b - -
+Benoni: classical, 9...a6, 10.a4
+rnbq1rk1/1p3ppp/4pn2/p1bp4/2P5/P3PN2/1P3PPP/RNBQKB1R w KQ -
+QGA: classical, Rubinstein variation *
+rnbq1rk1/1pp1ppbp/p4np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Russian, Alekhine (Hungarian) variation
+rnbq1rk1/1pp2pbp/3p1np1/p2Pp3/2P1P3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+King's Indian: Petrosian system, Stein variation
+rnbq1rk1/1pp2ppp/1b3n2/p2NN3/1P1PP3/P7/2P2PPP/R1BQKB1R b KQ -
+Ruy Lopez: open, Schlechter defense *
+rnbq1rk1/1ppp1ppp/1b3n2/p3p3/1P2P3/P1N2N2/2PPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Wing attack *
+rnbq1rk1/2p1bppp/p2p1n2/1p2p3/3PP3/1BP2N1P/PP3PP1/RNBQR1K1 b - -
+Ruy Lopez: closed, Breyer, 10.d4
+rnbq1rk1/2p1bppp/p2p1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Breyer defense
+rnbq1rk1/p1p1bpp1/1p2p2p/3n4/3P3B/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QGD: Tartakower (Makagonov-Bondarevsky) system, 8.cd Nxd5
+rnbq1rk1/p1p1bpp1/1p2pn1p/3p4/2PP3B/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QGD: Tartakower (Makagonov-Bondarevsky) system
+rnbq1rk1/p1p1ppbp/1p1p1np1/8/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+King's Indian: S\"amisch, double fianchetto variation
+rnbq1rk1/p1p1ppbp/1p3np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Russian, Levenfish variation
+rnbq1rk1/p1p1ppbp/1p4p1/8/2BPP3/2P5/P3NPPP/R1BQK2R w KQ -
+Gr\"unfeld: exchange, Simagin's lesser variation
+rnbq1rk1/p1p2ppp/1p2pn2/3p4/1bPP4/2NBPN2/PP3PPP/R1BQK2R w KQ -
+Nimzo-Indian: 4.e3, main line with ...b6
+rnbq1rk1/p1pp1ppp/4pn2/1p6/2PP4/P1Q5/1P2PPPP/R1B1KBNR w KQ -
+Nimzo-Indian: classical, Adorjan gambit
+rnbq1rk1/p1pp1ppp/5n2/1p1Np3/1bB1P3/8/PPPP1PPP/R1BQK1NR w KQ -
+Ruy Lopez: classical defense, Zaitsev variation *
+rnbq1rk1/p2p1ppp/2p2n2/2b1p3/B3P3/2N5/PPPP1PPP/R1BQK1NR w KQ -
+Evans gambit *
+rnbq1rk1/p2p1ppp/2p2n2/2b1p3/B3P3/2NP4/PPP2PPP/R1BQK1NR b KQ -
+Evans gambit *
+rnbq1rk1/p3ppbp/1p3np1/2pp4/3P1P2/4PN2/PPP1B1PP/RNBQ1RK1 w - -
+Dutch: stonewall, Botwinnik variation *
+rnbq1rk1/p3ppbp/1p3np1/2pp4/8/1P2PN2/PBPPBPPP/RN1Q1RK1 w - -
+Queen's Indian: Euwe variation *
+rnbq1rk1/p4ppp/1p2pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, Keres variation
+rnbq1rk1/p4ppp/2P2n2/2b1p3/B7/2N5/PPPP1PPP/R1BQK1NR b KQ -
+Evans gambit: compromised defense *
+rnbq1rk1/p4ppp/2p2n2/2bpp1B1/B3P3/2NP4/PPP2PPP/R2QK1NR b KQ -
+Evans gambit: Alapin-Steinitz variation *
+rnbq1rk1/p4ppp/2p2n2/2bpp3/4P3/1BNP4/PPP2PPP/R1BQK1NR b KQ -
+Evans gambit: Lasker defense *
+rnbq1rk1/p4ppp/2p2n2/2bpp3/B3P3/2NP4/PPPB1PPP/R2QK1NR b KQ -
+Evans gambit: Sanders-Alapin variation *
+rnbq1rk1/p4ppp/2p5/2bpp3/B3n3/2N2N2/PPPP1PPP/R1BQ1RK1 w - -
+Evans gambit: Richardson attack *
+rnbq1rk1/p4ppp/5n2/2bpp3/8/1BNP4/PPP2PPP/R1BQK1NR b KQ -
+Evans gambit: normal variation *
+rnbq1rk1/pp1p1ppp/2p2n2/b7/4PB2/P1NP4/1PP3PP/R2QKBNR w KQ -
+Ruy Lopez: Siesta, Kopayev variation *
+rnbq1rk1/pp1p1ppp/4pn2/2P5/1bP5/2N5/PPQ1PPPP/R1B1KBNR w KQ -
+Nimzo-Indian: classical, Pir\'c variation
+rnbq1rk1/pp1pppbp/5np1/2p5/3P4/4PN2/PPP1BPPP/RNBQK2R w KQ -
+English: Neo-Catalan declined *
+rnbq1rk1/pp2b1pp/2p1pn2/3p1p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+Dutch: stonewall with Nc3
+rnbq1rk1/pp2b1pp/2p1pn2/3p1p2/2PP4/BP3NP1/P3PPBP/RN1Q1RK1 b - -
+Dutch: stonewall with Ba3
+rnbq1rk1/pp2p1bp/2pp1np1/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+Dutch: Leningrad, main variation with c6
+rnbq1rk1/pp2ppbp/2p2np1/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.O-O c6
+rnbq1rk1/pp2ppbp/2p2np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Russian, Szabo (Boleslavsky) variation
+rnbq1rk1/pp2ppbp/3p1np1/2p3B1/2PPP3/2N5/PP2BPPP/R2QK1NR w KQ -
+King's Indian: Averbakh, 6...c5
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+King's Indian: fianchetto, Yugoslav, 7.O-O
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+King's Indian: fianchetto, Yugoslav system
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PPPP2/2N2N2/PP2B1PP/R1BQK2R b KQ -
+King's Indian: Four pawns attack, with Be2 and Nf3
+rnbq1rk1/pp2ppbp/3p1np1/2pP4/2P1PP2/2N2N2/PP4PP/R1BQKB1R b KQ -
+King's Indian: Four pawns attack, dynamic line
+rnbq1rk1/pp2ppbp/3p1np1/8/3NP3/2N1BP2/PPP3PP/R2QKB1R w KQ -
+Sicilian: dragon, Yugoslav attack, 7...O-O
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P1P2/4PN2/PPP1B1PP/RNBQ1RK1 b - -
+Dutch: stonewall variation *
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/2P2NP1/PP2PPBP/RNBQ1RK1 b - -
+Neo-Gr\"unfeld, 6.O-O c6 *
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/4PN2/PPPNBPPP/R1BQ1RK1 b - -
+Catalan: closed, 6...Nbd7 *
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.O-O *
+rnbq1rk1/pp2ppbp/5np1/2pp4/5P2/3PPN2/PPP1B1PP/RNBQ1RK1 b - -
+Dutch: classical variation *
+rnbq1rk1/pp2ppbp/5np1/2pp4/8/1P2PN2/PBPPBPPP/RN1QK2R w KQ -
+Queen's Indian: old main line, 6.O-O *
+rnbq1rk1/pp2ppbp/5np1/2ppN3/5P2/4P3/PPPPB1PP/RNBQ1RK1 b - -
+Dutch defense, Alekhine variation *
+rnbq1rk1/pp2ppbp/5np1/3p4/3N4/6P1/PPP1PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O *
+rnbq1rk1/pp2ppbp/5np1/3p4/3P4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+Neo-Gr\"unfeld, 6.O-O, main line *
+rnbq1rk1/pp2ppbp/5np1/3p4/3P4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.O-O, main line
+rnbq1rk1/pp2ppbp/5np1/3p4/8/1N4P1/PPP1PPBP/RNBQ1RK1 b - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O Nb6 *
+rnbq1rk1/pp2ppbp/5np1/8/2pN4/6P1/PP2PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O c5, 8.dc *
+rnbq1rk1/pp2ppbp/6p1/2Pn4/8/5NP1/PP2PPBP/RNBQ1RK1 b - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O c5, 8.dc
+rnbq1rk1/pp2ppbp/6p1/2p5/2BPP3/2P5/P3NPPP/R1BQK2R w KQ -
+Gr\"unfeld: exchange, Spassky variation
+rnbq1rk1/pp2ppbp/6p1/2pn4/3P4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O c5, 8.Nc3
+rnbq1rk1/pp3pbp/2pp1np1/3Pp3/2P1P3/2N1BP2/PP4PP/R2QKBNR w KQ -
+King's Indian: S\"amisch, orthodox, 7.d5 c6
+rnbq1rk1/pp3pbp/2pp1np1/4p3/2PPP3/2N1BP2/PP2N1PP/R2QKB1R w KQ -
+King's Indian: S\"amisch, orthodox, 7.Nge2 c6
+rnbq1rk1/pp3pbp/2pp1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+King's Indian: orthodox, Donner variation
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+Benoni: classical, 9.O-O
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+Benoni: classical without 9.O-O
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4PP2/2N2N2/PP4PP/R1BQKB1R w KQ -
+Benoni: four pawns attack
+rnbq1rk1/pp3pbp/3p1np1/2pP4/8/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+Benoni: fianchetto variation
+rnbq1rk1/pp3pbp/3p1np1/2ppP3/2P2P2/2N2N2/PP2B1PP/R1BQK2R b KQ -
+King's Indian: Four pawns attack, Florentine gambit
+rnbq1rk1/pp3pbp/3p1np1/3pp3/2P1P3/2N1BP2/PP2N1PP/R2QKB1R w KQ -
+King's Indian: S\"amisch, orthodox main line
+rnbq1rk1/pp3pbp/3ppnp1/2pP2B1/2P1P3/2N5/PP2BPPP/R2QK1NR w KQ -
+King's Indian: Averbakh, main line
+rnbq1rk1/pp3pbp/3ppnp1/2pP4/2P1PP2/2N2N2/PP2B1PP/R1BQK2R b KQ -
+King's Indian: Four pawns attack
+rnbq1rk1/pp3ppp/1b3n2/2ppN3/1P1PP3/P1N5/2P2PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, Harksen gambit *
+rnbq1rk1/pp3ppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P1BPPP/R2QK2R b KQ -
+Ruy Lopez: open, classical defense *
+rnbq1rk1/pp3ppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R w KQ -
+Ruy Lopez: open, 9.c3 *
+rnbq1rk1/pp3ppp/1bp2n2/4N3/1PBPp3/P1N1B3/2P2PPP/R2QK2R b KQ -
+Ruy Lopez: open, Italian variation *
+rnbq1rk1/pp3ppp/1bp2n2/8/1PNPp3/P1N1B3/2P2PPP/R2QKB1R b KQ -
+Ruy Lopez: open, Berlin variation *
+rnbq1rk1/pp3ppp/2p2n2/2bP2N1/2B1p3/2N5/PPPP1PPP/R1BQK2R w KQ -
+two knights: Max Lange attack, Krause variation *
+rnbq1rk1/pp3ppp/2p2n2/2bPp1B1/2B5/2NP4/PPP2PPP/R2QK1NR b KQ -
+Scotch gambit: Anderssen (Paulsen, Suhle) counter-attack *
+rnbq1rk1/pp3ppp/2p2n2/3pp3/1b2P3/1BN2N2/PPPP1PPP/R1BQ1RK1 b - -
+Ruy Lopez: classical defense, Benelux variation *
+rnbq1rk1/pp3ppp/2p2n2/3pp3/2P5/2NP1N2/PP1QPPPP/R3KB1R w KQ -
+Sicilian: Canal-Sokolsky attack, Bronstein gambit *
+rnbq1rk1/pp3ppp/2p2n2/b2PN3/4p3/P1N5/1PPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: closed, Basque gambit (North Spanish variation) *
+rnbq1rk1/pp3ppp/3b1n2/2ppN1B1/3P4/3B4/PPP2PPP/RN1Q1RK1 b - -
+Petrov: classical attack, Tarrasch variation *
+rnbq1rk1/pp3ppp/3b1n2/2ppN3/3P4/2N5/PPP1BPPP/R1BQK2R w KQ -
+Petrov: classical attack, Jaenisch variation *
+rnbq1rk1/pp3ppp/3b4/2pnp3/8/P2PPNP1/1P3P1P/RNBQKB1R b KQ -
+Sicilian: Kan, Gipslis variation *
+rnbq1rk1/pp3ppp/3b4/2ppN3/3PB3/8/PPP2PPP/RNBQ1RK1 b - -
+Petrov: modern attack, Trifunovi\'c variation *
+rnbq1rk1/pp3ppp/4p3/1B6/3PP3/5N2/P2Q1PPP/R3K2R b KQ -
+QGD: Semi-Tarrasch, Kmoch variation
+rnbq1rk1/pp3ppp/4p3/2pn4/3P4/P1P1PP2/6PP/R1BQKBNR w KQ -
+Nimzo-Indian: S\"amisch, Botvinnik variation
+rnbq1rk1/pp3ppp/4pn2/2bP4/8/4PN2/PP3PPP/RNBQKB1R b KQ -
+QGA: classical, Steinitz variation *
+rnbq1rk1/pp3ppp/4pn2/2bp4/2P5/4PN2/PP3PPP/RNBQKB1R w KQ -
+QGA: classical variation, 6.O-O *
+rnbq1rk1/pp3ppp/4pn2/2bp4/2P5/P3PN2/1P3PPP/RNBQKB1R b KQ -
+QGA: classical, 6...a6 *
+rnbq1rk1/pp3ppp/4pn2/2p5/1bBP4/2N1PN2/PP3PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, Gligori\'c system with 7...dc
+rnbq1rk1/pp3ppp/4pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQK2R w KQ -
+Nimzo-Indian: 4.e3, main line with ...c5
+rnbq1rk1/pp3ppp/5n2/2bpp3/2P5/P3PN2/1P3PPP/RNBQKB1R w KQ -
+QGA: classical, Geller variation *
+rnbq1rk1/pp4pp/2p5/2bppp2/3PP1n1/2P4N/PP1NBPPP/R1BQ1RK1 b - -
+Philidor: Hanham, Berger variation *
+rnbq1rk1/ppp1b1pp/3ppn2/5p2/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Dutch: classical variation
+rnbq1rk1/ppp1b1pp/4pn2/3p1p2/2PP4/1P3NP1/P3PPBP/RNBQ1RK1 b - -
+Dutch: stonewall, Botwinnik variation
+rnbq1rk1/ppp1b1pp/4pn2/3p1p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+Dutch: stonewall with Nc3
+rnbq1rk1/ppp1b1pp/4pn2/3p1p2/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Dutch: stonewall variation
+rnbq1rk1/ppp1bpp1/4p2p/3p4/2PPn2B/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QGD: Lasker defense
+rnbq1rk1/ppp1bpp1/4pB1p/3p4/2PP4/2N1PN2/PP3PPP/R2QKB1R b KQ -
+QGD: Neo-orthodox variation, 7.Bxf6
+rnbq1rk1/ppp1bpp1/4pn1p/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QGD: Neo-orthodox variation
+rnbq1rk1/ppp1bpp1/4pn1p/3p4/2PP3B/2N1PN2/PP3PPP/R2QKB1R b KQ -
+QGD: Neo-orthodox variation, 7.Bh4
+rnbq1rk1/ppp1bppp/4pn2/3p2B1/2PP4/2N1P3/PP3PPP/2RQKBNR b K -
+QGD: Anti-neo-orthodox variation
+rnbq1rk1/ppp1bppp/4pn2/3p2B1/2PP4/2N1P3/PP3PPP/R2QKBNR w KQ -
+QGD: 4.Bg5 Be7, 5.e3 O-O
+rnbq1rk1/ppp1bppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R b KQ -
+QGD: 6.Nf3
+rnbq1rk1/ppp1bppp/8/3p4/3Pn3/3B1N2/PPP2PPP/RNBQ1RK1 w - -
+Petrov: classical attack, Mason variation
+rnbq1rk1/ppp1ppbp/1n4p1/8/3P4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O Nb6
+rnbq1rk1/ppp1ppbp/3p1np1/4P3/3P1P2/2N2N2/PPP3PP/R1BQKB1R b KQ -
+Pirc: Austrian attack, 6.e5
+rnbq1rk1/ppp1ppbp/3p1np1/6B1/2PPP3/2N2N2/PP3PPP/R2QKB1R b KQ -
+King's Indian: Zinnowitz variation
+rnbq1rk1/ppp1ppbp/3p1np1/6B1/2PPP3/2N5/PP2BPPP/R2QK1NR b KQ -
+King's Indian: Averbakh system
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N1B3/PP2BPPP/R2QK1NR b KQ -
+King's Indian: Semi-Averbakh system
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N1BN2/PP3PPP/R2QKB1R b KQ -
+King's Indian: Larsen variation
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2N2/PP2BPPP/R1BQK2R b KQ -
+King's Indian: 6.Be2
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2P2/PP4PP/R1BQKBNR w KQ -
+King's Indian: S\"amisch, 5...O-O
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPPP2/2N5/PP2B1PP/R1BQK1NR b KQ -
+King's Indian: Four pawns attack, 6.Be2
+rnbq1rk1/ppp1ppbp/3p1np1/8/3PP3/6P1/PPP1NPBP/RNBQK2R b KQ -
+R\'eti: King's Indian attack, Pachman system *
+rnbq1rk1/ppp1ppbp/3p1np1/8/3PPP2/2N1BN2/PPP3PP/R2QKB1R b KQ -
+Pirc: Austrian attack, 6.Be3
+rnbq1rk1/ppp1ppbp/3p1np1/8/3PPP2/2N2N2/PPP3PP/R1BQKB1R w KQ -
+Pirc: Austrian attack
+rnbq1rk1/ppp1ppbp/3p1np1/8/3PPP2/2NB1N2/PPP3PP/R1BQK2R b KQ -
+Pirc: Austrian attack, 6.Bd3
+rnbq1rk1/ppp1ppbp/5np1/3p4/1PPP4/2N1PN2/P4PPP/R1BQKB1R b KQ -
+Gr\"unfeld: Makogonov variation
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP1B2/2N1P3/PP3PPP/2RQKBNR b K -
+Gr\"unfeld: Gr\"unfeld gambit, Capablanca variation
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP1B2/2N1P3/PP3PPP/R2QKBNR w KQ -
+Gr\"unfeld: Gr\"unfeld gambit
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP1B2/2N1PN2/PP3PPP/R2QKB1R b KQ -
+Gr\"unfeld with Bf4 & e3
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/1QN1PN2/PP3PPP/R1B1KB1R b KQ -
+Gr\"unfeld with e3 & Qb3
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/2N1PN2/PP1B1PPP/R2QKB1R b KQ -
+Gr\"unfeld: Opo\v censky variation
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/2NBPN2/PP3PPP/R1BQK2R b KQ -
+Gr\"unfeld with e3 & Bd3
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+Neo-Gr\"unfeld, 6.O-O
+rnbq1rk1/ppp1ppbp/5np1/3p4/5P2/2P3PN/PP1PP1BP/RNBQK2R b KQ -
+Dutch: Leningrad, Basman system *
+rnbq1rk1/ppp1ppbp/5np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R b KQ -
+Gr\"unfeld: Russian variation with e4
+rnbq1rk1/ppp1ppbp/6p1/3n4/3P4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O
+rnbq1rk1/ppp2pbp/3p1np1/3Pp3/2P1P3/2N1BP2/PP4PP/R2QKBNR b KQ -
+King's Indian: S\"amisch, orthodox, 7.d5
+rnbq1rk1/ppp2pbp/3p1np1/3Pp3/2P1P3/2N2N2/PP2BPPP/R1BQK2R b KQ -
+King's Indian: Petrosian system
+rnbq1rk1/ppp2pbp/3p1np1/4P3/2P1P3/2N2N2/PP2BPPP/R1BQK2R b KQ -
+King's Indian: Andersson variation
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N1BN2/PP2BPPP/R2QK2R b KQ -
+King's Indian: Gligori\'c-Taimanov system
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+King's Indian: S\"amisch, orthodox variation
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+King's Indian: orthodox variation
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+King's Indian: classical variation
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N3P1/PP2NPBP/R1BQK2R b KQ -
+King's Indian: Pomar system
+rnbq1rk1/ppp2pbp/4pnp1/3p4/2PP4/1QN1PN2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Botvinnik variation
+rnbq1rk1/ppp2ppp/1b3n2/3pN3/1P2P3/P1N5/2PP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, 7.Bb3 *
+rnbq1rk1/ppp2ppp/1b3n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R b KQ -
+Ruy Lopez: open, 8...Be6 *
+rnbq1rk1/ppp2ppp/1b3n2/4N3/1P1Pp3/P1N5/2P2PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, 8.de *
+rnbq1rk1/ppp2ppp/1b3n2/4N3/1P1Pp3/P7/2P1NPPP/R1BQKB1R b KQ -
+Ruy Lopez: open, Zukertort variation *
+rnbq1rk1/ppp2ppp/3b1n2/3pN3/3P4/8/PPP1BPPP/RNBQ1RK1 b - -
+Petrov: classical attack, Mason variation *
+rnbq1rk1/ppp2ppp/3bpn2/3p4/2PP4/P1N1P3/1P2NPPP/R1BQKB1R w KQ -
+Nimzo-Indian: Simagin variation
+rnbq1rk1/ppp2ppp/4pn2/3p4/1bPP4/2N1PN2/PP3PPP/R1BQKB1R w KQ -
+Nimzo-Indian: 4.e3 e8g8, 5.Nf3 d7d5
+rnbq1rk1/ppp2ppp/4pn2/3p4/1bPP4/2NBP3/PP3PPP/R1BQK1NR w KQ -
+Nimzo-Indian: 4.e3 O-O, 5.Bd3 d5
+rnbq1rk1/ppp2ppp/4pn2/3p4/2PP4/P1PBP3/5PPP/R1BQK1NR b KQ -
+Nimzo-Indian: 4.e3, Botvinnik system
+rnbq1rk1/ppp2ppp/5P2/2b4Q/2pp4/2P5/PP3PPP/RNB1K1NR w KQ -
+Bishop's opening: Pratt variation
+rnbq1rk1/ppp2ppp/5n2/2b1p3/4p3/2PP4/PP1NBPPP/R1BQK1NR w KQ -
+Philidor: Hanham, Steiner variation *
+rnbq1rk1/ppp2ppp/5n2/2bP2N1/2B1p3/2N5/PPPP1PPP/R1BQK2R b KQ -
+two knights: Max Lange attack, Steinitz variation *
+rnbq1rk1/ppp2ppp/5n2/2bP4/2B1p3/2N2N2/PPPP1PPP/R1BQK2R w KQ -
+two knights: Max Lange attack *
+rnbq1rk1/ppp2ppp/5n2/2bPN3/8/2N5/PPPP1PPP/R1BQKB1R b KQ -
+Two knights defense *
+rnbq1rk1/ppp2ppp/5n2/2bPp3/8/2N2N2/PPPP1PPP/R1BQKB1R w KQ -
+Two knights defense *
+rnbq1rk1/ppp2ppp/5n2/2bpp3/4P3/2PP4/PP1N1PPP/R1BQKBNR w KQ -
+Philidor: Hanham, Krause variation *
+rnbq1rk1/ppp2ppp/5n2/3Pp3/1b6/2N2N2/PPPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: Berlin defense, Nyholm attack *
+rnbq1rk1/ppp2ppp/5n2/3pN3/1b2P3/2N5/PPPPBPPP/R1BQK2R b KQ -
+Ruy Lopez: open Berlin defense, 5...Be7 *
+rnbq1rk1/ppp2ppp/5n2/3pN3/1b2P3/P1N5/1PPP1PPP/R1BQKB1R b KQ -
+Ruy Lopez: Berlin defense, Rosenthal variation *
+rnbq1rk1/ppp2ppp/5n2/3pN3/4P3/P1PP4/2P2PPP/R1BQKB1R b KQ -
+Ruy Lopez: Steinitz defense deferred, Rubinstein variation *
+rnbq1rk1/ppp2ppp/5n2/3pp1B1/4P3/P1PP1N2/2P2PPP/R2QKB1R b KQ -
+Ruy Lopez: Steinitz defense deferred, Lipnitsky variation *
+rnbq1rk1/ppp2ppp/5n2/3pp3/1b2P3/2NP4/PPPN1PPP/R1BQKB1R b KQ -
+Ruy Lopez: closed Berlin defense, Chigorin variation *
+rnbq1rk1/ppp2ppp/5n2/4N3/1b2p3/2N5/PPPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Berlin defense, Minckwitz variation *
+rnbq1rk1/ppp2ppp/5n2/8/1b2p3/2NN4/PPPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open Berlin defense, l'Hermet variation *
+rnbq1rk1/ppp2ppp/5n2/b2PN3/8/P1N5/1PPP1PPP/R1BQKB1R b KQ -
+Ruy Lopez: open, Riga variation *
+rnbq1rk1/ppp2ppp/5n2/b2p4/4P3/2NN4/PPPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open Berlin defense, Showalter variation *
+rnbq1rk1/ppp2ppp/5n2/b2pN3/1P2P3/P1N5/2PP1PPP/R1BQKB1R b KQ -
+Ruy Lopez: open, 6.d4 b5 *
+rnbq1rk1/ppp2ppp/5n2/b2pN3/4P3/P1N5/1PPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, 6.d4 *
+rnbq1rk1/ppp2ppp/5n2/b2pp3/4P3/P1N2N2/1PPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: closed, center attack *
+rnbq1rk1/ppp2ppp/5n2/b3N3/1P1pP3/P1N5/2PP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, Richter variation *
+rnbq1rk1/ppp2ppp/8/2b1p3/8/2P1NN2/PP1P1nPP/R1BQKB1R w KQ -
+Scotch: Cochrane variation *
+rnbq1rk1/ppp2ppp/8/3pb3/2PPn3/3B4/PP3PPP/RNBQ1RK1 w - -
+Petrov: modern attack, Trifunovi\'c variation
+rnbq1rk1/ppp2ppp/8/b2pN3/1P2n3/P1N5/2PP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, Friess attack *
+rnbq1rk1/pppnbppp/4p3/3pP1B1/3P3P/2N5/PPP2PP1/R2QKBNR w KQ -
+French: Albin-Alekhine-Ch\^atard attack, Spielmann variation
+rnbq1rk1/pppp1pp1/5n1p/4p1B1/4P2P/P1P5/1PP2PP1/R2QKBNR b KQ -
+Ruy Lopez: exchange variation, Alapin gambit *
+rnbq1rk1/pppp1ppp/1b3n2/4p3/1P2P3/P1N2N2/1BPP1PPP/R2QKB1R b KQ -
+Ruy Lopez: Archangelsk (counterthrust) variation *
+rnbq1rk1/pppp1ppp/1b3n2/4p3/1P2P3/P1NP1N2/2P2PPP/R1BQKB1R b KQ -
+Ruy Lopez: ...b5 & ...d6 *
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQ -
+Nimzo-Indian: Reshevsky variation
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQ -
+Nimzo-Indian: 4.e3 O-O
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2N1PN2/PP3PPP/R1BQKB1R b KQ -
+Nimzo-Indian: 4.e3 e8g8, 5.Nf3, without ...d5
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2NBP3/PP3PPP/R1BQK1NR b KQ -
+Nimzo-Indian: 4.e3 O-O, 5.Bd3
+rnbq1rk1/pppp1ppp/4pn2/8/2PP4/P1P1P3/5PPP/R1BQKBNR b KQ -
+Nimzo-Indian: S\"amisch variation
+rnbq1rk1/pppp1ppp/4pn2/8/2PP4/P1P5/4PPPP/R1BQKBNR w KQ -
+Nimzo-Indian: S\"amisch variation
+rnbq1rk1/pppp1ppp/5n2/4N3/1b2P3/2N5/PPPP1PPP/R1BQKB1R b KQ -
+Ruy Lopez: Berlin defense, open variation *
+rnbq1rk1/pppp1ppp/5n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: Berlin defense, 4.O-O *
+rnbq1rk1/pppp1ppp/5n2/4p3/1b2P3/2NP1N2/PPP2PPP/R1BQKB1R b KQ -
+Ruy Lopez: Berlin defense, 4.O-O, d6 *
+rnbq1rk1/pppp1ppp/5n2/4p3/1bB1P3/2N2N2/PPPP1PPP/R1BQK2R b KQ -
+Ruy Lopez: Berlin defense, Beverwijk variation *
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1P2P2/1PP3PP/R1BQKBNR b KQ -
+Ruy Lopez: exchange, Gligori\'c variation *
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1P5/1PP2PPP/R1BQKBNR w KQ -
+Ruy Lopez: exchange variation, 5.O-O *
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1PQ4/1PP2PPP/R1B1KBNR b KQ -
+Ruy Lopez: exchange, Bronstein variation *
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1b2N2/1PPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Exchange variation doubly deferred (DERLD) *
+rnbq1rk1/pppp1ppp/5n2/b3N3/4P3/P1N5/1PPP1PPP/R1BQKB1R b KQ -
+Ruy Lopez: open (Tarrasch) defense *
+rnbq1rk1/pppp1ppp/5n2/b3p3/2B1P3/P1N2N2/1PPP1PPP/R1BQK2R b KQ -
+Ruy Lopez: M\"oller defense *
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: 5.O-O *
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPPBPPP/R1BQK2R b KQ -
+Ruy Lopez: closed defense *
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1NP1N2/1PP2PPP/R1BQKB1R b KQ -
+Ruy Lopez: Steinitz defense deferred (Russian defense) *
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQ -
+Ruy Lopez: modern Steinitz defense, 5.O-O *
+rnbq1rk1/pppp1ppp/8/3Pp3/1b6/8/PPPPNPPP/R1BQKB1R b KQ -
+Ruy Lopez: Bird's defense, Paulsen variation *
+rnbq1rk1/pppp2p1/8/2b2PPp/3pn3/3B1N2/PPP2P1P/RNBQK2R w KQ -
+KGA: Kieseritsky, Rice gambit *
+rnbq1rk1/pppp2pp/5n2/2b1pP2/6P1/8/PPPP1PBP/RNBQK1NR w KQ -
+KGA: Hanstein gambit *
+rnbq1rk1/pppp2pp/5n2/2b1pPP1/3P4/8/PPP2P1P/RNBQKBNR b KQ -
+KGA: Muzio gambit, Brentano defense *
+rnbq1rk1/pppp2pp/5n2/2b1pPP1/8/8/PPPP1P1P/RNBQKBNR w KQ -
+KGA: Muzio gambit *
+rnbq1rk1/pppp2pp/5n2/2b1pPP1/8/8/PPPPQP1P/RNB1KBNR b KQ -
+KGA: Muzio gambit, Kling and Horwitz counter-attack *
+rnbq1rk1/ppppb1pp/4p3/5p2/2PPn3/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Dutch defense, Alekhine variation
+rnbq1rk1/ppppb1pp/4pn2/5p2/2PP4/5NP1/PP2PPBP/RNBQK2R w KQ -
+Dutch defense
+rnbq1rk1/ppppppbp/5np1/6B1/3P4/2P2N2/PP2PPPP/RN1QKB1R b KQ -
+R\'eti: King's Indian attack, Yugoslav variation *
+rnbq2k1/pp1p1ppp/1bp5/8/1P1Nr3/P1P5/4BPPP/R1BQ1RK1 b - -
+Ruy Lopez: Marshall counter-attack, 11...c6 *
+rnbq2k1/pp3ppp/1bp5/3p4/1P1Nr3/P1P5/4BPPP/R1BQ1RK1 w - -
+Ruy Lopez: Marshall, main line, 12.d2d4 *
+rnbq2k1/pp3ppp/1bp5/4r3/1P1Pp3/P1N1P3/2PQB1PP/R4RK1 w - -
+Ruy Lopez: open, Tarrasch trap *
+rnbq2k1/pp3ppp/2p1r3/3p4/1P1P4/P2B4/5PPP/R1BQ1RK1 w - -
+Ruy Lopez: Marshall, Kevitz variation *
+rnbq2k1/pppp1ppp/1b6/3N4/1PBpr1n1/P4N2/2P2PPP/R1BQ1K1R b - -
+Ruy Lopez: Rabinovich variation *
+rnbq3r/pp4pp/2P2nk1/8/2Bbp3/2N5/PPPP1PPP/R1BQK2R w KQ -
+Giuoco Piano: Ghulam Kassim variation *
+rnbq3r/pppp1k2/3b1n1p/8/4PQ1P/8/PPPP2P1/RNB1KB1R w KQ -
+KGA: Allgaier, Horny defense
+rnbqk1n1/pppp1p1r/7b/4N2p/2BPPppP/2N5/PPP3P1/R1BQK2R b KQq -
+KGA: Kieseritsky, long whip defense, Jaenisch variation
+rnbqk1nb/pp3p2/2pp4/4N1p1/2BPPp2/2N5/PPP3P1/R1BQK3 b Qkq -
+KGA: Greco gambit
+rnbqk1nr/1p1p1ppp/p3p3/2b5/3NP3/3B4/PPP2PPP/RNBQK2R w KQkq -
+Sicilian: Kan, Polugaievsky variation
+rnbqk1nr/5ppp/2p1p3/pp6/PbpP4/2N1PN2/1P1B1PPP/R2QKB1R w KQkq -
+QGD: semi-Slav, Abrahams variation
+rnbqk1nr/p1p1bppp/1p2p3/3pP3/3P4/2N1B3/PPP2PPP/R2QKBNR w KQkq -
+French: classical, Frankfurt variation
+rnbqk1nr/p1pp1ppp/8/1pb1p3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Wing gambit *
+rnbqk1nr/p1pp2pp/8/1Bb1pp2/4P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: MacDonnell double gambit *
+rnbqk1nr/pp1p1ppp/2p5/2b1p3/2B1P1Q1/8/PPPP1PPP/RNB1K1NR b KQkq -
+Bishop's opening: del Rio variation *
+rnbqk1nr/pp1p1ppp/2p5/2b1p3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Philidor variation *
+rnbqk1nr/pp1p1ppp/2p5/2b1p3/2BPP3/8/PPP2PPP/RNBQK1NR b KQkq -
+Bishop's opening: Lewis counter-gambit *
+rnbqk1nr/pp1pp2p/6p1/2pP1p2/2P5/2P5/P3PPPP/R1BQKBNR w KQkq -
+Beefeater defense
+rnbqk1nr/pp1ppp1p/6pb/2p5/2P1P3/5N2/PP1P1PPP/RNBQKB1R w KQkq -
+Sicilian: Acton extension
+rnbqk1nr/pp1pppbp/8/2p3B1/3P4/8/PPP1PPPP/RN1QKBNR w KQkq -
+Grob: Fritz gambit *
+rnbqk1nr/pp1pppbp/8/2pP2B1/8/8/PPP1PPPP/RN1QKBNR b KQkq -
+Grob: Romford counter-gambit *
+rnbqk1nr/pp2bppp/2p5/3p4/3PpB2/2P1P3/PP3PPP/RN1QKBNR w KQkq -
+Caro-Kann: advance, Short variation *
+rnbqk1nr/pp2ppb1/2p3p1/3pP2p/3P1P2/2N5/PPP3PP/R1BQKBNR w KQkq -
+Robatsch defense: Gurgenidze variation
+rnbqk1nr/pp2ppbp/2pp2p1/8/3PP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Robatsch defense: two knights, Suttles variation
+rnbqk1nr/pp2ppbp/6p1/1Bpp4/5P2/4PN2/PPPP2PP/RNBQK2R b KQkq -
+Dutch defense: Dutch-Indian (Nimzo-Dutch) variation *
+rnbqk1nr/pp2ppbp/6p1/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+Catalan: closed *
+rnbqk1nr/pp2ppbp/6p1/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R b KQkq -
+King's Indian: 3.g3, counterthrust variation *
+rnbqk1nr/pp2ppbp/6p1/2pp4/5P2/4PN2/PPPP2PP/RNBQKB1R w KQkq -
+Dutch defense *
+rnbqk1nr/pp2ppbp/6p1/2pp4/5P2/4PN2/PPPPB1PP/RNBQK2R b KQkq -
+Dutch defense *
+rnbqk1nr/pp2ppbp/6p1/3p4/3N4/6P1/PPP1PPBP/RNBQK2R b KQkq -
+Neo-Gr\"unfeld, 5.cd *
+rnbqk1nr/pp3ppp/4p3/2ppP3/1b1P2Q1/2N5/PPP2PPP/R1B1KBNR b KQkq -
+French: Winawer, advance, Russian variation
+rnbqk1nr/pp3ppp/4p3/2ppP3/1b1P4/2N5/PPP2PPP/R1BQKBNR w KQkq -
+French: Winawer, advance variation
+rnbqk1nr/pp3ppp/4p3/2ppP3/1b1P4/2N5/PPPB1PPP/R2QKBNR b KQkq -
+French: Winawer, advance, Bogolyubov variation
+rnbqk1nr/pp3ppp/4p3/2ppP3/1b1P4/P1N5/1PP2PPP/R1BQKBNR b KQkq -
+French: Winawer, advance, 5.a3
+rnbqk1nr/pp3ppp/4p3/2ppP3/3P4/P1P5/2P2PPP/R1BQKBNR b KQkq -
+French: Winawer, advance variation
+rnbqk1nr/pp3ppp/4p3/3pP3/1P6/2p2N2/1PP2PPP/R1BQKB1R b KQkq -
+French: Winawer, advance, Rauzer variation
+rnbqk1nr/ppp1bppp/3p4/4p3/2B1P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+Philidor: Steinitz variation
+rnbqk1nr/ppp1bppp/4p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: Charousek (Petrosian) variation
+rnbqk1nr/ppp1bppp/4p3/3pP1B1/3P4/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: classical, Vistaneckis (Nimzovich) variation
+rnbqk1nr/ppp1p1bp/3p2p1/5p2/2PPP3/2N5/PP3PPP/R1BQKBNR w KQkq -
+Modern defense: Averbakh system, Randspringer variation
+rnbqk1nr/ppp1ppbp/3p2p1/8/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Modern defense
+rnbqk1nr/ppp1ppbp/3p2p1/8/2PPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+Modern defense: Averbakh system
+rnbqk1nr/ppp1ppbp/3p2p1/8/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+Robatsch defense: two knights variation
+rnbqk1nr/ppp1ppbp/3p2p1/8/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Robatsch (modern) defense
+rnbqk1nr/ppp1ppbp/3p2p1/8/3PP3/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+Robatsch defense: Geller's system
+rnbqk1nr/ppp1ppbp/3p2p1/8/3PPP2/2N5/PPP3PP/R1BQKBNR b KQkq -
+Robatsch defense: Pseudo-Austrian attack
+rnbqk1nr/ppp1ppbp/6p1/3p4/5P2/5NP1/PPPPP2P/RNBQKB1R b KQkq -
+Dutch defense *
+rnbqk1nr/ppp2p1p/3b4/6p1/8/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Bird: From gambit, Lasker variation
+rnbqk1nr/ppp2pb1/3p3p/6p1/2BPPp1P/3Q1N2/PPP3P1/RNB1K2R b KQkq -
+KGA: Philidor gambit, Schultz variation
+rnbqk1nr/ppp2ppp/1b1p4/8/2P1p3/1N6/PP1PPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Kmoch variation *
+rnbqk1nr/ppp2ppp/3b4/3Pp3/8/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+QP counter-gambit: Maroczy gambit
+rnbqk1nr/ppp2ppp/3b4/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: Schlechter variation *
+rnbqk1nr/ppp2ppp/3bp3/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's pawn: stonewall attack *
+rnbqk1nr/ppp2ppp/3p4/2b1P3/4P3/5N2/PPPP2PP/RNBQKB1R b KQkq -
+KGD: classical, Soldatenkov variation
+rnbqk1nr/ppp2ppp/3p4/2b1p3/1P2PP2/5N2/P1PP2PP/RNBQKB1R b KQkq -
+KGD: classical, Heath variation
+rnbqk1nr/ppp2ppp/3p4/2b1p3/4PP2/2P2N2/PP1P2PP/RNBQKB1R b KQkq -
+KGD: classical, 4.c3
+rnbqk1nr/ppp2ppp/3p4/2b1p3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+Bishop's opening: Calabrese counter-gambit, Jaenisch variation *
+rnbqk1nr/ppp2ppp/4p3/3p4/1b1PP3/2N5/PPP1NPPP/R1BQKB1R b KQkq -
+French: Winawer, Alekhine (Mar\'oczy) gambit
+rnbqk1nr/ppp2ppp/4p3/3p4/1b1PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+French: Winawer (Nimzovich) variation
+rnbqk1nr/ppp2ppp/4p3/3p4/1b1PP3/2N5/PPPB1PPP/R2QKBNR b KQkq -
+French: Winawer, fingerslip variation
+rnbqk1nr/ppp2ppp/4p3/3pP3/1b1P4/2N5/PPP2PPP/R1BQKBNR b KQkq -
+French: Winawer, advance variation
+rnbqk1nr/ppp2ppp/4p3/8/3Pp3/P1b5/1PP1NPPP/R1BQKB1R w KQkq -
+French: Winawer, Alekhine gambit
+rnbqk1nr/ppp2ppp/8/2bp4/3Np3/3P4/PPP1PPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Balogh variation *
+rnbqk1nr/ppp2ppp/8/2bpp3/2B1P3/2P5/PP1P1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Lewis counter-gambit
+rnbqk1nr/ppp2ppp/8/2bpp3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Lewis gambit *
+rnbqk1nr/ppp2ppp/8/2bpp3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Bishop's opening: Ponziani gambit *
+rnbqk1nr/ppp2ppp/8/4P3/1bP5/4p3/PP1B1PPP/RN1QKBNR w KQkq -
+QGD: Albin counter-gambit, Lasker trap
+rnbqk1nr/ppp3pp/3p4/2b1pp2/4PP2/2P2N2/PP1P2PP/RNBQKB1R w KQkq -
+KGD: classical counter-gambit
+rnbqk1nr/ppp3pp/4P3/2bp2N1/4p3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Philidor: Philidor counter-gambit, Berger variation
+rnbqk1nr/ppp3pp/8/2b2p2/2BpP3/2P2N2/PP4PP/RNBQK2R b KQkq -
+KGD: classical, R\'eti variation
+rnbqk1nr/pppp1pbp/8/4N3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Paulsen defense
+rnbqk1nr/pppp1pbp/8/6p1/2B1Pp1P/5N2/PPPP2P1/RNBQK2R b KQkq -
+KGA: Philidor gambit
+rnbqk1nr/pppp1pbp/8/6p1/2B1Pp2/5N2/PPPP2PP/RNBQ1RK1 b kq -
+KGA: Hanstein gambit
+rnbqk1nr/pppp1pbp/8/6p1/2B1Pp2/5N2/PPPP2PP/RNBQK2R w KQkq -
+King's knight's gambit
+rnbqk1nr/pppp1ppp/4p3/8/1bPP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Queen's pawn: Franco-Indian (Keres) defense
+rnbqk1nr/pppp1ppp/8/2b1p3/1PB1P3/8/P1PP1PPP/RNBQK1NR b KQkq -
+Bishop's opening: Wing gambit
+rnbqk1nr/pppp1ppp/8/2b1p3/2B1P3/2P5/PP1P1PPP/RNBQK1NR b KQkq -
+Bishop's opening: Philidor variation
+rnbqk1nr/pppp1ppp/8/2b1p3/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+Bishop's opening: Classical variation *
+rnbqk1nr/pppp1ppp/8/2b1p3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Classical variation
+rnbqk1nr/pppp1ppp/8/2b1p3/2BPP3/8/PPP2PPP/RNBQK1NR b KQkq -
+Bishop's opening: Lewis gambit
+rnbqk1nr/pppp1ppp/8/2b1p3/4P3/2P5/PP1P1PPP/RNBQKBNR b KQkq -
+Bishop's opening: Philidor counter-attack *
+rnbqk1nr/pppp1ppp/8/2b1p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+Bishop's opening: Berlin defense *
+rnbqk1nr/pppp1ppp/8/2b1p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Bishop's opening *
+rnbqk1nr/pppp1ppp/8/2b1p3/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+Bishop's opening: Calabrese counter-gambit *
+rnbqk1nr/pppp1ppp/8/2b1p3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: classical variation
+rnbqk1nr/pppp1ppp/8/2b1p3/8/2P5/PP1PPPPP/RNBQKBNR w KQkq -
+Caro-Kann: Hillbilly attack *
+rnbqk1nr/pppp1ppp/8/2b1p3/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Krejcik variation *
+rnbqk1nr/pppp1ppp/8/4p3/1bB1PP2/8/P1PP2PP/RNBQK1NR b KQkq -
+Bishop's opening: MacDonnell double gambit
+rnbqk1nr/pppp1ppp/8/4p3/1bP5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English, Kramnik-Shirov counterattack
+rnbqk1nr/pppp1ppp/8/8/2B1P2b/5N2/PPPP3p/RNBQ1R1K b kq -
+KGA: Cunningham, three pawns gambit
+rnbqk1nr/pppp1ppp/8/8/2B1Pp1b/5NP1/PPPP3P/RNBQK2R b KQkq -
+KGA: Cunningham, Bertin gambit
+rnbqk1nr/pppp1ppp/8/8/2BPP2b/5N2/P1P4p/RNBQ1R1K b kq -
+Bishop's opening: Four pawns' gambit
+rnbqk1nr/pppp2pp/3b4/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Schurig gambit *
+rnbqk1nr/pppp2pp/8/2b1pP2/1P6/8/P1PP1PPP/RNBQKBNR b KQkq -
+KGA: bishop's gambit, Bryan counter-gambit *
+rnbqk1nr/pppp2pp/8/2b1pP2/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+KGA: bishop's gambit, Bledow variation *
+rnbqk1nr/pppp2pp/8/2b1pP2/5P2/8/PPPP2PP/RNBQKBNR b KQkq -
+KGA: bishop's gambit, L\'opez-Gianutio counter-gambit *
+rnbqk1nr/pppp2pp/8/2b1pP2/8/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+KGA: bishop's gambit, Maurian defense *
+rnbqk1nr/pppp2pp/8/2b1pP2/8/2P5/PP1P1PPP/RNBQKBNR b KQkq -
+KGA: bishop's gambit, Ruy L\'opez defense *
+rnbqk1nr/pppp2pp/8/2b1pP2/8/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+KGA: bishop's gambit, Cozio (Morphy) defense *
+rnbqk1nr/pppp2pp/8/2b1pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: bishop's gambit *
+rnbqk1nr/pppp2pp/8/2b1pP2/8/8/PPPPNPPP/RNBQKB1R b KQkq -
+KGA: bishop's gambit, Steinitz defense *
+rnbqk1nr/pppp2pp/8/2b1pp2/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Bishop's opening: Greco gambit *
+rnbqk1nr/pppp2pp/8/4Pp2/1b1p4/8/PPP2PPP/RNBQKBNR w KQkq -
+KGD: Falkbeer, Nimzovich variation *
+rnbqk1nr/pppp2pp/8/4pP2/3b4/2P5/PP3PPP/RNBQKBNR b KQkq -
+KGA: bishop's gambit, Anderssen variation *
+rnbqk1nr/pppp2pp/8/4pP2/3b4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+KGA: bishop's gambit, Morphy variation *
+rnbqk1nr/ppppb1pp/8/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Lesser bishop's (Petroff-Jaenisch-Tartakower) gambit *
+rnbqk1nr/ppppbp1p/8/4N3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Polerio defense
+rnbqk1nr/ppppbppp/8/8/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Cunningham defense
+rnbqk1nr/ppppp1bp/6p1/5p2/3P4/6PN/PPP1PPBP/RNBQK2R b KQkq -
+Dutch: Leningrad, Karlsbad variation
+rnbqk1nr/ppppppbp/6p1/8/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+Robatsch defense
+rnbqk1nr/ppppppbp/6p1/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Robatsch (modern) defense
+rnbqk1nr/ppppppbp/6p1/8/3PPP2/8/PPP3PP/RNBQKBNR b KQkq -
+Robatsch defense: three pawns attack
+rnbqk1nr/ppppppbp/8/8/3P2p1/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Grob: spike attack *
+rnbqk1r1/ppp2pP1/4p3/3p4/1b1P2Qp/2N5/PPP2PP1/R3KBNR b KQq -
+French: MacCutcheon, Grigoriev variation
+rnbqk2r/1p2bp2/p2ppn1p/6p1/3NPP1B/2N2Q2/PPP3PP/R3KB1R w KQkq -
+Sicilian: Najdorf, G\"oteborg (Argentine) variation
+rnbqk2r/1p2bppp/p2ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+Sicilian: Najdorf, 7...Be7
+rnbqk2r/1pp2ppp/1b3n2/p2p4/4p3/1N1P2P1/PPP1PPBP/RNBQK2R w KQkq -
+Alekhine's defense: modern, Keres variation *
+rnbqk2r/1ppnbppp/p3p3/3pP1B1/3P3P/2N5/PPP2PP1/R2QKBNR w KQkq -
+French: Albin-Alekhine-Ch\^atard attack, Mar\'oczy variation
+rnbqk2r/2pp1ppp/5n2/ppb1p3/4P3/1BN5/PPPP1PPP/R1BQK1NR w KQkq -
+Evans gambit declined, 5.a4 *
+rnbqk2r/p1p2ppp/1p1bpn2/3p4/2PP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+Queen's pawn game, Rubinstein (Colle-Zukertort) variation *
+rnbqk2r/p1pp1ppp/1p2pn2/8/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQkq -
+Nimzo-Indian: Fischer variation, 5.Ne2
+rnbqk2r/p1pp1ppp/1p2pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+Nimzo-Indian: Fischer variation
+rnbqk2r/p1pp1ppp/5n2/1Bb1p3/4P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Evans gambit *
+rnbqk2r/p1pp1ppp/5n2/1pb1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Evans gambit declined *
+rnbqk2r/p1pp1ppp/5n2/1pb1p3/2BPP3/2N5/PPP2PPP/R1BQK1NR b KQkq -
+Evans counter-gambit *
+rnbqk2r/p1pp1ppp/8/2b1p3/Np2n1Q1/1B6/PPPP1PPP/R1B1K1NR b KQkq -
+Evans gambit declined, Hirschbach variation *
+rnbqk2r/p1pp1ppp/8/2b1p3/Np2n3/1B5N/PPPP1PPP/R1BQK2R b KQkq -
+Evans gambit declined, Lange variation *
+rnbqk2r/p2p1pp1/4pn1p/1ppP4/1bP4B/2N5/PP2PPPP/R2QKBNR w KQkq -
+Nimzo-Indian: Leningrad, ...b5 gambit
+rnbqk2r/p2p1ppp/1p2pn2/2p5/2PP4/P1P1P3/5PPP/R1BQKBNR w KQkq -
+Nimzo-Indian: S\"amisch, O'Kelly variation
+rnbqk2r/p2p1ppp/2p2n2/1pb1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Giuoco Piano: Bird's attack *
+rnbqk2r/p2p1ppp/2p2n2/2b1p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Evans gambit: Mayet defense *
+rnbqk2r/p2p1ppp/2p2n2/2b1p3/4P3/2N5/PPPPBPPP/R1BQK1NR b KQkq -
+Evans gambit: 5...Be7 *
+rnbqk2r/p2p1ppp/2p2n2/2b1p3/4P3/2NB4/PPPP1PPP/R1BQK1NR b KQkq -
+Evans gambit: Stone-Ware variation *
+rnbqk2r/p2p1ppp/2p2n2/2b1p3/B3P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Evans gambit *
+rnbqk2r/p4ppp/2p2n2/1Bb1p3/8/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Scotch gambit *
+rnbqk2r/p4ppp/2p2n2/2b5/B3p3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Scotch gambit: Cochrane variation *
+rnbqk2r/p4ppp/2p2n2/2bpp3/B3P3/2NP4/PPP2PPP/R1BQK1NR b KQkq -
+Evans gambit *
+rnbqk2r/p4ppp/2p2n2/2bpp3/BP2P3/2N5/P1PP1PPP/R1BQK1NR b KQkq -
+Evans gambit: Leonhardt variation *
+rnbqk2r/p4ppp/2p2n2/2bpp3/N3P3/8/PPPPBPPP/R1BQK1NR b KQkq -
+Evans gambit: Cordel variation *
+rnbqk2r/pp1n1ppp/4p3/2bpP3/5PQ1/2N5/PPP3PP/R1B1KBNR b KQkq -
+French: Steinitz, Bradford attack
+rnbqk2r/pp1nbppp/4p3/2ppP1B1/3P3P/2N5/PPP2PP1/R2QKBNR w KQkq -
+French: Albin-Alekhine-Ch\^atard attack, Breyer variation
+rnbqk2r/pp1p1ppp/2p2n2/2b1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Giuoco Piano *
+rnbqk2r/pp1p1ppp/2p2n2/2b1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Giuoco Piano *
+rnbqk2r/pp1p1ppp/2p2n2/2b1p3/2B1P3/2N5/PPPPQPPP/R1B1K1NR b KQkq -
+Giuoco Piano: close variation *
+rnbqk2r/pp1p1ppp/2p2n2/2b1p3/4P3/3P4/PPP1BPPP/RNBQK1NR w KQkq -
+Philidor: Steinitz variation *
+rnbqk2r/pp1p1ppp/2p2n2/4p3/1b2P3/1BN5/PPPP1PPP/R1BQK1NR b KQkq -
+Ruy Lopez: classical defense, Charousek variation *
+rnbqk2r/pp1p1ppp/2p2n2/4p3/1bB1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Ruy Lopez: classical defense, 4.c3 *
+rnbqk2r/pp1p1ppp/2p2n2/4p3/1bB1P3/2N5/PPPPQPPP/R1B1K1NR b KQkq -
+Ruy Lopez: classical defense, Boden variation *
+rnbqk2r/pp1p1ppp/2p2n2/4p3/1bB1PP2/2N5/PPPP2PP/R1BQK1NR b KQkq -
+Ruy Lopez: Cordel gambit *
+rnbqk2r/pp1p1ppp/2p2n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQkq -
+Ruy Lopez: modern Steinitz defense *
+rnbqk2r/pp1p1ppp/2p2n2/b3p3/4P3/P1NP4/1PPB1PPP/R2QKBNR b KQkq -
+Ruy Lopez: modern Steinitz defense *
+rnbqk2r/pp1p1ppp/2p2n2/b3p3/4PP2/P1NP4/1PP3PP/R1BQKBNR b KQkq -
+Ruy Lopez: modern Steinitz defense, siesta variation *
+rnbqk2r/pp1p1ppp/4p3/2pP4/1bP1n3/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+Nimzo-Indian: three knights, Euwe variation
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQkq -
+Nimzo-Indian: 4.e3 c5, 5.Ne2 (Rubinstein, anti-H\"ubner system)
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+Nimzo-Indian: 4.e3 c5
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, 4...c5
+rnbqk2r/pp1p1ppp/4pn2/2p5/2PP4/P1P1P3/5PPP/R1BQKBNR b KQkq -
+Nimzo-Indian: S\"amisch variation
+rnbqk2r/pp1p1ppp/4pn2/2pP4/1bP5/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+Nimzo-Indian: three knights, Korchnoi variation
+rnbqk2r/pp1p1ppp/4pn2/4P3/1b1N4/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Sicilian: Pin, Koch variation
+rnbqk2r/pp1p1ppp/4pn2/8/1b1NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Pin variation (Sicilian counter-attack)
+rnbqk2r/pp1p1ppp/5n2/2p1p3/2P5/3P4/PP1QPPPP/RN2KBNR w KQkq -
+Sicilian: Canal-Sokolsky attack, Sokolsky variation *
+rnbqk2r/pp1p1ppp/5n2/4p3/1b1NP3/2NB4/PPP2PPP/R1BQK2R w KQkq -
+Sicilian: Pin, Jaffe variation
+rnbqk2r/pp1p1ppp/5n2/b1p1p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQkq -
+Ruy Lopez: modern Steinitz defense, Duras (Keres) variation *
+rnbqk2r/pp1pp1bp/2p3pn/5p2/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Dutch: Leningrad, Basman system
+rnbqk2r/pp1pppbp/5np1/2P5/8/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+English: Neo-Catalan accepted *
+rnbqk2r/pp1pppbp/5np1/2p5/1P6/P3PN2/2PP1PPP/RNBQKB1R b KQkq -
+English: Romanishin gambit *
+rnbqk2r/pp2npbp/6p1/3pp3/8/1N4P1/PPP1PPBP/RNBQK2R w KQkq -
+Neo-Gr\"unfeld, 5.cd, main line *
+rnbqk2r/pp2nppp/4p3/2ppP3/3P2Q1/P1P5/2P2PPP/R1B1KBNR b KQkq -
+French: Winawer, advance, poisoned pawn variation
+rnbqk2r/pp2nppp/4p3/2ppP3/3P4/P1P2N2/2P2PPP/R1BQKB1R b KQkq -
+French: Winawer, advance, positional main line
+rnbqk2r/pp2nppp/4p3/2ppP3/3P4/P1P5/2P2PPP/R1BQKBNR w KQkq -
+French: Winawer, advance, 6...Ne7
+rnbqk2r/pp2nppp/4p3/2ppP3/P2P4/2P5/2P2PPP/R1BQKBNR b KQkq -
+French: Winawer, advance, Smyslov variation
+rnbqk2r/pp2ppbp/3p1np1/2p5/3PPP2/2N2N2/PPP3PP/R1BQKB1R w KQkq -
+Pirc: Austrian attack, dragon formation
+rnbqk2r/pp2ppbp/3p1np1/8/3NP3/2N1B3/PPP1BPPP/R2QK2R b KQkq -
+Sicilian: dragon, classical attack
+rnbqk2r/pp2ppbp/3p1np1/8/3NP3/2N1BP2/PPP3PP/R2QKB1R b KQkq -
+Sicilian: dragon, Yugoslav attack
+rnbqk2r/pp2ppbp/5np1/1Bpp4/8/1P2PN2/PBPP1PPP/RN1QK2R b KQkq -
+Queen's Indian: Capablanca variation *
+rnbqk2r/pp2ppbp/5np1/2Pp4/8/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+Catalan: open, classical line *
+rnbqk2r/pp2ppbp/5np1/2Pp4/8/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+Catalan: open, 5.Nf3 *
+rnbqk2r/pp2ppbp/5np1/2pp4/3P4/4PN2/PPP1BPPP/RNBQK2R w KQkq -
+Catalan: closed, 5.Nf3 *
+rnbqk2r/pp2ppbp/5np1/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Neo-Gr\"unfeld, 5.Nf3 *
+rnbqk2r/pp2ppbp/5np1/2pp4/5P2/4PN2/PPPPB1PP/RNBQ1RK1 b kq -
+Dutch defense *
+rnbqk2r/pp2ppbp/5np1/2pp4/5P2/5NP1/PPPPP1BP/RNBQK2R w KQkq -
+Dutch: Leningrad, main variation *
+rnbqk2r/pp2ppbp/5np1/2pp4/8/1P2PN2/PBPPBPPP/RN1QK2R b KQkq -
+Queen's Indian: 5.Bg2 Be7 *
+rnbqk2r/pp2ppbp/6p1/2p4n/2PP4/1P3N2/PB1P1PPP/RN1QKB1R w KQkq -
+Queen's Indian: Rubinstein variation *
+rnbqk2r/pp2ppbp/6p1/2p5/2PP2n1/1P3N2/PB1P1PPP/RN1QKB1R w KQkq -
+Queen's Indian: B\"urger variation *
+rnbqk2r/pp3pbp/3p1np1/1BpP4/4PP2/2N5/PP4PP/R1BQK1NR b KQkq -
+Benoni: Taimanov variation
+rnbqk2r/pp3pbp/3p1np1/2pP2B1/4P3/2N2N2/PP3PPP/R2QKB1R b KQkq -
+Benoni: classical, 8.Bg5
+rnbqk2r/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQK2R b KQkq -
+Benoni: classical without 9.O-O
+rnbqk2r/pp3pbp/3p1np1/2pPP3/5P2/2N5/PP4PP/R1BQKBNR b KQkq -
+Benoni: Mikenas variation
+rnbqk2r/pp3pp1/3ppn1p/2pP4/1bP4B/2N5/PP2PPPP/R2QKBNR w KQkq -
+Nimzo-Indian: Leningrad, main line
+rnbqk2r/pp3ppp/2p2n2/1BbP4/3p4/5N2/PPP1QPPP/RNB1K2R b KQkq -
+Bishop's opening: Urusov gambit, Panov variation *
+rnbqk2r/pp3ppp/2p2n2/2b1p3/4P3/1B1p4/PPPPQPPP/RNB1K1NR w KQkq -
+Giuoco Piano: Eisinger variation *
+rnbqk2r/pp3ppp/2p2n2/2bP4/2BPp3/2N2N2/PPP2PPP/R1BQK2R b KQkq d3
+Giuoco Piano *
+rnbqk2r/pp3ppp/2p2n2/2bPN3/4p3/2N5/PPPPBPPP/R1BQK2R b KQkq -
+Hungarian defense: Tartakower variation *
+rnbqk2r/pp3ppp/2p2n2/2bpp3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Giuoco Piano *
+rnbqk2r/pp3ppp/2p2n2/2bpp3/4P3/1BN5/PPPPQPPP/R1B1K1NR b KQkq -
+Giuoco Piano: center-holding variation *
+rnbqk2r/pp3ppp/2p2n2/2bpp3/4P3/2PP4/PP1N1PPP/R1BQKBNR w KQkq -
+Philidor: Hanham, Delmar variation *
+rnbqk2r/pp3ppp/2p2n2/b2pp3/4P3/P1NP2P1/1PPB1P1P/R2QKBNR b KQkq -
+Ruy Lopez: modern Steinitz defense, fianchetto (Bronstein) variation *
+rnbqk2r/pp3ppp/2p2n2/b2pp3/4P3/P1NP4/1PPBNPPP/R2QKB1R b KQkq -
+Ruy Lopez: modern Steinitz defense, Rubinstein variation *
+rnbqk2r/pp3ppp/2pb1n2/3p4/2PPp3/1QN1P3/PP3PPP/R1B1KBNR w KQkq -
+French: advance, Milner-Barry gambit *
+rnbqk2r/pp3ppp/2pb4/4n3/3pP3/3P1N2/PPP1B1PP/RNBQK2R b KQkq -
+Ponziani counter-gambit, Cordel variation *
+rnbqk2r/pp3ppp/2pbpn2/3p4/2PP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+Colle system *
+rnbqk2r/pp3ppp/3p1n2/2p1p3/1b2P3/2NP1N2/PPP2PPP/R1BQKB1R w KQkq -
+Ruy Lopez: Berlin defense, Duras variation *
+rnbqk2r/pp3ppp/3p1n2/b1p1p3/4P3/P1NP1N2/1PP2PPP/R1BQKB1R w KQkq -
+Ruy Lopez: Morphy defense, Duras variation *
+rnbqk2r/pp3ppp/4p3/2Pn4/8/P1P2P2/4P1PP/R1BQKBNR b KQkq -
+Nimzo-Indian: S\"amisch, Keres variation
+rnbqk2r/pp3ppp/4pn2/2b3B1/3p4/P3P3/1PP2PPP/RN1QKBNR w KQkq -
+QGA: Alekhine defense, Alatortsev variation *
+rnbqk2r/pp3ppp/4pn2/2bp4/2P5/4PN2/PP3PPP/RNBQKB1R b KQkq -
+QGA: classical variation *
+rnbqk2r/pp3ppp/4pn2/2pP4/3P4/P1P2P2/4P1PP/R1BQKBNR b KQkq -
+Nimzo-Indian: S\"amisch variation
+rnbqk2r/pp3ppp/5n2/1B1pN3/1b1Pp3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Giuoco Piano: Anderssen variation *
+rnbqk2r/pp3ppp/5n2/2bpp3/2B5/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Giuoco Piano *
+rnbqk2r/pp3ppp/5n2/2bpp3/8/1BNP4/PPP2PPP/R1BQK1NR b KQkq -
+Giuoco Piano: LaBourdonnais variation *
+rnbqk2r/pp3ppp/5n2/2ppp3/1b2P3/2NP4/PPPB1PPP/R2QKBNR w KQkq -
+Ruy Lopez: old Steinitz defense, semi-Duras variation *
+rnbqk2r/pp4pp/2p2n2/2bPp3/2B2P2/8/PPP3PP/RNBQK1NR w KQkq -
+KGD: classical, R\'eti variation *
+rnbqk2r/pp4pp/4p3/2Pn1p2/8/P1P2P2/4P1PP/R1BQKBNR w KQkq -
+Nimzo-Indian: S\"amisch, Romanovsky variation
+rnbqk2r/ppn1bppp/8/2p1p3/8/2NP2PN/PP2PPBP/R1BQK2R b KQkq -
+Sicilian: accelerated fianchetto, Simagin variation *
+rnbqk2r/ppp1b1pp/3p1n2/3Pp3/4N3/2PB4/PP3PPP/RNBQK2R w KQkq -
+Ponziani counter-gambit, Cordel variation
+rnbqk2r/ppp1bppp/4p3/3p2B1/2PPn3/2N1P3/PP3PPP/R2QKBNR w KQkq -
+QGD: Lasker variation
+rnbqk2r/ppp1bppp/4p3/3pP1B1/3Pn3/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: classical, Tartakower variation
+rnbqk2r/ppp1bppp/4p3/3pP3/3P2Q1/2N5/PPP2PPP/R3KBNR b KQkq -
+French: classical, Anderssen-Richter variation
+rnbqk2r/ppp1bppp/4pB2/3p4/3PP3/2N5/PPP2PPP/R2QKBNR b KQkq -
+French: classical, Anderssen variation
+rnbqk2r/ppp1bppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR w KQkq -
+QGD: 4.Bg5 Be7
+rnbqk2r/ppp1bppp/4pn2/3p2B1/3PP3/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: classical
+rnbqk2r/ppp1bppp/4pn2/3p4/2P5/5NP1/PP1PPPBP/RNBQ1RK1 b kq -
+English: Neo-Catalan declined
+rnbqk2r/ppp1bppp/4pn2/3p4/2PP1B2/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+QGD: classical variation (5.Bf4)
+rnbqk2r/ppp1bppp/4pn2/3p4/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+Catalan: closed, 5.Nf3
+rnbqk2r/ppp1bppp/4pn2/8/2pP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+Catalan: open, classical line
+rnbqk2r/ppp1bppp/5n2/3p2B1/3Np3/2PP4/PP2PPPP/RN1QKB1R b KQkq -
+Alekhine's defense: modern, Flohr variation *
+rnbqk2r/ppp1bppp/5n2/3pp3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Tayler opening *
+rnbqk2r/ppp1bppp/8/3pP3/4n3/2N2N2/PPPP2PP/R1BQKB1R w KQkq -
+Vienna gambit: Breyer variation
+rnbqk2r/ppp1npbp/6p1/3pp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+R\'eti: King's Indian attack, Pachman system
+rnbqk2r/ppp1nppp/8/8/3PN3/8/PP3PPP/R2QKBNR w KQkq -
+Bishop's opening: Lisitsyn variation *
+rnbqk2r/ppp1ppbp/1n1p2p1/4P3/P2P4/1B3N2/1PP2PPP/RNBQK2R b KQkq -
+Alekhine's defense: modern, Keres variation
+rnbqk2r/ppp1ppbp/1n4p1/8/3PP3/6P1/PP2NPBP/RNBQK2R b KQkq -
+Neo-Gr\"unfeld, 5.cd, main line
+rnbqk2r/ppp1ppbp/3p1np1/6B1/2PP4/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+King's Indian: Smyslov system
+rnbqk2r/ppp1ppbp/3p1np1/6B1/2PPP3/2N5/PP3PPP/R2QKBNR b KQkq -
+King's Indian: accelerated Averbakh system
+rnbqk2r/ppp1ppbp/3p1np1/8/2BPPP2/2N5/PPP3PP/R1BQK1NR b KQkq -
+Pirc: Austrian attack, Ljubojevi\'c variation
+rnbqk2r/ppp1ppbp/3p1np1/8/2PP4/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+King's Indian: fianchetto variation
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+King's Indian: 5.Nf3
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N2P2/PP4PP/R1BQKBNR b KQkq -
+King's Indian: S\"amisch variation
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N3P1/PP3P1P/R1BQKBNR b KQkq -
+King's Indian with e4 & g3
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N4P/PP3PP1/R1BQKBNR b KQkq -
+King's Indian: Makagonov system (5.h3)
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N5/PP2BPPP/R1BQK1NR b KQkq -
+King's Indian: 5.Be2
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N5/PP2NPPP/R1BQKB1R b KQkq -
+King's Indian: Kramer system
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPPP2/2N5/PP4PP/R1BQKBNR b KQkq -
+King's Indian: Four pawns attack
+rnbqk2r/ppp1ppbp/3p1np1/8/3PP1P1/2N5/PPP1BP1P/R1BQK1NR b KQkq -
+Pirc: Chinese variation
+rnbqk2r/ppp1ppbp/3p1np1/8/3PP2P/2N5/PPP1BPP1/R1BQK1NR b KQkq -
+Pirc: bayonet (Mariotti) attack
+rnbqk2r/ppp1ppbp/3p1np1/8/3PP3/2N2N1P/PPP2PP1/R1BQKB1R b KQkq -
+Pirc: classical, h3 system
+rnbqk2r/ppp1ppbp/3p1np1/8/3PP3/2N2N2/PPP1BPPP/R1BQK2R b KQkq -
+Pirc: classical system, 5.Be2
+rnbqk2r/ppp1ppbp/3p1np1/8/3PP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Pirc: classical (two knights) system
+rnbqk2r/ppp1ppbp/5np1/3p2B1/2PP4/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+Gr\"unfeld: 5.Bg5
+rnbqk2r/ppp1ppbp/5np1/3p4/2P5/1P3N2/PB1PPPPP/RN1QKB1R b KQkq -
+Queen's Indian: Marienbad system *
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP1B2/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+Gr\"unfeld: 5.Bf4
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/1QN2N2/PP2PPPP/R1B1KB1R b KQkq -
+Gr\"unfeld: Russian variation
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+Gr\"unfeld: 5.e3
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+Gr\"unfeld: Three knights variation
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+Neo-Gr\"unfeld, 5.Nf3
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+King's Indian: 3.g3, counterthrust variation
+rnbqk2r/ppp1ppbp/5np1/3p4/Q1PP4/2N2N2/PP2PPPP/R1B1KB1R b KQkq -
+Gr\"unfeld: Flohr variation
+rnbqk2r/ppp1ppbp/6p1/3n4/3P4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+Neo-Gr\"unfeld, 5.cd
+rnbqk2r/ppp1ppbp/6p1/8/2BPP3/2P5/P4PPP/R1BQK1NR b KQkq -
+Gr\"unfeld: exchange, classical variation
+rnbqk2r/ppp1ppbp/6p1/8/3PP3/2P2N2/P4PPP/R1BQKB1R b KQkq -
+Gr\"unfeld: modern exchange variation
+rnbqk2r/ppp1ppbp/6pn/3p4/5P2/4PN2/PPPP2PP/RNBQKB1R w KQkq -
+Dutch defense, Blackburne variation *
+rnbqk2r/ppp1ppbp/6pn/3p4/5P2/6P1/PPPPP1BP/RNBQK1NR w KQkq -
+Dutch: Leningrad, Karlsbad variation *
+rnbqk2r/ppp2p1p/3b1n2/3PN3/2B2ppP/8/PPPP2P1/RNBQ1RK1 b kq -
+KGA: Kieseritsky, Rice gambit
+rnbqk2r/ppp2p2/4p1pp/3pP3/3Pn1Q1/2P5/P1PB1PPP/R3KBNR w KQkq -
+French: MacCutcheon, Lasker variation, 8...g6
+rnbqk2r/ppp2pbp/6p1/3np3/8/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+English: Anglo-Gr\"unfeld defense, Korchnoi variation
+rnbqk2r/ppp2pp1/4pP1p/3p2B1/1b1P4/2N5/PPP2PPP/R2QKBNR b KQkq -
+French: MacCutcheon, Chigorin variation
+rnbqk2r/ppp2pp1/4pn1p/3pP3/1b1P3B/2N5/PPP2PPP/R2QKBNR b KQkq -
+French: MacCutcheon, Bernstein variation
+rnbqk2r/ppp2pp1/4pn1p/3pP3/1b1P4/2N1B3/PPP2PPP/R2QKBNR b KQkq -
+French: MacCutcheon, Janowski variation
+rnbqk2r/ppp2pp1/4pn1p/3pP3/1b1P4/2N5/PPP2PPP/R1BQKBNR b KQkq -
+French: MacCutcheon, Dr. Olland (Dutch) variation
+rnbqk2r/ppp2pp1/4pn1p/3pP3/3P4/2b5/PPPB1PPP/R2QKBNR w KQkq -
+French: MacCutcheon, Lasker variation
+rnbqk2r/ppp2ppp/3b1n2/3pN3/3P4/3B4/PPP2PPP/RNBQK2R b KQkq -
+Petrov: classical attack, Marshall variation *
+rnbqk2r/ppp2ppp/3b3n/8/3P4/5N2/PPP1P1PP/RNBQKB1R b KQkq -
+Bird: From gambit, Lipke variation
+rnbqk2r/ppp2ppp/3b4/3np3/2B5/P3P3/1P1P1PPP/RNBQK1NR b KQkq -
+Sicilian: Kan, Polugaievsky variation *
+rnbqk2r/ppp2ppp/3b4/3np3/8/P3P1P1/1P1P1P1P/RNBQKBNR b KQkq -
+Sicilian: Kan, Swiss cheese variation *
+rnbqk2r/ppp2ppp/3b4/3np3/8/P3P3/1P1P1PPP/RNBQKBNR w KQkq -
+Sicilian: Kan, 5.Bd3 *
+rnbqk2r/ppp2ppp/3b4/3p4/3Pn3/3B1N2/PPP2PPP/RNBQK2R w KQkq -
+Petrov: classical attack, Marshall variation
+rnbqk2r/ppp2ppp/3bpn2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+Queen's pawn game *
+rnbqk2r/ppp2ppp/3p1n2/2b1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Giuoco Pianissimo *
+rnbqk2r/ppp2ppp/3p1n2/2b1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Giuoco Pianissimo *
+rnbqk2r/ppp2ppp/3p1n2/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Two knights defense (Modern bishop's opening) *
+rnbqk2r/ppp2ppp/3p1n2/4p3/1b2P3/5N2/PPPPNPPP/R1BQKB1R b KQkq -
+Ruy Lopez: Berlin defense, Mortimer variation *
+rnbqk2r/ppp2ppp/3p1n2/4p3/4P3/2bP1N2/PPP2PPP/R1BQKB1R w KQkq -
+Ruy Lopez: Berlin defense, Anderssen variation *
+rnbqk2r/ppp2ppp/3p1n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R w KQkq -
+Ruy Lopez: Anderssen variation *
+rnbqk2r/ppp2ppp/3p4/2b1pP2/2B1P1n1/2N5/PPPP2PP/R1BQK1NR b KQkq -
+Giuoco Pianissimo: Dubois variation *
+rnbqk2r/ppp2ppp/3p4/2b5/N2pP1n1/5N2/PPP2PPP/R1BQKB1R w KQkq -
+two knights defense: Kieseritsky variation *
+rnbqk2r/ppp2ppp/3p4/4p3/1b2n3/2P2N2/PP1PNPPP/R1BQKB1R b KQkq -
+Ruy Lopez: Berlin defense, Mortimer trap *
+rnbqk2r/ppp2ppp/4p3/3p4/2PPn3/P1Q5/1P2PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, Noa variation, main line
+rnbqk2r/ppp2ppp/4p3/3p4/2PPn3/P7/1PQ1PPPP/R1B1KBNR b KQkq -
+Nimzo-Indian: classical, Noa variation, main line, 7.Qc2
+rnbqk2r/ppp2ppp/4pn2/3p2B1/1b1PP3/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: MacCutcheon variation
+rnbqk2r/ppp2ppp/4pn2/3p2B1/1bPP4/5N2/PP2PPPP/RN1QKB1R w KQkq -
+QGD: Vienna variation
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD: Ragozin variation
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, Noa variation
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/P1N5/1PQ1PPPP/R1B1KBNR b KQkq -
+Nimzo-Indian: classical, Noa variation, 5.a3
+rnbqk2r/ppp2ppp/4pn2/3pP1B1/1b1P4/2N5/PPP2PPP/R2QKBNR b KQkq -
+French: MacCutcheon, advance variation
+rnbqk2r/ppp2ppp/4pn2/6B1/1bpP4/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+QGD: Ragozin, Vienna variation
+rnbqk2r/ppp2ppp/5n2/1BbPp3/8/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Scotch gambit *
+rnbqk2r/ppp2ppp/5n2/2bPp3/1PP5/8/P2P1PPP/RNBQKBNR b KQkq -
+Center game, Kieseritsky variation *
+rnbqk2r/ppp2ppp/5n2/2bPp3/8/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Scotch gambit: Dubois-R\'eti defense *
+rnbqk2r/ppp2ppp/5n2/2bPp3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Scotch gambit *
+rnbqk2r/ppp2ppp/5n2/2bPp3/8/2N5/PPPPBPPP/R1BQK1NR b KQkq -
+Scotch gambit: Benima defense *
+rnbqk2r/ppp2ppp/5n2/2bPp3/8/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Bishop's opening/Petrov: Urusov gambit *
+rnbqk2r/ppp2ppp/5n2/2bpp3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Two knights defense *
+rnbqk2r/ppp2ppp/5n2/2bpp3/4P3/3P1N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Nimzovich, Klein variation *
+rnbqk2r/ppp2ppp/5n2/3P4/1b3P2/2NPp3/PPPB2PP/R2QKBNR w KQkq -
+KGD: Falkbeer, Morphy gambit
+rnbqk2r/ppp2ppp/5n2/3Pp3/1b6/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Scotch: Relfsson gambit (`MacLopez') *
+rnbqk2r/ppp2ppp/5n2/3p4/1b1P4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, Noa variation, 5.cd ed
+rnbqk2r/ppp2ppp/5n2/3pp3/4P3/P1PP1P2/2P3PP/R1BQKBNR b KQkq -
+Ruy Lopez: modern Steinitz defense, Alapin variation *
+rnbqk2r/ppp2ppp/5n2/3pp3/4P3/P1PP4/2P2PPP/R1BQKBNR w KQkq -
+Ruy Lopez: modern Steinitz defense, Richter variation *
+rnbqk2r/ppp2ppp/8/1Bbp4/3NP1n1/2N5/PPP2PPP/R1BQK2R b KQkq -
+two knights defense: Pincus variation *
+rnbqk2r/ppp2ppp/8/2bPp3/2B3n1/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Scotch gambit *
+rnbqk2r/ppp2ppp/8/2bPp3/5P2/3P3N/PPP3Pn/RNBQKB1R w KQkq -
+Philidor: L\'opez counter-gambit, Jaenisch variation *
+rnbqk2r/ppp2ppp/8/2bPp3/6n1/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Two knights defense, Perreux variation *
+rnbqk2r/ppp2ppp/8/2bp4/3NP1n1/2N5/PPP2PPP/R1BQKB1R w KQkq -
+two knights defense: Lolli attack *
+rnbqk2r/ppp2ppp/8/2bpp3/4P1n1/2PP4/PP1N1PPP/R1BQKBNR w KQkq -
+Philidor: Hanham, Kmoch variation *
+rnbqk2r/ppp3p1/8/2bppPPp/4nP2/8/PPPPQ2P/RNB1KBNR w KQkq -
+KGA: Kieseritsky, Salvio defense, Cozio variation *
+rnbqk2r/ppp3p1/8/3ppPPp/3b4/7P/PPP3K1/RNBQ1BNR w kq -
+KGA: Allgaier, Urusov attack *
+rnbqk2r/ppp3pp/5n2/2bppPP1/8/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: Ghulam Kassim gambit *
+rnbqk2r/ppp3pp/5p2/3np3/1b2P3/3P1N2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Prins variation, Venice attack *
+rnbqk2r/pppn1pp1/4p2p/3pP3/1b1P4/2N5/PPPB1PPP/R2QKBNR w KQkq -
+French: MacCutcheon, Tartakower variation
+rnbqk2r/pppnb1pp/4pp2/3pP1B1/3P3P/2N5/PPP2PP1/R2QKBNR w KQkq -
+French: Albin-Alekhine-Ch\^atard attack, Teichmann variation
+rnbqk2r/pppnbppp/4p3/3pP1B1/3P3P/2N5/PPP2PP1/R2QKBNR b KQkq -
+French: Albin-Alekhine-Ch\^atard attack
+rnbqk2r/pppp1ppp/1b3n2/4p3/1PB1P3/P1N5/2PP1PPP/R1BQK1NR b KQkq -
+Ruy Lopez: Graz variation *
+rnbqk2r/pppp1ppp/1b3n2/4p3/NP2P3/P7/2PP1PPP/R1BQKBNR b KQkq -
+Ruy Lopez: Taimanov (chase/wing/accelerated counterthrust) variation *
+rnbqk2r/pppp1ppp/4pn2/6B1/1bPP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+Nimzo-Indian: Leningrad variation
+rnbqk2r/pppp1ppp/4pn2/8/1bP5/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+English: Nimzo-English opening
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/1QN5/PP2PPPP/R1B1KBNR b KQkq -
+Nimzo-Indian: Spielmann variation
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR b KQkq -
+Nimzo-Indian: 4.e3
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+Nimzo-Indian: three knights variation
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N2P2/PP2P1PP/R1BQKBNR b KQkq -
+Nimzo-Indian: Kmoch variation
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N3P1/PP2PP1P/R1BQKBNR b KQkq -
+Nimzo-Indian: Romanishin-Kasparov (Steiner) system
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Nimzo-Indian defense
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N5/PPQ1PPPP/R1B1KBNR b KQkq -
+Nimzo-Indian: classical variation
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2NQ4/PP2PPPP/R1B1KBNR b KQkq -
+Nimzo-Indian: Mikenas attack
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/5N2/PP1NPPPP/R1BQKB1R b KQkq -
+Bogo-Indian defense, Gr\"unfeld variation
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Bogo-Indian defense
+rnbqk2r/pppp1ppp/4pn2/8/2PP4/P1P5/4PPPP/R1BQKBNR b KQkq -
+Nimzo-Indian: S\"amisch variation
+rnbqk2r/pppp1ppp/5n2/1B2p3/1b2P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Ruy Lopez: Alapin's defense *
+rnbqk2r/pppp1ppp/5n2/2b1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Giuoco Piano *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Two knights defense *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+King's pawn game *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/2N5/PPPPBPPP/R1BQK1NR b KQkq -
+Hungarian defense *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov: Italian variation *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Rousseau gambit *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4PP2/3P4/PPP3PP/RNBQKBNR b KQkq -
+Philidor: L\'opez counter-gambit *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+Latvian gambit, 3.Bc4 *
+rnbqk2r/pppp1ppp/5n2/3Np3/1b2P3/8/PPPP1PPP/R1BQKBNR b KQkq -
+Ruy Lopez: Bird's defense *
+rnbqk2r/pppp1ppp/5n2/4P3/1bB2p2/2N5/PPPP2PP/R1BQK1NR b KQkq -
+KGA: bishop's gambit, Paulsen attack
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P1P1/2N5/PPPP1P1P/R1BQKBNR b KQkq -
+Ruy Lopez: Brentano defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P1Q1/2N5/PPPP1PPP/R1B1KBNR w KQkq -
+Vienna: Zhuravlev countergambit
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Ruy Lopez: Berlin defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N2P2/PPPP2PP/R1BQKBNR b KQkq -
+Ruy Lopez: Nuremberg variation *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+Ruy Lopez: fianchetto (Smyslov/Barnes) defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Ruy Lopez (Spanish opening) *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N5/PPPPBPPP/R1BQK1NR b KQkq -
+Ruy Lopez: Lucena defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N5/PPPPNPPP/R1BQKB1R b KQkq -
+Ruy Lopez: Cozio defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N5/PPPPQPPP/R1B1KBNR b KQkq -
+Ruy Lopez: Vinogradov variation *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2NP4/PPP2PPP/R1BQKBNR b KQkq -
+Ruy Lopez: old Steinitz defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Ruy Lopez: Schliemann defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1bB1P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Ruy Lopez: classical (Cordel) defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+Sicilian: Nimzovich-Rossolimo attack (with ...g6, without ...d6) *
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+English: Bremen, Smyslov system
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Sicilian: Nimzovich-Rossolimo attack (without ...d6) *
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/3P4/PP1BPPPP/RN1QKBNR b KQkq -
+Sicilian: Canal-Sokolsky attack, 3...Bd7 *
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/3P4/PP2PPPP/RNBQKBNR w KQkq -
+Sicilian: Canal-Sokolsky (Nimzovich-Rossolimo, Moscow) attack *
+rnbqk2r/pppp1ppp/5n2/4p3/2B1P3/2N5/PPPP1bPP/R1BQK1NR w KQkq -
+Giuoco Piano: Jerome gambit *
+rnbqk2r/pppp1ppp/5n2/4p3/4P3/P1PP4/2P2PPP/R1BQKBNR b KQkq -
+Ruy Lopez: modern Steinitz defense, exchange variation *
+rnbqk2r/pppp1ppp/5n2/4p3/4P3/P1b2N2/1PPP1PPP/R1BQKB1R w KQkq -
+Ruy Lopez: Treybal (Bayreuth) variation (exchange var. deferred) *
+rnbqk2r/pppp1ppp/5n2/4p3/4P3/P1b5/1PPP1PPP/R1BQKBNR w KQkq -
+Ruy Lopez: exchange variation *
+rnbqk2r/pppp1ppp/5n2/4p3/Nb2P3/8/PPPP1PPP/R1BQKBNR b KQkq -
+Ruy Lopez: Pollock defense *
+rnbqk2r/pppp1ppp/5n2/b2Np3/4P3/P7/1PPP1PPP/R1BQKBNR b KQkq -
+Ruy Lopez: Bird's defense deferred *
+rnbqk2r/pppp1ppp/5n2/b3p3/1P2P3/P1N5/2PP1PPP/R1BQKBNR b KQkq -
+Ruy Lopez: Caro variation *
+rnbqk2r/pppp1ppp/5n2/b3p3/2B1P3/P1N5/1PPP1PPP/R1BQK1NR b KQkq -
+Ruy Lopez: Classical defense deferred *
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R b KQkq -
+Ruy Lopez: Morphy defense *
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N3P1/1PPP1P1P/R1BQKBNR b KQkq -
+Ruy Lopez: fianchetto defense deferred *
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N5/1PPP1PPP/R1BQKBNR w KQkq -
+Ruy Lopez *
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N5/1PPPNPPP/R1BQKB1R b KQkq -
+Ruy Lopez: Cozio defense deferred *
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR b KQkq -
+Ruy Lopez: modern Steinitz defense *
+rnbqk2r/pppp1ppp/5n2/b3p3/4PP2/P1N5/1PPP2PP/R1BQKBNR b KQkq -
+Ruy Lopez: Schliemann defense deferred *
+rnbqk2r/pppp1ppp/5n2/bB2p3/4P3/P1N5/1PPP1PPP/R1BQK1NR b KQkq -
+Ruy Lopez: Alapin's defense deferred *
+rnbqk2r/pppp1ppp/8/2b1P3/3Pn3/8/PPP3PP/RNBQKBNR b KQkq -
+Latvian: Polerio variation *
+rnbqk2r/pppp1ppp/8/2b1P3/4n3/5N2/PPPP2PP/RNBQKB1R b KQkq -
+Latvian: corkscrew counter-gambit *
+rnbqk2r/pppp1ppp/8/2b1p3/2B1P1n1/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+two knights defense: Wilkes Barre (Traxler) variation *
+rnbqk2r/pppp1ppp/8/2b1p3/4P1n1/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Two knights defense *
+rnbqk2r/pppp1ppp/8/2b5/1P1pP1n1/2N2N2/P1P2PPP/R1BQKB1R b KQkq -
+two knights defense: Ulvestad variation *
+rnbqk2r/pppp1ppp/8/2b5/3NP3/2N5/PPP2nPP/R1BQKB1R w KQkq -
+two knights defense: Fegatello attack *
+rnbqk2r/pppp1ppp/8/2b5/N2pP1n1/5N2/PPP2PPP/R1BQKB1R b KQkq -
+two knights defense *
+rnbqk2r/pppp1ppp/8/2bN4/3pP1n1/5N2/PPP2PPP/R1BQKB1R b KQkq -
+two knights defense: Fritz variation *
+rnbqk2r/pppp1ppp/8/8/Nb1pP1n1/5N2/PPP2PPP/R1BQKB1R w KQkq -
+Two knights defense *
+rnbqk2r/pppp2p1/5n2/2b1pP1p/6P1/8/PPPP1PBP/RNBQK1NR w KQkq -
+KGA: Philidor gambit *
+rnbqk2r/pppp2p1/8/2b1pPPp/4n3/5N2/PPPP1P1P/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Berlin defense, 6.Bc4 *
+rnbqk2r/pppp2p1/8/2b1pPPp/8/7P/PPPP1K2/RNBQ1BNR w kq -
+KGA: Allgaier, Walker attack *
+rnbqk2r/pppp2pp/4pn2/5p2/1bPP4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+Dutch defense: Dutch-Indian (Nimzo-Dutch) variation
+rnbqk2r/pppp2pp/5n2/2b1pP2/6P1/2N5/PPPP1P1P/R1BQKBNR b KQkq -
+KGA: Blachly gambit *
+rnbqk2r/pppp2pp/5n2/2b1pP2/6P1/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: King's knight's gambit *
+rnbqk2r/pppp2pp/5n2/2b1pP2/6P1/8/PPPP1PBP/RNBQK1NR b KQkq -
+King's knight's gambit *
+rnbqk2r/pppp2pp/5n2/2b1pP2/8/5N2/PPPPBPPP/RNBQK2R b KQkq -
+KGA: Cunningham, Euwe defense *
+rnbqk2r/pppp2pp/5n2/2b2P2/3N4/2P5/P4PPP/RNBQKB1R b KQkq -
+KGA: Abbazia defense, Botvinnik variation *
+rnbqk2r/pppp2pp/5n2/4pPP1/8/8/PPPP1b1P/RNBQKBNR w KQkq -
+KGA: Lolli gambit (wild Muzio gambit) *
+rnbqk2r/pppp2pp/8/2b1pPP1/4n3/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: Salvio gambit *
+rnbqk2r/pppp3p/5np1/2b1pP1B/8/8/PPPP1PPP/RNBQK1NR w KQkq -
+KGA: Cunningham, Bertin gambit *
+rnbqk2r/ppppb1pp/4pn2/5p2/2PP4/6P1/PP1BPPBP/RN1QK1NR w KQkq -
+Dutch-Indian, Alekhine variation
+rnbqk2r/ppppb1pp/4pn2/5p2/2PP4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+Dutch defense
+rnbqk2r/ppppbppp/3n4/4p2Q/8/1BN5/PPPP1PPP/R1B1K1NR w KQkq -
+Vienna game
+rnbqk2r/ppppbppp/5n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Inverted Hungarian *
+rnbqk2r/ppppbppp/5n2/8/2B1Pp2/5N2/PPPP2PP/RNBQK2R w KQkq -
+KGA: Cunningham, Euwe defense
+rnbqk2r/ppppbppp/7n/8/N3P3/2P2N1P/P4PP1/R1BQKB1R w KQkq -
+two knights defense: Steinitz variation *
+rnbqk2r/ppppbppp/8/4P3/N3n3/2P2N1P/P1Q2PP1/R1B1KB1R b KQkq -
+two knights defense: G\"oring variation *
+rnbqk2r/ppppbppp/8/8/N3P1n1/2P2N1P/P4PP1/R1BQKB1R b KQkq -
+Two knights defense *
+rnbqk2r/ppppbppp/8/8/N3P1n1/2P2N2/P4PPP/R1BQKB1R w KQkq -
+Two knights defense *
+rnbqk2r/ppppp1bp/5np1/5p2/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+Dutch: Leningrad, main variation
+rnbqk2r/ppppp2p/6pb/5P2/3P4/8/PPP2PPP/RN1QKBNR b KQkq -
+Amar gambit *
+rnbqk2r/ppppppbp/5np1/6B1/3P4/8/PPPNPPPP/R2QKBNR b KQkq -
+R\'eti: King's Indian attack, Keres variation *
+rnbqk2r/ppppppbp/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+R\'eti: King's Indian attack *
+rnbqk2r/ppppppbp/5np1/8/2PPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+King's Indian: 4.e4
+rnbqkb1r/1p2pppp/p2p1n2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: Najdorf, 6.Bg5
+rnbqkb1r/1p2pppp/p2p1n2/8/2BNP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Sicilian: Najdorf, Lipnitzky attack
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N1B3/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: Najdorf, Byrne (English) attack
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N3P1/PPP2P1P/R1BQKB1R b KQkq -
+Sicilian: Najdorf, Zagreb (fianchetto) variation
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N4P/PPP2PP1/R1BQKB1R b KQkq -
+Sicilian: Najdorf, Adams attack
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+Sicilian: Najdorf, Opo\v censky variation
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Najdorf
+rnbqkb1r/1p2pppp/p2p1n2/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+Sicilian: Najdorf, 6.f4
+rnbqkb1r/1p2pppp/p4n2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+Queen's Indian: Petrosian system *
+rnbqkb1r/1p3p1p/p2ppnp1/8/2PNP3/3B4/PP3PPP/RNBQ1RK1 w kq -
+Sicilian: Kan, Gipslis variation
+rnbqkb1r/1p3ppp/p1p1pn2/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: accelerated Meran (Alekhine variation)
+rnbqkb1r/1p3ppp/p2ppn2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Najdorf, 6...e6
+rnbqkb1r/1p3ppp/p2ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R b KQkq -
+Sicilian: Najdorf, 7.f4
+rnbqkb1r/1p3ppp/p2ppn2/8/3NP3/2N1B3/PPPQ1PPP/R3KB1R b KQkq -
+Sicilian: Scheveningen, English variation
+rnbqkb1r/1p3ppp/p2ppn2/8/3NP3/2N5/PPP1BPPP/R1BQK2R w KQkq -
+Sicilian: Scheveningen (Paulsen), classical variation
+rnbqkb1r/1p3ppp/p3pn2/2p5/2BP4/4PN2/PP2QPPP/RNB2RK1 b kq -
+QGA: classical, 7.Qe2
+rnbqkb1r/1p3ppp/p3pn2/2p5/2BP4/4PN2/PP3PPP/RNBQ1RK1 w kq -
+QGA: classical, 6...a6
+rnbqkb1r/1p3ppp/p3pn2/2p5/2BPP3/5N2/PP3PPP/RNBQ1RK1 b kq -
+QGA: classical, Geller variation
+rnbqkb1r/1p3ppp/p3pn2/2p5/P1BP4/4PN2/1P3PPP/RNBQ1RK1 b kq -
+QGA: classical, Rubinstein variation
+rnbqkb1r/1p3ppp/p4n2/1N1pp1B1/Q1P5/2N5/PP2PPPP/R3KB1R b KQkq -
+QGD: Semi-Tarrasch, Krause variation
+rnbqkb1r/1pp1pppp/p4n2/8/2pPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+QGA, Bogolyubov variation
+rnbqkb1r/1ppp1ppp/p3pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Dzindzikhashvili defense
+rnbqkb1r/2pp1ppp/p3pn2/1p6/2P5/5NP1/PP1PPPBP/RNBQK2R w KQkq -
+English: Romanishin gambit
+rnbqkb1r/3ppppp/P4n2/2pP4/8/8/PP2PPPP/RNBQKBNR b KQkq -
+Benk\"o gambit accepted
+rnbqkb1r/3ppppp/p4n2/1PpP4/8/2N5/PP2PPPP/R1BQKBNR b KQkq -
+Benk\"o gambit: Zaitsev system
+rnbqkb1r/3ppppp/p4n2/1PpP4/8/8/PP2PPPP/RNBQKBNR w KQkq -
+Benk\"o gambit half accepted
+rnbqkb1r/4pppp/3p1n2/1NpP4/1pB1P3/8/PP3PPP/R1BQK1NR b KQkq -
+Benk\"o gambit: Nescaf\'e Frapp\'e attack
+rnbqkb1r/5ppp/p2ppn2/1p4B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+Sicilian: Najdorf, Polugayevsky variation
+rnbqkb1r/5ppp/p2ppn2/1p6/3NP3/1BN5/PPP2PPP/R1BQK2R w KQkq -
+Sicilian: Sozin with ...a6 and ...b5
+rnbqkb1r/5ppp/p3pn2/1pp5/2BP4/4PN2/PP2QPPP/RNB2RK1 w kq -
+QGA: classical, 7...b5
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2P5/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+English: Queens Indian formation
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP1B2/5N2/PP2PPPP/RN1QKB1R b KQkq -
+Queen's Indian: Miles variation
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+Queen's Indian: 4.Nc3
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+Queen's Indian: 4.e3
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Queen's Indian defense
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/5NP1/PP2PP1P/RNBQKB1R b KQkq -
+Queen's Indian: 4.g3
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/P4N2/1P2PPPP/RNBQKB1R b KQkq -
+Queen's Indian: Petrosian system
+rnbqkb1r/p1pp1ppp/5n2/1p2p3/2P5/3P4/PP2PPPP/RNBQKBNR w KQkq -
+Sicilian: wing gambit deferred *
+rnbqkb1r/p1pp1ppp/5n2/1p4N1/2P1p3/2N5/PP1PPPPP/R1BQKB1R w KQkq -
+English: Bellon gambit
+rnbqkb1r/p1pp1ppp/5n2/1p6/2PPp3/4P3/PP3PPP/RNBQKBNR w KQkq -
+French: Wing gambit *
+rnbqkb1r/p1pp2pp/5n2/1p2pp2/2B1P3/3P4/PPP2PPP/RNBQK1NR w KQkq -
+KGD: classical, Heath variation *
+rnbqkb1r/p1ppp1pp/1p3n2/6B1/3Pp3/2N5/PPP2PPP/R2QKBNR w KQkq -
+Dutch: Staunton gambit, Nimzovich variation
+rnbqkb1r/p1pppp1p/5np1/1p1P4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+King's Indian: Danube gambit
+rnbqkb1r/p1pppp1p/5np1/1p6/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+R\'eti: King's Indian attack, R\'eti-Smyslov variation *
+rnbqkb1r/p1pppppp/1p3n2/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Queen's Indian accelerated
+rnbqkb1r/p1pppppp/1p3n2/8/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's Indian defense
+rnbqkb1r/p1pppppp/1p3n2/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+R\'eti: Nimzovich-Larsen attack *
+rnbqkb1r/p1pppppp/5n2/1p6/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Santasiere's folly *
+rnbqkb1r/p1pppppp/5n2/1p6/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+R\'eti: King's Indian attack, Spassky's variation
+rnbqkb1r/p1pppppp/8/1p1nP3/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+Alekhine's defense: O'Sullivan gambit
+rnbqkb1r/p2n1ppp/1p2p3/2ppP3/3P4/2PB4/PP1N1PPP/R1BQK1NR w KQkq -
+French: Tarrasch, Botvinnik variation
+rnbqkb1r/p2p1pp1/5n1p/1ppP2B1/8/5N2/PP2PPPP/RN1QKB1R w KQkq -
+Blumenfeld counter-gambit, Spielmann variation
+rnbqkb1r/p2p1ppp/4pn2/1ppP2B1/2P5/5N2/PP2PPPP/RN1QKB1R b KQkq -
+Blumenfeld counter-gambit, Dus-Chotimursky variation
+rnbqkb1r/p2p1ppp/4pn2/1ppP4/2P5/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Blumenfeld counter-gambit
+rnbqkb1r/p2ppp1p/1p3np1/2p3B1/3P4/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+English: Torre defensive system *
+rnbqkb1r/p2ppp1p/1p3np1/2p5/3P1B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+English: London defensive system *
+rnbqkb1r/p2ppppp/1p3n2/2p3B1/3P4/2P5/PP2PPPP/RN1QKBNR b KQkq -
+English: Caro-Kann defensive system, Bogolyubov variation *
+rnbqkb1r/p2ppppp/1p3n2/2p5/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+English: Caro-Kann defensive system *
+rnbqkb1r/p2ppppp/5n2/1ppP4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+Benk\"o gambit
+rnbqkb1r/p3pppp/2p2n2/1p2P3/2pP4/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+QGD Slav: Tolush-Geller gambit
+rnbqkb1r/p3pppp/5n2/1ppP4/2p1P3/2N5/PP3PPP/R1BQKBNR w KQkq -
+QGA: Linares variation
+rnbqkb1r/p4p2/2p1p2p/1p1nP1N1/2pP3B/2N5/PP3PPP/R2QKB1R w KQkq -
+QGD semi-Slav: anti-Meran, Alatortsev system
+rnbqkb1r/p4p2/2p1pP1p/1p2N3/2pP3p/2N5/PP3PPP/R2QKB1R b KQkq -
+QGD semi-Slav: Ekstrom variation
+rnbqkb1r/p4p2/2p1pn1p/1p2P1N1/2pP3B/2N5/PP3PPP/R2QKB1R b KQkq -
+QGD semi-Slav: anti-Meran gambit
+rnbqkb1r/p4ppp/2p5/3n4/2B2p2/5N2/PPPP2PP/RNBQK2R w KQkq -
+KGA: Abbazia defense, Botvinnik variation
+rnbqkb1r/p5pp/4pn2/1Ppp4/8/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Blumenfeld counter-gambit accepted
+rnbqkb1r/pp1n1ppp/4p3/2ppP3/3P1P2/2N2N2/PPP3PP/R1BQKB1R b KQkq -
+French: Steinitz variation
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+English: Bremen system, Keres variation
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Ponziani: Jaenisch counter-attack *
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Ponziani opening *
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/4P3/2N5/PPPPBPPP/R1BQK1NR b KQkq -
+Ponziani: Romanishin variation *
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/4P3/2N5/PPPPNPPP/R1BQKB1R b KQkq -
+Ponziani: R\'eti variation *
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Ponziani counter-gambit *
+rnbqkb1r/pp1p1ppp/2p2n2/8/2B1Pp2/2N5/PPPP2PP/R1BQK1NR w KQkq -
+KGA: bishop's gambit, Jaenisch variation
+rnbqkb1r/pp1p1ppp/2p5/3Nn3/1P1NP3/8/P1P2PPP/R1BQKB1R w KQkq -
+two knights defense: Fritz, Gruber variation *
+rnbqkb1r/pp1p1ppp/4pn2/2P5/8/4B3/PPP1PPPP/RN1QKBNR b KQkq -
+R\'eti accepted: Keres variation *
+rnbqkb1r/pp1p1ppp/4pn2/2p3B1/3PP3/5N2/PPP2PPP/RN1QKB1R b KQkq -
+Queen's pawn: Torre attack, Wagner gambit
+rnbqkb1r/pp1p1ppp/4pn2/2p5/2P1P3/2N5/PP1P1PPP/R1BQKBNR w KQkq -
+English: Mikenas-Carls, Sicilian variation
+rnbqkb1r/pp1p1ppp/4pn2/2pP4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+Benoni defense
+rnbqkb1r/pp1p1ppp/4pn2/8/2PN4/8/PP2PPPP/RNBQKB1R w KQkq -
+English: symmetrical variation
+rnbqkb1r/pp1p1ppp/4pn2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Anderssen variation
+rnbqkb1r/pp1p1ppp/5n2/2p1N3/8/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: Kaufmann attack *
+rnbqkb1r/pp1p1ppp/5n2/2p1p3/2P5/6PB/PP1PPP1P/RNBQK1NR b KQkq -
+Sicilian: Acton extension *
+rnbqkb1r/pp1p1ppp/5n2/2p1p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Dresden opening *
+rnbqkb1r/pp1p1ppp/5n2/2pPp3/2P5/8/PP2PPPP/RNBQKBNR w KQkq e6
+Czech Benoni defense
+rnbqkb1r/pp1p2pp/2p2n2/4pp2/2B1P3/3P4/PPP2PPP/RNBQK1NR w KQkq -
+KGD: classical, 4.c3 *
+rnbqkb1r/pp1p2pp/2p2n2/4pp2/2B1PP2/3P4/PPP3PP/RNBQK1NR b KQkq -
+KGD: classical counter-gambit *
+rnbqkb1r/pp1pp1pp/2p2n2/6B1/3Pp3/2N5/PPP2PPP/R2QKBNR w KQkq -
+Dutch: Staunton gambit, Chigorin variation
+rnbqkb1r/pp1ppp1p/5np1/2p5/3P4/2P1P3/PP3PPP/RNBQKBNR b KQkq -
+English: Kurajica defense *
+rnbqkb1r/pp1ppp1p/5np1/2p5/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+English opening: Agincourt variation *
+rnbqkb1r/pp1ppp1p/5np1/2p5/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+English: Neo-Catalan *
+rnbqkb1r/pp1ppppp/1n6/2p1P3/8/1B1P4/PPP2PPP/RNBQK1NR b KQkq -
+Alekhine's defense: Kmoch variation
+rnbqkb1r/pp1ppppp/2p2n2/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Caro-Masi defense
+rnbqkb1r/pp1ppppp/5n2/2P5/8/8/PPP1PPPP/RNBQKBNR b KQkq -
+R\'eti accepted *
+rnbqkb1r/pp1ppppp/5n2/2p1P3/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+English, Nimzovich, Flohr variation *
+rnbqkb1r/pp1ppppp/5n2/2p5/2P5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+English: symmetrical variation
+rnbqkb1r/pp1ppppp/5n2/2p5/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+English: symmetrical, Benoni formation
+rnbqkb1r/pp1ppppp/5n2/2p5/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Benoni defense
+rnbqkb1r/pp1ppppp/5n2/2p5/3P4/4P3/PPP2PPP/RNBQKBNR b KQkq -
+English opening: Agincourt variation *
+rnbqkb1r/pp1ppppp/5n2/2p5/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+R\'eti opening *
+rnbqkb1r/pp1ppppp/5n2/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian: Nimzovich-Rubinstein variation
+rnbqkb1r/pp1ppppp/5n2/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+English, Nimzovich variation *
+rnbqkb1r/pp1ppppp/5n2/2p5/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+English opening *
+rnbqkb1r/pp1ppppp/5n2/2pP4/8/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Old Benoni defense
+rnbqkb1r/pp1ppppp/5n2/2pP4/8/8/PPP1PPPP/RNBQKBNR b KQkq -
+R\'eti: advance variation *
+rnbqkb1r/pp1ppppp/5n2/2pP4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+Old Benoni defense
+rnbqkb1r/pp1ppppp/5n2/3P4/2p5/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Hawk (Habichd) defense
+rnbqkb1r/pp1ppppp/8/2pP4/2P1n3/8/PP2PPPP/RNBQKBNR w KQkq -
+Vulture defense
+rnbqkb1r/pp2pp1p/2p2np1/3p4/2P5/1P3N2/PB1PPPPP/RN1QKB1R w KQkq -
+English: Bled variation
+rnbqkb1r/pp2pp1p/2p2np1/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD Slav\Gr\"unfeld: Schlechter variation
+rnbqkb1r/pp2pp1p/2p2p2/8/3P4/8/PPP2PPP/R1BQKBNR w KQkq -
+Caro-Kann: Bronstein-Larsen variation
+rnbqkb1r/pp2pp1p/2pp1np1/8/3PP3/2N1B3/PPPQ1PPP/R3KBNR b KQkq -
+Pirc: 150 attack
+rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N1B3/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: dragon, 6.Be3
+rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: dragon variation
+rnbqkb1r/pp2pp1p/3p1np1/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+Sicilian: dragon, Levenfish variation
+rnbqkb1r/pp2pp1p/5np1/2pP4/4p3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+QGD: Albin counter-gambit, 5.g3 *
+rnbqkb1r/pp2pp1p/5np1/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+Queen's Indian: 4.g3 *
+rnbqkb1r/pp2pp1p/5np1/2pp4/8/1P2PN2/PBPP1PPP/RN1QKB1R b KQkq -
+Queen's Indian: 4.g3 Bb7 *
+rnbqkb1r/pp2pp1p/5np1/2pp4/8/BP2PN2/P1PP1PPP/RN1QKB1R b KQkq -
+Queen's Indian: Nimzovich variation (exaggerated fianchetto) *
+rnbqkb1r/pp2pp1p/5np1/3p4/2PP4/2N5/PP3PPP/R1BQKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik attack, 5...g6
+rnbqkb1r/pp2pp1p/6p1/2p3B1/2PPp3/8/PP1QPPPP/R3KBNR w KQkq -
+Gr\"unfeld: Lundin variation
+rnbqkb1r/pp2pppp/2p2n2/3P4/2P5/8/PP1P1PPP/RNBQKBNR w KQkq -
+Scandinavian gambit
+rnbqkb1r/pp2pppp/2p2n2/3p4/2P5/1P3N2/PB1PPPPP/RN1QKB1R b KQkq -
+English: Caro-Kann defensive system
+rnbqkb1r/pp2pppp/2p2n2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+QGD Slav: 4.Nc3
+rnbqkb1r/pp2pppp/2p2n2/3p4/2PP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+QGD Slav: 4.e3
+rnbqkb1r/pp2pppp/2p2n2/3p4/2PP4/5N2/PP1NPPPP/R1BQKB1R b KQkq -
+QGD Slav: Breyer variation
+rnbqkb1r/pp2pppp/2p2n2/8/2pP4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+QGD Slav: 5.e3 (Alekhine variation)
+rnbqkb1r/pp2pppp/2p2n2/8/2pP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD Slav accepted
+rnbqkb1r/pp2pppp/2p2n2/8/2pPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+QGD Slav: Slav gambit
+rnbqkb1r/pp2pppp/2p2n2/8/3PN3/3B4/PPP2PPP/R1BQK1NR b KQkq -
+Caro-Kann: Alekhine gambit
+rnbqkb1r/pp2pppp/2p2n2/8/P1pP4/2N2N2/1P2PPPP/R1BQKB1R b KQkq -
+QGD Slav accepted: Alapin variation
+rnbqkb1r/pp2pppp/2pp1n2/8/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Pirc: Ufimtsev-Pytel variation
+rnbqkb1r/pp2pppp/3p1n2/2p5/3PP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Cortlever (Alatortsev) variation
+rnbqkb1r/pp2pppp/3p1n2/2pP4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+Benoni defense, Hromodka system
+rnbqkb1r/pp2pppp/3p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Sicilian
+rnbqkb1r/pp2pppp/3p1n2/8/3NP3/5P2/PPP3PP/RNBQKB1R b KQkq -
+Sicilian: Prins (Moscow) variation
+rnbqkb1r/pp2pppp/5n2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R b KQkq -
+Bogo-Indian defense *
+rnbqkb1r/pp2pppp/5n2/2Pp4/1P6/8/P1P1PPPP/RNBQKBNR b KQkq -
+QGA: Ericson variation *
+rnbqkb1r/pp2pppp/5n2/2Pp4/3P4/8/PP3PPP/RNBQKBNR b KQkq -
+Caro-Kann: Panov-Botvinnik, Gunderam attack
+rnbqkb1r/pp2pppp/5n2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Queen's gambit accepted *
+rnbqkb1r/pp2pppp/5n2/2Pp4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+QGA: 3.Nf3 *
+rnbqkb1r/pp2pppp/5n2/2Pp4/8/P7/1PP1PPPP/RNBQKBNR b KQkq -
+QGA: Alekhine defense *
+rnbqkb1r/pp2pppp/5n2/2p3N1/4p3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Budapest: Adler variation *
+rnbqkb1r/pp2pppp/5n2/2p5/1PPp4/4PN2/P2P1PPP/RNBQKB1R b KQkq -
+Blumenfeld counter-gambit *
+rnbqkb1r/pp2pppp/5n2/2pP4/4p3/8/PPP2PPP/RNBQKBNR w KQkq -
+QGD: Albin counter-gambit *
+rnbqkb1r/pp2pppp/5n2/2pp4/2P5/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+English: symmetrical, Benoni formation *
+rnbqkb1r/pp2pppp/5n2/2pp4/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+QGD Slav: 3.Nf3 *
+rnbqkb1r/pp2pppp/5n2/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+Neo-Gr\"unfeld defense *
+rnbqkb1r/pp2pppp/5n2/2pp4/5P2/4PN2/PPPP2PP/RNBQKB1R w KQkq -
+Bird's opening: Lasker variation
+rnbqkb1r/pp2pppp/5n2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R b KQkq -
+Queen's Indian defense *
+rnbqkb1r/pp2pppp/5n2/2pp4/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+Queen's pawn game *
+rnbqkb1r/pp2pppp/5n2/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian, 3.Nf3 *
+rnbqkb1r/pp2pppp/5n2/2pp4/8/P3PN2/1PPP1PPP/RNBQKB1R b KQkq -
+Dzindzikhashvili defense *
+rnbqkb1r/pp2pppp/5n2/2ppN3/8/4P3/PPPP1PPP/RNBQKB1R b KQkq -
+D\"ory defense *
+rnbqkb1r/pp2pppp/5n2/3p4/2PP4/2N5/PP3PPP/R1BQKBNR b KQkq -
+Caro-Kann: Panov-Botvinnik attack
+rnbqkb1r/pp2pppp/5n2/3p4/3P4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+QGD Slav: exchange variation *
+rnbqkb1r/pp2pppp/5n2/3p4/3P4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav: exchange variation
+rnbqkb1r/pp2pppp/5n2/8/1pPP4/4PN2/P5PP/RNBQKB1R b KQkq -
+Blumenfeld counter-gambit accepted *
+rnbqkb1r/pp2pppp/8/2pn4/8/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+English: symmetrical, three knights system
+rnbqkb1r/pp2pppp/8/2pn4/8/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+English: symmetrical variation *
+rnbqkb1r/pp3p1p/2p1pnp1/3p4/2PP4/4PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD: Spielmann variation
+rnbqkb1r/pp3p1p/3p1np1/2pP2B1/8/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+Benoni: Uhlmann variation
+rnbqkb1r/pp3p1p/3p1np1/2pP4/4P3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+Benoni: classical with e4 and Nf3
+rnbqkb1r/pp3p1p/3p1np1/2pP4/4PP2/2N5/PP4PP/R1BQKBNR b KQkq -
+Benoni: pawn storm variation
+rnbqkb1r/pp3p1p/3p1np1/2pP4/8/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+Benoni defense
+rnbqkb1r/pp3p1p/3p1np1/2pP4/8/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+Benoni: fianchetto variation
+rnbqkb1r/pp3p1p/3p1np1/2pP4/8/2N5/PP1NPPPP/R1BQKB1R b KQkq -
+Benoni: Nimzovich (knight's tour) variation
+rnbqkb1r/pp3p1p/3p1np1/2pPp3/2P1P3/2N5/PP3PPP/R1BQKBNR w KQkq -
+Czech Benoni: King's Indian system
+rnbqkb1r/pp3ppp/2p1pn2/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: 5.e3
+rnbqkb1r/pp3ppp/2p1pn2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD semi-Slav
+rnbqkb1r/pp3ppp/2p1pn2/3p4/2PP4/4PN2/PP1N1PPP/R1BQKB1R b KQkq -
+QGD Slav
+rnbqkb1r/pp3ppp/2p1pn2/6B1/2pP4/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+QGD semi-Slav: 5.Bg5 dc
+rnbqkb1r/pp3ppp/2p1pn2/6B1/2pPP3/2N2N2/PP3PPP/R2QKB1R b KQkq -
+QGD semi-Slav: Botvinnik system (anti-Meran)
+rnbqkb1r/pp3ppp/2p1pn2/8/P1pP4/2N2N2/1P2PPPP/R1BQKB1R w KQkq -
+QGD Slav: Soultanb\'eieff variation
+rnbqkb1r/pp3ppp/2p2n2/3Pp3/4P3/8/PP1P1PPP/RNBQKBNR w KQkq -
+Sicilian: Andreaschek gambit *
+rnbqkb1r/pp3ppp/2p2n2/3Pp3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Scotch: G\"oring gambit *
+rnbqkb1r/pp3ppp/2p2n2/3Pp3/8/3P4/PP2PPPP/RNBQKBNR w KQkq -
+Sicilian: Tartakower variation *
+rnbqkb1r/pp3ppp/2p2n2/3p2B1/3P4/2N5/PP2PPPP/R2QKBNR w KQkq -
+QGD: exchange, positional line, 5...c6
+rnbqkb1r/pp3ppp/2p2n2/3p2B1/3P4/2N5/PPQ1PPPP/R3KBNR b KQkq -
+QGD: exchange, positional line, 6.Qc2
+rnbqkb1r/pp3ppp/2p2n2/3p4/2PPp3/1Q2P3/PP1B1PPP/RN2KBNR b KQkq -
+French: advance, Wade variation *
+rnbqkb1r/pp3ppp/2p2n2/3p4/2PPp3/2N1P3/PP1B1PPP/R2QKBNR b KQkq -
+French: advance, Euwe variation *
+rnbqkb1r/pp3ppp/2p2n2/3p4/2PPp3/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+French: advance, Paulsen attack *
+rnbqkb1r/pp3ppp/2p2n2/3pp3/8/3P2P1/PPP1PPBP/RNBQK1NR w KQkq -
+Robatsch defense: Geller's system *
+rnbqkb1r/pp3ppp/2p2n2/4N3/2BpP3/2N5/PPPP1PPP/R1BQK2R b KQkq -
+Ponziani: Fraser defense *
+rnbqkb1r/pp3ppp/2p2n2/4p3/3pPP2/2NP4/PPP3PP/R1BQKBNR w KQkq -
+Ponziani counter-gambit, Schmidt attack *
+rnbqkb1r/pp3ppp/2p2p2/8/2BP4/8/PPP2PPP/R1BQK1NR b KQkq -
+Caro-Kann: Forg\'acs variation
+rnbqkb1r/pp3ppp/2p2p2/8/3P4/8/PPP2PPP/R1BQKBNR w KQkq -
+Caro-Kann: Tartakower (Nimzovich) variation
+rnbqkb1r/pp3ppp/3p1n2/1B2p3/3NP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Sicilian: Venice attack
+rnbqkb1r/pp3ppp/3p1n2/1B2p3/3NP3/5P2/PPP3PP/RNBQK2R b KQkq -
+Sicilian: Prins variation, Venice attack
+rnbqkb1r/pp3ppp/3p1n2/2pP4/4P3/2N5/PP3PPP/R1BQKBNR b KQkq -
+Benoni: 6.e4
+rnbqkb1r/pp3ppp/3ppn2/1B6/3NP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Sicilian: Scheveningen, Vitoli\'n\'s variation
+rnbqkb1r/pp3ppp/3ppn2/8/2BNP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Sicilian: Sozin attack
+rnbqkb1r/pp3ppp/3ppn2/8/3NP1P1/2N5/PPP2P1P/R1BQKB1R b KQkq -
+Sicilian: Scheveningen, Keres attack
+rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N3P1/PPP2P1P/R1BQKB1R b KQkq -
+Sicilian: Scheveningen, fianchetto variation
+rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+Sicilian: Scheveningen, 6.Be2
+rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Scheveningen variation
+rnbqkb1r/pp3ppp/3ppn2/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+Sicilian: Scheveningen, 6.f4
+rnbqkb1r/pp3ppp/4p3/2pn4/3P4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+QGD: Semi-Tarrasch with e3
+rnbqkb1r/pp3ppp/4pn2/2Pp2B1/8/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+QGA, Janowsky-Larsen variation *
+rnbqkb1r/pp3ppp/4pn2/2Pp4/1P6/P7/2P1PPPP/RNBQKBNR b KQkq -
+QGA: Haberditz variation *
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/4BN2/PPP1PPPP/RN1QKB1R b KQkq -
+QGA, Flohr variation *
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+QGA: 4...e6 *
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+QGA, 4.e3 *
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+QGA, Smyslov variation *
+rnbqkb1r/pp3ppp/4pn2/2p5/2BP4/4PN2/PP3PPP/RNBQ1RK1 b kq -
+QGA: classical variation, 6.O-O
+rnbqkb1r/pp3ppp/4pn2/2p5/2BP4/4PN2/PP3PPP/RNBQK2R w KQkq -
+QGA: classical variation
+rnbqkb1r/pp3ppp/4pn2/2pP2B1/3P4/2N5/PP2PPPP/R2QKBNR b KQkq -
+QGD: Semi-Tarrasch
+rnbqkb1r/pp3ppp/4pn2/2pP4/3P4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+QGD: Semi-Tarrasch, 5.cd
+rnbqkb1r/pp3ppp/4pn2/2pp2B1/2PP4/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+QGD: Semi-Tarrasch defense, Pillsbury variation
+rnbqkb1r/pp3ppp/4pn2/2pp2B1/2PP4/2N5/PP2PPPP/R2QKBNR w KQkq -
+QGD: Been-Koomen variation
+rnbqkb1r/pp3ppp/4pn2/2pp4/2P5/1P2PN2/PB1P1PPP/RN1QKB1R b KQkq -
+English: Wimpey system
+rnbqkb1r/pp3ppp/4pn2/2pp4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD: Semi-Tarrasch defense
+rnbqkb1r/pp3ppp/4pn2/2pp4/3P1B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+QGD Slav: 4.e3 Bf5 *
+rnbqkb1r/pp3ppp/4pn2/2pp4/3P4/1P1BPN2/P1P2PPP/RNBQK2R b KQkq -
+Queen's pawn game, Rubinstein (Colle-Zukertort) variation
+rnbqkb1r/pp3ppp/4pn2/2pp4/3P4/1P2PN2/P1PN1PPP/R1BQKB1R b KQkq -
+Queen's pawn game, Zukertort variation
+rnbqkb1r/pp3ppp/4pn2/2pp4/3P4/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav: 4.e3 *
+rnbqkb1r/pp3ppp/4pn2/2pp4/3P4/2PBPN2/PP3PPP/RNBQK2R b KQkq -
+Colle system
+rnbqkb1r/pp3ppp/4pn2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+Queen's Indian: 4.e3 *
+rnbqkb1r/pp3ppp/4pn2/3p2B1/2PQ4/2N2N2/PP2PPPP/R3KB1R b KQkq -
+QGD: Semi-Tarrasch, Primitive Pillsbury variation
+rnbqkb1r/pp3ppp/4pn2/3p4/2PP4/2N5/PP3PPP/R1BQKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik attack, 5...e6
+rnbqkb1r/pp3ppp/4pn2/8/2Bp4/4PN2/PP3PPP/RNBQ1RK1 w kq -
+QGA: classical, Steinitz variation
+rnbqkb1r/pp3ppp/5n2/2Ppp3/8/P7/1PP1PPPP/RNBQKBNR w KQkq -
+QGA: Alekhine defense, Borisenko-Furman variation *
+rnbqkb1r/pp3ppp/5n2/2p3B1/3pp3/1N1P4/PPP1PPPP/RN1QKB1R w KQkq -
+Alekhine's defense: modern, Vitolins attack *
+rnbqkb1r/pp3ppp/5n2/2pp2B1/3Np3/3P4/PPP1PPPP/RN1QKB1R w KQkq -
+Alekhine's defense: modern, Alekhine variation *
+rnbqkb1r/pp3ppp/5n2/2ppp1B1/8/3P2P1/PPP1PPBP/RN1QK1NR b KQkq -
+Robatsch defense: Rossolimo variation *
+rnbqkb1r/pp3ppp/8/2pnp3/8/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+Sicilian: accelerated fianchetto, Mar\'oczy bind *
+rnbqkb1r/pp3ppp/8/2pnp3/8/2N3P1/PP1PPPBP/R1BQK1NR b KQkq -
+Sicilian: accelerated fianchetto, Mar\'oczy bind, 5...Bg7 *
+rnbqkb1r/pp3ppp/8/2pnp3/8/P3P3/1P1P1PPP/RNBQKBNR w KQkq -
+Sicilian: Kan, Mar\'oczy bind (R\'eti variation) *
+rnbqkb1r/pp4pp/2p1p3/3p1p2/2PPn3/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: stonewall defense
+rnbqkb1r/pp4pp/2p1p3/3p1p2/2PPn3/3BPN2/PP1N1PPP/R1BQK2R w KQkq -
+QGD: Stonewall variation
+rnbqkb1r/pp4pp/5n2/3p2B1/2p5/1NN1P3/PPP1P1PP/R2QKB1R w KQkq -
+Alekhine's defense: four pawns attack, Ilyin-Genevsky variation *
+rnbqkb1r/ppn1pppp/8/2p5/8/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: symmetrical, Rubinstein system
+rnbqkb1r/ppp1p1pp/5n2/3p4/8/3B3N/PPP2PPP/RNBQK2R w KQkq -
+Bird: From gambit, Lipke variation *
+rnbqkb1r/ppp1pp1p/1n1p2p1/4P3/2PP1P2/8/PP4PP/RNBQKBNR w KQkq -
+Alekhine's defense: four pawns attack, fianchetto variation
+rnbqkb1r/ppp1pp1p/1n1p4/4P1p1/2PP1P2/8/PP4PP/RNBQKBNR w KQkq -
+Alekhine's defense: four pawns attack, Planinc variation
+rnbqkb1r/ppp1pp1p/1n4p1/8/8/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: Anglo-Gr\"unfeld, Czech defense
+rnbqkb1r/ppp1pp1p/3p1np1/6B1/3PP3/2N5/PPP2PPP/R2QKBNR b KQkq -
+Pirc: Byrne variation
+rnbqkb1r/ppp1pp1p/3p1np1/8/2BPP3/2N5/PPP2PPP/R1BQK1NR b KQkq -
+Pirc: Holmov system
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+Pirc: classical (two knights) system
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PP3/2N3P1/PPP2P1P/R1BQKBNR b KQkq -
+Pirc: Sveshnikov system
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PP3/2N5/PPP1BPPP/R1BQK1NR b KQkq -
+Pirc defense
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Pirc defense
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PPP2/2N5/PPP3PP/R1BQKBNR b KQkq -
+Pirc: Austrian attack
+rnbqkb1r/ppp1pp1p/3p2p1/3nP3/3P4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Alekhine's defense: modern, fianchetto variation
+rnbqkb1r/ppp1pp1p/5np1/3P4/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+Scandinavian: Richter variation
+rnbqkb1r/ppp1pp1p/5np1/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+Gr\"unfeld: Stockholm variation
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP1B2/2N5/PP2PPPP/R2QKBNR b KQkq -
+Gr\"unfeld: 4.Bf4
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP2P1/2N5/PP2PP1P/R1BQKBNR b KQkq -
+Gr\"unfeld: Spike gambit
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/1QN5/PP2PPPP/R1B1KBNR b KQkq -
+Gr\"unfeld: Russian variation
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+Gr\"unfeld: Three knights variation
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Gr\"unfeld defense
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Neo-Gr\"unfeld defense
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/5P2/PP2P1PP/RNBQKBNR w KQkq -
+Neo-Gr\"unfeld defense
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/6P1/PP2PP1P/RNBQKBNR w KQkq -
+Neo-Gr\"unfeld (Kemeri) defense
+rnbqkb1r/ppp1pp1p/5np1/3p4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian: fianchetto without c4 *
+rnbqkb1r/ppp1pp1p/5np1/8/2pP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGA, Smyslov variation
+rnbqkb1r/ppp1pp1p/6p1/3n4/3P4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Gr\"unfeld: exchange variation
+rnbqkb1r/ppp1pp1p/6p1/8/8/2n3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: Anglo-Gr\"unfeld, Smyslov defense
+rnbqkb1r/ppp1pppp/1n1P4/8/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+Alekhine's defense: exchange variation
+rnbqkb1r/ppp1pppp/1n1p4/4P3/2PP1P2/8/PP4PP/RNBQKBNR b KQkq -
+Alekhine's defense: four pawns attack
+rnbqkb1r/ppp1pppp/1n1p4/4P3/3P4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Alekhine's defense: modern, Schmid variation
+rnbqkb1r/ppp1pppp/3p1n2/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Old Indian defense
+rnbqkb1r/ppp1pppp/3p1n2/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+R\'eti: old Indian attack *
+rnbqkb1r/ppp1pppp/3p1n2/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Pirc defense
+rnbqkb1r/ppp1pppp/3p4/3nP3/2BP4/8/PPP2PPP/RNBQK1NR b KQkq -
+Alekhine's defense: Balogh variation
+rnbqkb1r/ppp1pppp/3p4/3nP3/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+Alekhine's defense
+rnbqkb1r/ppp1pppp/3p4/3nP3/3P4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Alekhine's defense: modern variation
+rnbqkb1r/ppp1pppp/3p4/3nP3/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+Alekhine's defense
+rnbqkb1r/ppp1pppp/5n2/2P5/3p4/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+Hawk (Habichd) defense *
+rnbqkb1r/ppp1pppp/5n2/3P4/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+Scandinavian defense
+rnbqkb1r/ppp1pppp/5n2/3P4/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+Scandinavian defense
+rnbqkb1r/ppp1pppp/5n2/3p2B1/3P4/2N5/PPP1PPPP/R2QKBNR b KQkq -
+Richter-Veresov attack
+rnbqkb1r/ppp1pppp/5n2/3p2B1/3P4/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+Torre attack (Tartakower variation)
+rnbqkb1r/ppp1pppp/5n2/3p2B1/8/3P4/PPP1PPPP/RN1QKBNR b KQkq -
+Old Indian: Tartakower (Wade) variation *
+rnbqkb1r/ppp1pppp/5n2/3p4/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English: Anglo-Gr\"unfeld defense
+rnbqkb1r/ppp1pppp/5n2/3p4/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+Queen's pawn game, Krause variation *
+rnbqkb1r/ppp1pppp/5n2/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QGD: Marshall defense
+rnbqkb1r/ppp1pppp/5n2/3p4/3P1B2/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+Queen's bishop game
+rnbqkb1r/ppp1pppp/5n2/3p4/3P2P1/5P2/PPP1P2P/RNBQKBNR b KQkq -
+Gedult attack
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/2N5/PPP1PPPP/R1BQKBNR b KQkq -
+Queen's pawn game, Chigorin variation *
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/3BP3/PPP2PPP/RNBQK1NR b KQkq -
+Queen's pawn: stonewall attack
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+Queen's pawn game
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Queen's pawn game *
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's pawn game
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn game *
+rnbqkb1r/ppp1pppp/5n2/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+Blackmar-Diemer gambit
+rnbqkb1r/ppp1pppp/5n2/3p4/3PP3/5P2/PPP3PP/RNBQKBNR b KQkq -
+Blackmar-Diemer gambit
+rnbqkb1r/ppp1pppp/5n2/3p4/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Alekhine's defense: Scandinavian variation
+rnbqkb1r/ppp1pppp/5n2/3p4/8/1P3N2/P1PPPPPP/RNBQKB1R b KQkq -
+Queen's Indian defense *
+rnbqkb1r/ppp1pppp/5n2/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Queen's pawn game *
+rnbqkb1r/ppp1pppp/5n2/3p4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+King's Indian: East Indian defense *
+rnbqkb1r/ppp1pppp/5n2/3pN3/8/8/PPPPPPPP/RNBQKB1R b KQkq -
+D\"ory defense *
+rnbqkb1r/ppp1pppp/5n2/8/2Pp4/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+Old Benoni defense *
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+QGA, 4.Nc3
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+QGA, 4.e3
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Queen's gambit accepted
+rnbqkb1r/ppp1pppp/5n2/8/Q1pP4/5N2/PP2PPPP/RNB1KB1R b KQkq -
+QGA: Mannheim variation
+rnbqkb1r/ppp1pppp/8/3n4/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+Scandinavian: Marshall variation
+rnbqkb1r/ppp1pppp/8/3n4/8/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+English: Anglo-Gr\"unfeld defense
+rnbqkb1r/ppp1pppp/8/3np3/3P4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Alekhine's defense: modern, Larsen variation
+rnbqkb1r/ppp1pppp/8/8/1nPP4/8/PP3PPP/RNBQKBNR w KQkq -
+Scandinavian: Kiel variation
+rnbqkb1r/ppp2Npp/3p1n2/8/4P3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Petrov: Cochrane gambit
+rnbqkb1r/ppp2p1p/5n2/3p4/4PpNP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Berlin defense, Rivi\`ere variation
+rnbqkb1r/ppp2p1p/5n2/3pN3/3PPBpP/8/PPP3P1/RN1QKB1R b KQkq -
+KGA: Kieseritsky, Brentano defense
+rnbqkb1r/ppp2p1p/8/3pN3/3PnBpP/8/PPPN2P1/R2QKB1R b KQkq -
+KGA: Kieseritsky, Brentano defense, Caro variation
+rnbqkb1r/ppp2pp1/4pn1p/3p2B1/2PP4/5N2/PP2PPPP/RN1QKB1R w KQkq -
+QGD: Capablanca-Duras variation
+rnbqkb1r/ppp2pp1/5n1p/3p2B1/3Np3/3P4/PPP1PPPP/RN1QKB1R w KQkq -
+Alekhine's defense: modern, Panov variation *
+rnbqkb1r/ppp2ppp/1n6/1B2p3/8/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Scotch: Romanishin variation *
+rnbqkb1r/ppp2ppp/1n6/4p3/2B5/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Scotch: Potter variation *
+rnbqkb1r/ppp2ppp/3p1n2/4N3/8/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: French attack *
+rnbqkb1r/ppp2ppp/3p1n2/4P3/4P3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: Nimzovich variation
+rnbqkb1r/ppp2ppp/3p1n2/4p1N1/3PP3/8/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: Nimzovich, Locock variation
+rnbqkb1r/ppp2ppp/3p1n2/4p3/2BPP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+Philidor: Nimzovich, Klein variation
+rnbqkb1r/ppp2ppp/3p1n2/4p3/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+Old Indian: Ukrainian variation, 4.Nf3
+rnbqkb1r/ppp2ppp/3p1n2/4p3/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Old Indian: Ukrainian variation
+rnbqkb1r/ppp2ppp/3p1n2/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Nimzovich (Jaenisch) variation
+rnbqkb1r/ppp2ppp/3p1n2/4p3/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+R\'eti: Lisitsin gambit deferred *
+rnbqkb1r/ppp2ppp/3p1n2/8/2N1P3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Petrov: Paulsen attack
+rnbqkb1r/ppp2ppp/3p1n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: exchange variation
+rnbqkb1r/ppp2ppp/3p1n2/8/3P4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: classical attack, close variation
+rnbqkb1r/ppp2ppp/3p4/3QP3/4n3/5N2/PPP2PPP/RNB1KB1R b KQkq -
+Philidor: Nimzovich, Rellstab variation
+rnbqkb1r/ppp2ppp/3p4/4P3/2P1P1n1/8/PP3PPP/RNBQKBNR w KQkq -
+Budapest: Alekhine variation, Balogh gambit
+rnbqkb1r/ppp2ppp/3p4/4P3/4n3/5N2/PPPN1PPP/R1BQKB1R b KQkq -
+Philidor: Nimzovich, Sokolsky variation
+rnbqkb1r/ppp2ppp/3p4/8/2P1n3/5N2/PP1P1PPP/RNBQKB1R b KQkq -
+Petrov: Kaufmann attack
+rnbqkb1r/ppp2ppp/3p4/8/3Pn3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Petrov: classical attack
+rnbqkb1r/ppp2ppp/3p4/8/4n3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Petrov: Nimzovich attack
+rnbqkb1r/ppp2ppp/3p4/8/4n3/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+Petrov: French attack
+rnbqkb1r/ppp2ppp/3p4/8/4n3/5N2/PPPPQPPP/RNB1KB1R b KQkq -
+Petrov: Cozio (Lasker) attack
+rnbqkb1r/ppp2ppp/3pp3/2PnP3/2B5/2N5/PP1P1PPP/R1BQK1NR w KQkq -
+Alekhine's defense: two pawns' attack, Mikenas variation
+rnbqkb1r/ppp2ppp/4n3/3pP3/8/3P1Q2/PPP3PP/RNB1KBNR w KQkq -
+Latvian: Nimzovich variation *
+rnbqkb1r/ppp2ppp/4pn2/3P4/2P5/8/PP1P1PPP/RNBQKBNR w KQkq -
+Scandinavian: Icelandic gambit
+rnbqkb1r/ppp2ppp/4pn2/3P4/3P4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+QGD: exchange variation
+rnbqkb1r/ppp2ppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+QGD: 4.Bg5
+rnbqkb1r/ppp2ppp/4pn2/3p2B1/2PP4/5N2/PP2PPPP/RN1QKB1R b KQkq -
+QGD
+rnbqkb1r/ppp2ppp/4pn2/3p4/2P5/5NP1/PP1PPP1P/RNBQKB1R w KQkq -
+English: Neo-Catalan
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP1B2/2N5/PP2PPPP/R2QKBNR b KQkq -
+QGD: Harrwitz attack
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+QGD: 4.Nf3
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: 3...Nf6
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/6P1/PP2PPBP/RNBQK1NR b KQkq -
+Catalan: closed
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/3BPN2/PPP2PPP/RNBQK2R b KQkq -
+Queen's pawn game
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+Queen's pawn game *
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+Queen's pawn game
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's pawn game *
+rnbqkb1r/ppp2ppp/4pn2/3p4/3PP3/2N1B3/PPP2PPP/R2QKBNR b KQkq -
+French: Henneberger variation
+rnbqkb1r/ppp2ppp/4pn2/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+French defense
+rnbqkb1r/ppp2ppp/4pn2/3p4/3PP3/2NB4/PPP2PPP/R1BQK1NR b KQkq -
+French: Swiss variation
+rnbqkb1r/ppp2ppp/4pn2/3p4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+French: Tarrasch, closed variation
+rnbqkb1r/ppp2ppp/4pn2/3p4/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+Queen's pawn: Yusupov-Rubinstein system *
+rnbqkb1r/ppp2ppp/4pn2/3pP3/2P5/2N5/PP1P1PPP/R1BQKBNR b KQkq -
+English: Mikenas-Carls, Flohr variation
+rnbqkb1r/ppp2ppp/4pn2/3pP3/3P4/2N5/PPP2PPP/R1BQKBNR b KQkq -
+French: Steinitz variation
+rnbqkb1r/ppp2ppp/4pn2/6B1/3Pp3/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: Burn variation
+rnbqkb1r/ppp2ppp/4pn2/8/2p5/5NP1/PP1PPPBP/RNBQK2R w KQkq -
+English: Neo-Catalan accepted
+rnbqkb1r/ppp2ppp/4pn2/8/2pP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGA: 4...e6
+rnbqkb1r/ppp2ppp/4pn2/8/2pP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+Catalan: open, 5.Nf3
+rnbqkb1r/ppp2ppp/4pn2/8/3P4/2N2N2/PPP3PP/R1BQKB1R w KQkq -
+Blackmar-Diemer: Euwe defense
+rnbqkb1r/ppp2ppp/4pn2/8/Q1pP4/6P1/PP2PPBP/RNB1K1NR b KQkq -
+Catalan: open, 5.Qa4
+rnbqkb1r/ppp2ppp/5n2/3B4/4Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Morphy variation
+rnbqkb1r/ppp2ppp/5n2/3Np3/4P3/8/PPPP1PPP/R1BQKBNR b KQkq -
+Scotch: Lolli variation *
+rnbqkb1r/ppp2ppp/5n2/3P4/4PP2/8/PPP3PP/RNBQKBNR b KQkq -
+KGD: Falkbeer, 5.de
+rnbqkb1r/ppp2ppp/5n2/3P4/4pP2/2N5/PPPPQ1PP/R1B1KBNR b KQkq -
+KGD: Falkbeer, Rubinstein variation
+rnbqkb1r/ppp2ppp/5n2/3P4/4pP2/3P4/PPP1Q1PP/RNB1KBNR b KQkq -
+KGD: Falkbeer, R\'eti variation
+rnbqkb1r/ppp2ppp/5n2/3P4/4pP2/3P4/PPPN2PP/R1BQKBNR b KQkq -
+KGD: Falkbeer, Keres variation
+rnbqkb1r/ppp2ppp/5n2/3P4/5p2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Abbazia defense, modern variation
+rnbqkb1r/ppp2ppp/5n2/3Pp3/8/3P4/PP2PPPP/RNBQKBNR b KQkq -
+Sicilian *
+rnbqkb1r/ppp2ppp/5n2/3Pp3/8/3P4/PPP2PPP/RNBQKBNR b KQkq -
+Philidor: exchange variation *
+rnbqkb1r/ppp2ppp/5n2/3Pp3/8/4P3/PP1P1PPP/RNBQKBNR b KQkq -
+Sicilian defense *
+rnbqkb1r/ppp2ppp/5n2/3p2B1/3Np3/3P4/PPP1PPPP/RN1QKB1R b KQkq -
+Alekhine's defense: modern variation, 4...Bg4 *
+rnbqkb1r/ppp2ppp/5n2/3p2B1/3P4/2N5/PP2PPPP/R2QKBNR b KQkq -
+QGD: exchange, positional line
+rnbqkb1r/ppp2ppp/5n2/3p2B1/3P4/2N5/PPP2PPP/R2QKBNR b KQkq -
+French: exchange, Svenonius variation
+rnbqkb1r/ppp2ppp/5n2/3p4/2PPp3/4P3/PP3PPP/RNBQKBNR w KQkq -
+French: advance, Nimzovich system *
+rnbqkb1r/ppp2ppp/5n2/3p4/3NP3/8/PPP1PPPP/RNBQKB1R b KQkq -
+Alekhine's defense: modern, Larsen variation *
+rnbqkb1r/ppp2ppp/5n2/3p4/3Np3/3P2P1/PPP1PP1P/RNBQKB1R b KQkq -
+Alekhine's defense: modern, fianchetto variation *
+rnbqkb1r/ppp2ppp/5n2/3p4/3Np3/3P4/PPP1PPPP/RNBQKB1R w KQkq -
+Alekhine's defense: modern variation *
+rnbqkb1r/ppp2ppp/5n2/3p4/4p3/1N1P4/PPP1PPPP/RNBQKB1R b KQkq -
+Alekhine's defense: modern, Schmid variation *
+rnbqkb1r/ppp2ppp/5n2/3p4/8/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+Petrov: classical attack, close variation *
+rnbqkb1r/ppp2ppp/5n2/3pN3/4P3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Petrov: modern attack, Symmetrical variation *
+rnbqkb1r/ppp2ppp/5n2/3pN3/8/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: classical attack *
+rnbqkb1r/ppp2ppp/5n2/3pp3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+English: Bremen, reverse dragon
+rnbqkb1r/ppp2ppp/5n2/3pp3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Sicilian defense *
+rnbqkb1r/ppp2ppp/5n2/3pp3/2P5/3P1N2/PP2PPPP/RNBQKB1R b KQkq -
+Sicilian: Cortlever (Alatortsev) variation *
+rnbqkb1r/ppp2ppp/5n2/3pp3/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+Sicilian: Marshall variation *
+rnbqkb1r/ppp2ppp/5n2/3pp3/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Blackmar-Diemer: Lemberg counter-gambit
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Scotch opening *
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: Nimzovich (Jaenisch) variation *
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/3P4/PPP2PPP/RNBQKBNR w KQkq -
+Philidor's defense *
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/3P4/PPPN1PPP/R1BQKBNR b KQkq -
+Philidor: Hanham variation *
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov: modern (Steinitz) attack *
+rnbqkb1r/ppp2ppp/5n2/3pp3/4PP2/2N5/PPPP2PP/R1BQKBNR w KQkq -
+Vienna gambit
+rnbqkb1r/ppp2ppp/5n2/3pp3/4PP2/2NP4/PPP3PP/R1BQKBNR b KQkq -
+Vienna gambit, Steinitz variation
+rnbqkb1r/ppp2ppp/5n2/3pp3/4PP2/3P4/PPP3PP/RNBQKBNR b KQkq -
+Philidor: Philidor counter-gambit *
+rnbqkb1r/ppp2ppp/5n2/4p2Q/8/2N5/PPPP1PPP/R1B1KBNR w KQkq -
+Scotch: Fraser attack *
+rnbqkb1r/ppp2ppp/5n2/4p3/4p3/3P1N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Nimzovich variation *
+rnbqkb1r/ppp2ppp/8/3P4/4nP2/8/PPP1Q1PP/RNB1KBNR b KQkq -
+KGD: Falkbeer, Charousek gambit
+rnbqkb1r/ppp2ppp/8/3n4/3p4/8/PPP2PPP/RNBQKBNR w KQkq -
+Philidor: Paulsen attack *
+rnbqkb1r/ppp2ppp/8/3np2Q/8/2N5/PPPP1PPP/R1B1KBNR b KQkq -
+Scotch: Pulling counter-attack *
+rnbqkb1r/ppp2ppp/8/3np3/2B5/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Scotch game *
+rnbqkb1r/ppp2ppp/8/3np3/3P4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+Sicilian: Nimzovich variation *
+rnbqkb1r/ppp2ppp/8/3np3/4P3/2N5/PP1P1PPP/R1BQKBNR b KQkq -
+Sicilian: Labourdonnais-L\"owenthal variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/2N1P3/PP1P1PPP/R1BQKBNR b KQkq -
+Sicilian defense *
+rnbqkb1r/ppp2ppp/8/3np3/8/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+Sicilian defense *
+rnbqkb1r/ppp2ppp/8/3np3/8/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Scotch: Schmidt variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Scotch game *
+rnbqkb1r/ppp2ppp/8/3np3/8/2N5/PPQPPPPP/R1B1KBNR b KQkq -
+Sicilian: Flohr variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: exchange variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/3P2P1/PPP2P1P/RNBQKBNR b KQkq -
+Philidor: Larsen variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/3P4/PP2PPPP/RNBQKBNR w KQkq -
+Sicilian *
+rnbqkb1r/ppp2ppp/8/3np3/8/3P4/PPP2PPP/RNBQKBNR w KQkq -
+Philidor: exchange variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+Sicilian: Anderssen variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/P3P3/1P1P1PPP/RNBQKBNR b KQkq -
+Sicilian: Kan variation *
+rnbqkb1r/ppp2ppp/8/3pP3/4n3/2N2Q2/PPPP2PP/R1B1KBNR b KQkq -
+Vienna gambit: Paulsen attack
+rnbqkb1r/ppp2ppp/8/3pP3/4n3/2NP4/PPP3PP/R1BQKBNR b KQkq -
+Vienna gambit
+rnbqkb1r/ppp2ppp/8/3pp3/2B1n3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Boden-Kieseritsky gambit: Lichtenhein defense
+rnbqkb1r/ppp2ppp/8/3pp3/4N3/8/PPPP1PPP/R1BQKBNR w KQkq -
+Irish (Chicago) gambit *
+rnbqkb1r/ppp2ppp/8/3pp3/4P1n1/3P1N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Nimzovich, Locock variation *
+rnbqkb1r/ppp2ppp/8/4P3/3P2n1/4p3/PPP3PP/RNBQKBNR w KQkq -
+Philidor: Philidor counter-gambit, del Rio attack *
+rnbqkb1r/ppp2ppp/8/4p2Q/1n6/2N5/PPPP1PPP/R1B1KBNR w KQkq -
+Scotch: Horwitz attack *
+rnbqkb1r/ppp2ppp/8/4p3/1n2P3/2NP4/PP3PPP/R1BQKBNR b KQkq -
+Sicilian: Labourdonnais-L\"owenthal (Kalashnikov) variation *
+rnbqkb1r/ppp2ppp/8/4p3/1n6/2N1P3/PP1P1PPP/R1BQKBNR w KQkq -
+Sicilian, Sz\'en (`anti-Taimanov') variation *
+rnbqkb1r/ppp2ppp/8/4p3/8/2n3P1/PP1PPP1P/R1BQKBNR w KQkq -
+Sicilian: accelerated fianchetto, exchange variation *
+rnbqkb1r/ppp2ppp/8/8/4p3/2P2N2/P1PP1PPP/R1BQKB1R w KQkq -
+Scotch: Mieses variation *
+rnbqkb1r/ppp3p1/8/3ppPPp/8/7P/PPPP1K2/RNBQ1BNR w kq -
+KGA: Allgaier, Thorold variation *
+rnbqkb1r/ppp3pN/3p3n/5p2/2BpP3/8/PPP2PPP/RNBQK2R b KQkq -
+Philidor: L\'opez counter-gambit, Jaenisch variation
+rnbqkb1r/ppp3pp/5n2/3ppP2/6P1/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: Rosentreter gambit *
+rnbqkb1r/ppp3pp/5p2/3np3/8/3P1N2/PP2PPPP/RNBQKB1R w KQkq -
+Sicilian: Prins (Moscow) variation *
+rnbqkb1r/ppp3pp/8/3pPp2/3Pn3/2N2Q2/PPP3PP/R1B1KBNR b KQkq -
+Vienna gambit: Heyde variation
+rnbqkb1r/ppp3pp/8/3pPp2/4n3/2N2Q2/PPPP2PP/R1B1KBNR w KQkq f6
+Vienna gambit: Bardeleben variation
+rnbqkb1r/ppp3pp/8/3ppPP1/4n3/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: S\o rensen gambit *
+rnbqkb1r/pppn1ppp/4p3/3pP3/3P2Q1/2N5/PPP2PPP/R1B1KBNR b KQkq -
+French: Steinitz, Gledhill attack
+rnbqkb1r/pppnpppp/4P3/3p4/8/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Alekhine's defense: Spielmann variation
+rnbqkb1r/pppp1p1p/5n2/4N3/2B1PppP/8/PPPP2P1/RNBQK2R b KQkq -
+KGA: Kieseritsky, Berlin defense, 6.Bc4
+rnbqkb1r/pppp1p1p/5n2/4N3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Berlin defense
+rnbqkb1r/pppp1p1p/5n2/6N1/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Allgaier, Schlechter defense
+rnbqkb1r/pppp1p1p/5np1/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+English: Bremen system with ...g6
+rnbqkb1r/pppp1p1p/5np1/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Konstantinopolsky opening *
+rnbqkb1r/pppp1ppp/2n5/8/2P1PP2/8/PP4PP/RNBQKBNR w KQkq -
+Budapest: Alekhine, Abonyi variation
+rnbqkb1r/pppp1ppp/4p3/8/2PPn3/5N2/PP2PPPP/RNBQKB1R w KQkq -
+D\"ory defense
+rnbqkb1r/pppp1ppp/4pn2/6B1/2PP4/8/PP2PPPP/RN1QKBNR b KQkq -
+Neo-Indian (Seirawan) attack
+rnbqkb1r/pppp1ppp/4pn2/6B1/3P4/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+Queen's pawn: Torre attack
+rnbqkb1r/pppp1ppp/4pn2/8/2P1P3/2N5/PP1P1PPP/R1BQKBNR b KQkq -
+English: Mikenas-Carls variation
+rnbqkb1r/pppp1ppp/4pn2/8/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English opening
+rnbqkb1r/pppp1ppp/4pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+Queen's pawn game
+rnbqkb1r/pppp1ppp/4pn2/8/2PP4/6P1/PP2PP1P/RNBQKBNR b KQkq -
+Catalan opening
+rnbqkb1r/pppp1ppp/4pn2/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Queen's pawn game
+rnbqkb1r/pppp1ppp/4pn2/8/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+Queen's pawn: Yusupov-Rubinstein system
+rnbqkb1r/pppp1ppp/5n2/4p1B1/8/3P4/PPP1PPPP/RN1QKBNR b KQkq -
+R\'eti: Wade defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Vienna game
+rnbqkb1r/pppp1ppp/5n2/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Petrov: Italian variation
+rnbqkb1r/pppp1ppp/5n2/4p3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Berlin defense
+rnbqkb1r/pppp1ppp/5n2/4p3/2B1PP2/8/PPPP2PP/RNBQK1NR b KQkq -
+Bishop's opening: Greco gambit
+rnbqkb1r/pppp1ppp/5n2/4p3/2BPP3/8/PPP2PPP/RNBQK1NR b KQkq -
+Bishop's opening: Ponziani gambit
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/1P6/P2PPPPP/RNBQKBNR b KQkq -
+Sicilian: Katalimov variation *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+English: Carls' Bremen system
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+Sicilian defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English opening
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/3P4/PP2PPPP/RNBQKBNR b KQkq -
+Sicilian *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/4P3/PP1P1PPP/RNBQKBNR b KQkq -
+Sicilian defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+Sicilian: Nimzovich-Rubinstein variation *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/6P1/PP1PPP1P/RNBQKBNR b KQkq -
+Sicilian: Hungarian variation *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/8/PPQPPPPP/RNB1KBNR b KQkq -
+Sicilian: Quinteros variation *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/P7/1P1PPPPP/RNBQKBNR b KQkq -
+Sicilian: O'Kelly variation *
+rnbqkb1r/pppp1ppp/5n2/4p3/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Budapest defense declined
+rnbqkb1r/pppp1ppp/5n2/4p3/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Tennison (Lemberg, Zukertort) gambit *
+rnbqkb1r/pppp1ppp/5n2/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Petrov: modern (Steinitz) attack
+rnbqkb1r/pppp1ppp/5n2/4p3/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+QP counter-gambit (elephant gambit) *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Petrov three knights game
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+Vienna: Paulsen-Mieses variation
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+King's pawn game *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna: Falkbeer variation
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+Philidor's defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+Petrov's defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov's defense
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5P2/PPPP2PP/RNBQKBNR b KQkq -
+Damiano's defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5Q2/PPPP1PPP/RNB1KBNR b KQkq -
+Greco defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+King's knight opening *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/8/PPPPQPPP/RNB1KBNR b KQkq -
+Gunderam defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/P1N5/1PPP1PPP/R1BQKBNR b KQkq -
+Vienna: Mengarini variation
+rnbqkb1r/pppp1ppp/5n2/4p3/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Vienna gambit
+rnbqkb1r/pppp1ppp/5n2/4p3/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+Latvian counter-gambit *
+rnbqkb1r/pppp1ppp/5n2/4p3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: 2...Nf6
+rnbqkb1r/pppp1ppp/5n2/4p3/5P2/2N5/PPPPP1PP/R1BQKBNR b KQkq -
+KP: Colorado counter *
+rnbqkb1r/pppp1ppp/5n2/4p3/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+R\'eti: Pirc-Lisitsin gambit *
+rnbqkb1r/pppp1ppp/5n2/4p3/8/2N5/PPPPPPPP/R1BQKBNR w KQkq -
+KP: Nimzovich defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/Q1P5/8/PP1PPPPP/RNB1KBNR b KQkq -
+Sicilian: Stiletto (Althouse) variation *
+rnbqkb1r/pppp1ppp/5n2/8/2B1Pp2/2N5/PPPP2PP/R1BQK1NR b KQkq -
+KGA: bishop's gambit, Bogolyubov variation
+rnbqkb1r/pppp1ppp/5n2/8/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Cozio (Morphy) defense
+rnbqkb1r/pppp1ppp/5n2/8/2BpP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+Bishop's opening/Petrov: Urusov gambit
+rnbqkb1r/pppp1ppp/5n2/8/3pP3/3B4/PPP2PPP/RNBQK1NR b KQkq -
+QP counter-gambit: Maroczy gambit *
+rnbqkb1r/pppp1ppp/5n2/8/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Schallop defense
+rnbqkb1r/pppp1ppp/8/2n1p3/8/3P1N2/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: Paulsen attack *
+rnbqkb1r/pppp1ppp/8/4N3/4n3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Petrov: Damiano variation *
+rnbqkb1r/pppp1ppp/8/4N3/4n3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov: Damiano variation
+rnbqkb1r/pppp1ppp/8/4P3/2P1P1n1/8/PP3PPP/RNBQKBNR b KQkq -
+Budapest: Alekhine variation
+rnbqkb1r/pppp1ppp/8/4P3/2P1n3/8/PP2PPPP/RNBQKBNR w KQkq -
+Budapest: Fajarowicz variation
+rnbqkb1r/pppp1ppp/8/4P3/2P1n3/8/PPQ1PPPP/RNB1KBNR b KQkq -
+Budapest: Fajarowicz, Steiner variation
+rnbqkb1r/pppp1ppp/8/4P3/2P2Bn1/8/PP2PPPP/RN1QKBNR b KQkq -
+Budapest: Rubinstein variation
+rnbqkb1r/pppp1ppp/8/4P3/2P3n1/5N2/PP2PPPP/RNBQKB1R b KQkq -
+Budapest: Adler variation
+rnbqkb1r/pppp1ppp/8/4P3/2P3n1/8/PP2PPPP/RNBQKBNR w KQkq -
+Budapest defense
+rnbqkb1r/pppp1ppp/8/4P3/3Qn3/5N2/PPP2PPP/RNB1KB1R b KQkq -
+Petrov: modern attack, main line
+rnbqkb1r/pppp1ppp/8/4P3/3pn3/5N2/PPP1QPPP/RNB1KB1R b KQkq -
+Petrov: modern attack, Steinitz variation
+rnbqkb1r/pppp1ppp/8/4p3/2B1n3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Boden-Kieseritsky gambit
+rnbqkb1r/pppp1ppp/8/4p3/2B1n3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Vienna game
+rnbqkb1r/pppp1ppp/8/4p3/3Pn3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: modern attack, Symmetrical variation
+rnbqkb1r/pppp1ppp/8/4p3/4nP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Latvian: Fraser defense *
+rnbqkb1r/pppp1ppp/8/4p3/8/3P1N2/PPP2nPP/RNBQKB1R w KQkq -
+Petrov: Cochrane gambit *
+rnbqkb1r/pppp2p1/5n2/4pP1p/6P1/8/PPPP1P1P/RNBQKBNR w KQkq -
+King's knight's gambit *
+rnbqkb1r/pppp2p1/8/4pPPp/3Pn3/8/PPP2P1P/RNBQKBNR b KQkq -
+KGA: Kieseritsky, Brentano (Campbell) defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n2P/8/PPPP1P2/RNBQKBNR b KQkq -
+KGA: Kieseritsky, long whip (Stockwhip, classical) defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n3/2N5/PPPP1P1P/R1BQKBNR b KQkq -
+KGA: Kieseritsky, Neumann defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n3/3P4/PPP2P1P/RNBQKBNR b KQkq -
+KGA: Kieseritsky, Kolisch defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n3/5N2/PPPP1P1P/RNBQKB1R b KQkq -
+KGA: Kieseritsky, Berlin defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n3/8/PPPP1PBP/RNBQK1NR b KQkq -
+KGA: Kieseritsky, Paulsen defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n3/8/PPPPBP1P/RNBQK1NR b KQkq -
+KGA: Kieseritsky, Polerio defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n3/8/PPPPQP1P/RNB1KBNR b KQkq -
+KGA: Kieseritsky, Salvio (Rosenthal) defense *
+rnbqkb1r/pppp2p1/8/4pPPp/6n1/5N2/PPPP1P1P/RNBQKB1R b KQkq -
+KGA: Allgaier, Schlechter defense *
+rnbqkb1r/pppp2p1/8/4pPPp/6n1/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: Allgaier gambit *
+rnbqkb1r/pppp2p1/8/4pPnp/3P4/5N2/PPP2P1P/RNBQKB1R b KQkq -
+KGA: Kieseritsky, Berlin defense, Rivi\`ere variation *
+rnbqkb1r/pppp2pp/4pn2/5p2/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+Bird's opening: Lasker variation *
+rnbqkb1r/pppp2pp/4pn2/5p2/2PP4/6P1/PP2PPBP/RNBQK1NR b KQkq -
+Dutch defense
+rnbqkb1r/pppp2pp/4pn2/5p2/3P4/6PN/PPP1PPBP/RNBQK2R b KQkq -
+Dutch defense, Blackburne variation
+rnbqkb1r/pppp2pp/5n2/4N3/2B1p3/8/PPPP1PPP/RNBQK2R w KQkq -
+Latvian: corkscrew counter-gambit
+rnbqkb1r/pppp2pp/5n2/4p3/2B1p3/3P4/PPP2PPP/RNBQK1NR w KQkq -
+KGD: classical, Soldatenkov variation *
+rnbqkb1r/pppp2pp/5n2/4pP2/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+KGA: Abbazia defense (classical defense, modern defense[!]) *
+rnbqkb1r/pppp2pp/5n2/4pP2/5P2/8/PPPP2PP/RNBQKBNR b KQkq -
+KGA: Gianutio counter-gambit *
+rnbqkb1r/pppp2pp/5n2/4pP2/8/3P4/PPP2PPP/RNBQKBNR b KQkq -
+KGA: Fischer defense *
+rnbqkb1r/pppp2pp/5n2/4pP2/8/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+KGA: Schallop defense *
+rnbqkb1r/pppp2pp/5n2/4pP2/8/7P/PPPP1PP1/RNBQKBNR b KQkq -
+KGA: Becker defense *
+rnbqkb1r/pppp2pp/5n2/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+King's knight's gambit *
+rnbqkb1r/pppp2pp/5n2/4pP2/8/8/PPPPBPPP/RNBQK1NR b KQkq -
+KGA: Cunningham defense *
+rnbqkb1r/pppp2pp/5n2/4pP2/8/8/PPPPNPPP/RNBQKB1R b KQkq -
+KGA: Bonsch-Osmolovsky variation *
+rnbqkb1r/pppp2pp/5n2/4pp2/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+KGD: Falkbeer, Tartakower variation *
+rnbqkb1r/pppp2pp/5n2/5P2/3p4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+KGA: Abbazia defense, modern variation *
+rnbqkb1r/ppppnppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: Keres variation (2.Ne2) *
+rnbqkb1r/ppppnppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Alapin's opening *
+rnbqkb1r/ppppnppp/8/8/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Steinitz defense
+rnbqkb1r/ppppnppp/8/8/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Bonsch-Osmolovsky variation
+rnbqkb1r/ppppp1pp/5n2/5p2/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+Dutch with c4 & Nc3
+rnbqkb1r/ppppp1pp/5n2/5p2/2PP4/6P1/PP2PP1P/RNBQKBNR b KQkq -
+Dutch with c4 & g3
+rnbqkb1r/ppppp1pp/5n2/5p2/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Dutch defense
+rnbqkb1r/ppppp1pp/5n2/5p2/3P2P1/2N5/PPP1PP1P/R1BQKBNR b KQkq -
+Dutch, Spielmann gambit
+rnbqkb1r/ppppp1pp/5n2/5p2/4P3/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+R\'eti: Lisitsin gambit deferred
+rnbqkb1r/ppppp1pp/5n2/6B1/3Pp3/2N5/PPP2PPP/R2QKBNR b KQkq -
+Dutch: Staunton gambit, Staunton's line
+rnbqkb1r/ppppp1pp/5n2/8/3Pp1P1/2N5/PPP2P1P/R1BQKBNR b KQkq -
+Dutch: Staunton gambit, Tartakower variation
+rnbqkb1r/ppppp1pp/5n2/8/4pPP1/2N5/PPPP3P/R1BQKBNR b KQkq -
+Bird's opening, Swiss gambit
+rnbqkb1r/ppppp1pp/5n2/8/6P1/3B4/PPP2P1P/RNBQK1NR b KQkq -
+Bird: From gambit, Lasker variation *
+rnbqkb1r/ppppp2p/5np1/5p2/2PP4/6P1/PP2PP1P/RNBQKBNR w KQkq -
+Dutch: Leningrad variation
+rnbqkb1r/ppppp2p/5np1/5p2/3P4/6P1/PPP1PPBP/RNBQK1NR w KQkq -
+Dutch defense
+rnbqkb1r/ppppp2p/5np1/6B1/3Pp2P/2N5/PPP2PP1/R2QKBNR b KQkq -
+Dutch: Staunton gambit, Alekhine variation
+rnbqkb1r/ppppp2p/5np1/6B1/3Pp3/2N2P2/PPP3PP/R2QKBNR b KQkq -
+Dutch: Staunton gambit, Lasker variation
+rnbqkb1r/ppppp2p/5ppn/8/2PPP3/8/PP3PPP/RNBQKBNR w KQkq -
+Hippopotamus defense
+rnbqkb1r/ppppp2p/6pn/5p2/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Dutch defense: Bladel variation
+rnbqkb1r/pppppp1p/5np1/3P4/2P5/8/PP2PPPP/RNBQKBNR b KQkq -
+King's Indian: Anti-Gr\"unfeld
+rnbqkb1r/pppppp1p/5np1/6B1/3P4/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+King's Indian: Torre attack
+rnbqkb1r/pppppp1p/5np1/8/1P6/5N2/P1PPPPPP/RNBQKB1R b KQkq -
+R\'eti: King's Indian attack, Spassky's variation *
+rnbqkb1r/pppppp1p/5np1/8/1P6/5NP1/P1PPPP1P/RNBQKB1R b KQkq -
+R\'eti: King's Indian attack, R\'eti-Smyslov variation
+rnbqkb1r/pppppp1p/5np1/8/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+King's Indian defense, 3.Nc3
+rnbqkb1r/pppppp1p/5np1/8/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+King's Indian, 3.Nf3
+rnbqkb1r/pppppp1p/5np1/8/2PP4/6P1/PP2PP1P/RNBQKBNR b KQkq -
+King's Indian: 3.g3
+rnbqkb1r/pppppp1p/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+R\'eti: King's Indian attack (with ...c5) *
+rnbqkb1r/pppppp1p/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+King's Indian defense
+rnbqkb1r/pppppp1p/5np1/8/2PP4/8/PPQ1PPPP/RNB1KBNR b KQkq -
+Queen's pawn: Mengarini attack
+rnbqkb1r/pppppp1p/5np1/8/3P1B2/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+King's Indian: London system
+rnbqkb1r/pppppp1p/5np1/8/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+King's Indian: East Indian defense
+rnbqkb1r/pppppp1p/5np1/8/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+King's Indian: fianchetto without c4
+rnbqkb1r/pppppp1p/5np1/8/3P4/6P1/PPP1PP1P/RNBQKBNR b KQkq -
+R\'eti: King's Indian attack *
+rnbqkb1r/pppppp1p/5np1/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+R\'eti: King's Indian attack (Barcza system) *
+rnbqkb1r/pppppp1p/5np1/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Benko's opening: reversed Alekhine *
+rnbqkb1r/pppppp1p/5np1/8/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+R\'eti: King's Indian attack *
+rnbqkb1r/pppppp1p/5np1/8/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+R\'eti: King's Indian attack
+rnbqkb1r/ppppppnp/6p1/4P3/3P2P1/8/PPP2P1P/RNBQKBNR w KQkq -
+Norwegian defense
+rnbqkb1r/pppppppp/1n6/2P1P3/8/8/PP1P1PPP/RNBQKBNR b KQkq -
+Alekhine's defense: two pawns' (Lasker's) attack
+rnbqkb1r/pppppppp/1n6/4P3/2P5/1P6/P2P1PPP/RNBQKBNR b KQkq -
+Alekhine's defense: Steiner variation
+rnbqkb1r/pppppppp/5n2/6B1/3P4/8/PPP1PPPP/RN1QKBNR b KQkq -
+Trompovsky attack (Ruth, Opo\v censk\'y opening)
+rnbqkb1r/pppppppp/5n2/8/1PP5/8/P2PPPPP/RNBQKBNR b KQkq -
+English orang-utan
+rnbqkb1r/pppppppp/5n2/8/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+Alekhine's defense: Krejcik variation
+rnbqkb1r/pppppppp/5n2/8/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+English opening
+rnbqkb1r/pppppppp/5n2/8/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+English opening
+rnbqkb1r/pppppppp/5n2/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English, 1...Nf6 (Anglo-Indian defense)
+rnbqkb1r/pppppppp/5n2/8/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+Queen's pawn game
+rnbqkb1r/pppppppp/5n2/8/3P1B2/8/PPP1PPPP/RN1QKBNR b KQkq -
+Queen's pawn: London system
+rnbqkb1r/pppppppp/5n2/8/3P1P2/8/PPP1P1PP/RNBQKBNR b KQkq -
+Canard opening
+rnbqkb1r/pppppppp/5n2/8/3P2P1/8/PPP1PP1P/RNBQKBNR b KQkq -
+Queen's pawn: Bronstein gambit
+rnbqkb1r/pppppppp/5n2/8/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Queen's pawn game
+rnbqkb1r/pppppppp/5n2/8/3P4/5P2/PPP1P1PP/RNBQKBNR b KQkq -
+Paleface attack
+rnbqkb1r/pppppppp/5n2/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+R\'eti opening *
+rnbqkb1r/pppppppp/5n2/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn game
+rnbqkb1r/pppppppp/5n2/8/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+Alekhine's defense: Mar\'oczy variation
+rnbqkb1r/pppppppp/5n2/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Alekhine's defense
+rnbqkb1r/pppppppp/5n2/8/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+R\'eti v Dutch *
+rnbqkb1r/pppppppp/5n2/8/6P1/8/PPPPPP1P/RNBQKBNR b KQkq -
+R\'eti: Herrstr\"om gambit *
+rnbqkb1r/pppppppp/5n2/8/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: Indian variation
+rnbqkb1r/pppppppp/5n2/8/8/3P4/PPP1PPPP/RNBQKBNR b KQkq -
+R\'eti opening *
+rnbqkb1r/pppppppp/5n2/8/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+R\'eti opening *
+rnbqkb1r/pppppppp/5n2/8/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+R\'eti opening
+rnbqkb1r/pppppppp/5n2/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+R\'eti opening *
+rnbqkb1r/pppppppp/7n/8/1P6/8/P1PPPPPP/RNBQKBNR w KQkq -
+Polish: T\"ubingen variation
+rnbqkb1r/pppppppp/7n/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Amar (Paris) opening *
+rnbqkb1r/pppppppp/8/3nP3/2P5/8/PP1P1PPP/RNBQKBNR b KQkq -
+Alekhine's defense
+rnbqkb1r/pppppppp/8/3nP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+Alekhine's defense
+rnbqkb1r/pppppppp/8/3nP3/8/1P6/P1PP1PPP/RNBQKBNR b KQkq -
+Alekhine's defense: Welling variation
+rnbqkb1r/pppppppp/8/3nP3/8/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Alekhine's defense: S\"amisch attack
+rnbqkb1r/pppppppp/8/3nP3/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+Alekhine's defense
+rnbqkb1r/pppppppp/8/4P3/4n3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Alekhine's defense: Mokele Mbembe (B\"ucker) variation
+rnbqkb1r/pppppppp/8/8/3Pn3/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+D\"ory defense
+rnbqkbnr/1p1p1p1p/p3p1p1/8/3NP3/3B4/PPP2PPP/RNBQK2R w KQkq -
+Sicilian: Kan, Swiss cheese variation
+rnbqkbnr/1p1p1ppp/p3p3/8/2PNP3/8/PP3PPP/RNBQKB1R b KQkq -
+Sicilian: Kan, Mar\'oczy bind (R\'eti variation)
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Sicilian: Kan, 5.Nc3
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/3B4/PPP2PPP/RNBQK2R b KQkq -
+Sicilian: Kan, 5.Bd3
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Kan variation
+rnbqkbnr/1p1ppppp/p7/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian: O'Kelly variation
+rnbqkbnr/1pp1pppp/p7/8/2pP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+QGA: Alekhine defense
+rnbqkbnr/1pp1pppp/p7/8/2pPP3/5N2/PP3PPP/RNBQKB1R b KQkq -
+QGA: Alekhine defense, Borisenko-Furman variation
+rnbqkbnr/1pp2ppp/p3p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: Janowski variation
+rnbqkbnr/1ppp1ppp/p3p3/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+St. George defense
+rnbqkbnr/1ppp1ppp/p7/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: Mengarini's opening *
+rnbqkbnr/1pppppp1/8/p6p/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Crab opening *
+rnbqkbnr/1pppppp1/p6p/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Global opening *
+rnbqkbnr/1ppppppp/8/p7/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Corn stalk defense
+rnbqkbnr/1ppppppp/8/p7/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Ware (Meadow Hay) opening *
+rnbqkbnr/1ppppppp/p7/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+St. George (Baker) defense
+rnbqkbnr/1ppppppp/p7/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Anderssen's opening *
+rnbqkbnr/2p1pppp/p7/1p6/2pP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGA: Haberditz variation
+rnbqkbnr/2pp1ppp/P7/4p3/8/8/PP1PPPPP/RNBQKBNR b KQkq -
+Sicilian: wing gambit, Carlsbad variation *
+rnbqkbnr/2pp1ppp/p7/1P2p3/8/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: wing gambit, Marshall variation *
+rnbqkbnr/p1p1pppp/8/1p6/2pP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+QGA: Ericson variation
+rnbqkbnr/p1p2ppp/1p2p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: Alapin variation
+rnbqkbnr/p1pp1ppp/1p2p3/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Queen's pawn: Keres defense
+rnbqkbnr/p1pp1ppp/1p6/4p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French: R\'eti (Spielmann) variation *
+rnbqkbnr/p1pp1ppp/1p6/8/3Np3/8/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Welling variation *
+rnbqkbnr/p1pp1ppp/8/1p2p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: wing gambit *
+rnbqkbnr/p1pp1ppp/8/1p6/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Bryan counter-gambit
+rnbqkbnr/p1pp2pp/1p6/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Orsini gambit *
+rnbqkbnr/p1pppppp/1p6/8/1P6/8/P1PPPPPP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack: Polish variation *
+rnbqkbnr/p1pppppp/1p6/8/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack: English variation *
+rnbqkbnr/p1pppppp/1p6/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack: classical variation *
+rnbqkbnr/p1pppppp/1p6/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn: English defense
+rnbqkbnr/p1pppppp/1p6/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack: modern variation *
+rnbqkbnr/p1pppppp/1p6/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Owen defense
+rnbqkbnr/p1pppppp/1p6/8/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack: Dutch variation *
+rnbqkbnr/p1pppppp/1p6/8/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack: symmetrical variation *
+rnbqkbnr/p1pppppp/1p6/8/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: symmetrical variation
+rnbqkbnr/p1pppppp/1p6/8/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+Nimzovich-Larsen attack: Indian variation *
+rnbqkbnr/p1pppppp/1p6/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack *
+rnbqkbnr/p1pppppp/8/1p6/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English: Jaenisch gambit
+rnbqkbnr/p1pppppp/8/1p6/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Polish defense
+rnbqkbnr/p1pppppp/8/1p6/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: Polish variation
+rnbqkbnr/p1pppppp/8/1p6/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+Polish: Outflank variation *
+rnbqkbnr/p1pppppp/8/1p6/8/7N/PPPPPPPP/RNBQKB1R b KQkq -
+Polish: T\"ubingen variation *
+rnbqkbnr/p1pppppp/8/1p6/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Polish (Sokolsky) opening *
+rnbqkbnr/p2p1ppp/1p6/2p5/4p3/1N6/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Steiner variation *
+rnbqkbnr/p2p1ppp/8/1Pp1p3/8/8/PP1PPPPP/RNBQKBNR w KQkq c6
+Sicilian: wing gambit, Santasiere variation *
+rnbqkbnr/p2p1ppp/8/1pp5/2BpP3/5N2/PPP2PPP/RNBQK2R w KQkq -
+Center game, Kieseritsky variation
+rnbqkbnr/p2ppppp/1p6/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian: Katalimov variation
+rnbqkbnr/p2ppppp/8/1pp5/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+English orang-utan *
+rnbqkbnr/p3pppp/2p5/1p1p4/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Caro-Kann: Gurgenidze counter-attack
+rnbqkbnr/p4ppp/2p5/3pp3/8/2N5/PPPPPPPP/R1BQKBNR w KQkq -
+KP: Nimzovich defense, Wheeler gambit *
+rnbqkbnr/p4ppp/8/1pP5/N2p4/8/PP2PPPP/R1BQKBNR w KQkq b6
+QGD: Tarrasch defense, Tarrasch gambit
+rnbqkbnr/pp1p1ppp/2p5/4p3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Philidor counter-attack
+rnbqkbnr/pp1p1ppp/2p5/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: Alapin's variation (2.c3) *
+rnbqkbnr/pp1p1ppp/2p5/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: Lopez opening *
+rnbqkbnr/pp1p1ppp/2p5/8/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Ruy L\'opez defense
+rnbqkbnr/pp1p1ppp/4p3/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian defense
+rnbqkbnr/pp1p1ppp/4p3/2pP4/4P3/8/PPP2PPP/RNBQKBNR b KQkq -
+Old Benoni: Franco-Benoni defense
+rnbqkbnr/pp1p1ppp/4p3/8/3pP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian defense
+rnbqkbnr/pp1p1ppp/8/2p1p3/3P4/2P5/PP2PPPP/RNBQKBNR b KQkq -
+Caro-Kann: anti-anti-Caro-Kann defense *
+rnbqkbnr/pp1p1ppp/8/2p1p3/4P3/6P1/PPPP1P1P/RNBQKBNR b KQkq -
+English: Adorjan defense *
+rnbqkbnr/pp1p1ppp/8/2p1p3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: Mafia defense
+rnbqkbnr/pp1p1ppp/8/2p1p3/8/2P5/PP1PPPPP/RNBQKBNR w KQkq -
+Caro-Kann: anti-Caro-Kann defense *
+rnbqkbnr/pp1p1ppp/8/2p1p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French defense, Steiner variation *
+rnbqkbnr/pp1p1ppp/8/2p5/3Np3/8/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense *
+rnbqkbnr/pp1p1ppp/8/2p5/3p4/2P2N2/PP2PPPP/RNBQKB1R b KQkq -
+Scandinavian gambit *
+rnbqkbnr/pp1p1ppp/8/2p5/3p4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+Scandinavian: Icelandic gambit *
+rnbqkbnr/pp1p1ppp/8/2pPp3/8/8/PPP1PPPP/RNBQKBNR w KQkq e6
+Old Benoni defense
+rnbqkbnr/pp1p1ppp/8/4p3/3pP3/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+Sicilian: Andreaschek gambit
+rnbqkbnr/pp1p1ppp/8/8/2p1p3/1N6/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: two pawns' (Lasker's) attack *
+rnbqkbnr/pp1pp1pp/8/2p2p2/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Mujannah opening *
+rnbqkbnr/pp1pp1pp/8/2pP1p2/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+Old Benoni: Mujannah formation
+rnbqkbnr/pp1ppp1p/6p1/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian: Hungarian variation
+rnbqkbnr/pp1ppppp/2p5/8/1P6/8/P1PPPPPP/RNBQKBNR w KQkq -
+Polish: Outflank variation
+rnbqkbnr/pp1ppppp/2p5/8/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+Caro-Kann: Hillbilly attack
+rnbqkbnr/pp1ppppp/2p5/8/2P1P3/8/PP1P1PPP/RNBQKBNR b KQkq -
+Caro-Kann: anti-Caro-Kann defense
+rnbqkbnr/pp1ppppp/2p5/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English: Caro-Kann defensive system
+rnbqkbnr/pp1ppppp/2p5/8/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+Caro-Kann defense
+rnbqkbnr/pp1ppppp/2p5/8/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Caro-Kann defense
+rnbqkbnr/pp1ppppp/2p5/8/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+Caro-Kann: closed (Breyer) variation
+rnbqkbnr/pp1ppppp/2p5/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Caro-Kann defense
+rnbqkbnr/pp1ppppp/2p5/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Saragossa opening *
+rnbqkbnr/pp1ppppp/8/2p5/1P2P3/8/P1PP1PPP/RNBQKBNR b KQkq -
+Sicilian: wing gambit
+rnbqkbnr/pp1ppppp/8/2p5/1P6/8/P1PPPPPP/RNBQKBNR b KQkq -
+English: Jaenisch gambit *
+rnbqkbnr/pp1ppppp/8/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+English: symmetrical variation
+rnbqkbnr/pp1ppppp/8/2p5/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+English: symmetrical variation *
+rnbqkbnr/pp1ppppp/8/2p5/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English: symmetrical variation
+rnbqkbnr/pp1ppppp/8/2p5/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Old Benoni defense
+rnbqkbnr/pp1ppppp/8/2p5/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+Sicilian: Smith-Morra gambit
+rnbqkbnr/pp1ppppp/8/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Sicilian: closed
+rnbqkbnr/pp1ppppp/8/2p5/4P3/2P5/PP1P1PPP/RNBQKBNR b KQkq -
+Sicilian: Alapin's variation (2.c3)
+rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+Sicilian defense
+rnbqkbnr/pp1ppppp/8/2p5/4P3/6P1/PPPP1P1P/RNBQKBNR b KQkq -
+Sicilian: Steinitz variation
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+English opening *
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Sicilian defense
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPPNPPP/RNBQKB1R b KQkq -
+Sicilian: Keres variation (2.Ne2)
+rnbqkbnr/pp1ppppp/8/2p5/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+Sicilian: Grand Prix attack
+rnbqkbnr/pp1ppppp/8/2p5/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+English: Anglo-Dutch defense *
+rnbqkbnr/pp1ppppp/8/2p5/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: English variation
+rnbqkbnr/pp1ppppp/8/2p5/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+English: Caro-Kann defensive system *
+rnbqkbnr/pp1ppppp/8/2p5/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+English opening *
+rnbqkbnr/pp1ppppp/8/2p5/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+English, 1...Nf6 (Anglo-Indian defense) *
+rnbqkbnr/pp1ppppp/8/2p5/8/6P1/PPPPPP1P/RNBQKBNR b KQkq -
+English opening *
+rnbqkbnr/pp1ppppp/8/2p5/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+English opening *
+rnbqkbnr/pp1ppppp/8/8/1p2P3/P7/2PP1PPP/RNBQKBNR b KQkq -
+Sicilian: wing gambit, Marshall variation
+rnbqkbnr/pp1ppppp/8/8/1pP1P3/8/P2P1PPP/RNBQKBNR b KQkq c3
+Sicilian: wing gambit, Santasiere variation
+rnbqkbnr/pp1ppppp/8/8/3pP3/2P5/PP3PPP/RNBQKBNR b KQkq -
+Sicilian: Smith-Morra gambit
+rnbqkbnr/pp1ppppp/8/8/4P3/p7/2PP1PPP/RNBQKBNR w KQkq -
+Sicilian: wing gambit, Carlsbad variation
+rnbqkbnr/pp2p1pp/5p2/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+Neo-Gr\"unfeld defense *
+rnbqkbnr/pp2pp1p/2p3p1/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Caro-Kann: Gurgenidze system
+rnbqkbnr/pp2pp1p/3p2p1/2pP4/8/2N5/PPP1PPPP/R1BQKBNR w KQkq -
+Old Benoni: Schmid's system
+rnbqkbnr/pp2pp1p/6p1/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+Neo-Gr\"unfeld (Kemeri) defense *
+rnbqkbnr/pp2pp1p/6p1/2pp4/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Dutch with c4 & g3 *
+rnbqkbnr/pp2pp1p/6p1/2pp4/5P2/5NP1/PPPPP2P/RNBQKB1R b KQkq -
+Dutch: Leningrad variation *
+rnbqkbnr/pp2pp1p/6p1/2pp4/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+Catalan opening *
+rnbqkbnr/pp2pp1p/6p1/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian: 3.g3 *
+rnbqkbnr/pp2pppp/2p5/3P4/3P4/8/PP2PPPP/RNBQKBNR b KQkq -
+QGD Slav defense: exchange variation
+rnbqkbnr/pp2pppp/2p5/3P4/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+Caro-Kann: exchange variation
+rnbqkbnr/pp2pppp/2p5/3p2P1/8/8/PPPPPPBP/RNBQK1NR b KQkq -
+Grob: spike attack
+rnbqkbnr/pp2pppp/2p5/3p4/2P1P3/8/PP1P1PPP/RNBQKBNR w KQkq -
+Caro-Kann: anti-anti-Caro-Kann defense
+rnbqkbnr/pp2pppp/2p5/3p4/2P5/1P3N2/P2PPPPP/RNBQKB1R b KQkq -
+English: Caro-Kann defensive system
+rnbqkbnr/pp2pppp/2p5/3p4/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+QGD Slav: 3.Nf3
+rnbqkbnr/pp2pppp/2p5/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QGD Slav defense
+rnbqkbnr/pp2pppp/2p5/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+Caro-Kann defense
+rnbqkbnr/pp2pppp/2p5/3p4/3PP3/5P2/PPP3PP/RNBQKBNR b KQkq -
+Caro-Kann: Tartakower (fantasy) variation
+rnbqkbnr/pp2pppp/2p5/3p4/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Caro-Kann defense
+rnbqkbnr/pp2pppp/2p5/3p4/3PP3/8/PPPN1PPP/R1BQKBNR b KQkq -
+Caro-Kann: 3.Nd2
+rnbqkbnr/pp2pppp/2p5/3p4/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Caro-Kann: two knights variation
+rnbqkbnr/pp2pppp/2p5/3p4/4P3/2N2Q2/PPPP1PPP/R1B1KBNR b KQkq -
+Caro-Kann: Goldman (Spielmann) variation
+rnbqkbnr/pp2pppp/2p5/3pP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+Caro-Kann: advance variation
+rnbqkbnr/pp2pppp/2p5/8/2pPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+QGD Slav defense, Alekhine variation
+rnbqkbnr/pp2pppp/2p5/8/3PN3/8/PPP2PPP/R1BQKBNR b KQkq -
+Caro-Kann defense
+rnbqkbnr/pp2pppp/2p5/8/3Pp3/2N2P2/PPP3PP/R1BQKBNR b KQkq -
+Caro-Kann: Rasa-Studier gambit
+rnbqkbnr/pp2pppp/3p4/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Sicilian: Canal-Sokolsky (Nimzovich-Rossolimo, Moscow) attack
+rnbqkbnr/pp2pppp/3p4/2p5/1P2P3/5N2/P1PP1PPP/RNBQKB1R b KQkq -
+Sicilian: wing gambit deferred
+rnbqkbnr/pp2pppp/3p4/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian
+rnbqkbnr/pp2pppp/3p4/2pP4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+Old Benoni defense
+rnbqkbnr/pp2pppp/3p4/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+Sicilian
+rnbqkbnr/pp2pppp/3p4/8/3QP3/5N2/PPP2PPP/RNB1KB1R b KQkq -
+Sicilian, Chekhover variation
+rnbqkbnr/pp2pppp/3p4/8/3pP3/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+Sicilian: Tartakower variation
+rnbqkbnr/pp2pppp/3p4/8/3pP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian
+rnbqkbnr/pp2pppp/8/1Bpp4/8/4P3/PPPP1PPP/RNBQK1NR b KQkq -
+Queen's pawn: Franco-Indian (Keres) defense *
+rnbqkbnr/pp2pppp/8/2Pp4/8/8/PPP1PPPP/RNBQKBNR b KQkq -
+Queen's gambit accepted *
+rnbqkbnr/pp2pppp/8/2p1N3/2Pp4/8/PP1PPPPP/RNBQKB1R b KQkq -
+Vulture defense *
+rnbqkbnr/pp2pppp/8/2p1N3/4p3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Budapest: Fajarowicz variation *
+rnbqkbnr/pp2pppp/8/2p3N1/4p3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Budapest defense *
+rnbqkbnr/pp2pppp/8/2p5/1P1p4/5NP1/P1PPPP1P/RNBQKB1R b KQkq -
+King's Indian: Danube gambit *
+rnbqkbnr/pp2pppp/8/2p5/1PPp4/5N2/P2PPPPP/RNBQKB1R b KQkq -
+Benk\"o gambit *
+rnbqkbnr/pp2pppp/8/2p5/2Pp4/3P1N2/PP2PPPP/RNBQKB1R b KQkq -
+Benoni defense, Hromodka system *
+rnbqkbnr/pp2pppp/8/2p5/2Pp4/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+Benoni defense *
+rnbqkbnr/pp2pppp/8/2p5/2PpP3/5N2/PP1P1PPP/RNBQKB1R b KQkq e3
+Czech Benoni defense *
+rnbqkbnr/pp2pppp/8/2p5/3p4/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian: Anti-Gr\"unfeld *
+rnbqkbnr/pp2pppp/8/2pp4/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+Benoni defense *
+rnbqkbnr/pp2pppp/8/2pp4/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+QGD: symmetrical (Austrian) defense *
+rnbqkbnr/pp2pppp/8/2pp4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QGD: symmetrical (Austrian) defense
+rnbqkbnr/pp2pppp/8/2pp4/3P1B2/8/PPP1PPPP/RN1QKBNR b KQkq -
+QGD: Grau (Sahovic) defense *
+rnbqkbnr/pp2pppp/8/2pp4/3P1B2/8/PPP1PPPP/RN1QKBNR w KQkq -
+Queen's pawn, Mason variation, Steinitz counter-gambit
+rnbqkbnr/pp2pppp/8/2pp4/3P4/2N5/PPP1PPPP/R1BQKBNR b KQkq -
+QGD: Chigorin defense *
+rnbqkbnr/pp2pppp/8/2pp4/3P4/2P5/PP2PPPP/RNBQKBNR b KQkq -
+QGD Slav defense *
+rnbqkbnr/pp2pppp/8/2pp4/3P4/4P3/PPP2PPP/RNBQKBNR b KQkq -
+Queen's gambit declined *
+rnbqkbnr/pp2pppp/8/2pp4/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+QGD: Marshall defense *
+rnbqkbnr/pp2pppp/8/2pp4/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's pawn game, Krause variation
+rnbqkbnr/pp2pppp/8/2pp4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's gambit declined *
+rnbqkbnr/pp2pppp/8/2pp4/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+QGD: Albin counter-gambit *
+rnbqkbnr/pp2pppp/8/2pp4/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+Budapest defense declined *
+rnbqkbnr/pp2pppp/8/2pp4/5P2/4P3/PPPP2PP/RNBQKBNR b KQkq -
+Dutch defense *
+rnbqkbnr/pp2pppp/8/2pp4/5P2/5N2/PPPPP1PP/RNBQKB1R b KQkq -
+Dutch defense *
+rnbqkbnr/pp2pppp/8/2pp4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch defense *
+rnbqkbnr/pp2pppp/8/2pp4/8/1P2P3/P1PP1PPP/RNBQKBNR b KQkq -
+Queen's pawn: Keres defense *
+rnbqkbnr/pp2pppp/8/2pp4/8/1P3N2/P1PPPPPP/RNBQKB1R b KQkq -
+Queen's Indian accelerated *
+rnbqkbnr/pp2pppp/8/2pp4/8/2N2N2/PPPPPPPP/R1BQKB1R b KQkq -
+Kevitz-Trajkovich defense *
+rnbqkbnr/pp2pppp/8/2pp4/8/3P1N2/PPP1PPPP/RNBQKB1R b KQkq -
+Old Indian defense *
+rnbqkbnr/pp2pppp/8/2pp4/8/3P4/PPP1PPPP/RNBQKBNR w KQkq -
+Old Indian defense *
+rnbqkbnr/pp2pppp/8/2pp4/8/4PN2/PPPP1PPP/RNBQKB1R b KQkq -
+Queen's pawn game *
+rnbqkbnr/pp2pppp/8/2pp4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Queen's pawn game *
+rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+King's Indian defense *
+rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+R\'eti: King's Indian attack (with ...c5)
+rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPPBP/RNBQK2R b KQkq -
+R\'eti: King's Indian attack
+rnbqkbnr/pp2pppp/8/3p4/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+Caro-Kann: Panov-Botvinnik attack
+rnbqkbnr/pp2pppp/8/3p4/3p4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+QGD Slav defense: exchange variation *
+rnbqkbnr/pp2pppp/8/8/1pPp4/P4N2/3PPPPP/RNBQKB1R b KQkq -
+Benk\"o gambit half accepted *
+rnbqkbnr/pp2pppp/8/8/2Pp4/p4N2/3PPPPP/RNBQKB1R w KQkq -
+Benk\"o gambit accepted *
+rnbqkbnr/pp3ppp/2p1p3/3p4/2P5/5NP1/PP1PPP1P/RNBQKB1R w KQkq -
+English: Kurajica defense
+rnbqkbnr/pp3ppp/2p1p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: semi-Slav
+rnbqkbnr/pp3ppp/2p1p3/3p4/2PPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+QGD: semi-Slav, Marshall gambit
+rnbqkbnr/pp3ppp/2p1p3/8/2pP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD: semi-Slav, Noteboom variation
+rnbqkbnr/pp3ppp/2p5/3B4/4Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Anderssen variation
+rnbqkbnr/pp3ppp/2p5/3Pp3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+Danish gambit: S\o rensen defense *
+rnbqkbnr/pp3ppp/2p5/3Pp3/5P2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: Nimzovich counter-gambit
+rnbqkbnr/pp3ppp/2p5/3Pp3/8/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: Smith-Morra gambit *
+rnbqkbnr/pp3ppp/2p5/3Pp3/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+Danish gambit *
+rnbqkbnr/pp3ppp/2p5/3p4/2PPp3/2N1P3/PP3PPP/R1BQKBNR b KQkq -
+French: advance variation *
+rnbqkbnr/pp3ppp/2p5/3p4/2PPp3/4P3/PP3PPP/RNBQKBNR w KQkq -
+French: advance variation *
+rnbqkbnr/pp3ppp/2p5/3pp3/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD Slav: Winawer counter-gambit
+rnbqkbnr/pp3ppp/2pp4/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+English, Keres variation
+rnbqkbnr/pp3ppp/3p4/2pPp3/4P3/8/PPP2PPP/RNBQKBNR w KQkq -
+Semi-Benoni (`blockade variation')
+rnbqkbnr/pp3ppp/4p3/2PpP3/8/8/PPP2PPP/RNBQKBNR b KQkq -
+French: advance, Steinitz variation
+rnbqkbnr/pp3ppp/4p3/2pp4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: Tarrasch defense
+rnbqkbnr/pp3ppp/4p3/2pp4/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+French: Marshall variation
+rnbqkbnr/pp3ppp/4p3/2pp4/3PP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Marshall variation
+rnbqkbnr/pp3ppp/4p3/2pp4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+French: Tarrasch, open variation
+rnbqkbnr/pp3ppp/4p3/2pp4/4P3/2N3P1/PPPP1P1P/R1BQKBNR w KQkq -
+Sicilian: closed, Korchnoi variation
+rnbqkbnr/pp3ppp/4p3/2ppP3/1P6/5N2/P1PP1PPP/RNBQKB1R b KQkq -
+French: Wing gambit
+rnbqkbnr/pp3ppp/4p3/2ppP3/3P2Q1/8/PPP2PPP/RNB1KBNR b KQkq -
+French: advance, Nimzovich variation
+rnbqkbnr/pp3ppp/4p3/2ppP3/3P4/2P5/PP3PPP/RNBQKBNR b KQkq -
+French: advance variation
+rnbqkbnr/pp3ppp/4p3/2ppP3/3P4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+French: advance, Nimzovich system
+rnbqkbnr/pp3ppp/4p3/3P4/3p4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: Tarrasch, von Hennig-Schara gambit
+rnbqkbnr/pp3ppp/4p3/8/2Bp4/5N2/PPPN1PPP/R1BQK2R w KQkq -
+French: Tarrasch, Eliskases variation
+rnbqkbnr/pp3ppp/8/1Npp4/8/8/PPP1PPPP/RNBQKB1R b KQkq -
+Scandinavian: Kiel variation *
+rnbqkbnr/pp3ppp/8/2Ppp3/5P2/8/PPP1P1PP/RNBQKBNR b KQkq -
+QGA: Schwartz defense *
+rnbqkbnr/pp3ppp/8/2Ppp3/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+QGA: 3.e4 *
+rnbqkbnr/pp3ppp/8/2p1p1N1/4p3/3P4/PPP2PPP/RNBQKB1R b KQkq -
+Budapest: Alekhine variation, Balogh gambit *
+rnbqkbnr/pp3ppp/8/2p1p1N1/4p3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Budapest: Alekhine variation *
+rnbqkbnr/pp3ppp/8/2pp4/3Np3/3P4/PPP1PPPP/RNBQKB1R w KQkq -
+Alekhine's defense *
+rnbqkbnr/pp3ppp/8/2pp4/3P4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+QGD: Tarrasch defense
+rnbqkbnr/pp3ppp/8/2pp4/3P4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: Tarrasch defense, 4.cd ed
+rnbqkbnr/pp3ppp/8/2pp4/3P4/8/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik attack *
+rnbqkbnr/pp3ppp/8/2pp4/3P4/8/PPPN1PPP/R1BQKBNR w KQkq -
+French: Tarrasch, open, 4.ed ed
+rnbqkbnr/pp3ppp/8/2pp4/3PP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+QGD: Tarrasch defense, Marshall gambit
+rnbqkbnr/pp3ppp/8/2pp4/8/1N1p4/PPP1PPPP/RNBQKB1R w KQkq -
+Alekhine's defense: exchange variation *
+rnbqkbnr/pp3ppp/8/2ppp3/5P2/4P3/PPPP2PP/RNBQKBNR w KQkq -
+Dutch: Staunton gambit deferred *
+rnbqkbnr/pp3ppp/8/2ppp3/8/5PPN/PPPPP2P/RNBQKB1R b KQkq -
+Hippopotamus defense *
+rnbqkbnr/pp3ppp/8/3p4/2pP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Caro-Kann: Panov-Botvinnik, Gunderam attack *
+rnbqkbnr/pp4pp/8/2p1pp2/8/2N5/PPPP1PPP/RNBQKB1R b KQkq -
+Budapest: Alekhine, Abonyi variation *
+rnbqkbnr/pp4pp/8/2pp1p2/4p1P1/1N1P4/PPP1PP1P/RNBQKB1R b KQkq -
+Alekhine's defense: four pawns attack, Planinc variation *
+rnbqkbnr/pp4pp/8/2pp1p2/4p3/1N1P2P1/PPP1PP1P/RNBQKB1R b KQkq -
+Alekhine's defense: four pawns attack, fianchetto variation *
+rnbqkbnr/pp4pp/8/2pp1p2/4p3/1N1P4/PPP1PPPP/RNBQKB1R w KQkq -
+Alekhine's defense: four pawns attack *
+rnbqkbnr/pp4pp/8/2pp1p2/4pB2/1N1P4/PPP1PPPP/RN1QKB1R b KQkq -
+Alekhine's defense: four pawns attack, Trifunovi\'c variation *
+rnbqkbnr/pp4pp/8/2pp4/4p3/1NN5/PPP1PPPP/R1BQKB1R b KQkq -
+Alekhine's defense: four pawns attack, 6...Nc6 *
+rnbqkbnr/ppp1p1pp/3p4/5p2/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+(Dutch:) Balogh defense
+rnbqkbnr/ppp1p1pp/5p2/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Paleface attack *
+rnbqkbnr/ppp1p1pp/8/3p1p2/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Canard opening *
+rnbqkbnr/ppp1p1pp/8/5p2/2pPP3/8/PP3PPP/RNBQKBNR w KQkq -
+QGA: Schwartz defense
+rnbqkbnr/ppp1p2p/5p2/3p2p1/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Gedult attack *
+rnbqkbnr/ppp1pp1p/6p1/3p4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch defense *
+rnbqkbnr/ppp1pp1p/6p1/3p4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+R\'eti: King's Indian attack
+rnbqkbnr/ppp1pp1p/8/3p2p1/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch, Krejcik gambit *
+rnbqkbnr/ppp1pp1p/8/3p2p1/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Queen's pawn: Bronstein gambit *
+rnbqkbnr/ppp1ppp1/7p/3p4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch, Korchnoi attack *
+rnbqkbnr/ppp1pppp/3p4/8/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+Old Indian defense
+rnbqkbnr/ppp1pppp/3p4/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's Pawn
+rnbqkbnr/ppp1pppp/3p4/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+Mieses opening *
+rnbqkbnr/ppp1pppp/3p4/8/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+R\'eti opening
+rnbqkbnr/ppp1pppp/3p4/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Mieses opening *
+rnbqkbnr/ppp1pppp/8/3p2B1/3P4/8/PPP1PPPP/RN1QKBNR b KQkq -
+Levitsky attack (Queen's bishop attack)
+rnbqkbnr/ppp1pppp/8/3p4/1P6/5N2/P1PPPPPP/RNBQKB1R b KQkq -
+Santasiere's folly
+rnbqkbnr/ppp1pppp/8/3p4/1P6/8/P1PPPPPP/RNBQKBNR b KQkq -
+Polish defense *
+rnbqkbnr/ppp1pppp/8/3p4/2P2P2/8/PP1PP1PP/RNBQKBNR b KQkq -
+Mujannah opening
+rnbqkbnr/ppp1pppp/8/3p4/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+R\'eti opening
+rnbqkbnr/ppp1pppp/8/3p4/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+Old Benoni defense *
+rnbqkbnr/ppp1pppp/8/3p4/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+Queen's gambit declined
+rnbqkbnr/ppp1pppp/8/3p4/3P1B2/8/PPP1PPPP/RN1QKBNR b KQkq -
+Queen's pawn, Mason variation
+rnbqkbnr/ppp1pppp/8/3p4/3P4/2N5/PPP1PPPP/R1BQKBNR b KQkq -
+Queen's pawn: Chigorin variation
+rnbqkbnr/ppp1pppp/8/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Queen's pawn game
+rnbqkbnr/ppp1pppp/8/3p4/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+Queen's pawn game *
+rnbqkbnr/ppp1pppp/8/3p4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn game
+rnbqkbnr/ppp1pppp/8/3p4/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+Blackmar gambit
+rnbqkbnr/ppp1pppp/8/3p4/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+Tennison (Lemberg, Zukertort) gambit
+rnbqkbnr/ppp1pppp/8/3p4/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+Queen's pawn: Charlick (Englund) gambit *
+rnbqkbnr/ppp1pppp/8/3p4/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Scandinavian (center counter) defense
+rnbqkbnr/ppp1pppp/8/3p4/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+Bird's opening: Williams gambit
+rnbqkbnr/ppp1pppp/8/3p4/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+Dutch *
+rnbqkbnr/ppp1pppp/8/3p4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Bird's opening
+rnbqkbnr/ppp1pppp/8/3p4/8/1P3N2/P1PPPPPP/RNBQKB1R b KQkq -
+R\'eti: Nimzovich-Larsen attack
+rnbqkbnr/ppp1pppp/8/3p4/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+Queen's pawn: English defense *
+rnbqkbnr/ppp1pppp/8/3p4/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: classical variation
+rnbqkbnr/ppp1pppp/8/3p4/8/2N5/PPPPPPPP/R1BQKBNR b KQkq -
+Queen's pawn: Lundin (Kevitz-Mikenas) defense *
+rnbqkbnr/ppp1pppp/8/3p4/8/3P1N2/PPP1PPPP/RNBQKB1R b KQkq -
+R\'eti: old Indian attack
+rnbqkbnr/ppp1pppp/8/3p4/8/3P4/PPP1PPPP/RNBQKBNR b KQkq -
+Queen's Pawn *
+rnbqkbnr/ppp1pppp/8/3p4/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+Queen's pawn *
+rnbqkbnr/ppp1pppp/8/3p4/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+Queen's pawn game *
+rnbqkbnr/ppp1pppp/8/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+R\'eti opening
+rnbqkbnr/ppp1pppp/8/3p4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+R\'eti: King's Indian attack (Barcza system)
+rnbqkbnr/ppp1pppp/8/3p4/8/6P1/PPPPPP1P/RNBQKBNR b KQkq -
+Modern defense *
+rnbqkbnr/ppp1pppp/8/3p4/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Queen's pawn *
+rnbqkbnr/ppp1pppp/8/8/2Pp1P2/8/PP1PP1PP/RNBQKBNR b KQkq -
+Old Benoni: Mujannah formation *
+rnbqkbnr/ppp1pppp/8/8/2Pp4/3P4/PP2PPPP/RNBQKBNR b KQkq -
+Old Benoni defense *
+rnbqkbnr/ppp1pppp/8/8/2Pp4/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+Old Benoni defense *
+rnbqkbnr/ppp1pppp/8/8/2Pp4/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+R\'eti: advance variation
+rnbqkbnr/ppp1pppp/8/8/2PpP3/8/PP1P1PPP/RNBQKBNR b KQkq e3
+Old Benoni defense *
+rnbqkbnr/ppp1pppp/8/8/2p5/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+R\'eti accepted
+rnbqkbnr/ppp1pppp/8/8/2pP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+QGA: 3.Nf3
+rnbqkbnr/ppp1pppp/8/8/2pP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Queen's gambit accepted
+rnbqkbnr/ppp1pppp/8/8/2pPP3/8/PP3PPP/RNBQKBNR b KQkq -
+QGA: 3.e4
+rnbqkbnr/ppp2p1p/3p2p1/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Larsen variation
+rnbqkbnr/ppp2p1p/3p4/4N3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Kolisch defense
+rnbqkbnr/ppp2p1p/8/3p2p1/4p3/6P1/PPPPPPNP/RNBQKB1R b KQkq -
+Norwegian defense *
+rnbqkbnr/ppp2p1p/8/3p4/2B1Ppp1/5N2/PPPP2PP/RNBQ1RK1 w kq -
+KGA: Muzio gambit, Brentano defense
+rnbqkbnr/ppp2p1p/8/3pN3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Brentano (Campbell) defense
+rnbqkbnr/ppp2ppp/3p4/4p3/2P5/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+English opening
+rnbqkbnr/ppp2ppp/3p4/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Philidor's defense
+rnbqkbnr/ppp2ppp/3p4/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Philidor's defense
+rnbqkbnr/ppp2ppp/3p4/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: Indian opening *
+rnbqkbnr/ppp2ppp/3p4/4p3/8/2P5/PP1PPPPP/RNBQKBNR w KQkq -
+Caro-Kann: closed (Breyer) variation *
+rnbqkbnr/ppp2ppp/3p4/4p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French: King's Indian attack *
+rnbqkbnr/ppp2ppp/3p4/4p3/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Mar\'oczy variation *
+rnbqkbnr/ppp2ppp/3p4/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: exchange variation
+rnbqkbnr/ppp2ppp/3p4/8/3pP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: exchange variation
+rnbqkbnr/ppp2ppp/3p4/8/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Fischer defense
+rnbqkbnr/ppp2ppp/3pp3/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Lengfellner system
+rnbqkbnr/ppp2ppp/4p3/3P4/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+French: exchange variation
+rnbqkbnr/ppp2ppp/4p3/3p4/2P5/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+English opening: Agincourt variation
+rnbqkbnr/ppp2ppp/4p3/3p4/2P5/5NP1/PP1PPP1P/RNBQKB1R b KQkq -
+English opening: Agincourt variation
+rnbqkbnr/ppp2ppp/4p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+QGD: 3.Nc3
+rnbqkbnr/ppp2ppp/4p3/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Queen's gambit declined
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+French: Paulsen variation
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/3B4/PPP2PPP/RNBQK1NR b KQkq -
+French: Schlechter variation
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/4B3/PPP2PPP/RN1QKBNR b KQkq -
+French: Alapin variation
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+French defense
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/8/PPPN1PPP/R1BQKBNR b KQkq -
+French: Tarrasch
+rnbqkbnr/ppp2ppp/4p3/3p4/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+French: Two knights variation
+rnbqkbnr/ppp2ppp/4p3/3p4/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+French: Pelikan variation
+rnbqkbnr/ppp2ppp/4p3/3pP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+French: advance variation
+rnbqkbnr/ppp2ppp/4p3/8/3Pp3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+French: Rubinstein variation
+rnbqkbnr/ppp2ppp/8/1B1P4/4pP2/8/PPPP2PP/RNBQK1NR b KQkq -
+KGD: Falkbeer, Nimzovich variation
+rnbqkbnr/ppp2ppp/8/3P4/3N4/8/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: Paulsen attack
+rnbqkbnr/ppp2ppp/8/3P4/4pP2/3P4/PPP3PP/RNBQKBNR b KQkq -
+KGD: Falkbeer, 4.d3
+rnbqkbnr/ppp2ppp/8/3P4/4pP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: Falkbeer, 3...e4
+rnbqkbnr/ppp2ppp/8/3Pp3/5P2/8/PPPP2PP/RNBQKBNR b KQkq -
+KGD: Falkbeer counter-gambit
+rnbqkbnr/ppp2ppp/8/3Pp3/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+Center game *
+rnbqkbnr/ppp2ppp/8/3p4/1P1Np3/8/P1PPPPPP/RNBQKB1R b KQkq -
+Alekhine's defense: O'Sullivan gambit *
+rnbqkbnr/ppp2ppp/8/3p4/2B1P3/8/PB3PPP/RN1QK1NR w KQkq -
+Danish gambit: Schlechter defense
+rnbqkbnr/ppp2ppp/8/3p4/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Bledow variation
+rnbqkbnr/ppp2ppp/8/3p4/3N4/8/PPP1PPPP/RNBQKB1R b KQkq -
+Scandinavian: Marshall variation *
+rnbqkbnr/ppp2ppp/8/3p4/3Np3/3P4/PPP1PPPP/RNBQKB1R b KQkq -
+Alekhine's defense *
+rnbqkbnr/ppp2ppp/8/3p4/3Np3/8/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense *
+rnbqkbnr/ppp2ppp/8/3p4/3Pp3/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: advance variation *
+rnbqkbnr/ppp2ppp/8/3p4/3Pp3/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: advance variation *
+rnbqkbnr/ppp2ppp/8/3p4/3p4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: exchange variation *
+rnbqkbnr/ppp2ppp/8/3p4/3p4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: exchange variation *
+rnbqkbnr/ppp2ppp/8/3p4/3p4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Scandinavian defense *
+rnbqkbnr/ppp2ppp/8/3p4/3p4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+Scandinavian: Richter variation *
+rnbqkbnr/ppp2ppp/8/3p4/3pP3/2P5/PP3PPP/RNBQKBNR w KQkq -
+Danish gambit: S\o rensen defense
+rnbqkbnr/ppp2ppp/8/3p4/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Abbazia defense (classical defense, modern defense[!])
+rnbqkbnr/ppp2ppp/8/3pP3/8/8/PPPPP1PP/RNBQKBNR b KQkq -
+Dutch: Staunton gambit *
+rnbqkbnr/ppp2ppp/8/3pp3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: Smith-Morra gambit *
+rnbqkbnr/ppp2ppp/8/3pp3/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QGD: Albin counter-gambit
+rnbqkbnr/ppp2ppp/8/3pp3/3P4/2P5/PP2PPPP/RNBQKBNR b KQkq -
+Caro-Kann defense *
+rnbqkbnr/ppp2ppp/8/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR b KQkq -
+French defense *
+rnbqkbnr/ppp2ppp/8/3pp3/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Blackmar gambit *
+rnbqkbnr/ppp2ppp/8/3pp3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+QP counter-gambit (elephant gambit)
+rnbqkbnr/ppp2ppp/8/3pp3/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+KGD: Falkbeer, Milner-Barry variation
+rnbqkbnr/ppp2ppp/8/3pp3/4PP2/5N2/PPPP2PP/RNBQKB1R b KQkq -
+KGD: Falkbeer, Tartakower variation
+rnbqkbnr/ppp2ppp/8/3pp3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: Falkbeer counter-gambit
+rnbqkbnr/ppp2ppp/8/3pp3/5P2/3P4/PPP1P1PP/RNBQKBNR b KQkq -
+(Dutch:) Balogh defense *
+rnbqkbnr/ppp2ppp/8/3pp3/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch: Staunton gambit *
+rnbqkbnr/ppp2ppp/8/3pp3/8/2N2P2/PPPPP1PP/R1BQKBNR b KQkq -
+KP: Neo-Mongoloid defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/2N5/PPPPPPPP/R1BQKBNR w KQkq -
+KP: Nimzovich defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/2P2N2/PP1PPPPP/RNBQKB1R b KQkq -
+Caro-Masi defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/2P5/PP1PPPPP/RNBQKBNR w KQkq -
+Caro-Kann defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/3P1N2/PPP1PPPP/RNBQKB1R b KQkq -
+Pirc defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/3PP3/PPP2PPP/RNBQKBNR b KQkq -
+Lengfellner system *
+rnbqkbnr/ppp2ppp/8/3pp3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/5P2/PPPPPKPP/RNBQ1BNR b kq -
+Fried fox defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/6P1/PPPPPPBP/RNBQK1NR b KQkq -
+Robatsch (modern) defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/BP6/P1PPPPPP/RN1QKBNR b KQkq -
+Guatemala defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/P3P3/1PPP1PPP/RNBQKBNR b KQkq -
+St. George defense *
+rnbqkbnr/ppp2ppp/8/4P3/2Pp4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+QGD: Albin counter-gambit
+rnbqkbnr/ppp2ppp/8/4p3/2Pp4/4P3/PP1P1PPP/RNBQKBNR w KQkq -
+Old Benoni: Franco-Benoni defense *
+rnbqkbnr/ppp2ppp/8/4p3/2PpP3/3P4/PP3PPP/RNBQKBNR b KQkq -
+Semi-Benoni (`blockade variation') *
+rnbqkbnr/ppp2ppp/8/8/2pPp3/4P3/PP3PPP/RNBQKBNR w KQkq -
+French: advance, Steinitz variation *
+rnbqkbnr/ppp3pp/3p4/4Pp2/3p4/8/PPP2PPP/RNBQKBNR w KQkq -
+KGD: Falkbeer, 4.d3 *
+rnbqkbnr/ppp3pp/3p4/4pp2/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Philidor: L\'opez counter-gambit
+rnbqkbnr/ppp3pp/3p4/4pp2/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+Philidor: Philidor counter-gambit, Zukertort variation
+rnbqkbnr/ppp3pp/3p4/4pp2/3PP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Philidor counter-gambit
+rnbqkbnr/ppp3pp/4P3/3p2N1/4p3/8/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: Philidor counter-gambit, del Rio attack
+rnbqkbnr/ppp3pp/4p3/3p1p2/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+French: Tarrasch, Haberditz variation
+rnbqkbnr/ppp3pp/5p2/3pp3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: Tartakower (fantasy) variation *
+rnbqkbnr/ppp3pp/5p2/3pp3/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Blackmar-Diemer gambit *
+rnbqkbnr/ppp3pp/8/3Ppp2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+Halasz gambit *
+rnbqkbnr/ppp3pp/8/3pN3/2B1p3/8/PPPP1PPP/RNBQK2R w KQkq -
+Latvian: Polerio variation
+rnbqkbnr/ppp3pp/8/3ppP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Villemson (Steinitz) gambit *
+rnbqkbnr/ppp3pp/8/3ppp2/8/6P1/PPPPPPBP/RNBQK1NR w KQkq -
+Robatsch defense: three pawns attack *
+rnbqkbnr/ppp3pp/8/4pp2/3p4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+KGD: Falkbeer, 5.de *
+rnbqkbnr/pppp1B1p/8/8/4Ppp1/5N2/PPPP2PP/RNBQK2R b KQkq -
+KGA: Lolli gambit (wild Muzio gambit)
+rnbqkbnr/pppp1p1p/6p1/4p3/2P1P3/8/PP1P1PPP/RNBQKBNR w KQkq -
+English: Adorjan defense
+rnbqkbnr/pppp1p1p/6p1/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: Steinitz variation *
+rnbqkbnr/pppp1p1p/8/4N3/2B1Ppp1/8/PPPP2PP/RNBQK2R b KQkq -
+KGA: Salvio gambit
+rnbqkbnr/pppp1p1p/8/4N3/3PPpp1/8/PPP3PP/RNBQKB1R b KQkq -
+KGA: S\o rensen gambit
+rnbqkbnr/pppp1p1p/8/6N1/4PppP/8/PPPP2P1/RNBQKB1R b KQkq -
+KGA: Allgaier gambit
+rnbqkbnr/pppp1p1p/8/6p1/2B1Pp2/5N2/PPPP2PP/RNBQK2R b KQkq -
+KGA: King's knight's gambit
+rnbqkbnr/pppp1p1p/8/6p1/3PPp2/5N2/PPP3PP/RNBQKB1R b KQkq -
+KGA: Rosentreter gambit
+rnbqkbnr/pppp1p1p/8/6p1/4Pp1P/5N2/PPPP2P1/RNBQKB1R b KQkq -
+King's knight's gambit
+rnbqkbnr/pppp1p1p/8/6p1/4Pp2/2N2N2/PPPP2PP/R1BQKB1R b KQkq -
+KGA: Quaade gambit
+rnbqkbnr/pppp1p1p/8/8/2B1Ppp1/2N2N2/PPPP2PP/R1BQK2R b KQkq -
+KGA: MacDonnell gambit
+rnbqkbnr/pppp1p1p/8/8/2B1Ppp1/5N2/PPPP2PP/RNBQ1RK1 b kq -
+KGA: Muzio gambit
+rnbqkbnr/pppp1p1p/8/8/2BPPpp1/5N2/PPP3PP/RNBQK2R b KQkq -
+KGA: Ghulam Kassim gambit
+rnbqkbnr/pppp1p2/8/4N2p/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, long whip (Stockwhip, classical) defense
+rnbqkbnr/pppp1pp1/7p/8/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Becker defense
+rnbqkbnr/pppp1ppp/4p3/4P3/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+French: Steinitz attack
+rnbqkbnr/pppp1ppp/4p3/8/2P1P3/8/PP1P1PPP/RNBQKBNR b KQkq -
+French defense, Steiner variation
+rnbqkbnr/pppp1ppp/4p3/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English opening
+rnbqkbnr/pppp1ppp/4p3/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn
+rnbqkbnr/pppp1ppp/4p3/8/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+French defense
+rnbqkbnr/pppp1ppp/4p3/8/4P3/1P6/P1PP1PPP/RNBQKBNR b KQkq -
+French: R\'eti (Spielmann) variation
+rnbqkbnr/pppp1ppp/4p3/8/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+French defense
+rnbqkbnr/pppp1ppp/4p3/8/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+French: King's Indian attack
+rnbqkbnr/pppp1ppp/4p3/8/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+French defense
+rnbqkbnr/pppp1ppp/4p3/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+French defense
+rnbqkbnr/pppp1ppp/4p3/8/4P3/8/PPPPQPPP/RNB1KBNR b KQkq -
+French: Chigorin variation
+rnbqkbnr/pppp1ppp/4p3/8/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+French: Labourdonnais variation
+rnbqkbnr/pppp1ppp/4p3/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Van't Kruijs opening *
+rnbqkbnr/pppp1ppp/8/4N3/4p3/8/PPPPPPPP/RNBQKB1R b KQkq -
+Alekhine's defense: Mokele Mbembe (B\"ucker) variation *
+rnbqkbnr/pppp1ppp/8/4p2Q/4P3/8/PPPP1PPP/RNB1KBNR b KQkq -
+KP: Patzer opening
+rnbqkbnr/pppp1ppp/8/4p3/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+Bishop's opening
+rnbqkbnr/pppp1ppp/8/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+English opening
+rnbqkbnr/pppp1ppp/8/4p3/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+English, Nimzovich variation
+rnbqkbnr/pppp1ppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+Sicilian defense *
+rnbqkbnr/pppp1ppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English opening
+rnbqkbnr/pppp1ppp/8/4p3/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+Scandinavian (center counter) defense *
+rnbqkbnr/pppp1ppp/8/4p3/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn: Charlick (Englund) gambit
+rnbqkbnr/pppp1ppp/8/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Vienna game
+rnbqkbnr/pppp1ppp/8/4p3/4P3/2P5/PP1P1PPP/RNBQKBNR b KQkq -
+KP: Lopez opening
+rnbqkbnr/pppp1ppp/8/4p3/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+KP: Indian opening
+rnbqkbnr/pppp1ppp/8/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+King's knight opening
+rnbqkbnr/pppp1ppp/8/4p3/4P3/5P2/PPPP2PP/RNBQKBNR b KQkq -
+KP: King's head opening
+rnbqkbnr/pppp1ppp/8/4p3/4P3/5Q2/PPPP1PPP/RNB1KBNR b KQkq -
+KP: Napoleon's opening
+rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+King's pawn game *
+rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+King's pawn game
+rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPPNPPP/RNBQKB1R b KQkq -
+Alapin's opening
+rnbqkbnr/pppp1ppp/8/4p3/4P3/P7/1PPP1PPP/RNBQKBNR b KQkq -
+KP: Mengarini's opening
+rnbqkbnr/pppp1ppp/8/4p3/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+King's gambit
+rnbqkbnr/pppp1ppp/8/4p3/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+Fred *
+rnbqkbnr/pppp1ppp/8/4p3/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Bird: From gambit
+rnbqkbnr/pppp1ppp/8/4p3/6P1/8/PPPPPP1P/RNBQKBNR b KQkq -
+Reversed Grob (Borg/Basman defense/macho Grob) *
+rnbqkbnr/pppp1ppp/8/4p3/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+Owen defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: modern variation
+rnbqkbnr/pppp1ppp/8/4p3/8/2N5/PPPPPPPP/R1BQKBNR b KQkq -
+KP: Nimzovich defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/2N5/PPPPPPPP/R1BQKBNR w KQkq -
+Dunst (Sleipner,Heinrichsen) opening
+rnbqkbnr/pppp1ppp/8/4p3/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+Caro-Kann defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/3P4/PPP1PPPP/RNBQKBNR w KQkq -
+Mieses opening
+rnbqkbnr/pppp1ppp/8/4p3/8/3P4/PPPNPPPP/R1BQKBNR b KQkq -
+Valencia opening
+rnbqkbnr/pppp1ppp/8/4p3/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+French defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+Alekhine's defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+Benko's opening: reversed Alekhine
+rnbqkbnr/pppp1ppp/8/4p3/8/5P2/PPPPP1PP/RNBQKBNR b KQkq -
+Barnes defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/5P2/PPPPPKPP/RNBQ1BNR b kq -
+Hammerschlag (Fried fox/Pork chop opening)
+rnbqkbnr/pppp1ppp/8/4p3/8/6P1/PPPPPP1P/RNBQKBNR b KQkq -
+Robatsch (modern) defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/7P/PPPPPPP1/RNBQKBNR b KQkq -
+Carr's defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+King's pawn opening *
+rnbqkbnr/pppp1ppp/8/4p3/8/N7/PPPPPPPP/R1BQKBNR b KQkq -
+Lemming defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/P1N5/1PPPPPPP/R1BQKBNR b KQkq -
+Battambang opening
+rnbqkbnr/pppp1ppp/8/4p3/8/P6P/1PPPPPP1/RNBQKBNR b KQkq -
+Global opening
+rnbqkbnr/pppp1ppp/8/4p3/8/P7/1PPPPPPP/RNBQKBNR b KQkq -
+St. George (Baker) defense *
+rnbqkbnr/pppp1ppp/8/4p3/P6P/8/1PPPPPP1/RNBQKBNR b KQkq -
+Crab opening
+rnbqkbnr/pppp1ppp/8/4p3/P7/8/1PPPPPPP/RNBQKBNR b KQkq -
+Corn stalk defense *
+rnbqkbnr/pppp1ppp/8/8/2B1Pp2/8/PPPP2PP/RNBQK1NR b KQkq -
+KGA: bishop's gambit
+rnbqkbnr/pppp1ppp/8/8/2P1p3/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+English, Nimzovich, Flohr variation
+rnbqkbnr/pppp1ppp/8/8/3Np3/8/PPPPPPPP/RNBQKB1R b KQkq -
+Alekhine's defense *
+rnbqkbnr/pppp1ppp/8/8/3PPp2/8/PPP3PP/RNBQKBNR b KQkq -
+KGA: Villemson (Steinitz) gambit
+rnbqkbnr/pppp1ppp/8/8/3QP3/8/PPP2PPP/RNB1KBNR b KQkq -
+Center game
+rnbqkbnr/pppp1ppp/8/8/3p4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Scandinavian defense *
+rnbqkbnr/pppp1ppp/8/8/3pP3/2P5/PP3PPP/RNBQKBNR b KQkq -
+Danish gambit
+rnbqkbnr/pppp1ppp/8/8/3pP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Center game
+rnbqkbnr/pppp1ppp/8/8/3pPP2/8/PPP3PP/RNBQKBNR b KQkq -
+Halasz gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp1P/8/PPPP2P1/RNBQKBNR b KQkq -
+KGA: Pawn's gambit (Stamma gambit)
+rnbqkbnr/pppp1ppp/8/8/4Pp2/1P6/P1PP2PP/RNBQKBNR b KQkq -
+KGA: Orsini gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+KGA: Keres (Mason-Steinitz) gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/3B4/PPPP2PP/RNBQK1NR b KQkq -
+KGA: Schurig gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/5N2/PPPP2PP/RNBQKB1R b KQkq -
+King's knight's gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/5Q2/PPPP2PP/RNB1KBNR b KQkq -
+KGA: Breyer gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/8/PPPP1KPP/RNBQ1BNR b kq -
+KGA: Tumbleweed gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/8/PPPP2PP/RNBQKBNR w KQkq -
+King's gambit accepted
+rnbqkbnr/pppp1ppp/8/8/4Pp2/8/PPPPB1PP/RNBQK1NR b KQkq -
+KGA: Lesser bishop's (Petroff-Jaenisch-Tartakower) gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/8/PPPPQ1PP/RNB1KBNR b KQkq -
+KGA: Carrera (Basman) gambit
+rnbqkbnr/pppp1ppp/8/8/4p3/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French: Steinitz attack *
+rnbqkbnr/pppp1ppp/8/8/4p3/8/PPPPPPPP/RNBQKBNR b KQkq -
+Alekhine's defense: Brooklyn defense *
+rnbqkbnr/pppp2p1/8/4pP1p/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Pawn's gambit (Stamma gambit) *
+rnbqkbnr/pppp2pp/4p3/5p2/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+Dutch defense, Rubinstein variation
+rnbqkbnr/pppp2pp/4p3/5p2/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Dutch defense
+rnbqkbnr/pppp2pp/4p3/5p2/2PPP3/8/PP3PPP/RNBQKBNR b KQkq -
+Dutch: Staunton gambit deferred
+rnbqkbnr/pppp2pp/4p3/5p2/3P2P1/3Q4/PPP1PP1P/RNB1KBNR b KQkq -
+Dutch, Von Pretzel gambit
+rnbqkbnr/pppp2pp/5p2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Damiano's defense
+rnbqkbnr/pppp2pp/5p2/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: King's head opening *
+rnbqkbnr/pppp2pp/8/4Pp2/3p4/8/PPP2PPP/RNBQKBNR b KQkq -
+KGD: Falkbeer, 3...e4 *
+rnbqkbnr/pppp2pp/8/4pP2/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+King's gambit accepted *
+rnbqkbnr/pppp2pp/8/4pp2/2B1P3/3P4/PPP2PPP/RNBQK1NR b KQkq -
+Bishop's opening: Calabrese counter-gambit, Jaenisch variation
+rnbqkbnr/pppp2pp/8/4pp2/2B1P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Latvian gambit, 3.Bc4
+rnbqkbnr/pppp2pp/8/4pp2/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+KGD: classical variation *
+rnbqkbnr/pppp2pp/8/4pp2/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Calabrese counter-gambit
+rnbqkbnr/pppp2pp/8/4pp2/2P1P3/8/PP1P1PPP/RNBQKBNR b KQkq -
+KGD: Mafia defense *
+rnbqkbnr/pppp2pp/8/4pp2/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: Grand Prix attack *
+rnbqkbnr/pppp2pp/8/4pp2/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Bird's opening: Williams gambit *
+rnbqkbnr/pppp2pp/8/4pp2/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+KGD: Falkbeer counter-gambit *
+rnbqkbnr/pppp2pp/8/4pp2/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+KGD: 2...Nf6 *
+rnbqkbnr/pppp2pp/8/4pp2/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Latvian counter-gambit
+rnbqkbnr/pppp2pp/8/4pp2/4P3/5Q2/PPPP1PPP/RNB1KBNR b KQkq -
+KGD: Norwalde variation *
+rnbqkbnr/pppp2pp/8/4pp2/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+King's gambit *
+rnbqkbnr/pppp2pp/8/4pp2/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French: Labourdonnais variation *
+rnbqkbnr/pppp2pp/8/5p2/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, L\'opez-Gianutio counter-gambit
+rnbqkbnr/pppp2pp/8/5p2/3pP3/2P5/PP3PPP/RNBQKBNR b KQkq -
+KGD: Nimzovich counter-gambit *
+rnbqkbnr/pppp2pp/8/5p2/3pP3/8/PPP2PPP/RNBQKBNR w KQkq -
+KGD: Falkbeer counter-gambit *
+rnbqkbnr/pppp2pp/8/5p2/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Gianutio counter-gambit
+rnbqkbnr/pppp3p/6p1/4pp2/4P3/8/PPPPQPPP/RNB1KBNR b KQkq -
+KGD: Keene's defense *
+rnbqkbnr/ppppp1pp/5p2/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Barnes defense
+rnbqkbnr/ppppp1pp/5p2/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Gedult's opening *
+rnbqkbnr/ppppp1pp/8/5p2/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English: Anglo-Dutch defense
+rnbqkbnr/ppppp1pp/8/5p2/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+Dutch defense
+rnbqkbnr/ppppp1pp/8/5p2/3P2P1/8/PPP1PP1P/RNBQKBNR b KQkq -
+Dutch, Krejcik gambit
+rnbqkbnr/ppppp1pp/8/5p2/3P4/3Q4/PPP1PPPP/RNB1KBNR b KQkq -
+Dutch, Manhattan (Alapin, Ulvestad) variation
+rnbqkbnr/ppppp1pp/8/5p2/3P4/6P1/PPP1PP1P/RNBQKBNR b KQkq -
+Dutch defense
+rnbqkbnr/ppppp1pp/8/5p2/3P4/7P/PPP1PPP1/RNBQKBNR b KQkq -
+Dutch, Korchnoi attack
+rnbqkbnr/ppppp1pp/8/5p2/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+Bird's opening *
+rnbqkbnr/ppppp1pp/8/5p2/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Dutch
+rnbqkbnr/ppppp1pp/8/5p2/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+Dutch: Staunton gambit
+rnbqkbnr/ppppp1pp/8/5p2/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+R\'eti: Pirc-Lisitsin gambit
+rnbqkbnr/ppppp1pp/8/5p2/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+Bird: From gambit *
+rnbqkbnr/ppppp1pp/8/5p2/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Fred
+rnbqkbnr/ppppp1pp/8/5p2/6P1/8/PPPPPP1P/RNBQKBNR b KQkq -
+Bird: Hobbs gambit *
+rnbqkbnr/ppppp1pp/8/5p2/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: Dutch variation
+rnbqkbnr/ppppp1pp/8/5p2/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+R\'eti v Dutch
+rnbqkbnr/ppppp1pp/8/5p2/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Bird's opening *
+rnbqkbnr/ppppp1pp/8/5pB1/3P4/8/PPP1PPPP/RN1QKBNR b KQkq -
+Dutch, 2.Bg5 variation
+rnbqkbnr/ppppp1pp/8/8/3Pp3/8/PPP2PPP/RNBQKBNR w KQkq -
+Dutch: Staunton gambit
+rnbqkbnr/pppppp1p/6p1/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English opening
+rnbqkbnr/pppppp1p/6p1/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Modern defense
+rnbqkbnr/pppppp1p/6p1/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Robatsch (modern) defense
+rnbqkbnr/pppppp1p/6p1/8/7P/8/PPPPPPP1/RNBQKBNR b KQkq -
+Lasker simul special *
+rnbqkbnr/pppppp1p/6p1/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Benko's opening *
+rnbqkbnr/pppppp1p/8/6p1/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Reversed Grob (Borg/Basman defense/macho Grob)
+rnbqkbnr/pppppp1p/8/6p1/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Bird: Hobbs gambit
+rnbqkbnr/pppppp1p/8/6p1/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+R\'eti: Herrstr\"om gambit
+rnbqkbnr/pppppp1p/8/6p1/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Grob's attack *
+rnbqkbnr/ppppppp1/7p/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Carr's defense
+rnbqkbnr/ppppppp1/7p/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Clemenz (Mead's, Basman's or de Klerk's) opening *
+rnbqkbnr/ppppppp1/8/7p/8/6P1/PPPPPP1P/RNBQKBNR w KQkq -
+Lasker simul special
+rnbqkbnr/ppppppp1/8/7p/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Anti-Borg (Desprez) opening *
+rnbqkbnr/pppppppp/8/4P3/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+Alekhine's defense: Brooklyn defense
+rnbqkbnr/pppppppp/8/8/1P6/8/P1PPPPPP/RNBQKBNR b KQkq -
+Polish (Sokolsky) opening
+rnbqkbnr/pppppppp/8/8/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+English opening
+rnbqkbnr/pppppppp/8/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+Queen's pawn
+rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+King's pawn opening
+rnbqkbnr/pppppppp/8/8/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+Bird's opening
+rnbqkbnr/pppppppp/8/8/6P1/8/PPPPPP1P/RNBQKBNR b KQkq -
+Grob's attack
+rnbqkbnr/pppppppp/8/8/7P/8/PPPPPPP1/RNBQKBNR b KQkq -
+Anti-Borg (Desprez) opening
+rnbqkbnr/pppppppp/8/8/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack
+rnbqkbnr/pppppppp/8/8/8/2N5/PPPPPPPP/R1BQKBNR b KQkq -
+Dunst (Sleipner, Heinrichsen) opening
+rnbqkbnr/pppppppp/8/8/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+Saragossa opening
+rnbqkbnr/pppppppp/8/8/8/3P4/PPP1PPPP/RNBQKBNR b KQkq -
+Mieses opening
+rnbqkbnr/pppppppp/8/8/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+Van't Kruijs opening
+rnbqkbnr/pppppppp/8/8/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+R\'eti opening
+rnbqkbnr/pppppppp/8/8/8/5P2/PPPPP1PP/RNBQKBNR b KQkq -
+Gedult's opening
+rnbqkbnr/pppppppp/8/8/8/6P1/PPPPPP1P/RNBQKBNR b KQkq -
+Benko's opening
+rnbqkbnr/pppppppp/8/8/8/7N/PPPPPPPP/RNBQKB1R b KQkq -
+Amar (Paris) opening
+rnbqkbnr/pppppppp/8/8/8/7P/PPPPPPP1/RNBQKBNR b KQkq -
+Clemenz (Mead's, Basman's or de Klerk's) opening
+rnbqkbnr/pppppppp/8/8/8/N7/PPPPPPPP/R1BQKBNR b KQkq -
+Durkin's attack
+rnbqkbnr/pppppppp/8/8/8/P7/1PPPPPPP/RNBQKBNR b KQkq -
+Anderssen's opening
+rnbqkbnr/pppppppp/8/8/P7/8/1PPPPPPP/RNBQKBNR b KQkq -
+Ware (Meadow Hay) opening
+rnbqkr2/pppp1pQp/8/2b1P3/3P4/5N2/PPP3PP/RNB1KB1n b KQq -
+Latvian: Behting variation *
+rnbqkr2/ppppbp1p/5N2/4Q3/8/8/PPPP1nPP/R1B1KBNR b KQq -
+Blackburne shilling gambit *
+rnbqr1k1/1p1p1ppp/pbp2n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, Suetin variation *
+rnbqr1k1/1p3pp1/2p2n1p/p1bpp3/4P3/PBNP1N2/1PP1QPPP/R1B1K2R w KQ -
+Giuoco Piano: Tarrasch variation *
+rnbqr1k1/1pb2ppp/2p2n2/p2pp3/NPP1P3/P2P1N2/2Q1BPPP/R1B1K2R w KQ -
+Ruy Lopez: closed, Balla variation *
+rnbqr1k1/1ppp1ppp/1b3n2/p3p3/1P2P3/P1N2N2/2PPBPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, anti-Marshall 8.a4 *
+rnbqr1k1/p1pp1ppp/5n2/1p2p3/1bP1P3/2N3P1/PP1P1PBP/R1BQK1NR w KQ -
+Sicilian: Nimzovich-Rossolimo attack, Gurgenidze variation *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N1P/2P1BPP1/R1BQ1RK1 b - -
+Ruy Lopez: closed, Smyslov defense *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N2/1BP1BPPP/R2Q1RK1 b - -
+Ruy Lopez: closed, Flohr-Zaitsev system (Lenzerheide variation) *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, 9.h3 *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP4/2PNBPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed, Ragozin-Petrosian (`Keres') variation *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NPBN2/2P1BPPP/R2Q1RK1 b - -
+Ruy Lopez: closed, Kholmov variation *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P2P1N2/2P1BPPP/RNBQ1RK1 b - -
+Ruy Lopez: closed, Breyer defense *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/PP2P3/2NP1N2/2P1BPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed, Keres (9...a5) variation *
+rnbqr1k1/pp1p1ppp/1bp2n2/4P3/1P1p4/P1N2N2/2P1BPPP/R1BQ1RK1 b - -
+Ruy Lopez: Marshall, Herman Steiner variation *
+rnbqr1k1/pp1p1ppp/1bp2n2/4p3/1P1PP3/P1N2N2/2P1BPPP/R1BQ1RK1 b - -
+Ruy Lopez: Marshall counter-attack *
+rnbqr1k1/pp1p1ppp/1bp2n2/4p3/1P2P3/P1N2N2/2PPBPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, 8.c3 *
+rnbqr1k1/pp1p1ppp/1bp2n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed (with ...d6) *
+rnbqr1k1/pp3p1p/1bp3pQ/3p4/1P1N4/P1PB4/5PPP/R1B2RK1 b - -
+Ruy Lopez: Marshall, main line, 14...Qh3 *
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+Benoni: classical, 9...Re8
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4P3/2N5/PP1NBPPP/R1BQ1RK1 b - -
+Benoni: classical, 9...Re8, 10.Nd2
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4PP2/2N2N2/PP2B1PP/R1BQK2R w KQ -
+Benoni: four pawns attack, main line
+rnbqr1k1/pp3pp1/1bp2n1p/3pp3/1P2P3/P2P1N2/2P1BPPP/RNBQ1RK1 w - -
+Ruy Lopez: closed, Breyer, 10.d4 *
+rnbqr1k1/pp3pp1/1bp2n1p/3pp3/1P2P3/P2P1N2/2PNBPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed, Breyer, Borisenko variation *
+rnbqr1k1/pp3pp1/1bp4p/3pp2n/1P2P3/P2P1N2/2PNBPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, Breyer, Simagin variation *
+rnbqr1k1/pp3ppB/3b1n2/3pN1B1/3p1P2/8/PPP3PP/RN1Q1RK1 b - -
+Petrov: classical attack, Marshall trap *
+rnbqr1k1/pp3ppp/1bp2n2/3pp1B1/1P2P3/P1NP1N2/2P1BPPP/R2Q1RK1 b - -
+Ruy Lopez: closed, Bogolyubov variation *
+rnbqr1k1/pp3ppp/1bp2n2/3pp3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, 9.d4 *
+rnbqr1k1/pp3ppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P1BPPP/R2QK2R w KQ -
+Ruy Lopez: open, 9...Be7, 10.Re1 *
+rnbqr1k1/pp3ppp/1bp5/3nN3/1P1PN3/P3B3/2P1BPPP/R2Q1RK1 b - -
+Ruy Lopez: open, Breslau variation *
+rnbqr1k1/pp3ppp/1bpp1n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, Pilnik variation *
+rnbqr1k1/pp3ppp/3b1n2/2ppN1B1/3P1P2/2N5/PPP1B1PP/R2QK2R w KQ -
+Petrov: classical attack, Krause variation *
+rnbqr1k1/pp3ppp/3b1n2/2ppN1BB/3P1P2/2N5/PPP3PP/R2QK2R b KQ -
+Petrov: classical attack, Mar\'oczy variation *
+rnbqr1k1/ppb2pp1/2p2n1p/3pp3/1PP1P3/P1NP1N2/4BPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed, Borisenko defense *
+rnbqr1k1/ppb2pp1/2p2n1p/3pp3/NP2P3/P1PP1N2/2Q1BPPP/R1B2RK1 b - -
+Ruy Lopez: closed, Rossolimo defense *
+rnbqr1k1/ppb2pp1/2p2n1p/3pp3/NPP1P3/P2P1N2/2Q1BPPP/R1B2RK1 b - -
+Ruy Lopez: closed, Chigorin defense *
+rnbqr1k1/ppb2pp1/2p2n1p/3pp3/NPP1P3/P2P4/3NBPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed, Keres (...Nd7) defense *
+rnbqr1k1/ppbp1pp1/2p2n1p/4p3/NP2P3/P2P1N2/2P1BPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed (9...Na5) *
+rnbqr1k1/ppbp1pp1/2p2n1p/4p3/NPP1P3/P2P1N2/4BPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed (10...c5) *
+rnbqr1k1/ppbp1ppp/2p2n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, Lutikov variation *
+rnbqr1k1/ppp2ppp/1b3n2/3pp3/1P2P3/P1NP1N2/2P1BPPP/R1BQK2R w KQ -
+Ruy Lopez: closed, 7...d6, 8.d4 *
+rnbqr1k1/ppp2ppp/3b1n2/3pN3/3P4/2N5/PPP1BPPP/R1BQK2R w KQ -
+Petrov: classical attack, Chigorin variation *
+rnbqr1k1/ppp2ppp/5n2/2PP4/2B5/2N1B3/PPP2PpP/R2QK2R w KQ -
+two knights: Max Lange attack, Schlechter variation *
+rnbqr1k1/ppp2ppp/8/2PP4/2B3n1/2N1BpP1/PPP2P1P/R2QK2R b KQ -
+two knights: Max Lange attack, Loman defense *
+rnbqr1k1/pppp1ppp/1b3n2/4p3/1P2P3/P1N2N2/1BPPBPPP/R2QK2R b KQ -
+Ruy Lopez: Trajkovi\'c counter-attack *
+rnbqr1k1/pppp1ppp/1b3n2/4p3/1P2P3/P1N2N2/2PPBPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed, 7...O-O *
+rnbqr1k1/pppp1ppp/1b3n2/4p3/1P2P3/P1N2N2/2PPBPPP/R1BQK2R w KQ -
+Ruy Lopez: closed *
+rnbqr1k1/pppp1ppp/5n2/b3p3/4P3/P1NP1N2/1PP1BPPP/R1BQK2R b KQ -
+Ruy Lopez: closed, Averbach variation *
+rnbr2k1/1pq1ppbp/5np1/p1pp4/3P4/1PP1PN2/P2NBPPP/R1BQ1RK1 w - -
+Catalan: closed, Zagoryansky variation *
+rnbr2k1/pp2qppp/5n2/2b1N3/3Pp3/P1N1B3/2PQBPPP/R4RK1 b - -
+Ruy Lopez: open, Howell attack, Ekstr\"om variation *
+rnq1kb1r/pp3ppp/4pn2/3p1b2/3P4/NQ2PN2/PP1B1PPP/R3KB1R b KQkq -
+QGD Slav: Landau variation
--- /dev/null
+1r1qr1k1/p1n2pbp/bp1p1np1/2pP2B1/P1N1P3/2N2P2/1P2B1PP/R2Q1R1K b - -
+BI.06
+1rbq1rk1/1pp1ppbp/p1np1np1/8/2PP4/2N2NPP/PP2PPB1/R1BQ1RK1 w - -
+KI.70
+1rbq1rk1/1pp1ppbp/p1np1np1/8/2PPP2P/2N1BP2/PPQ1N1P1/R3KB1R b KQ -
+KI.33
+1rbq1rk1/1pp1ppbp/p1np1np1/8/2PPP3/2N1BP2/PP1Q2PP/R1N1KB1R b KQ -
+KI.34
+1rbq1rk1/1pp1ppbp/p1np1np1/8/2PPP3/2N1BP2/PP1QN1PP/R3KB1R w KQ -
+KI.35
+1rbq1rk1/4ppbp/p2p1np1/nppP4/2P5/1PN3P1/PBQNPPBP/R4RK1 b - -
+KI.66
+1rbq1rk1/pp2ppbp/2np1np1/2p5/4P3/2NP1NP1/PPP2PBP/R1BQ1RK1 w - -
+EO.13*
+1rbqk1nr/pp1pppbp/2n3p1/2p5/4P3/2N3P1/PPPP1PBP/R1BQK1NR w KQk -
+EO.15*
+1rbqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NP2P1/PPP2PBP/R1BQK1NR w KQk -
+EO.16*
+1rbqr1k1/1p1n1pbp/p2p1np1/2pP4/P1N5/2N3PP/1P2PPB1/R1BQ1RK1 b - -
+BI.21
+2bq1rk1/1p1nbppp/r1n5/p3p3/2Pp4/P2P1NP1/1P1N1PBP/R1BQR1K1 w - -
+BI.01*
+2kr1b1r/pppq1ppp/2n5/3np3/6b1/2NPPN2/PP2BPPP/R1BQ1RK1 b - -
+SI.28*
+2kr1b1r/pppq1ppp/2n5/3np3/6b1/P1NPPN2/1P1B1PPP/R2QKB1R b KQ -
+SI.30*
+2kr1b1r/pppq1ppp/2n5/3np3/6b1/P1NPPN2/1P3PPP/R1BQKB1R w KQ -
+SI.29*
+2rqkb1r/pp2pppp/2n2n2/2Pp3b/8/4PN1P/PPP1BPP1/RNBQ1RK1 b k -
+QO.07*
+2rqkb1r/pp2pppp/5n2/3p4/3P4/1P5P/P1P1QPP1/RNB2RK1 b k -
+QO.06*
+2rqkb1r/pp3ppp/2n1pn2/2pp3b/3P4/1P2PN1P/PBP1BPP1/RN1Q1RK1 b k -
+QO.09*
+2rqkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w k -
+QO.11*
+3rkb1r/1pq2ppp/p1n1pn2/2p2b2/Q2P4/2N1PN2/PP2BPPP/R1B2RK1 b k -
+QO.02*
+r1b1k2r/ppp2pp1/3q1nn1/3p4/7p/2P4P/PP1NPPP1/R2QKBNR w KQkq -
+CK.12*
+r1b1kb1r/1pq2ppp/p1nppn2/8/3NPP2/2N5/PPP1B1PP/R1BQ1RK1 w kq -
+SI.24
+r1b1kb1r/pp1n1ppp/2p1pn2/q2p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQkq -
+QO.15
+r1b1kb1r/pp2pppp/1qn2n2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+GI.10*
+r1b1kb1r/ppqppppp/2n2n2/1Bp5/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+EO.58*
+r1b1kbnr/1p2pppp/p1q5/2pp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+NI.20*
+r1b1kbnr/pp3ppp/2n5/2p1q3/4p3/2N1P3/PP1P1PPP/R1BQKBNR w KQkq -
+EO.55*
+r1b1kbnr/ppq1pppp/2n5/1Bp5/2p5/4PN2/PP1P1PPP/RNBQ1RK1 b kq -
+NI.21*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+NI.22*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R b KQkq -
+NI.23*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+NI.24*
+r1b1kbnr/ppqp1ppp/2n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+SI.40
+r1b2rk1/1p1nqppp/2n5/p3p3/2Pp4/P2P1NP1/1P3PBP/RN1Q1RK1 w - -
+BI.14*
+r1b2rk1/2q1bppp/p2p1n2/npp1p3/3PP3/2P2N1P/PPBN1PP1/R1BQR1K1 b - -
+RL.24
+r1b2rk1/pp2bppp/2n1pn2/q2p4/2P2B2/P1N1PN2/1PQ2PPP/3RKB1R w K -
+QO.02
+r1b2rk1/pp2ppbp/2n2np1/2pq4/8/1P2PN2/PB1PBPPP/RN1QK2R w KQ -
+EO.39*
+r1b2rk1/pp2ppbp/2q2np1/2pp4/2P5/1P2P3/PB1PBPPP/RN1Q1RK1 b - -
+QI.13*
+r1b2rk1/pp2ppbp/2q2np1/2pp4/5P2/1P2P3/PBPPB1PP/RN1Q1RK1 b - -
+QI.12*
+r1b2rk1/ppq1ppbp/2n2np1/2ppN3/8/1P2P3/PBPPBPPP/RN1Q1RK1 w - -
+QI.11*
+r1b2rk1/ppq2ppp/2n1pn2/2p5/2BP4/P1P1PN2/5PPP/R1BQ1RK1 w - -
+NI.01
+r1bq1rk1/1p1n1pbp/2pp1np1/p3p3/2PPP3/2N2N2/PP3PPP/R1BQRBK1 w - -
+KI.09
+r1bq1rk1/1p1n1pbp/p2p1np1/2pP4/P3P3/2N2N2/1P2BPPP/R1BQ1RK1 w - -
+BI.15
+r1bq1rk1/1p1nb1pp/2n2p2/p3p3/2Pp4/1P1P1NP1/P1N2PBP/R1BQR1K1 b - -
+BI.07*
+r1bq1rk1/1p1nb1pp/2n2p2/p3p3/2Pp4/3P2P1/PPNN1PBP/R1BQR1K1 b - -
+BI.08*
+r1bq1rk1/1p1nb1pp/2n5/p3pp2/2Pp4/P2P1NP1/1P1N1PBP/R1BQR1K1 w - -
+BI.02*
+r1bq1rk1/1p1nbppp/2n5/p3p3/2Pp4/P2P1NP1/1P1N1PBP/R1BQR1K1 b - -
+BI.03*
+r1bq1rk1/1p1nbppp/2n5/p3p3/2PpN3/3P1NP1/PP3PBP/R1BQR1K1 b - -
+BI.04*
+r1bq1rk1/1p1nppbp/2n3p1/p7/2Pp4/P2P1NP1/1P1N1PBP/R1BQR1K1 b - -
+BI.22*
+r1bq1rk1/1p2bppp/2n2n2/p3p3/2Pp4/P2P1NP1/1P1N1PBP/R1BQ1RK1 b - -
+BI.15*
+r1bq1rk1/1p2ppb1/2n3pp/p1n5/2Pp4/P2P1NP1/1P1N1PBP/1RBQR1K1 w - -
+BI.21*
+r1bq1rk1/1p3pp1/2n2b1p/p3p3/2Pp4/P2P1NP1/1P1N1PBP/R2Q1RK1 b - -
+BI.10*
+r1bq1rk1/1p3ppp/2n1pn2/pBbp4/5B2/2P1PN2/PP3PPP/RN1QK2R w KQ -
+SL.05*
+r1bq1rk1/1p3ppp/p1nbpn2/1Bpp4/2PP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+NI.02*
+r1bq1rk1/1pp1ppbp/p1np1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+KI.71
+r1bq1rk1/2p1bpp1/p1np1n1p/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+RL.22
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/3PP3/1BP2N2/PP3PPP/RNBQR1K1 b - -
+RL.20
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 b - -
+RL.21
+r1bq1rk1/2p1bppp/p2p1n2/np2p3/4P3/2P2N1P/PPBP1PP1/RNBQR1K1 b - -
+RL.23
+r1bq1rk1/2ppbppp/p1n2n2/1p2p3/P3P3/1B3N2/1PPP1PPP/RNBQR1K1 b - -
+RL.18
+r1bq1rk1/3nppbp/p1pp1np1/1p6/2PPP3/2NBBP2/PP2N1PP/R2Q1RK1 w - -
+KI.46
+r1bq1rk1/5ppp/p1p1pn2/2bp4/2P5/2N1PN2/PPQ2PPP/R1B2RK1 b - -
+NI.01*
+r1bq1rk1/p1p2ppp/5n2/3p2B1/1b6/2NB4/PPP2PPP/R2Q1RK1 b - -
+SO.03
+r1bq1rk1/p3bp1p/2n2np1/1pp1p3/3pPP1N/3P2P1/PPP1N1BP/R1BQ1RK1 b - -
+KI.04*
+r1bq1rk1/p3bppp/2n2n2/1pp1p3/3pP3/3P1NP1/PPP1NPBP/R1BQ1RK1 w - -
+KI.05*
+r1bq1rk1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N1BP2/PP1QN1PP/R3KB1R w KQ -
+KI.42
+r1bq1rk1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N2N2/PP3PPP/R1BQRBK1 b - -
+KI.10
+r1bq1rk1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N2NP1/PP3PBP/R1BQ1RK1 w - -
+KI.63
+r1bq1rk1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N2NPP/PP3PB1/R1BQ1RK1 b - -
+KI.62
+r1bq1rk1/pp1n1ppp/4pn2/2p5/1bBP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+NI.03
+r1bq1rk1/pp1nbppp/2n5/2p1p3/3pP3/3P1NP1/PPP1NPBP/R1BQ1RK1 w - -
+KI.07*
+r1bq1rk1/pp1nbppp/2n5/4p3/2Pp4/3P1NP1/PP1N1PBP/R1BQR1K1 b - -
+BI.05*
+r1bq1rk1/pp1nbppp/2n5/4p3/2Pp4/N2P1NP1/PP3PBP/R1BQR1K1 b - -
+BI.09*
+r1bq1rk1/pp1pppbp/2n2np1/1Bp5/4P3/2N2N2/PPPP1PPP/R1BQ1RK1 w - -
+EO.01*
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/1P2PN2/PB1PBPPP/RN1QK2R b KQ -
+EO.40*
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/1P3NP1/PB1PPPBP/RN1QK2R b KQ -
+EO.48*
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 b - -
+EO.27*
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w - -
+EO.27
+r1bq1rk1/pp1pppbp/2n2np1/8/2PN4/2N1P3/PP2BPPP/R1BQK2R b KQ -
+EO.41*
+r1bq1rk1/pp1pppbp/2n2np1/8/2PN4/2N3P1/PP2PPBP/R1BQ1RK1 b - -
+EO.26
+r1bq1rk1/pp2bppp/2n1p3/2pn4/3PP3/2N2NP1/PP3PBP/R1BQ1RK1 b - -
+TD.02
+r1bq1rk1/pp2bppp/2n2n2/2p1p3/3pP3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+KI.12*
+r1bq1rk1/pp2bppp/2n2n2/2pp2B1/3P4/2N2NP1/PP2PPBP/R2Q1RK1 b - -
+TD.03
+r1bq1rk1/pp2bppp/2n2n2/2pp4/3P4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+TD.04
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 w - -
+KI.15*
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 b - -
+KI.14*
+r1bq1rk1/pp2bppp/2n2n2/4p1B1/2Pp4/3P1NP1/PP3PBP/RN1Q1RK1 b - -
+BI.16*
+r1bq1rk1/pp2bppp/2n5/2pp4/3P4/5NP1/PP2PPBP/R1BQ1RK1 w - -
+TD.01
+r1bq1rk1/pp2bppp/2nn4/2p1p3/3pPP2/3P2P1/PPPNN1BP/R1BQ1RK1 b - -
+KI.01*
+r1bq1rk1/pp2bppp/2nppn2/6B1/3NP3/2N5/PPPQ1PPP/2KR1B1R w - -
+SI.28
+r1bq1rk1/pp2nppp/2nb4/4p3/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 w - -
+BI.36*
+r1bq1rk1/pp2ppb1/2n2npp/2pp4/8/P1NP1NP1/1PP1PPBP/1RBQ1RK1 b - -
+KI.70*
+r1bq1rk1/pp2ppbp/2n2np1/2p5/2P5/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+KI.68*
+r1bq1rk1/pp2ppbp/2n2np1/2p5/2P5/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+KI.68
+r1bq1rk1/pp2ppbp/2n2np1/2p5/N1Pp4/3P1NP1/PP2PPBP/R1BQ1RK1 b - -
+KI.67*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 w - -
+KI.69*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 b - -
+KI.65*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/1P2PN2/PBPPBPPP/RN1Q1RK1 w - -
+QI.09*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/2NP1NP1/PPP1PPBP/R1BQ1RK1 w - -
+KI.72*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/2PP1NP1/PP2PPBP/RNBQ1RK1 w - -
+KI.75*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/P1NP1NP1/1PP1PPBP/R1BQ1RK1 b - -
+KI.71*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/Q7/2PP1NP1/PP2PPBP/RNB2RK1 b - -
+KI.74*
+r1bq1rk1/pp2ppbp/2n2np1/2ppN3/8/1P2P3/PBPPBPPP/RN1Q1RK1 b - -
+QI.10*
+r1bq1rk1/pp2ppbp/2n2np1/3p4/2PP4/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+TD.04*
+r1bq1rk1/pp2ppbp/2n2np1/8/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 w - -
+BI.24*
+r1bq1rk1/pp2ppbp/2n2np1/8/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 b - -
+BI.23*
+r1bq1rk1/pp2ppbp/2n3p1/2pn4/8/2N2NP1/PP1PPPBP/R1BQ1RK1 w - -
+EO.26*
+r1bq1rk1/pp2ppbp/2n3p1/8/2BPP3/4B3/P3NPPP/R2Q1RK1 b - -
+GI.06
+r1bq1rk1/pp2ppbp/2np1np1/8/2BNP3/2N1BP2/PPPQ2PP/R3K2R b KQ -
+SI.18
+r1bq1rk1/pp2ppbp/3p1np1/n1pP4/2P5/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+KI.67
+r1bq1rk1/pp2ppbp/5np1/3p4/2PP4/2N5/PP2BPPP/R1BQ1RK1 b - -
+TD.01*
+r1bq1rk1/pp3pb1/2n2npp/2ppp3/4P3/2PP1NP1/PP1N1PBP/R1BQ1RK1 w - -
+KI.62*
+r1bq1rk1/pp3pb1/2n2npp/2ppp3/4P3/2PP1NP1/PP1N1PBP/R1BQR1K1 b - -
+KI.61*
+r1bq1rk1/pp3pbp/2n2np1/2ppp3/4P3/2PP1NP1/PP1N1PBP/R1BQ1RK1 b - -
+KI.63*
+r1bq1rk1/pp3pbp/2n2np1/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+KI.64*
+r1bq1rk1/pp3pbp/2n2np1/3pp3/2PN4/2N1P3/PP2BPPP/R1BQ1RK1 w - -
+TD.02*
+r1bq1rk1/pp3ppp/2n1pn2/1Bbp4/2P5/4PN2/PP1N1PPP/R1BQ1RK1 b - -
+NI.03*
+r1bq1rk1/pp3ppp/2n1pn2/2pp4/1bPP4/P1NBPN2/1P3PPP/R1BQ1RK1 b - -
+NI.02
+r1bq1rk1/pp3ppp/2n2n2/1Bbp4/8/1P2PN2/P4PPP/RNBQ1RK1 b - -
+NI.04*
+r1bq1rk1/pp3ppp/2nbpn2/1Bpp4/2PP4/4PN2/PP3PPP/RNBQ1RK1 w - -
+NI.05*
+r1bq1rk1/ppp1b1pp/2n5/3npp2/8/P1NPPN2/1PQ2PPP/R1B1KB1R b KQ -
+SI.24*
+r1bq1rk1/ppp1bppp/2n2n2/3pp1B1/8/3P1NP1/PPP1PPBP/RN1Q1RK1 b - -
+PU.01*
+r1bq1rk1/ppp1n1bp/3p2p1/3Ppp1n/1PP1P3/2N2NP1/P3BP1P/R1BQ1RK1 w - -
+KI.04
+r1bq1rk1/ppp1npbp/3p1np1/3Pp3/1PP1P3/2N2N2/P3BPPP/R1BQ1RK1 b - -
+KI.05
+r1bq1rk1/ppp1npbp/3p1np1/3Pp3/2P1P3/2N2N2/PP1BBPPP/R2Q1RK1 b - -
+KI.06
+r1bq1rk1/ppp1npbp/3p1np1/3Pp3/2P1P3/2N5/PP1NBPPP/R1BQ1RK1 b - -
+KI.07
+r1bq1rk1/ppp1npbp/3p1np1/3Pp3/2P1P3/2N5/PP2BPPP/R1BQNRK1 b - -
+KI.03
+r1bq1rk1/ppp1ppbp/2np1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+KI.72
+r1bq1rk1/ppp1ppbp/2np1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+KI.73
+r1bq1rk1/ppp1ppbp/2np1np1/8/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+KI.36
+r1bq1rk1/ppp2pbp/2np1np1/4p3/2P5/2NP1NP1/PP2PPBP/1RBQ1RK1 b - -
+EO.13
+r1bq1rk1/ppp2pbp/2np1np1/4p3/2PPP3/2N1BN2/PP2BPPP/R2Q1RK1 b - -
+KI.08
+r1bq1rk1/ppp2ppp/1n3n2/8/1b1P4/2NB4/PP2NPPP/R1BQK2R b KQ -
+FR.23*
+r1bq1rk1/pppn1pbp/3p1np1/3Pp3/2P1P3/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+KI.12
+r1bq1rk1/pppn1pbp/3p1np1/3Pp3/2P1P3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+KI.16
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+KI.65
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N1BN2/PP2BPPP/R2Q1RK1 b - -
+KI.13
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+KI.14
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQR1K1 b - -
+KI.11
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2NP1/PP3PBP/R1BQ1RK1 b - -
+KI.64
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/2RQKB1R b K -
+QO.11
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QO.12
+r1bq1rk1/pppnn1bp/3p2p1/3Ppp2/2P1P3/2N2P2/PP2B1PP/R1BQNRK1 w - -
+KI.02
+r1bq1rk1/pppnn1bp/3p2p1/3Ppp2/2P1P3/2NN4/PP2BPPP/R1BQ1RK1 w - -
+KI.01
+r1bq1rk1/pppnppbp/3p1np1/8/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+KI.48
+r1bq1rk1/pppp1ppp/2n2n2/4p3/1bP5/2N2NP1/PP1PPPBP/R1BQ1RK1 b - -
+EO.01
+r1bqk1nr/1p3ppp/p1nbp3/1Bpp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 w kq -
+NI.08*
+r1bqk1nr/p4ppp/2p5/2bpp3/8/6P1/PPP1PPBP/RNBQK2R w KQkq -
+GI.05*
+r1bqk1nr/pp1n1ppp/2pb4/3p4/2PPp3/4P3/PP1N1PPP/RNBQKB1R w KQkq -
+FR.17*
+r1bqk1nr/pp1p1pbp/2n1p1p1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+EO.29*
+r1bqk1nr/pp1p1pbp/2n3p1/2p1p3/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+EO.30*
+r1bqk1nr/pp1p1pbp/2n3p1/2p1p3/4P3/2NP2P1/PPP2PBP/R1BQK1NR b KQkq -
+EO.18*
+r1bqk1nr/pp1pppbp/2n3p1/1Bp5/4P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+EO.11*
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P1P3/2N3P1/PP1P1PBP/R1BQK1NR b KQkq -
+EO.30
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N1P1P1/PP1P1PBP/R1BQK1NR b KQkq -
+EO.29
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+EO.28
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR b KQkq -
+EO.31*
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+EO.31
+r1bqk1nr/pp1pppbp/2n3p1/2p5/4P3/5NP1/PPPP1PBP/RNBQK2R b KQkq -
+EO.14*
+r1bqk1nr/pp1pppbp/2n3p1/8/2P5/8/PPN1PPPP/RNBQKB1R b KQkq -
+EO.37*
+r1bqk1nr/pp1pppbp/2n3p1/8/2PN4/2N5/PP2PPPP/R1BQKB1R w KQkq -
+EO.35
+r1bqk1nr/pp1pppbp/2n3p1/8/2PN4/8/PP2PPPP/RNBQKB1R w KQkq -
+EO.38*
+r1bqk1nr/pp1pppbp/2n3p1/8/3N4/6P1/PPP1PP1P/RNBQKB1R w KQkq -
+EO.53*
+r1bqk1nr/pp2bppp/2n5/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+KI.27*
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NP2P1/PPP2PBP/R1BQK1NR w KQkq -
+SI.45
+r1bqk1nr/pp3pbp/2n1p1p1/2pp4/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+KI.78*
+r1bqk1nr/pp3pbp/2n3p1/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+KI.29*
+r1bqk1nr/pp4pp/2n5/4pp2/1bPp4/3P2P1/PP1N1PBP/RNBQK2R b KQkq -
+BI.33*
+r1bqk1nr/pp4pp/2nb4/2p1pp2/2Pp4/3P1NP1/PP2PPBP/RNBQ1RK1 w kq -
+KI.60*
+r1bqk1nr/ppp1ppbp/2np2p1/8/2PPP3/2N5/PP3PPP/R1BQKBNR w KQkq -
+KF.03
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P1P3/2N3P1/PP1P1PBP/R1BQK1NR w KQkq -
+EO.18
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P5/2N1P1P1/PP1PNPBP/R1BQK2R b KQkq -
+EO.17
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P5/2NP2P1/PP2PPBP/1RBQK1NR b Kkq -
+EO.16
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR b KQkq -
+SI.45*
+r1bqk1nr/ppp2ppp/8/2bpn3/8/2P5/PP1NPPPP/R1BQKBNR w KQkq -
+CK.09*
+r1bqk1nr/pppn1pbp/3p2p1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQK2R b KQkq -
+KF.01
+r1bqk1nr/pppnppbp/3p2p1/8/2PPP3/2N5/PP3PPP/R1BQKBNR w KQkq -
+KF.02
+r1bqk1nr/pppp1pbp/2n3p1/4p3/2P5/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+EO.19
+r1bqk1nr/pppp1pbp/2n3p1/4p3/2P5/2N3P1/PP1PPPBP/1RBQK1NR b Kkq -
+EO.15
+r1bqk1nr/pppp1ppp/2n5/2b1p3/1PB1P3/5N2/P1PP1PPP/RNBQK2R b KQkq -
+IG.05
+r1bqk1nr/pppp1ppp/2n5/2b1p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+IG.02
+r1bqk1nr/pppp1ppp/2n5/2b1p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+VG.02*
+r1bqk1nr/pppp1ppp/2n5/2b5/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+SO.05
+r1bqk2r/1p4pp/2nb1n2/p3pp2/2Pp4/P2P2P1/1P1N1PBP/RNBQ1RK1 w kq -
+BI.32*
+r1bqk2r/1pp1bppp/p1np1n2/4p3/B3P3/5N2/PPPP1PPP/RNBQR1K1 w kq -
+RL.16
+r1bqk2r/1pppbppp/p1B2n2/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+RL.14
+r1bqk2r/1pppbppp/p1n2n2/4p3/B2PP3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+RL.15
+r1bqk2r/1pppbppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+RL.13
+r1bqk2r/2p1bppp/p1np1n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQR1K1 w kq -
+RL.19
+r1bqk2r/2ppbppp/p1n2n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQR1K1 b kq -
+RL.17
+r1bqk2r/p4ppp/2pbpn2/2pp4/2P5/2NPPN2/PP3PPP/R1BQK2R b KQkq -
+NI.14*
+r1bqk2r/pp1pnpbp/2n1p1p1/2p5/4P3/2NP2P1/PPP2PBP/R1BQK1NR w KQkq -
+EO.17*
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+EO.28*
+r1bqk2r/pp1pppbp/2n2np1/2p5/4P3/2N3P1/PPPP1PBP/R1BQK1NR w KQkq -
+EO.19*
+r1bqk2r/pp1pppbp/2n2np1/8/2P5/2N5/PPN1PPPP/R1BQKB1R b KQkq -
+EO.36*
+r1bqk2r/pp1pppbp/2n2np1/8/3N4/6P1/PPP1PPBP/RNBQK2R w KQkq -
+EO.51*
+r1bqk2r/pp1pppbp/2n2np1/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+EO.03*
+r1bqk2r/pp2b1pp/2n2n2/2p1pp2/2Pp4/3PPNP1/PP3PBP/RNBQ1RK1 w kq -
+KI.57*
+r1bqk2r/pp2b1pp/2n2n2/2p2p2/2PPp3/3P1NP1/PP3PBP/RNBQ1RK1 w kq -
+KI.56*
+r1bqk2r/pp2b1pp/2n2n2/4pp2/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 b kq -
+BI.29*
+r1bqk2r/pp2b1pp/2n2n2/4ppB1/2Pp4/3P1NP1/PP3PBP/RN1Q1RK1 b kq -
+BI.30*
+r1bqk2r/pp2b1pp/2n5/2pnpp2/8/3P1NP1/PP2PPBP/RNBQ1RK1 w kq -
+KI.59*
+r1bqk2r/pp2bppp/2n1p3/2pn4/8/2N2NP1/PP1PPPBP/R1BQ1RK1 w kq -
+EO.41
+r1bqk2r/pp2bppp/2n2n2/2p1p3/3pP3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+KI.17*
+r1bqk2r/pp2bppp/2n2n2/2p1p3/3pP3/3P1NP1/PPPN1PBP/R1BQ1RK1 b kq -
+KI.16*
+r1bqk2r/pp2bppp/2n2n2/2ppp3/4P3/3P1N2/PPPNBPPP/R1BQK2R w KQkq -
+OI.01*
+r1bqk2r/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 b kq -
+KI.18*
+r1bqk2r/pp2bppp/2n2n2/2ppp3/4P3/3P2P1/PPPN1PBP/R1BQK1NR w KQkq -
+KF.01*
+r1bqk2r/pp2bppp/2n2n2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+KI.19*
+r1bqk2r/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+BI.17*
+r1bqk2r/pp2npbp/2n3p1/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+KI.28*
+r1bqk2r/pp2nppp/2n1p3/2ppP3/3P4/P1P2N2/2P2PPP/R1BQKB1R w KQkq -
+FR.13
+r1bqk2r/pp2nppp/2nb4/1B1p4/8/1N3N2/PPP2PPP/R1BQ1RK1 w kq -
+FR.23
+r1bqk2r/pp2nppp/2nbp3/1Bpp4/2PP4/4PN2/PP3PPP/RNBQ1RK1 b kq -
+NI.09*
+r1bqk2r/pp2ppbp/2n2np1/2pp4/8/2NP1NP1/PPP1PPBP/R1BQ1RK1 b kq -
+KI.73*
+r1bqk2r/pp3ppp/2n1pn2/2bp4/1P6/2P1PN2/P2N1PPP/R1BQKB1R b KQkq -
+SL.09*
+r1bqk2r/pp3ppp/2nbpn2/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQ1RK1 w kq -
+NI.07*
+r1bqk2r/pp3ppp/2nbpn2/1Bpp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 w kq -
+NI.06*
+r1bqk2r/pp3ppp/2nbpn2/3p4/2PN4/2N1P3/PP3PPP/R1BQKB1R w KQkq -
+TD.07*
+r1bqk2r/pp3ppp/2nppn2/2p5/2PP4/2PBPN2/P4PPP/R1BQK2R w KQkq -
+NI.14
+r1bqk2r/ppp1bppp/1nn5/4p3/4P3/P2P1N2/1P2BPPP/RNBQK2R b KQkq -
+SI.11*
+r1bqk2r/ppp1bppp/2n2n2/3pp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+PU.03*
+r1bqk2r/ppp1bppp/2n5/3np3/8/2NPPN2/PP3PPP/R1BQKB1R b KQkq -
+SI.22*
+r1bqk2r/ppp1bppp/2n5/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+SI.10*
+r1bqk2r/ppp1bppp/2n5/3np3/8/P2PPN2/1P3PPP/RNBQKB1R b KQkq -
+SI.23*
+r1bqk2r/ppp1bppp/2n5/3p4/3Pn3/3B1N2/PPP2PPP/RNBQ1RK1 w kq -
+RG.06
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/2NPPN2/PP3PPP/R1BQKB1R b KQkq -
+SI.26*
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+SI.13*
+r1bqk2r/ppp3pp/2nb1n2/3ppp2/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+PU.02*
+r1bqk2r/pppnbppp/3p1n2/4p3/2PPP3/2N2N2/PP2BPPP/R1BQK2R b KQkq -
+OI.01
+r1bqk2r/pppp1ppp/2n2n2/3Np3/1bP5/5NP1/PP1PPP1P/R1BQKB1R b KQkq -
+EO.02
+r1bqk2r/pppp1ppp/2n2n2/4p3/1b1PP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+SO.01
+r1bqk2r/pppp1ppp/2n2n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+KP.03*
+r1bqk2r/pppp1ppp/2n2n2/4p3/1bP5/2N1PN2/PP1P1PPP/R1BQKB1R w KQkq -
+EO.05
+r1bqkb1r/1p1n1ppp/p2ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+SI.06
+r1bqkb1r/1p2pppp/2n2n2/p1Pp4/5B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+SL.04*
+r1bqkb1r/1p3ppp/p1np1n2/1N2p1B1/4P3/2N5/PPP2PPP/R2QKB1R w KQkq -
+SI.36
+r1bqkb1r/1p3ppp/p1nppn2/6B1/3NP3/2N5/PPPQ1PPP/2KR1B1R b kq -
+SI.29
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+RL.12
+r1bqkb1r/1ppp1ppp/p1n5/4p3/B3n3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+RL.27
+r1bqkb1r/2p2ppp/p1p2n2/3p4/2PPp3/2N1P3/PP2NPPP/R1BQK2R b KQkq -
+FR.13*
+r1bqkb1r/2p2ppp/p1p2n2/3p4/2PPp3/4P3/PP2NPPP/RNBQK2R w KQkq -
+FR.12*
+r1bqkb1r/5p1p/p1np4/1p1Npp2/4P3/N7/PPP2PPP/R2QKB1R w KQkq -
+SI.38
+r1bqkb1r/5ppp/p1np1n2/1p2p1B1/4P3/N1N5/PPP2PPP/R2QKB1R w KQkq -
+SI.37
+r1bqkb1r/p2n1ppp/2p1pn2/1p6/2BP4/2N1PN2/PP3PPP/R1BQK2R w KQkq -
+SL.09
+r1bqkb1r/p4ppp/5n2/3pp3/8/4P3/PP3PPP/RNBQKB1R w KQkq -
+TD.08*
+r1bqkb1r/pp1npppp/2n5/8/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+BI.27*
+r1bqkb1r/pp1npppp/2n5/8/2Pp4/B2P1NP1/4PP1P/RN1QKB1R w KQkq -
+BI.40*
+r1bqkb1r/pp1p1ppp/2n1pn2/1Bp5/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+EO.05*
+r1bqkb1r/pp1p1ppp/2n1pn2/1N6/2P5/2N5/PP2PPPP/R1BQKB1R b KQkq -
+EO.33
+r1bqkb1r/pp1p1ppp/2n1pn2/2p5/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+EO.34*
+r1bqkb1r/pp1p1ppp/2n1pn2/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+EO.06*
+r1bqkb1r/pp1p1ppp/2n1pn2/8/2PN4/2N3P1/PP2PP1P/R1BQKB1R b KQkq -
+EO.32
+r1bqkb1r/pp1p1ppp/2n2n2/2p1p3/2P5/1P3N2/P2PPPPP/RNBQKB1R w KQkq -
+EO.43*
+r1bqkb1r/pp1p1ppp/2n2n2/2p1p3/8/1P2PN2/PBPP1PPP/RN1QKB1R b KQkq -
+EO.60*
+r1bqkb1r/pp1p1ppp/2n2n2/4p3/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+SI.35
+r1bqkb1r/pp1ppp1p/2n2np1/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+EO.04*
+r1bqkb1r/pp1ppp1p/5np1/1Bp5/3nP3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+EO.02*
+r1bqkb1r/pp1ppppp/2n2n2/1Bp5/8/4PN2/PPPP1PPP/RNBQK2R b KQkq -
+EO.59*
+r1bqkb1r/pp1ppppp/2n2n2/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+EO.21*
+r1bqkb1r/pp1ppppp/2n2n2/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+EO.09*
+r1bqkb1r/pp1ppppp/2n2n2/8/2PN4/8/PP2PPPP/RNBQKB1R b KQkq -
+EO.42*
+r1bqkb1r/pp1ppppp/2n2n2/8/3N4/6P1/PPP1PP1P/RNBQKB1R b KQkq -
+EO.52*
+r1bqkb1r/pp1ppppp/2n2n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+SI.34
+r1bqkb1r/pp1ppppp/n4n2/2P5/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+RE.18*
+r1bqkb1r/pp2n1pp/2n2p2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+KI.52*
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+NI.16*
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/8/1P2PN2/P1PP1PPP/RNBQK2R w KQkq -
+NI.13*
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+NI.10*
+r1bqkb1r/pp2pp1p/2n2np1/2pp4/4P3/3P1N2/PPPN1PPP/R1BQKB1R w KQkq -
+OI.02*
+r1bqkb1r/pp2pp1p/2n2np1/3p4/2PP4/2N5/PP3PPP/R1BQKBNR w KQkq -
+TD.09*
+r1bqkb1r/pp2pp1p/2n2np1/8/2Pp4/B2P1NP1/4PP1P/RN1QKB1R w KQkq -
+BI.39*
+r1bqkb1r/pp2pp1p/2n3p1/2pn4/8/2N1PN2/PP1P1PPP/R1BQKB1R w KQkq -
+EO.32*
+r1bqkb1r/pp2pppp/2n2n2/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R b KQkq -
+NI.27*
+r1bqkb1r/pp2pppp/2n2n2/1Bpp4/8/1P2PN2/P1PP1PPP/RNBQK2R b KQkq -
+NI.26*
+r1bqkb1r/pp2pppp/2n2n2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+NI.28*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/2PP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+TD.05*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+SL.03*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R b KQkq -
+GI.07*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+EO.08*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/8/3P1NP1/PPP1PPBP/RNBQK2R b KQkq -
+KI.76*
+r1bqkb1r/pp2pppp/2n2n2/3p4/2PP4/8/PP3PPP/RNBQKBNR w KQkq -
+TD.11*
+r1bqkb1r/pp2pppp/2n2n2/3p4/2Pp4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+TD.12*
+r1bqkb1r/pp2pppp/2n5/1Bpn4/8/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+EO.44*
+r1bqkb1r/pp2pppp/2n5/2n5/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+BI.26*
+r1bqkb1r/pp2pppp/2n5/2p5/1n6/2N1PN2/PP1P1PPP/R1BQKB1R w KQkq -
+EO.33*
+r1bqkb1r/pp2pppp/2n5/2pn4/8/2N3P1/PP1PPPBP/R1BQK1NR b KQkq -
+EO.35*
+r1bqkb1r/pp2pppp/2n5/2pn4/8/5NP1/PP1PPPBP/RNBQK2R w KQkq -
+EO.49
+r1bqkb1r/pp2pppp/2np1n2/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+EO.07*
+r1bqkb1r/pp2pppp/2np1n2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R b KQkq -
+SI.27
+r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+SI.25
+r1bqkb1r/pp3pp1/2n2n1p/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+KI.20*
+r1bqkb1r/pp3ppp/2n1p3/2pn4/3P4/2NBPN2/PP3PPP/R1BQK2R b KQkq -
+TD.07
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/2P5/5NP1/PP1PPPBP/RNBQ1RK1 b kq -
+KI.77*
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/2P1PN2/PP3PPP/RNBQKB1R w KQkq -
+SL.08*
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 b kq -
+GI.09*
+r1bqkb1r/pp3ppp/2n1pn2/3p4/2PP4/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+TD.06*
+r1bqkb1r/pp3ppp/2n2n2/2pp4/3P4/2N1PN2/PP3PPP/R1BQKB1R w KQkq -
+TD.06
+r1bqkb1r/pp3ppp/2n2n2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 b kq -
+KI.21*
+r1bqkb1r/pp3ppp/2n2n2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+KI.22*
+r1bqkb1r/pp3ppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQK2R b KQkq -
+BI.20*
+r1bqkb1r/pp3ppp/2n5/2pn4/4N3/4P3/PP1P1PPP/R1BQKBNR b KQkq -
+EO.54*
+r1bqkb1r/pp3ppp/2nppn2/8/2BNP3/2N5/PPP2PPP/R1BQK2R w KQkq -
+SI.26
+r1bqkb1r/pp3ppp/2nppn2/8/3NP3/2N5/PPP1BPPP/R1BQK2R w KQkq -
+SI.22
+r1bqkb1r/pp4pp/2n2n2/2p1pp2/1PPp4/3P1NP1/P3PPBP/RNBQ1RK1 b kq -
+KI.55*
+r1bqkb1r/pp4pp/2n2n2/2p1pp2/2P5/3PBNP1/PP3PBP/RN1Q1RK1 b kq -
+KI.58*
+r1bqkb1r/pp4pp/2n2n2/4pp2/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+BI.31*
+r1bqkb1r/ppn1pppp/2n5/2p5/8/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+EO.36
+r1bqkb1r/ppp2p1p/2n5/3np1p1/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+SI.20*
+r1bqkb1r/ppp2ppp/2n2n2/1B1pp3/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+SO.01*
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/8/3P1NP1/PPP1PPBP/RNBQK2R b KQkq -
+PU.10*
+r1bqkb1r/ppp2ppp/2n5/3np3/4P3/2N2N2/PP1P1PPP/R1BQKB1R b KQkq -
+SI.35*
+r1bqkb1r/ppp2ppp/2n5/3np3/4P3/3P1N2/PP3PPP/RNBQKB1R b KQkq -
+SI.03*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N1P3/PPQP1PPP/R1B1KBNR b KQkq -
+SI.40*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+SI.34*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+EO.03
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2NP1N2/PP2PPPP/R1BQKB1R b KQkq -
+SI.25*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3P1NP1/PP2PP1P/RNBQKB1R b KQkq -
+SI.15*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3PPN2/PP3PPP/RNBQKB1R b KQkq -
+SI.19*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R b KQkq -
+SI.14*
+r1bqkb1r/ppp2ppp/5n2/3Pp3/3n4/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+SO.02*
+r1bqkb1r/ppp2ppp/5n2/3pn3/8/2P5/PP1NPPPP/R1BQKBNR w KQkq -
+CK.08*
+r1bqkb1r/ppp3pp/2n2n2/3ppp2/8/3P1NP1/PPP1PPBP/RNBQ1RK1 b kq -
+PU.06*
+r1bqkb1r/ppp3pp/2n5/3npp2/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+SI.21*
+r1bqkb1r/ppp3pp/2n5/3npp2/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+SI.12*
+r1bqkb1r/pppn1ppp/3p1n2/4p1B1/2PP4/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+OI.03
+r1bqkb1r/pppn1ppp/3p1n2/4p3/2PP4/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+OI.02
+r1bqkb1r/pppn1ppp/5n2/3p4/2PP4/2N5/PP3PPP/R1BQKBNR b KQkq -
+FR.22*
+r1bqkb1r/pppn1ppp/5n2/3p4/2PP4/8/PP3PPP/RNBQKBNR w KQkq -
+FR.21*
+r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+KP.03
+r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+RL.07
+r1bqkb1r/pppp1ppp/2n2n2/3N4/3pP3/5N2/PPP2PPP/R1BQKB1R b KQkq -
+SO.02
+r1bqkb1r/pppp1ppp/2n2n2/4p1N1/2B1P3/8/PPPP1PPP/RNBQK2R b KQkq -
+KP.01
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+IG.01
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N1PN2/PP1P1PPP/R1BQKB1R b KQkq -
+EO.06
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N2NP1/PP1PPP1P/R1BQKB1R b KQkq -
+EO.04
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2NP1N2/PP2PPPP/R1BQKB1R b KQkq -
+EO.07
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+EO.08
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+KP.06*
+r1bqkb1r/pppp1ppp/2n2n2/8/2BpP3/5N2/PPP2PPP/RNBQK2R w KQkq -
+KP.02
+r1bqkb1r/ppppnppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+RL.04
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+RL.11
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+RL.10
+r1bqkbnr/1ppp1ppp/p1B5/4p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+RL.08
+r1bqkbnr/1ppp1ppp/p1n5/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+RL.09
+r1bqkbnr/2p2ppp/p1p5/3p4/2PPp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+FR.11*
+r1bqkbnr/4pppp/p1p5/2pp4/2P5/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+NI.19*
+r1bqkbnr/4pppp/p1p5/2pp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+NI.18*
+r1bqkbnr/p4ppp/2p5/2pp4/8/4PQ2/PPP2PPP/RNB1KB1R w KQkq -
+EO.56*
+r1bqkbnr/p4ppp/2p5/3pp3/8/6P1/PPP1PP1P/RNBQKB1R w KQkq -
+GI.04*
+r1bqkbnr/pp1npppp/2p5/8/2BPN3/8/PPP2PPP/R1BQK1NR b KQkq -
+CK.09
+r1bqkbnr/pp1npppp/2p5/8/3PN3/5N2/PPP2PPP/R1BQKB1R b KQkq -
+CK.08
+r1bqkbnr/pp1p1ppp/2n1p3/4P3/2P1Q3/2N5/PP3PPP/R1B1KBNR b KQkq -
+EO.55
+r1bqkbnr/pp1p1ppp/2n1p3/8/2PN4/8/PP2PPPP/RNBQKB1R w KQkq -
+EO.50
+r1bqkbnr/pp1p1ppp/2n1p3/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+SI.39
+r1bqkbnr/pp1p1ppp/2n5/2p1p3/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+EO.57*
+r1bqkbnr/pp1p1ppp/2n5/2p1p3/8/2P2N2/PP1PPPPP/RNBQKB1R w KQkq -
+EO.61*
+r1bqkbnr/pp1p1ppp/4p3/4n3/2PN4/2N5/PP3PPP/R1BQKB1R w KQkq -
+EO.54
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/2P5/2N1PN2/PP1P1PPP/R1BQKB1R b KQkq -
+EO.34
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+EO.20*
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/2P2N2/PP1P1PPP/RNBQKB1R b KQkq -
+EO.12*
+r1bqkbnr/pp1ppp1p/2n3p1/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+SI.33
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+EO.22*
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+EO.10*
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+SI.31
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+EO.23*
+r1bqkbnr/pp1ppppp/2n5/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+SI.32
+r1bqkbnr/pp2pp1p/2n3p1/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+NI.29*
+r1bqkbnr/pp2pppp/2n5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R b KQkq -
+NI.30*
+r1bqkbnr/pp2pppp/2n5/2pp4/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+TD.10*
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/2P1P3/PP3PPP/RNBQKBNR b KQkq -
+SL.06*
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+QO.16*
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+GI.03*
+r1bqkbnr/pp2pppp/2n5/2pp4/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+HD.05*
+r1bqkbnr/pp2pppp/2n5/2pp4/8/3P1N2/PPP1PPPP/RNBQKB1R w KQkq -
+OI.04*
+r1bqkbnr/pp2pppp/2n5/8/1pPp4/P4N2/3PPPPP/RNBQKB1R w KQkq -
+BI.44*
+r1bqkbnr/pp2pppp/2n5/8/2Pp4/B4NP1/3PPP1P/RN1QKB1R b KQkq -
+BI.41*
+r1bqkbnr/pp3pp1/2n4p/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 b kq -
+KI.30*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+NI.15*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/1P2PN2/P1PP1PPP/RNBQK2R b KQkq -
+NI.12*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 b kq -
+NI.11*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+NI.17*
+r1bqkbnr/pp3ppp/2n5/2p1p3/2Pp4/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+RE.13
+r1bqkbnr/pp3ppp/2n5/2p1p3/2PpP3/3P1N2/PP3PPP/RNBQKB1R w KQkq -
+OI.05*
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+TD.09
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+CK.03*
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/5N2/PPPN1PPP/R1BQKB1R w KQkq -
+FR.22
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/2NP2P1/PPP1PPBP/R1BQK1NR b KQkq -
+KF.03*
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R b KQkq -
+KI.31*
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/3P2P1/PPP1PPBP/RNBQK1NR w KQkq -
+KF.04*
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/3P2P1/PPPNPPBP/R1BQK1NR b KQkq -
+KF.02*
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/5NP1/PPPPPPBP/RNBQ1RK1 b kq -
+KI.32*
+r1bqkbnr/pp4pp/2n2p2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+KI.54*
+r1bqkbnr/pp4pp/2n2p2/2ppp3/8/P2P1NP1/1PP1PPBP/RNBQK2R b KQkq -
+KI.53*
+r1bqkbnr/pp4pp/2n5/5p2/2Ppp3/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+BI.34*
+r1bqkbnr/ppp1pppp/2n5/3p4/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+VO.06
+r1bqkbnr/ppp1pppp/2n5/8/2Pp4/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+OI.08*
+r1bqkbnr/ppp2pp1/6n1/3p3p/8/2P3B1/PP2PPPP/RN1QKBNR w KQkq -
+CK.11*
+r1bqkbnr/ppp2ppp/2n1p3/3p4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+FR.15
+r1bqkbnr/ppp2ppp/2n5/1B1p4/2PPp3/4P3/PP3PPP/RNBQK1NR b KQkq -
+FR.10*
+r1bqkbnr/ppp2ppp/2n5/1B1p4/3Pp3/4P3/PPP2PPP/RNBQK1NR w KQkq -
+FR.09*
+r1bqkbnr/ppp2ppp/2n5/1B1pp3/3P4/4P3/PPP2PPP/RNBQK1NR b KQkq -
+FR.08*
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+CK.05*
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+FR.04*
+r1bqkbnr/ppp2ppp/2n5/3pp3/8/3P1NP1/PPP1PP1P/RNBQKB1R b KQkq -
+PU.07*
+r1bqkbnr/ppp2ppp/2np4/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+RL.02
+r1bqkbnr/ppp2ppp/8/3p4/8/2P2P2/PP2PP1P/RNBQKB1R b KQkq -
+CK.07*
+r1bqkbnr/ppp2ppp/8/3p4/8/2P2P2/PP3PPP/RNBQKB1R b KQkq -
+CK.06*
+r1bqkbnr/ppp2ppp/8/3pn3/5B2/2P5/PP2PPPP/RN1QKBNR b KQkq -
+CK.10*
+r1bqkbnr/ppp2ppp/8/3pn3/8/4P3/PPP2PPP/RNBQKBNR w KQkq -
+FR.07*
+r1bqkbnr/ppp3pp/2n2p2/3pp3/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+PU.04*
+r1bqkbnr/ppp3pp/2n5/3ppp2/8/3P1NP1/PPP1PPBP/RNBQK2R b KQkq -
+PU.05*
+r1bqkbnr/pppn1ppp/8/3p4/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+FR.20*
+r1bqkbnr/pppn1ppp/8/3p4/2PQ4/4P3/PP3PPP/RNB1KBNR b KQkq -
+FR.19*
+r1bqkbnr/pppn1ppp/8/3p4/3Pp3/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+FR.16*
+r1bqkbnr/pppn1ppp/8/3pp3/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+FR.18*
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/2N1P3/PPP2PPP/R1BQKBNR b KQkq -
+FR.15*
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+FR.14*
+r1bqkbnr/pppp1p1p/2n3p1/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+RL.03
+r1bqkbnr/pppp1p1p/2n3p1/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+VG.01*
+r1bqkbnr/pppp1ppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+RL.01
+r1bqkbnr/pppp1ppp/2n5/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+IG.03
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+EO.21
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+EO.20
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+SI.44*
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+KP.06
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2P2N2/PP1P1PPP/RNBQKB1R b KQkq -
+KP.05
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+KP.07
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+VG.04*
+r1bqkbnr/pppp1ppp/2n5/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+SO.04
+r1bqkbnr/pppp1ppp/2n5/8/3Q4/8/PPP1PPPP/RNB1KBNR w KQkq -
+SD.02*
+r1bqkbnr/pppp1ppp/2n5/8/3pP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+SO.06
+r1bqkbnr/pppp1ppp/2n5/8/Q7/8/PPP1PPPP/RNB1KBNR b KQkq -
+SD.01*
+r1bqkbnr/pppp1ppp/8/1B2p3/3nP3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+RL.05
+r1bqkbnr/pppp2pp/2n5/1B2pp2/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+RL.06
+r1bqkbnr/pppp2pp/2n5/4pp2/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+VG.03*
+r1bqkbnr/pppppppp/2n5/8/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+VO.05
+r1bqkbnr/pppppppp/2n5/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+VO.04
+r1bqkbnr/pppppppp/2n5/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.15*
+r1bqnrk1/pp2b1pp/2n2p2/2p1p3/3pPP2/3P2P1/PPPNN1BP/R1BQ1RK1 b - -
+KI.02*
+r1bqnrk1/pp2bppp/2n5/2p1p3/3pP3/3P1NP1/PPP1NPBP/R1BQ1RK1 w - -
+KI.03*
+r1bqr1k1/1p1n1pbp/p2p1np1/2pP4/P3P3/2N5/1P1NBPPP/R1BQ1RK1 w - -
+BI.03
+r1bqr1k1/1p1n1pbp/p2p1np1/2pP4/P3P3/R1N5/1P1NBPPP/2BQ1RK1 b - -
+BI.01
+r1bqr1k1/1p1n1pbp/p2p1np1/2pP4/P3PP2/2N5/1P1NB1PP/R1BQ1RK1 b - -
+BI.02
+r1bqr1k1/1p1n1pbp/p2p1np1/2pP4/P7/2N3P1/1P1NPPBP/R1BQ1RK1 w - -
+BI.22
+r1bqr1k1/p1n2pbp/1p1p1np1/2pP4/P3P3/2N2P2/1P1NB1PP/R1BQ1RK1 w - -
+BI.07
+r1bqr1k1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N2NPP/PP3PB1/R1BQ1RK1 w - -
+KI.61
+r1bqr1k1/pp1n1pbp/3p1np1/2pP4/4P3/2N5/PP1NBPPP/R1BQ1RK1 w - -
+BI.05
+r1bqr1k1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+KI.11*
+r1bqr1k1/pp3pbp/3p1np1/2pPn3/P3P3/2N5/1P1NBPPP/R1BQ1RK1 w - -
+BI.04
+r1bqr1k1/pp3pbp/n2p1np1/2pP4/4P3/2N5/PP1NBPPP/R1BQ1RK1 w - -
+BI.09
+r1bqr1k1/ppbn1pp1/2p2n1p/3pp3/NPP1P3/P2P1N2/2Q1BPPP/R1B2RK1 w - -
+RL.24*
+r1bqr1k1/ppnn1pbp/3p2p1/2pP4/P3P3/2N2P2/1P1NB1PP/R1BQ1RK1 w - -
+BI.08
+r1bqrbk1/pp3ppp/2n2n2/2ppp3/4P3/2PP1NP1/PP1N1PBP/R1BQ1RK1 w - -
+KI.10*
+r1bqrbk1/pp3ppp/2n2n2/2ppp3/P3P3/2PP1NP1/1P1N1PBP/R1BQ1RK1 b - -
+KI.09*
+r1n1kb1r/pp1q2pp/2n1bp2/2ppp3/8/P1NP1NP1/1PP1PPBP/1RBQ1RK1 w kq -
+KI.34*
+r2q1r1k/1p2b1pp/2n2p2/p1n1p3/2Pp2b1/BP1P1NP1/P1N2PBP/1R1QR1K1 w - -
+BI.06*
+r2q1rk1/1bp1bppp/p1np1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+RL.26
+r2q1rk1/1p1n1pbp/p2p1np1/2pP4/P3P3/2N2B1P/1P3PP1/R1BQ1RK1 w - -
+BI.10
+r2q1rk1/1p2bppp/2n2n2/p3p1B1/2Pp2b1/P2P1NP1/1P3PBP/RN1Q1RK1 w - -
+BI.13*
+r2q1rk1/1p2bppp/2n2n2/p3pbB1/2Pp4/P2P1NP1/1P3PBP/RN1Q1RK1 w - -
+BI.12*
+r2q1rk1/1p2bppp/2n2n2/p3pbB1/2Pp4/P2P1NP1/1P3PBP/RN1QR1K1 b - -
+BI.11*
+r2q1rk1/p3nppp/4b3/2bpp3/8/2N3P1/PP2PPBP/R1BQ1RK1 w - -
+GI.06*
+r2q1rk1/pp1bbppp/2n2n2/2p1p3/3pP3/3P1NP1/PPP1NPBP/R1BQ1RK1 w - -
+KI.06*
+r2q1rk1/pp2bppp/2n1bn2/2ppp3/4P3/2NP1NP1/PPP2PBP/R1BQ1RK1 w - -
+KI.08*
+r2q1rk1/pp2bppp/2n1bn2/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+KI.13*
+r2q1rk1/pp2n1pp/2nbbp2/2ppp3/1P6/P1PP1NP1/3NPPBP/R1BQ1RK1 b - -
+KI.46*
+r2q1rk1/pp2ppbp/2n2np1/3p4/2PP2b1/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+TD.03*
+r2q1rk1/ppp2ppp/2nb4/1B6/3P2b1/5N2/P1P2PPP/R1BQ1RK1 w - -
+SO.03*
+r2qk1nr/pp2bppp/2n5/2p1p3/2Pp2b1/3P1NPP/PP2PPB1/RNBQ1RK1 b kq -
+KI.23*
+r2qk1nr/pp2bppp/2n5/2p1p3/2Pp2b1/3PPNP1/PP3PBP/RNBQ1RK1 b kq -
+KI.24*
+r2qk1nr/pp2bppp/2n5/2ppp3/2P3b1/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+KI.25*
+r2qk1nr/pp2bppp/2n5/2ppp3/6b1/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+KI.26*
+r2qk1nr/pp4pp/2nbbp2/2p1p3/1P1pP3/2PP1NP1/P4PBP/RNBQ1RK1 b kq -
+KI.38*
+r2qk1nr/pp4pp/2nbbp2/4p3/3pP3/3P1NP1/PP3PBP/RNBQ1RK1 w kq -
+KI.37*
+r2qk2r/2p2ppp/p1n1b3/1pbpP3/4n3/1BP2N2/PP3PPP/RNBQ1RK1 w kq -
+RL.30
+r2qk2r/pp2b1pp/2n2n2/6N1/2Ppp1b1/1Q4P1/PP3PBP/RNB1R1K1 b kq -
+BI.28*
+r2qk2r/pp2n1pp/2nbbp2/2pp4/2P1p3/PP1P1NP1/4PPBP/RNBQ1RK1 w kq -
+KI.44*
+r2qkb1r/1p1b1ppp/p1nppn2/6B1/3NP3/2N5/PPPQ1PPP/2KR1B1R w kq -
+SI.30
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1B3N2/PPP1QPPP/RNB2RK1 b kq -
+RL.28
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP3PPP/RNBQ1RK1 b kq -
+RL.29
+r2qkb1r/pp1n1ppp/2n5/4p2b/2Pp4/P2P1NPP/1P3PB1/RNBQK2R w KQkq -
+BI.18*
+r2qkb1r/pp1n1ppp/2p1pn2/3p1b2/2P5/1P3NP1/PB1PPPBP/RN1Q1RK1 b kq -
+RE.02
+r2qkb1r/pp1n1ppp/2p1pn2/3p4/2P3b1/1P3NP1/PB1PPPBP/RN1Q1RK1 b kq -
+RE.01
+r2qkb1r/pp2n1pp/2n1bp2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+KI.43*
+r2qkb1r/pp2pppp/2n2n2/2pp4/3P2b1/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+GI.08*
+r2qkb1r/pp2pppp/2n2n2/2pp4/4P1b1/3P1N2/PPPN1PPP/R1BQKB1R w KQkq -
+OI.03*
+r2qkb1r/pp2pppp/2n2n2/8/2Pp2b1/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+BI.25*
+r2qkb1r/pp3ppp/2n1pn2/2pp1b2/2PP4/4PN2/PP2BPPP/RNBQ1RK1 b kq -
+QO.03*
+r2qkb1r/pp3ppp/2n1pn2/2pp1b2/3P4/4PN2/PPP1BPPP/RNBQ1RK1 w kq -
+QO.04*
+r2qkb1r/pp3ppp/2n1pn2/2pp3b/3P4/1P2PN1P/P1P1BPP1/RNBQ1RK1 b kq -
+QO.10*
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 b kq -
+QO.12*
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P4/4PB1P/PPP2PP1/RNBQ1RK1 b kq -
+QO.14*
+r2qkb1r/pp3ppp/2n1pn2/2pp4/Q2P2b1/2P1PN2/PP1N1PPP/R1B1KB1R b KQkq -
+QO.15*
+r2qkb1r/pp3ppp/2n1pn2/3p4/3P4/1P3B1P/P1P2PP1/RNBQ1RK1 b kq -
+QO.08*
+r2qkb1r/pp3ppp/2n1pn2/5b2/2Bp4/4PN2/PP3PPP/RNBQ1RK1 w kq -
+QO.01*
+r2qkb1r/pp3ppp/2n2n2/2Ppp3/1P4b1/2P1PN2/P4PPP/RNBQKB1R b KQkq -
+SL.07*
+r2qkb1r/pp3ppp/2n2n2/4p3/2Pp2b1/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+BI.19*
+r2qkb1r/pp4pp/2n1bn2/2pp4/4pB2/1NN1P3/PPP2PPP/R2QKB1R w KQkq -
+AL.06*
+r2qkb1r/ppp2ppp/1nn1p3/4Pb2/2PP4/2N1BN2/PP4PP/R2QKB1R b KQkq -
+AL.06
+r2qkb1r/ppp2ppp/2n1b3/3np3/8/3P1NP1/PP2PPBP/RNBQK2R b KQkq -
+SI.16*
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+SI.27*
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+SI.04*
+r2qkb1r/ppp2ppp/2n5/4p3/1n2P1b1/P1NP1N2/1P3PPP/R1BQKB1R b KQkq -
+SI.36*
+r2qkb1r/ppp2ppp/n1n5/4p3/1P2P1b1/P1NP1N2/5PPP/R1BQKB1R b KQkq -
+SI.37*
+r2qkb1r/ppp2ppp/n7/4p3/1P1nPP2/P1NP4/5P1P/R1BQKB1R b KQkq -
+SI.38*
+r2qkb1r/ppp3pp/2n1bp2/3np3/8/3P1NP1/PP2PPBP/RNBQK2R w KQkq -
+SI.17*
+r2qkb1r/ppp3pp/2n5/3npp2/1P4b1/P2PPN2/5PPP/RNBQKB1R b KQkq -
+SI.07*
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/P2PPN2/1P1N1PPP/R1BQKB1R b KQkq -
+SI.06*
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/P2PPN2/1P2BPPP/RNBQK2R b KQkq -
+SI.09*
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/P2PPN2/1PQ2PPP/RNB1KB1R b KQkq -
+SI.05*
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/PQ1PPN2/1P3PPP/RNB1KB1R b KQkq -
+SI.08*
+r2qkbnr/pp1nppp1/2p4p/7P/3P4/3Q1NN1/PPP2PP1/R1B1K2R b KQkq -
+CK.12
+r2qkbnr/pp2pppp/2n5/1Bpp4/6b1/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+NI.25*
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+QO.13*
+r2qkbnr/pp2pppp/2n5/3p1b2/3P4/2P5/PP2BPPP/RNBQK1NR b KQkq -
+QO.05*
+r2qkbnr/pp3ppp/2n5/4pb2/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+BI.35*
+r2qkbnr/pp4pp/2n1bp2/2p1p3/3pP3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+KI.41*
+r2qkbnr/pp4pp/2n1bp2/2ppp3/8/1P1P1NP1/P1P1PPBP/RNBQ1RK1 b kq -
+KI.45*
+r2qkbnr/pp4pp/2n1bp2/2ppp3/8/2NP1NP1/PPP1PPBP/R1BQ1RK1 b kq -
+KI.36*
+r2qkbnr/pp4pp/2n1bp2/2ppp3/8/3P1NP1/PPPNPPBP/R1BQ1RK1 b kq -
+KI.48*
+r2qkbnr/pp4pp/2n2p2/2p1p3/2Pp2b1/3P1NP1/PP2PPBP/RNBQ1RK1 w kq -
+KI.50*
+r2qkbnr/pp4pp/2n2p2/2ppp3/6b1/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+KI.51*
+r2qkbnr/pp4pp/2n2p2/4p3/2Pp2b1/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+BI.37*
+r2qkbnr/ppp2ppp/2n5/3pp3/3P2b1/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+FR.06*
+r2qkbnr/ppp2ppp/2n5/3pp3/3P2b1/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+FR.05*
+r2qkbnr/ppp2ppp/2n5/3pp3/6b1/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+PU.09*
+r3k2r/pppq2pp/2n1bp2/2bnp3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w kq -
+SI.18*
+r3kb1r/pp1qn1pp/2n1bp2/2ppp3/4P3/2PP1NP1/PP1N1PBP/R1BQ1RK1 b kq -
+KI.42*
+r3kb1r/pp1qn1pp/2n1bp2/2ppp3/8/P1NP1NP1/1PP1PPBP/1RBQ1RK1 b kq -
+KI.35*
+r3kb1r/pp3ppp/1qn1bn2/3pp1B1/8/6P1/PPPNPPBP/RN1Q1RK1 w kq -
+GI.11*
+r3kb1r/ppq1n1p1/2n1bp2/2ppp2p/8/P1NP1NP1/1PP1PPBP/1RBQ1RK1 w kq -
+KI.33*
+r3kbnr/pp1q2pp/2n1bp2/2p1p3/3pP2N/3P2P1/PPP2PBP/RNBQ1RK1 w kq -
+KI.40*
+r3kbnr/pp1q2pp/2n1bp2/2ppp3/8/P2P1NP1/1PP1PPBP/RNBQ1RK1 w kq -
+KI.47*
+r3kbnr/pp1q2pp/2n1bp2/4p3/3pP3/3P1NP1/PP3PBP/RNBQ1RK1 w kq -
+KI.39*
+r3kbnr/pp1q2pp/2n2p2/2p1p3/2Pp2b1/3PPNP1/PP3PBP/RNBQ1RK1 w kq -
+KI.49*
+r4rk1/pbqnppbp/1pn3p1/2p5/NPPp4/P2P1NP1/4PPBP/1RBQ1RK1 w - -
+KI.66*
+rn1q1rk1/1p3pbp/p2p1np1/2pP2B1/P3P1b1/2N2N2/1P2BPPP/R2Q1RK1 b - -
+BI.13
+rn1q1rk1/1p3pbp/p2p1np1/2pP4/P3P3/2N5/1P1NQPPP/R1B2RK1 b - -
+BI.14
+rn1q1rk1/1p3pbp/p2p1np1/2pP4/P3PBb1/2N2N2/1P2BPPP/R2Q1RK1 b - -
+BI.12
+rn1q1rk1/pb1p1pbp/1p2pnp1/2p5/3P4/1P2PN2/PBP1BPPP/RN1Q1RK1 w - -
+RE.08*
+rn1q1rk1/pb1pbppp/1p2p3/2p5/2PP4/2Q2NP1/PP2PPBP/R1B2RK1 w - -
+QI.13
+rn1q1rk1/pb1pppbp/1p3np1/2p3B1/3P4/2P1PN2/PP1N1PPP/R2QKB1R w KQ -
+RE.01*
+rn1q1rk1/pb1pppbp/1p3np1/2p5/2P5/1P3NP1/PB1PPPBP/RN1Q1RK1 b - -
+EO.47*
+rn1q1rk1/pb1pppbp/1p3np1/2p5/2P5/1P3NP1/PB1PPPBP/RN1Q1RK1 w - -
+EO.47
+rn1q1rk1/pb1pppbp/1p3np1/2p5/3P1B2/2P1PN2/PP1N1PPP/R2QKB1R w KQ -
+RE.02*
+rn1q1rk1/pbp1bpp1/1p2pn1p/3p4/2PP3B/2N1PN2/PP3PPP/2RQKB1R w K -
+QO.09
+rn1q1rk1/pbp1bppp/1p2pn2/3p4/2P5/1P2PNP1/PB1P1PBP/RN1Q1RK1 b - -
+RE.08
+rn1q1rk1/pbppb1pp/1p2p3/5p2/2PP4/2Q2NP1/PP2PPBP/R1B2RK1 w - -
+QI.12
+rn1q1rk1/pbppbppp/1p2p3/8/2PPn3/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+QI.10
+rn1q1rk1/pbppbppp/1p2p3/8/2PPn3/2N2NP1/PPQ1PPBP/R1B2RK1 b - -
+QI.11
+rn1q1rk1/pbppbppp/1p2pn2/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+QI.09
+rn1q1rk1/pbppbppp/1p3n2/3p4/2P5/5NP1/PP2PPBP/RNBQ1RK1 w - -
+QI.08
+rn1q1rk1/pp3pbp/3p1np1/2pP4/4P1b1/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+BI.16
+rn1q1rk1/pp3pbp/3p1np1/2pP4/4PPb1/2N2N2/PP2B1PP/R1BQK2R w KQ -
+BI.30
+rn1q1rk1/pp3pbp/3pbnp1/2p5/2P1PP2/2N2N2/PP4PP/R1BQKB1R w KQ -
+KI.58
+rn1q1rk1/ppp1ppbp/3p1np1/8/3PP1b1/2N2N2/PPP1BPPP/R1BQ1RK1 w - -
+PU.01
+rn1q1rk1/pppnppbp/6p1/8/3PP1b1/1QN1BN2/PP3PPP/R3KB1R b KQ -
+GI.11
+rn1qk2r/pb1pbppp/1p2pn2/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w kq -
+EO.40
+rn1qk2r/pb1pbppp/1p2pn2/8/2PQ4/2N2NP1/PP2PPBP/R1B2RK1 b kq -
+EO.39
+rn1qk2r/pb1pppbp/1p3np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w kq -
+EO.48
+rn1qk2r/pb1pppbp/1p3np1/2p5/3P4/2P2NP1/PP2PPBP/RNBQK2R w KQkq -
+RE.03*
+rn1qk2r/pbppbppp/1p2pn2/8/2PP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+QI.07
+rn1qk2r/pp3ppp/2p1pn2/5b2/PbBP4/2N1PN2/1P3PPP/R1BQ1RK1 b kq -
+SL.05
+rn1qk2r/ppp1bppp/1n1pp3/4P2b/2PP4/5N1P/PP2BPP1/RNBQ1RK1 w kq -
+AL.01
+rn1qkb1r/3ppp1p/b4np1/2pP4/8/2N5/PP2PPPP/R1BQKBNR w KQkq -
+BI.41
+rn1qkb1r/4pp1p/b2p1np1/2pP4/8/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+BI.39
+rn1qkb1r/4pp1p/b2p1np1/2pP4/8/2N5/PP1NPPPP/R1BQKB1R b KQkq -
+BI.40
+rn1qkb1r/4pp1p/b2p1np1/2pP4/8/6P1/PP2PPBP/RNBQK1NR w KQkq -
+BI.42
+rn1qkb1r/p1pp1ppp/bp2pn2/8/2PP4/5NP1/PP2PP1P/RNBQKB1R w KQkq -
+QI.05
+rn1qkb1r/pbpp1ppp/1p2pn2/8/2P1P3/2N2N2/PP1P1PPP/R1BQKB1R w KQkq -
+EO.60
+rn1qkb1r/pbpp1ppp/1p2pn2/8/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+QI.06
+rn1qkb1r/pp2pppp/2p2n2/3p1b2/2P5/5NP1/PP1PPPBP/RNBQK2R w KQkq -
+RE.06
+rn1qkb1r/pp2pppp/2p2n2/3p4/2P3b1/5NP1/PP1PPPBP/RNBQK2R w KQkq -
+RE.05
+rn1qkb1r/pp2pppp/2p2n2/5b2/P1pP4/2N2N2/1P2PPPP/R1BQKB1R w KQkq -
+SL.04
+rn1qkb1r/ppp1pppp/3p4/3nP3/3P2b1/5N2/PPP2PPP/RNBQKB1R w KQkq -
+AL.03
+rn1qkb1r/ppp1pppp/5n2/3p1b2/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+QP.05*
+rn1qkb1r/ppp1pppp/5n2/3p1b2/8/5NP1/PPPPPPBP/RNBQK2R b KQkq -
+QP.03*
+rn1qkb1r/ppp1pppp/5n2/3p4/6b1/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+QP.04*
+rn1qkb1r/ppp1pppp/5n2/3p4/6b1/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+QP.02*
+rn1qkb1r/ppp1pppp/5n2/3p4/6b1/5NP1/PPPPPPBP/RNBQK2R b KQkq -
+QP.01*
+rn1qkb1r/ppp2ppp/3pp3/3nP3/3P2b1/5N2/PPP1BPPP/RNBQK2R w KQkq -
+AL.02
+rn1qkb1r/ppp2ppp/4pn2/8/2BP2b1/4PN2/PP3PPP/RNBQK2R w KQkq -
+QG.06
+rn1qkbnr/pbpp1ppp/1p2p3/8/3PP3/3B4/PPP2PPP/RNBQK1NR w KQkq -
+VO.03
+rn1qkbnr/pbpppppp/1p6/8/3PP3/3B4/PPP2PPP/RNBQK1NR b KQkq -
+VO.02
+rn1qkbnr/pp2pppp/2p3b1/8/3P3P/6N1/PPP2PP1/R1BQKBNR b KQkq -
+CK.11
+rn1qkbnr/pp2pppp/2p5/3pPb2/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+CK.04
+rn1qkbnr/pp2pppp/2p5/5b2/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+CK.10
+rn1qr1k1/1p3pbp/p2p1np1/2pP4/P3PBb1/2N2N2/1P2BPPP/R2Q1RK1 w - -
+BI.11
+rnb1k1nr/pp2ppbp/6p1/q1Pp4/8/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+CA.02*
+rnb1kb1r/1p3ppp/pq1ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+SI.08
+rnb1kb1r/1pq2ppp/p2ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+SI.05
+rnb1kb1r/ppp2ppp/4pq2/8/2PP4/2P5/P4PPP/R1BQKBNR b KQkq -
+EO.56
+rnb1kb1r/ppp2ppp/5n2/3qp3/8/3P4/PP2PPPP/RNBQKBNR w KQkq -
+SI.02*
+rnb1kbnr/pp3ppp/4p3/2pq4/3P4/8/PPPN1PPP/R1BQKBNR w KQkq -
+FR.19
+rnb1kbnr/ppp1pppp/8/3q4/8/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+SD.02
+rnb1kbnr/ppp1pppp/8/q7/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+SD.01
+rnb1r1k1/pp3pbp/1q4p1/2pPP1B1/6n1/2N2N2/PP2B1PP/R2QK2R w KQ -
+BI.28
+rnb2rk1/p1p1qpp1/1p5p/3p4/3P4/5N2/PP2PPPP/2RQKB1R w K -
+QO.06
+rnb2rk1/pp2ppbp/2pp1np1/q7/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+KI.74
+rnb2rk1/ppp1qppp/1b3n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R w KQ -
+RL.28*
+rnbq1rk1/1p1n1pbp/p2p2p1/2pP4/P3PP2/2NB1N2/1P4PP/R1BQK2R b KQ -
+BI.32
+rnbq1rk1/1pp1ppbp/p2p1np1/8/2PPP3/2N1BP2/PP1Q2PP/R3KBNR b KQ -
+KI.47
+rnbq1rk1/2p1bppp/p2p1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+RL.25
+rnbq1rk1/4ppbp/pp1p1np1/2p1P3/2PP4/2NBBP2/PP2N1PP/R2QK2R b KQ -
+KI.44
+rnbq1rk1/p1p1bpp1/1p2pn1p/3p4/2PP3B/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QO.10
+rnbq1rk1/p1p1ppbp/1p1p1np1/8/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+KI.45
+rnbq1rk1/p1p2pp1/1p3b1p/3p4/3P4/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QO.08
+rnbq1rk1/p2pppbp/1p3np1/2p5/3P4/4PN2/PPP1BPPP/RNBQ1RK1 w - -
+RE.09*
+rnbq1rk1/p3ppbp/3p1np1/1ppP4/2P1PP2/2N2N2/PP4PP/R1BQKB1R w KQ -
+KI.55
+rnbq1rk1/p4pbp/2pp1np1/1p1Pp3/2P1P3/2NBBP2/PP4PP/R2QK1NR w KQ -
+KI.38
+rnbq1rk1/p4ppp/1p2pn2/8/1bBP4/2N2N2/PP3PPP/R1BQ1RK1 w - -
+NI.04
+rnbq1rk1/pp1p1ppp/4pn2/2P5/1bP5/2N5/PPQ1PPPP/R1B1KBNR w KQ -
+NI.21
+rnbq1rk1/pp1p1ppp/4pn2/2p5/1bPP4/2NBPN2/PP3PPP/R1BQK2R b KQ -
+NI.07
+rnbq1rk1/pp1pppbp/5np1/2p5/2PP4/2N1PN2/PP3PPP/R1BQKB1R w KQ -
+KI.77
+rnbq1rk1/pp2bpp1/5n1p/2pp4/4p2B/1N1PP3/PPP1BPPP/RN1QK2R b KQ -
+AL.01*
+rnbq1rk1/pp2bppp/4pn2/2pp4/2PP1B2/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QO.03
+rnbq1rk1/pp2ppb1/3p1npp/2pP2B1/2P1P3/2N5/PP2BPPP/R2QK1NR w KQ -
+KI.23
+rnbq1rk1/pp2ppbp/2pp1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+KI.75
+rnbq1rk1/pp2ppbp/3p1np1/2p3B1/2PPP3/2N5/PP2BPPP/R2QK1NR w KQ -
+KI.25
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+KI.69
+rnbq1rk1/pp2ppbp/3p1np1/2pP2B1/2P1P3/2N2P2/PP4PP/R2QKBNR b KQ -
+KI.50
+rnbq1rk1/pp2ppbp/3p1np1/2pP4/2P1P3/2N5/PP3PPP/R1BQKBNR w KQ -
+RE.13*
+rnbq1rk1/pp2ppbp/3p1np1/2pP4/2P1PP2/2NB4/PP4PP/R1BQK1NR b KQ -
+KI.60
+rnbq1rk1/pp2ppbp/3p1np1/8/2PNPP2/2N5/PP2B1PP/R1BQK2R b KQ -
+KI.59
+rnbq1rk1/pp2ppbp/5np1/2Pp4/8/4PN2/PPP1BPPP/RNBQ1RK1 b - -
+CA.05*
+rnbq1rk1/pp2ppbp/5np1/2p5/3P4/1P3N2/PBPPBPPP/RN1Q1RK1 b - -
+QI.08*
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w - -
+GI.02*
+rnbq1rk1/pp2ppbp/5np1/2pp4/5P2/3P1NP1/PPP1P1BP/RNBQ1RK1 b - -
+HD.06*
+rnbq1rk1/pp2ppbp/5np1/2pp4/5P2/3PPN2/PPP1B1PP/RNBQ1RK1 b - -
+HD.01*
+rnbq1rk1/pp2ppbp/5np1/2pp4/5P2/4PN2/PPPPB1PP/RNBQ1RK1 w - -
+HD.02*
+rnbq1rk1/pp2ppbp/5np1/2pp4/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w - -
+KI.79*
+rnbq1rk1/pp3pbp/3p1np1/2pP4/2N5/2N5/PP2PPPP/R1BQKB1R w KQ -
+BI.26
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+BI.17
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4P3/2NB4/PP2NPPP/R1BQ1RK1 b - -
+BI.36
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4PP2/2N2N2/PP4PP/R1BQKB1R w KQ -
+BI.31
+rnbq1rk1/pp3pbp/3p1np1/2pP4/8/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+BI.24
+rnbq1rk1/pp3pbp/3p1np1/2ppP3/2P2P2/2N2N2/PP2B1PP/R1BQK2R b KQ -
+KI.56
+rnbq1rk1/pp3pbp/3p1np1/3Pp3/4P3/2N1BP2/PP1Q2PP/R3KBNR b KQ -
+KI.39
+rnbq1rk1/pp3pbp/3p1np1/3Pp3/4P3/2NBBP2/PP4PP/R2QK1NR b KQ -
+KI.37
+rnbq1rk1/pp3pbp/3ppnp1/2pP2B1/2P1P3/2N2P2/PP1Q2PP/R3KBNR b KQ -
+KI.49
+rnbq1rk1/pp3pbp/3ppnp1/2pP2B1/2P1P3/2N5/PP2BPPP/R2QK1NR w KQ -
+KI.24
+rnbq1rk1/pp3pbp/3ppnp1/2pP4/2P1PP2/2N2N2/PP2B1PP/R1BQK2R b KQ -
+KI.57
+rnbq1rk1/pp3ppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R w KQ -
+RL.29*
+rnbq1rk1/pp3ppp/1bp2n2/4N3/1PBPp3/P1N1B3/2P2PPP/R2QK2R b KQ -
+RL.30*
+rnbq1rk1/pp3ppp/4pn2/2bP4/5B2/2N1PN2/PP3PPP/R2QKB1R b KQ -
+QO.01
+rnbq1rk1/pp3ppp/4pn2/2bp4/2P5/P3PN2/1P3PPP/RNBQKB1R b KQ -
+QG.07*
+rnbq1rk1/pp3ppp/4pn2/2pp4/1bPP4/2NBP3/PP2NPPP/R1BQK2R w KQ -
+NI.09
+rnbq1rk1/pp3ppp/4pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQ1RK1 b - -
+NI.05
+rnbq1rk1/ppp1b1pp/3ppn2/5p2/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+HD.01
+rnbq1rk1/ppp1bpp1/4pn1p/8/2pP3B/2N2N2/PP2PPPP/2RQKB1R w K -
+QO.07
+rnbq1rk1/ppp1bppp/4pn2/3p4/2P5/1P3NP1/P2PPPBP/RNBQ1RK1 b - -
+RE.09
+rnbq1rk1/ppp1bppp/4pn2/3p4/2PP1B2/2N1PN2/PP3PPP/R2QKB1R b KQ -
+QO.04
+rnbq1rk1/ppp1bppp/4pn2/8/2pP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+CA.05
+rnbq1rk1/ppp1p1bp/3p1np1/5p2/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+HD.06
+rnbq1rk1/ppp1ppbp/3p1np1/6B1/2PPP3/2N2P2/PP4PP/R2QKBNR b KQ -
+KI.51
+rnbq1rk1/ppp1ppbp/3p1np1/6B1/2PPP3/2N5/PP2BPPP/R2QK1NR b KQ -
+KI.26
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PP4/2N1P1P1/PP3PBP/R1BQK1NR b KQ -
+KI.78
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PP4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+KI.79
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2N1P/PP3PP1/R1BQKB1R b KQ -
+KI.20
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2N2/PP2BPPP/R1BQK2R b KQ -
+KI.19
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2N2/PP3PPP/R1BQKB1R w KQ -
+KI.21
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2P2/PP2N1PP/R1BQKB1R b KQ -
+KI.52
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N3P1/PP3PBP/R1BQK1NR b KQ -
+KI.29
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N4P/PP3PP1/R1BQKBNR w KQ -
+KI.30
+rnbq1rk1/ppp1ppbp/3p1np1/8/3PPP2/2N2N2/PPP3PP/R1BQKB1R w KQ -
+PU.06
+rnbq1rk1/ppp1ppbp/3p1np1/8/3PPP2/2NB1N2/PPP3PP/R1BQK2R b KQ -
+PU.02
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R w KQ -
+GI.09
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+GI.02
+rnbq1rk1/ppp2pbp/3p1np1/3Pp3/2P1P3/2N1BP2/PP4PP/R2QKBNR b KQ -
+KI.41
+rnbq1rk1/ppp2pbp/3p1np1/3Pp3/2P1P3/2N2N2/PP2BPPP/R1BQK2R b KQ -
+KI.17
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N1BP2/PP2N1PP/R2QKB1R b KQ -
+KI.43
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+KI.15
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+KI.18
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N3P1/PP2NPBP/R1BQK2R b KQ -
+KI.28
+rnbq1rk1/ppp2pbp/3p2p1/3Pp2n/2P1P3/2N1BP2/PP1Q2PP/R3KBNR b KQ -
+KI.40
+rnbq1rk1/ppp2pp1/4pb1p/3p4/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QO.14
+rnbq1rk1/ppp2ppp/3b1n2/3pN3/3P4/2N5/PPP1BPPP/R1BQK2R b KQ -
+RG.06*
+rnbq1rk1/ppp2ppp/4pn2/3p4/1bPP4/2NBPN2/PP3PPP/R1BQK2R b KQ -
+NI.06
+rnbq1rk1/ppp2ppp/4pn2/3p4/1bPP4/P1NBP3/1P3PPP/R1BQK1NR b KQ -
+NI.08
+rnbq1rk1/ppp2ppp/5n2/b2pp3/4P3/P1N2N2/1PPPBPPP/R1BQK2R w KQ -
+RL.15*
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQ -
+NI.10
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQ -
+NI.11
+rnbq1rk1/pppp1ppp/4pn2/8/2PP4/P1Q5/1P2PPPP/R1B1KBNR b KQ -
+NI.20
+rnbq1rk1/pppp1ppp/5n2/4p3/1bP5/2N3P1/PP1PPPBP/R1BQK1NR w KQ -
+EO.11
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1b2N2/1PPPBPPP/R1BQK2R w KQ -
+RL.14*
+rnbq1rk1/pppp1ppp/5n2/b3N3/4P3/P1N5/1PPP1PPP/R1BQKB1R b KQ -
+RL.27*
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPPBPPP/R1BQK2R b KQ -
+RL.13*
+rnbq1rk1/ppppb1pp/4pn2/5p2/2PP4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+HD.02
+rnbq1rk1/ppppppbp/5np1/8/2PPP3/2N5/PP3PPP/R1BQKBNR w KQ -
+KI.32
+rnbqk1nr/pp2bppp/2p5/3p4/3P1B2/2N5/PP2PPPP/R2QKBNR w KQkq -
+QO.05
+rnbqk1nr/pp2ppbp/6p1/2pp4/5P2/2PP1N2/PP2P1PP/RNBQKB1R b KQkq -
+HD.04*
+rnbqk1nr/pp2ppbp/6p1/2pp4/5P2/4PN2/PPPP2PP/RNBQKB1R w KQkq -
+HD.03*
+rnbqk1nr/pp2ppbp/6p1/2pp4/5P2/5NP1/PPPPP1BP/RNBQK2R b KQkq -
+HD.07*
+rnbqk1nr/pp2ppbp/6p1/8/2Pp4/B2P1NP1/4PP1P/RN1QKB1R b KQkq -
+BI.42*
+rnbqk1nr/pp3ppp/4p3/2ppP3/1b1P4/2N5/PPP2PPP/R1BQKBNR w KQkq -
+FR.10
+rnbqk1nr/pp3ppp/4p3/2ppP3/3P4/P1P5/2P2PPP/R1BQKBNR b KQkq -
+FR.11
+rnbqk1nr/ppp1ppbp/3p2p1/8/2PPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+KF.04
+rnbqk1nr/ppp1ppbp/6p1/3p4/5P2/6P1/PPPPP2P/RNBQKBNR w KQkq -
+HD.09*
+rnbqk1nr/ppp2ppp/3b4/3pp3/8/1P2P3/PBPP1PPP/RN1QKBNR b KQkq -
+VO.03*
+rnbqk1nr/ppp2ppp/3b4/3pp3/8/1P6/PBPPPPPP/RN1QKBNR w KQkq -
+VO.02*
+rnbqk1nr/ppp2ppp/4p3/3p4/1b1PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+FR.08
+rnbqk1nr/ppp2ppp/4p3/3pP3/1b1P4/2N5/PPP2PPP/R1BQKBNR b KQkq -
+FR.09
+rnbqk1nr/pppp1ppp/8/2b1p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+IG.04*
+rnbqk1nr/ppppppbp/6p1/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+KF.05
+rnbqk2r/1p2bppp/p2p1n2/4p3/4P3/1NN5/PPP1BPPP/R1BQK2R w KQkq -
+SI.11
+rnbqk2r/1p2bppp/p2ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+SI.09
+rnbqk2r/1p3pb1/p2p1npp/2pP4/4P2B/2N5/PP1N1PPP/R2QKB1R b KQkq -
+BI.18
+rnbqk2r/1pp1ppbp/p2p1np1/8/2PPP3/2N2P2/PP4PP/R1BQKBNR w KQkq -
+KI.53
+rnbqk2r/p1pp1ppp/1p2pn2/8/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQkq -
+NI.13
+rnbqk2r/p1pp1ppp/1p2pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+NI.12
+rnbqk2r/p1pp1ppp/1p2pn2/8/1bPP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+NI.26
+rnbqk2r/p1pp1ppp/5n2/1pb1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+IG.05*
+rnbqk2r/pp1n1pbp/3p2p1/1BpP4/4PP2/2N5/PP4PP/R1BQK1NR w KQkq -
+BI.33
+rnbqk2r/pp1p1ppp/2p2n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQkq -
+RL.11*
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQkq -
+NI.16
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+NI.15
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+NI.22
+rnbqk2r/pp1p1ppp/4pn2/2p5/2PP4/P1P5/4PPPP/R1BQKBNR w KQkq -
+NI.19
+rnbqk2r/pp1p1ppp/4pn2/8/1bPN4/2N5/PP2PPPP/R1BQKB1R w KQkq -
+EO.44
+rnbqk2r/pp1pppbp/5np1/2P5/8/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+RE.10*
+rnbqk2r/pp1pppbp/5np1/2p3B1/3P4/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+RE.05*
+rnbqk2r/pp1pppbp/5np1/2p5/3P1B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+RE.06*
+rnbqk2r/pp1pppbp/5np1/2p5/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+RE.11*
+rnbqk2r/pp1pppbp/5np1/8/2PN4/2N5/PP2PPPP/R1BQKB1R b KQkq -
+EO.49*
+rnbqk2r/pp2nppp/4p3/2ppP3/3P4/P1P2N2/2P2PPP/R1BQKB1R b KQkq -
+FR.12
+rnbqk2r/pp2ppbp/2p2np1/3p4/2P5/1P3NP1/PB1PPPBP/RN1QK2R b KQkq -
+RE.03
+rnbqk2r/pp2ppbp/3p1np1/8/3NP3/2N1B3/PPP2PPP/R2QKB1R w KQkq -
+SI.16
+rnbqk2r/pp2ppbp/3p1np1/8/3NP3/2N1BP2/PPP3PP/R2QKB1R b KQkq -
+SI.17
+rnbqk2r/pp2ppbp/5np1/2Pp4/8/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+CA.03*
+rnbqk2r/pp2ppbp/5np1/2pp4/3P4/4PN2/PPP1BPPP/RNBQK2R w KQkq -
+CA.04*
+rnbqk2r/pp2ppbp/5np1/2pp4/8/1P2PN2/PBPP1PPP/RN1QKB1R w KQkq -
+QI.06*
+rnbqk2r/pp2ppbp/5np1/2pp4/8/1P2PN2/PBPPBPPP/RN1QK2R b KQkq -
+QI.07*
+rnbqk2r/pp3pbp/3p1np1/2pP2B1/4P3/2N2N2/PP3PPP/R2QKB1R b KQkq -
+BI.19
+rnbqk2r/pp3pbp/3p1np1/2pP2B1/4P3/2N2P2/PP4PP/R2QKBNR b KQkq -
+BI.37
+rnbqk2r/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP3PPP/R1BQKB1R w KQkq -
+BI.20
+rnbqk2r/pp3pbp/3p1np1/2pPP3/5P2/2N5/PP4PP/R1BQKBNR b KQkq -
+BI.34
+rnbqk2r/pp3ppp/4pn2/2bp2B1/8/4PN2/PPP2PPP/RN1QKB1R b KQkq -
+QG.06*
+rnbqk2r/ppp1bppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR w KQkq -
+QO.13
+rnbqk2r/ppp1bppp/4pn2/3p2B1/3PP3/2N5/PPP2PPP/R2QKBNR w KQkq -
+FR.06
+rnbqk2r/ppp1bppp/4pn2/3p4/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+CA.04
+rnbqk2r/ppp1bppp/5n2/3p2B1/3Np3/3PP3/PPP2PPP/RN1QKB1R b KQkq -
+AL.02*
+rnbqk2r/ppp1bppp/8/3p4/3Pn3/3B1N2/PPP2PPP/RNBQK2R w KQkq -
+RG.05
+rnbqk2r/ppp1ppbp/3p1np1/8/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+KI.76
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+KI.22
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N2P2/PP4PP/R1BQKBNR b KQkq -
+KI.54
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N5/PP2BPPP/R1BQK1NR b KQkq -
+KI.27
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N5/PP3PPP/R1BQKBNR w KQkq -
+KI.31
+rnbqk2r/ppp1ppbp/3p1np1/8/3PP3/2N2N2/PPP1BPPP/R1BQK2R b KQkq -
+PU.03
+rnbqk2r/ppp1ppbp/3p1np1/8/3PP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+PU.10
+rnbqk2r/ppp1ppbp/3p1np1/8/3PPP2/2N5/PPP3PP/R1BQKBNR w KQkq -
+PU.05
+rnbqk2r/ppp1ppbp/5np1/3p2B1/2PP4/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+GI.08
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/1QN2N2/PP2PPPP/R1B1KB1R b KQkq -
+GI.10
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+GI.07
+rnbqk2r/ppp1ppbp/6p1/3n4/8/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+EO.51
+rnbqk2r/ppp1ppbp/6p1/8/2BPP3/2P5/P4PPP/R1BQK1NR b KQkq -
+GI.05
+rnbqk2r/ppp2ppp/3b1n2/3pN3/3P4/8/PPP1BPPP/RNBQK2R b KQkq -
+RG.05*
+rnbqk2r/ppp2ppp/3b4/3np3/8/P3P3/1P1P1PPP/RNBQKBNR w KQkq -
+SI.42*
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+NI.27
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+NI.23
+rnbqk2r/ppp2ppp/5n2/2bPp3/8/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+KP.02*
+rnbqk2r/pppp1pbp/5np1/4p3/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+EO.14
+rnbqk2r/pppp1ppp/4pn2/6B1/1bPP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+NI.25
+rnbqk2r/pppp1ppp/4pn2/8/1bP5/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+EO.59
+rnbqk2r/pppp1ppp/4pn2/8/1bP5/2N2N2/PPQPPPPP/R1B1KB1R b KQkq -
+EO.58
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR b KQkq -
+NI.17
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+NI.28
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N3P1/PP2PP1P/R1BQKBNR b KQkq -
+NI.29
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+NI.30
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N5/PPQ1PPPP/R1B1KBNR b KQkq -
+NI.24
+rnbqk2r/pppp1ppp/4pn2/8/2PP4/P1P5/4PPPP/R1BQKBNR b KQkq -
+NI.18
+rnbqk2r/pppp1ppp/5n2/2b1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+IG.02*
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+IG.01*
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+IG.03*
+rnbqk2r/pppp1ppp/5n2/3Np3/1b2P3/8/PPPP1PPP/R1BQKBNR b KQkq -
+RL.05*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+RL.07*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+RL.03*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+RL.01*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N5/PPPPNPPP/R1BQKB1R b KQkq -
+RL.04*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2NP4/PPP2PPP/R1BQKBNR b KQkq -
+RL.02*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+RL.06*
+rnbqk2r/pppp1ppp/5n2/4p3/4P3/P1b5/1PPP1PPP/R1BQKBNR w KQkq -
+RL.08*
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R b KQkq -
+RL.12*
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N5/1PPP1PPP/R1BQKBNR w KQkq -
+RL.09*
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR b KQkq -
+RL.10*
+rnbqk2r/pppp1ppp/8/2b1p3/4P1n1/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+KP.01*
+rnbqk2r/ppppp1bp/5np1/5p2/2PP4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+HD.07
+rnbqk2r/ppppppbp/5np1/6B1/3P4/5N2/PPP1PPPP/RN1QKB1R w KQkq -
+QP.01
+rnbqk2r/ppppppbp/5np1/8/3P1B2/5N2/PPP1PPPP/RN1QKB1R w KQkq -
+QP.03
+rnbqkb1r/1p2pppp/p2p1n2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R b KQkq -
+SI.04
+rnbqkb1r/1p2pppp/p2p1n2/8/2BNP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+SI.13
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+SI.10
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+SI.14
+rnbqkb1r/1p2pppp/p2p1n2/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+SI.12
+rnbqkb1r/1p2pppp/p4n2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+QI.04*
+rnbqkb1r/1p3ppp/p2ppn2/8/3NP3/2N5/PPP1BPPP/R1BQK2R w KQkq -
+SI.23
+rnbqkb1r/1p3ppp/p3pn2/2p5/2BP4/4PN2/PP3PPP/RNBQ1RK1 w kq -
+QG.07
+rnbqkb1r/3ppppp/p4n2/1PpP4/8/2N5/PP2PPPP/R1BQKBNR b KQkq -
+BI.44
+rnbqkb1r/3ppppp/p4n2/1PpP4/8/4P3/PP3PPP/RNBQKBNR b KQkq -
+BI.43
+rnbqkb1r/3ppppp/p4n2/1PpP4/8/8/PP2PPPP/RNBQKBNR w KQkq -
+BI.45
+rnbqkb1r/5ppp/p2ppn2/1p4B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+SI.07
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+QI.03
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+QI.02
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/P4N2/1P2PPPP/RNBQKB1R b KQkq -
+QI.04
+rnbqkb1r/p2ppp1p/1p3np1/2p5/3P4/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+RE.04*
+rnbqkb1r/p2ppppp/1p3n2/2p5/2P1P3/2N2N2/PP1P1PPP/R1BQKB1R b KQkq -
+EO.43
+rnbqkb1r/p2ppppp/5n2/1ppP4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+BI.46
+rnbqkb1r/p2ppppp/5n2/1ppP4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+RE.17*
+rnbqkb1r/p4ppp/2p1pn2/1p4B1/2pPP3/2N2N2/PP3PPP/R2QKB1R w KQkq -
+SL.07
+rnbqkb1r/pp1n1ppp/4p3/2ppP3/3P4/2PB4/PP1N1PPP/R1BQK1NR b KQkq -
+FR.17
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+EO.12
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+KP.05*
+rnbqkb1r/pp1p1ppp/4pn2/2pP4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+RE.16*
+rnbqkb1r/pp1p1ppp/4pn2/8/2PN4/6P1/PP2PP1P/RNBQKB1R b KQkq -
+EO.45
+rnbqkb1r/pp1ppp1p/5np1/2p5/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+RE.07*
+rnbqkb1r/pp1ppp1p/5np1/2p5/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+RE.12*
+rnbqkb1r/pp1ppp1p/5np1/2pP4/2P5/8/PP2PPPP/RNBQKBNR b KQkq -
+RE.14*
+rnbqkb1r/pp1ppp1p/5np1/2pP4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+RE.15*
+rnbqkb1r/pp1ppppp/2p2n2/8/2P1P3/2N5/PP1P1PPP/R1BQKBNR b KQkq -
+EO.61
+rnbqkb1r/pp1ppppp/5n2/2P5/8/8/PPP1PPPP/RNBQKBNR b KQkq -
+RE.19*
+rnbqkb1r/pp1ppppp/5n2/2p5/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+OI.06
+rnbqkb1r/pp1ppppp/5n2/2pP4/2P5/8/PP2PPPP/RNBQKBNR b KQkq -
+BI.38
+rnbqkb1r/pp1ppppp/5n2/2pP4/8/2N5/PPP1PPPP/R1BQKBNR b KQkq -
+OI.08
+rnbqkb1r/pp1ppppp/5n2/8/2PN4/8/PP2PPPP/RNBQKB1R b KQkq -
+EO.46
+rnbqkb1r/pp1ppppp/8/3nP3/3p4/2P5/PP3PPP/RNBQKBNR w KQkq -
+SI.47
+rnbqkb1r/pp2p1pp/2pp1n2/5p2/2PP4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+HD.04
+rnbqkb1r/pp2pp1p/2p2p2/8/3P4/8/PPP2PPP/R1BQKBNR w KQkq -
+CK.07
+rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+SI.15
+rnbqkb1r/pp2pp1p/5np1/2pp4/8/BP2PN2/P1PP1PPP/RN1QKB1R b KQkq -
+QI.05*
+rnbqkb1r/pp2pp1p/6p1/2pn4/8/4PN2/PP1P1PPP/RNBQKB1R w KQkq -
+EO.45*
+rnbqkb1r/pp2pppp/2p2n2/3p4/2P5/1P3NP1/P2PPP1P/RNBQKB1R b KQkq -
+RE.04
+rnbqkb1r/pp2pppp/2p2n2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+SL.03
+rnbqkb1r/pp2pppp/5n2/2Pp4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+QG.05*
+rnbqkb1r/pp2pppp/5n2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R b KQkq -
+QI.02*
+rnbqkb1r/pp2pppp/5n2/2pp4/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+QI.01*
+rnbqkb1r/pp2pppp/5n2/3p4/2PP4/2N5/PP3PPP/R1BQKBNR b KQkq -
+CK.03
+rnbqkb1r/pp2pppp/5n2/3p4/3P4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+SL.02*
+rnbqkb1r/pp2pppp/5n2/3p4/3P4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+SL.02
+rnbqkb1r/pp2pppp/8/2pn4/8/2N1P3/PP1P1PPP/R1BQKBNR b KQkq -
+EO.50*
+rnbqkb1r/pp2pppp/8/2pn4/8/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+EO.42
+rnbqkb1r/pp2pppp/8/2pn4/8/2N3P1/PP1PPPBP/R1BQK1NR b KQkq -
+EO.38
+rnbqkb1r/pp2pppp/8/2pn4/8/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+EO.46*
+rnbqkb1r/pp3p1p/3p1np1/2pP2B1/8/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+BI.25
+rnbqkb1r/pp3p1p/3p1np1/2pP4/4PB2/2N5/PP3PPP/R2QKBNR b KQkq -
+BI.35
+rnbqkb1r/pp3p1p/3p1np1/2pP4/8/2N5/PP1NPPPP/R1BQKB1R b KQkq -
+BI.27
+rnbqkb1r/pp3ppp/2p1pn2/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+SL.08
+rnbqkb1r/pp3ppp/2p2p2/8/3P4/8/PPP2PPP/R1BQKBNR w KQkq -
+CK.06
+rnbqkb1r/pp3ppp/3p1n2/2pPp3/2P1P3/2N5/PP3PPP/R1BQKBNR b KQkq -
+OI.05
+rnbqkb1r/pp3ppp/3p1n2/4p3/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+SI.03
+rnbqkb1r/pp3ppp/3ppn2/8/3NP1P1/2N5/PPP2P1P/R1BQKB1R b KQkq -
+SI.20
+rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+SI.19
+rnbqkb1r/pp3ppp/3ppn2/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+SI.21
+rnbqkb1r/pp3ppp/4p3/8/3PP3/5N2/P4PPP/R1BQKB1R b KQkq -
+TD.08
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+QG.08*
+rnbqkb1r/pp3ppp/4pn2/2pP4/3P4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+TD.12
+rnbqkb1r/pp3ppp/4pn2/2pp4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+TD.05
+rnbqkb1r/pp3ppp/4pn2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+QI.03*
+rnbqkb1r/ppn1pppp/8/2p5/8/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+EO.37
+rnbqkb1r/ppp1pp1p/3p1np1/6B1/3PP3/2N5/PPP2PPP/R2QKBNR b KQkq -
+PU.09
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PP3/2N2P2/PPP3PP/R1BQKBNR b KQkq -
+PU.04
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+PU.07
+rnbqkb1r/ppp1pp1p/3p2p1/3nP3/3P4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+AL.04
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+GI.03
+rnbqkb1r/ppp1pp1p/6p1/3n4/8/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+EO.52
+rnbqkb1r/ppp1pp1p/6p1/3n4/8/2N3P1/PP1PPPBP/R1BQK1NR b KQkq -
+EO.53
+rnbqkb1r/ppp1pp1p/6p1/8/3PP3/2P5/P4PPP/R1BQKBNR b KQkq -
+GI.04
+rnbqkb1r/ppp1pppp/1n1P4/8/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+AL.08
+rnbqkb1r/ppp1pppp/1n1p4/4P3/2PP1P2/8/PP4PP/RNBQKBNR b KQkq -
+AL.07
+rnbqkb1r/ppp1pppp/3p1n2/8/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+OI.04
+rnbqkb1r/ppp1pppp/3p1n2/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+PU.08
+rnbqkb1r/ppp1pppp/3p4/3nP3/3P4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+AL.05
+rnbqkb1r/ppp1pppp/5n2/3P4/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+SD.03
+rnbqkb1r/ppp1pppp/5n2/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+QP.06*
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+QG.08
+rnbqkb1r/ppp2ppp/3p1n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+KP.07*
+rnbqkb1r/ppp2ppp/3p4/8/3Pn3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+RG.04
+rnbqkb1r/ppp2ppp/4pn2/3p2B1/3PP3/2N5/PPP2PPP/R2QKBNR b KQkq -
+FR.05
+rnbqkb1r/ppp2ppp/4pn2/3p4/2P1P3/2N5/PP1P1PPP/R1BQKBNR w KQkq -
+EO.57
+rnbqkb1r/ppp2ppp/4pn2/3p4/2P5/5NP1/PP1PPPBP/RNBQK2R b KQkq -
+RE.11
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QO.16
+rnbqkb1r/ppp2ppp/4pn2/3pP3/3P4/8/PPPN1PPP/R1BQKBNR b KQkq -
+FR.16
+rnbqkb1r/ppp2ppp/4pn2/8/2p5/5NP1/PP1PPPBP/RNBQK2R w KQkq -
+RE.10
+rnbqkb1r/ppp2ppp/4pn2/8/2pP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+CA.03
+rnbqkb1r/ppp2ppp/4pn2/8/Q1pP4/6P1/PP2PPBP/RNB1K1NR b KQkq -
+CA.02
+rnbqkb1r/ppp2ppp/5n2/3Pp3/8/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+SO.06*
+rnbqkb1r/ppp2ppp/5n2/3p2B1/3Np3/3P4/PPP1PPPP/RN1QKB1R b KQkq -
+AL.03*
+rnbqkb1r/ppp2ppp/5n2/3p4/3Np3/3P2P1/PPP1PP1P/RNBQKB1R b KQkq -
+AL.04*
+rnbqkb1r/ppp2ppp/5n2/3p4/3Np3/3P4/PPP1PPPP/RNBQKB1R w KQkq -
+AL.05*
+rnbqkb1r/ppp2ppp/5n2/3pN3/4P3/8/PPPP1PPP/RNBQKB1R b KQkq -
+RG.02*
+rnbqkb1r/ppp2ppp/5n2/3pN3/8/3P4/PPP2PPP/RNBQKB1R w KQkq -
+RG.04*
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/3P4/PPP2PPP/RNBQKBNR w KQkq -
+KP.08*
+rnbqkb1r/ppp2ppp/5n2/3pp3/4PP2/2N5/PPPP2PP/R1BQKBNR w KQkq -
+VG.03
+rnbqkb1r/ppp2ppp/8/3np3/2B5/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+SO.05*
+rnbqkb1r/ppp2ppp/8/3np3/8/2N1P3/PP1P1PPP/R1BQKBNR b KQkq -
+SI.39*
+rnbqkb1r/ppp2ppp/8/3np3/8/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+SI.33*
+rnbqkb1r/ppp2ppp/8/3np3/8/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+SI.32*
+rnbqkb1r/ppp2ppp/8/3np3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+SO.04*
+rnbqkb1r/ppp2ppp/8/3np3/8/4P3/PP1P1PPP/RNBQKBNR w KQkq -
+SI.41*
+rnbqkb1r/pppp1ppp/4pn2/6B1/3P4/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+QP.04
+rnbqkb1r/pppp1ppp/4pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+QI.01
+rnbqkb1r/pppp1ppp/4pn2/8/2PP4/6P1/PP2PP1P/RNBQKBNR b KQkq -
+CA.01
+rnbqkb1r/pppp1ppp/4pn2/8/3P1B2/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+QP.05
+rnbqkb1r/pppp1ppp/5n2/4N3/4P3/8/PPPP1PPP/RNBQKB1R b KQkq -
+RG.03
+rnbqkb1r/pppp1ppp/5n2/4p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+VG.02
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+EO.09
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+SI.31*
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+EO.10
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/3P4/PP2PPPP/RNBQKBNR b KQkq -
+SI.01*
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+SI.43*
+rnbqkb1r/pppp1ppp/5n2/4p3/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QG.01
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+VG.01
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+RG.01*
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+RG.01
+rnbqkb1r/pppp1ppp/5n2/4p3/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+KP.09*
+rnbqkb1r/pppp1ppp/5n2/4p3/8/2N5/PPPPPPPP/R1BQKBNR w KQkq -
+VO.05*
+rnbqkb1r/pppp1ppp/8/4P3/6n1/8/PPPPP1PP/RNBQKBNR w KQkq -
+HD.13*
+rnbqkb1r/pppp1ppp/8/4p3/3Pn3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+RG.02
+rnbqkb1r/pppp1ppp/8/4p3/4n3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+RG.03*
+rnbqkb1r/pppp2pp/4pn2/5p2/2PP4/6P1/PP2PPBP/RNBQK1NR b KQkq -
+HD.03
+rnbqkb1r/pppp2pp/5n2/4pP2/6P1/8/PPPP1P1P/RNBQKBNR b KQkq -
+KG.01*
+rnbqkb1r/pppp2pp/5n2/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KG.02*
+rnbqkb1r/ppppp1pp/5n2/5p2/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+HD.05
+rnbqkb1r/ppppp2p/5np1/5p2/2PP4/6P1/PP2PP1P/RNBQKBNR w KQkq -
+HD.08
+rnbqkb1r/pppppp1p/5np1/6B1/3P4/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+QP.02
+rnbqkb1r/pppppp1p/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+GI.01
+rnbqkb1r/pppppp1p/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+KI.80
+rnbqkb1r/pppppppp/5n2/8/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+QP.10*
+rnbqkb1r/pppppppp/5n2/8/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+QP.06
+rnbqkb1r/pppppppp/5n2/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+QP.09*
+rnbqkb1r/pppppppp/5n2/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+QP.07
+rnbqkb1r/pppppppp/5n2/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+AL.10
+rnbqkb1r/pppppppp/5n2/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+QP.11*
+rnbqkb1r/pppppppp/7n/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.16*
+rnbqkb1r/pppppppp/8/3nP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+AL.09
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/3B4/PPP2PPP/RNBQK2R b KQkq -
+SI.42
+rnbqkbnr/1ppppppp/p7/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.14*
+rnbqkbnr/p1pppppp/1p6/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+EO.63
+rnbqkbnr/p1pppppp/1p6/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+VO.01
+rnbqkbnr/p1pppppp/1p6/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.08*
+rnbqkbnr/p1pppppp/8/1p6/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.10*
+rnbqkbnr/pp1p1ppp/2p5/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+SI.46*
+rnbqkbnr/pp1p1ppp/4p3/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+SI.41
+rnbqkbnr/pp1p1ppp/8/2p1p3/4P3/6P1/PPPP1P1P/RNBQKBNR b KQkq -
+EO.62*
+rnbqkbnr/pp1ppp1p/6p1/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+EO.24*
+rnbqkbnr/pp1ppppp/2p5/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+CK.01
+rnbqkbnr/pp1ppppp/2p5/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.12*
+rnbqkbnr/pp1ppppp/8/2p5/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+OI.09
+rnbqkbnr/pp1ppppp/8/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+SI.44
+rnbqkbnr/pp1ppppp/8/2p5/4P3/2P5/PP1P1PPP/RNBQKBNR b KQkq -
+SI.46
+rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+SI.43
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+EO.25*
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+SI.48
+rnbqkbnr/pp1ppppp/8/2p5/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+HD.14*
+rnbqkbnr/pp1ppppp/8/2p5/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+EO.63*
+rnbqkbnr/pp1ppppp/8/2p5/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+QP.10
+rnbqkbnr/pp1ppppp/8/2p5/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+EO.64*
+rnbqkbnr/pp2pp1p/6p1/2pp4/5P2/5NP1/PPPPP2P/RNBQKB1R b KQkq -
+HD.08*
+rnbqkbnr/pp2pp1p/6p1/2pp4/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+CA.01*
+rnbqkbnr/pp2pppp/2p5/3p4/2P5/5NP1/PP1PPP1P/RNBQKB1R b KQkq -
+RE.07
+rnbqkbnr/pp2pppp/2p5/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+SL.01
+rnbqkbnr/pp2pppp/2p5/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+CK.05
+rnbqkbnr/pp2pppp/2p5/3p4/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+CK.02
+rnbqkbnr/pp2pppp/3p4/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+SI.01
+rnbqkbnr/pp2pppp/3p4/8/3QP3/5N2/PPP2PPP/RNB1KB1R b KQkq -
+SI.02
+rnbqkbnr/pp2pppp/8/2Pp4/8/8/PPP1PPPP/RNBQKBNR b KQkq -
+QG.03*
+rnbqkbnr/pp2pppp/8/2p5/1PPp4/5N2/P2PPPPP/RNBQKB1R b KQkq -
+BI.46*
+rnbqkbnr/pp2pppp/8/2p5/2Pp4/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+BI.38*
+rnbqkbnr/pp2pppp/8/2p5/2Pp4/5NP1/PP1PPP1P/RNBQKB1R w KQkq -
+RE.14
+rnbqkbnr/pp2pppp/8/2pp4/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+OI.06*
+rnbqkbnr/pp2pppp/8/2pp4/3P4/2P5/PP2PPPP/RNBQKBNR b KQkq -
+SL.01*
+rnbqkbnr/pp2pppp/8/2pp4/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+QG.02*
+rnbqkbnr/pp2pppp/8/2pp4/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+QG.01*
+rnbqkbnr/pp2pppp/8/2pp4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+HD.10*
+rnbqkbnr/pp2pppp/8/2pp4/8/3P4/PPP1PPPP/RNBQKBNR w KQkq -
+OI.07*
+rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+GI.01*
+rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+KI.80*
+rnbqkbnr/pp2pppp/8/8/1pPp4/P4N2/3PPPPP/RNBQKB1R b KQkq -
+BI.45*
+rnbqkbnr/pp3ppp/2p1p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+SL.06
+rnbqkbnr/pp3ppp/2p5/3P4/3Np3/8/PP1PPPPP/RNBQKB1R b KQkq -
+SI.47*
+rnbqkbnr/pp3ppp/4p3/2pp4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+TD.10
+rnbqkbnr/pp3ppp/4p3/2pp4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+FR.18
+rnbqkbnr/pp3ppp/4p3/8/1pPp4/P4N2/3PPPPP/RNBQKB1R w KQkq -
+BI.43*
+rnbqkbnr/pp3ppp/8/2Ppp3/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+QG.04*
+rnbqkbnr/pp3ppp/8/2pp4/3P4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+TD.11
+rnbqkbnr/pp3ppp/8/2pp4/3P4/5N2/PPPN1PPP/R1BQKB1R b KQkq -
+FR.21
+rnbqkbnr/pp3ppp/8/2pp4/3P4/8/PPPN1PPP/R1BQKBNR w KQkq -
+FR.20
+rnbqkbnr/pp3ppp/8/2pp4/8/1N1p4/PPP1PPPP/RNBQKB1R w KQkq -
+AL.08*
+rnbqkbnr/pp4pp/8/2pp1p2/4p3/1N1P4/PPP1PPPP/RNBQKB1R w KQkq -
+AL.07*
+rnbqkbnr/ppp1pppp/3p4/8/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+OI.07
+rnbqkbnr/ppp1pppp/3p4/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.13*
+rnbqkbnr/ppp1pppp/8/3p4/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+OI.09*
+rnbqkbnr/ppp1pppp/8/3p4/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+QP.08*
+rnbqkbnr/ppp1pppp/8/3p4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+QP.08
+rnbqkbnr/ppp1pppp/8/3p4/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+HD.12*
+rnbqkbnr/ppp1pppp/8/3p4/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+QP.07*
+rnbqkbnr/ppp1pppp/8/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+QP.09
+rnbqkbnr/ppp1pppp/8/3p4/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+QO.17*
+rnbqkbnr/ppp1pppp/8/8/1PPp4/5N2/P2PPPPP/RNBQKB1R b KQkq -
+RE.17
+rnbqkbnr/ppp1pppp/8/8/2Pp4/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+RE.16
+rnbqkbnr/ppp1pppp/8/8/2Pp4/5NP1/PP1PPP1P/RNBQKB1R b KQkq -
+RE.15
+rnbqkbnr/ppp1pppp/8/8/2p5/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+RE.19
+rnbqkbnr/ppp1pppp/8/8/2p5/N4N2/PP1PPPPP/R1BQKB1R b KQkq -
+RE.18
+rnbqkbnr/ppp1pppp/8/8/2pP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+QG.05
+rnbqkbnr/ppp1pppp/8/8/2pP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QG.03
+rnbqkbnr/ppp1pppp/8/8/2pPP3/8/PP3PPP/RNBQKBNR b KQkq -
+QG.04
+rnbqkbnr/ppp2ppp/3p4/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+EO.22
+rnbqkbnr/ppp2ppp/3p4/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+KP.08
+rnbqkbnr/ppp2ppp/3p4/4p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+FR.02*
+rnbqkbnr/ppp2ppp/4p3/3p4/2P5/5NP1/PP1PPP1P/RNBQKB1R b KQkq -
+RE.12
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+FR.04
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/8/PPPN1PPP/R1BQKBNR b KQkq -
+FR.14
+rnbqkbnr/ppp2ppp/4p3/3pP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+FR.03
+rnbqkbnr/ppp2ppp/4p3/8/3PN3/8/PPP2PPP/R1BQKBNR b KQkq -
+FR.07
+rnbqkbnr/ppp2ppp/8/3Pp3/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+KP.04*
+rnbqkbnr/ppp2ppp/8/3p4/3Np3/8/PPPPPPPP/RNBQKB1R w KQkq -
+AL.09*
+rnbqkbnr/ppp2ppp/8/3p4/3Pp3/4P3/PPP2PPP/RNBQKBNR w KQkq -
+FR.03*
+rnbqkbnr/ppp2ppp/8/3p4/3PpB2/2P5/PP2PPPP/RN1QKBNR b KQkq -
+CK.04*
+rnbqkbnr/ppp2ppp/8/3pp3/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QG.02
+rnbqkbnr/ppp2ppp/8/3pp3/3P4/2N5/PPP1PPPP/R1BQKBNR b KQkq -
+VO.06*
+rnbqkbnr/ppp2ppp/8/3pp3/3P4/2P5/PP2PPPP/RNBQKBNR b KQkq -
+CK.02*
+rnbqkbnr/ppp2ppp/8/3pp3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KG.04
+rnbqkbnr/ppp2ppp/8/3pp3/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+HD.11*
+rnbqkbnr/ppp2ppp/8/3pp3/8/3P1N2/PPP1PPPP/RNBQKB1R b KQkq -
+PU.08*
+rnbqkbnr/ppp2ppp/8/3pp3/8/6P1/PPPPPPBP/RNBQK1NR b KQkq -
+KF.05*
+rnbqkbnr/pppp1p1p/6p1/4p3/2P1P3/8/PP1P1PPP/RNBQKBNR w KQkq -
+EO.62
+rnbqkbnr/pppp1p1p/8/6p1/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KG.01
+rnbqkbnr/pppp1ppp/4p3/8/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+FR.02
+rnbqkbnr/pppp1ppp/4p3/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+FR.01
+rnbqkbnr/pppp1ppp/8/4p3/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+IG.04
+rnbqkbnr/pppp1ppp/8/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+EO.23
+rnbqkbnr/pppp1ppp/8/4p3/2P5/6P1/PP1PPP1P/RNBQKBNR b KQkq -
+EO.24
+rnbqkbnr/pppp1ppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+SI.48*
+rnbqkbnr/pppp1ppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+EO.25
+rnbqkbnr/pppp1ppp/8/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+VG.04
+rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+KP.10*
+rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP.10
+rnbqkbnr/pppp1ppp/8/4p3/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+KG.05
+rnbqkbnr/pppp1ppp/8/4p3/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+VO.01*
+rnbqkbnr/pppp1ppp/8/4p3/8/2N5/PPPPPPPP/R1BQKBNR b KQkq -
+VO.04*
+rnbqkbnr/pppp1ppp/8/4p3/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+CK.01*
+rnbqkbnr/pppp1ppp/8/4p3/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+FR.01*
+rnbqkbnr/pppp1ppp/8/4p3/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+AL.10*
+rnbqkbnr/pppp1ppp/8/4p3/8/6P1/PPPPPP1P/RNBQKBNR b KQkq -
+KF.06*
+rnbqkbnr/pppp1ppp/8/4p3/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.17*
+rnbqkbnr/pppp1ppp/8/8/3p4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+SD.03*
+rnbqkbnr/pppp1ppp/8/8/3pP3/8/PPP2PPP/RNBQKBNR w KQkq -
+KP.04
+rnbqkbnr/pppp1ppp/8/8/4Pp2/5N2/PPPP2PP/RNBQKB1R b KQkq -
+KG.02
+rnbqkbnr/pppp1ppp/8/8/4Pp2/8/PPPP2PP/RNBQKBNR w KQkq -
+KG.03
+rnbqkbnr/pppp2pp/8/4pP2/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+KG.03*
+rnbqkbnr/pppp2pp/8/4pp2/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+KG.04*
+rnbqkbnr/pppp2pp/8/4pp2/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+KP.09
+rnbqkbnr/pppp2pp/8/4pp2/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KG.05*
+rnbqkbnr/ppppp1pp/8/5p2/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+HD.14
+rnbqkbnr/ppppp1pp/8/5p2/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+HD.10
+rnbqkbnr/ppppp1pp/8/5p2/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+HD.12
+rnbqkbnr/ppppp1pp/8/5p2/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+HD.11
+rnbqkbnr/ppppp1pp/8/5p2/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.07*
+rnbqkbnr/ppppp1pp/8/6N1/4p3/8/PPPP1PPP/RNBQKB1R b KQkq -
+HD.13
+rnbqkbnr/ppppp2p/6p1/5p2/3P4/6P1/PPP1PPBP/RNBQK1NR b KQkq -
+HD.09
+rnbqkbnr/pppppp1p/6p1/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KF.06
+rnbqkbnr/pppppp1p/6p1/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.09*
+rnbqkbnr/pppppp1p/8/6p1/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.11*
+rnbqkbnr/pppppppp/8/8/1P6/8/P1PPPPPP/RNBQKBNR b KQkq -
+VO.10
+rnbqkbnr/pppppppp/8/8/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+EO.64
+rnbqkbnr/pppppppp/8/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+QO.17
+rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+VO.17
+rnbqkbnr/pppppppp/8/8/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+VO.07
+rnbqkbnr/pppppppp/8/8/6P1/8/PPPPPP1P/RNBQKBNR b KQkq -
+VO.11
+rnbqkbnr/pppppppp/8/8/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+VO.08
+rnbqkbnr/pppppppp/8/8/8/2N5/PPPPPPPP/R1BQKBNR b KQkq -
+VO.15
+rnbqkbnr/pppppppp/8/8/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+VO.12
+rnbqkbnr/pppppppp/8/8/8/3P4/PPP1PPPP/RNBQKBNR b KQkq -
+VO.13
+rnbqkbnr/pppppppp/8/8/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+QP.11
+rnbqkbnr/pppppppp/8/8/8/6P1/PPPPPP1P/RNBQKBNR b KQkq -
+VO.09
+rnbqkbnr/pppppppp/8/8/8/7N/PPPPPPPP/RNBQKB1R b KQkq -
+VO.16
+rnbqkbnr/pppppppp/8/8/8/P7/1PPPPPPP/RNBQKBNR b KQkq -
+VO.14
+rnbqr1k1/1ppp1ppp/1b3n2/p3p3/1P2P3/P1N2N2/2PPBPPP/R1BQ1RK1 w - -
+RL.18*
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N1P/2P1BPP1/R1BQ1RK1 b - -
+RL.22*
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N2/1BP1BPPP/R2Q1RK1 b - -
+RL.26*
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+RL.21*
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P2P1N2/2P1BPPP/RNBQ1RK1 b - -
+RL.25*
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4PP2/2N2N2/PP2B1PP/R1BQK2R w KQ -
+BI.29
+rnbqr1k1/pp3pbp/3p1np1/2pP4/8/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+BI.23
+rnbqr1k1/pp3ppp/1bp2n2/3pp3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+RL.20*
+rnbqr1k1/ppbp1pp1/2p2n1p/4p3/NP2P3/P2P1N2/2P1BPPP/R1BQ1RK1 w - -
+RL.23*
+rnbqr1k1/pppp1ppp/1b3n2/4p3/1P2P3/P1N2N2/2PPBPPP/R1BQK2R w KQ -
+RL.17*
+rnbqr1k1/pppp1ppp/1b3n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQK2R b KQ -
+RL.19*
+rnbqr1k1/pppp1ppp/5n2/b3p3/4P3/P1NP1N2/1PP1BPPP/R1BQK2R b KQ -
+RL.16*
--- /dev/null
+1r1qr1k1/p1n2pbp/bp1p1np1/2pP2B1/P1N1P3/2N2P2/1P2B1PP/R2Q1R1K b - -
+BI.06
+1rbq1rk1/1pp1ppbp/p1np1np1/8/2PP4/2N2NPP/PP2PPB1/R1BQ1RK1 w - -
+KI.70
+1rbq1rk1/1pp1ppbp/p1np1np1/8/2PPP2P/2N1BP2/PPQ1N1P1/R3KB1R b KQ -
+KI.33
+1rbq1rk1/1pp1ppbp/p1np1np1/8/2PPP3/2N1BP2/PP1Q2PP/R1N1KB1R b KQ -
+KI.34
+1rbq1rk1/1pp1ppbp/p1np1np1/8/2PPP3/2N1BP2/PP1QN1PP/R3KB1R w KQ -
+KI.35
+1rbq1rk1/4ppbp/p2p1np1/nppP4/2P5/1PN3P1/PBQNPPBP/R4RK1 b - -
+KI.66
+1rbq1rk1/pp2ppbp/2np1np1/2p5/4P3/2NP1NP1/PPP2PBP/R1BQ1RK1 w - -
+EO.13*
+1rbqk1nr/pp1pppbp/2n3p1/2p5/4P3/2N3P1/PPPP1PBP/R1BQK1NR w KQk -
+EO.15*
+1rbqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NP2P1/PPP2PBP/R1BQK1NR w KQk -
+EO.16*
+1rbqr1k1/1p1n1pbp/p2p1np1/2pP4/P1N5/2N3PP/1P2PPB1/R1BQ1RK1 b - -
+BI.21
+2bq1rk1/1p1nbppp/r1n5/p3p3/2Pp4/P2P1NP1/1P1N1PBP/R1BQR1K1 w - -
+BI.01*
+2kr1b1r/pppq1ppp/2n5/3np3/6b1/2NPPN2/PP2BPPP/R1BQ1RK1 b - -
+SI.28*
+2kr1b1r/pppq1ppp/2n5/3np3/6b1/P1NPPN2/1P1B1PPP/R2QKB1R b KQ -
+SI.30*
+2kr1b1r/pppq1ppp/2n5/3np3/6b1/P1NPPN2/1P3PPP/R1BQKB1R w KQ -
+SI.29*
+2rqkb1r/pp2pppp/2n2n2/2Pp3b/8/4PN1P/PPP1BPP1/RNBQ1RK1 b k -
+QO.07*
+2rqkb1r/pp2pppp/5n2/3p4/3P4/1P5P/P1P1QPP1/RNB2RK1 b k -
+QO.06*
+2rqkb1r/pp3ppp/2n1pn2/2pp3b/3P4/1P2PN1P/PBP1BPP1/RN1Q1RK1 b k -
+QO.09*
+2rqkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w k -
+QO.11*
+3rkb1r/1pq2ppp/p1n1pn2/2p2b2/Q2P4/2N1PN2/PP2BPPP/R1B2RK1 b k -
+QO.02*
+r1b1k2r/ppp2pp1/3q1nn1/3p4/7p/2P4P/PP1NPPP1/R2QKBNR w KQkq -
+CK.12*
+r1b1kb1r/1pq2ppp/p1nppn2/8/3NPP2/2N5/PPP1B1PP/R1BQ1RK1 w kq -
+SI.24
+r1b1kb1r/pp1n1ppp/2p1pn2/q2p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQkq -
+QO.15
+r1b1kb1r/pp2pppp/1qn2n2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+GI.10*
+r1b1kb1r/ppqppppp/2n2n2/1Bp5/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+EO.58*
+r1b1kbnr/1p2pppp/p1q5/2pp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+NI.20*
+r1b1kbnr/pp3ppp/2n5/2p1q3/4p3/2N1P3/PP1P1PPP/R1BQKBNR w KQkq -
+EO.55*
+r1b1kbnr/ppq1pppp/2n5/1Bp5/2p5/4PN2/PP1P1PPP/RNBQ1RK1 b kq -
+NI.21*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+NI.22*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R b KQkq -
+NI.23*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+NI.24*
+r1b1kbnr/ppqp1ppp/2n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+SI.40
+r1b2rk1/1p1nqppp/2n5/p3p3/2Pp4/P2P1NP1/1P3PBP/RN1Q1RK1 w - -
+BI.14*
+r1b2rk1/2q1bppp/p2p1n2/npp1p3/3PP3/2P2N1P/PPBN1PP1/R1BQR1K1 b - -
+RL.24
+r1b2rk1/pp2bppp/2n1pn2/q2p4/2P2B2/P1N1PN2/1PQ2PPP/3RKB1R w K -
+QO.02
+r1b2rk1/pp2ppbp/2n2np1/2pq4/8/1P2PN2/PB1PBPPP/RN1QK2R w KQ -
+EO.39*
+r1b2rk1/pp2ppbp/2q2np1/2pp4/2P5/1P2P3/PB1PBPPP/RN1Q1RK1 b - -
+QI.13*
+r1b2rk1/pp2ppbp/2q2np1/2pp4/5P2/1P2P3/PBPPB1PP/RN1Q1RK1 b - -
+QI.12*
+r1b2rk1/ppq1ppbp/2n2np1/2ppN3/8/1P2P3/PBPPBPPP/RN1Q1RK1 w - -
+QI.11*
+r1b2rk1/ppq2ppp/2n1pn2/2p5/2BP4/P1P1PN2/5PPP/R1BQ1RK1 w - -
+NI.01
+r1bq1rk1/1p1n1pbp/2pp1np1/p3p3/2PPP3/2N2N2/PP3PPP/R1BQRBK1 w - -
+KI.09
+r1bq1rk1/1p1n1pbp/p2p1np1/2pP4/P3P3/2N2N2/1P2BPPP/R1BQ1RK1 w - -
+BI.15
+r1bq1rk1/1p1nb1pp/2n2p2/p3p3/2Pp4/1P1P1NP1/P1N2PBP/R1BQR1K1 b - -
+BI.07*
+r1bq1rk1/1p1nb1pp/2n2p2/p3p3/2Pp4/3P2P1/PPNN1PBP/R1BQR1K1 b - -
+BI.08*
+r1bq1rk1/1p1nb1pp/2n5/p3pp2/2Pp4/P2P1NP1/1P1N1PBP/R1BQR1K1 w - -
+BI.02*
+r1bq1rk1/1p1nbppp/2n5/p3p3/2Pp4/P2P1NP1/1P1N1PBP/R1BQR1K1 b - -
+BI.03*
+r1bq1rk1/1p1nbppp/2n5/p3p3/2PpN3/3P1NP1/PP3PBP/R1BQR1K1 b - -
+BI.04*
+r1bq1rk1/1p1nppbp/2n3p1/p7/2Pp4/P2P1NP1/1P1N1PBP/R1BQR1K1 b - -
+BI.22*
+r1bq1rk1/1p2bppp/2n2n2/p3p3/2Pp4/P2P1NP1/1P1N1PBP/R1BQ1RK1 b - -
+BI.15*
+r1bq1rk1/1p2ppb1/2n3pp/p1n5/2Pp4/P2P1NP1/1P1N1PBP/1RBQR1K1 w - -
+BI.21*
+r1bq1rk1/1p3pp1/2n2b1p/p3p3/2Pp4/P2P1NP1/1P1N1PBP/R2Q1RK1 b - -
+BI.10*
+r1bq1rk1/1p3ppp/2n1pn2/pBbp4/5B2/2P1PN2/PP3PPP/RN1QK2R w KQ -
+SL.05*
+r1bq1rk1/1p3ppp/p1nbpn2/1Bpp4/2PP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+NI.02*
+r1bq1rk1/1pp1ppbp/p1np1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+KI.71
+r1bq1rk1/2p1bpp1/p1np1n1p/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+RL.22
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/3PP3/1BP2N2/PP3PPP/RNBQR1K1 b - -
+RL.20
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 b - -
+RL.21
+r1bq1rk1/2p1bppp/p2p1n2/np2p3/4P3/2P2N1P/PPBP1PP1/RNBQR1K1 b - -
+RL.23
+r1bq1rk1/2ppbppp/p1n2n2/1p2p3/P3P3/1B3N2/1PPP1PPP/RNBQR1K1 b - -
+RL.18
+r1bq1rk1/3nppbp/p1pp1np1/1p6/2PPP3/2NBBP2/PP2N1PP/R2Q1RK1 w - -
+KI.46
+r1bq1rk1/5ppp/p1p1pn2/2bp4/2P5/2N1PN2/PPQ2PPP/R1B2RK1 b - -
+NI.01*
+r1bq1rk1/p1p2ppp/5n2/3p2B1/1b6/2NB4/PPP2PPP/R2Q1RK1 b - -
+SO.03
+r1bq1rk1/p3bp1p/2n2np1/1pp1p3/3pPP1N/3P2P1/PPP1N1BP/R1BQ1RK1 b - -
+KI.04*
+r1bq1rk1/p3bppp/2n2n2/1pp1p3/3pP3/3P1NP1/PPP1NPBP/R1BQ1RK1 w - -
+KI.05*
+r1bq1rk1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N1BP2/PP1QN1PP/R3KB1R w KQ -
+KI.42
+r1bq1rk1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N2N2/PP3PPP/R1BQRBK1 b - -
+KI.10
+r1bq1rk1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N2NP1/PP3PBP/R1BQ1RK1 w - -
+KI.63
+r1bq1rk1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N2NPP/PP3PB1/R1BQ1RK1 b - -
+KI.62
+r1bq1rk1/pp1n1ppp/4pn2/2p5/1bBP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+NI.03
+r1bq1rk1/pp1nbppp/2n5/2p1p3/3pP3/3P1NP1/PPP1NPBP/R1BQ1RK1 w - -
+KI.07*
+r1bq1rk1/pp1nbppp/2n5/4p3/2Pp4/3P1NP1/PP1N1PBP/R1BQR1K1 b - -
+BI.05*
+r1bq1rk1/pp1nbppp/2n5/4p3/2Pp4/N2P1NP1/PP3PBP/R1BQR1K1 b - -
+BI.09*
+r1bq1rk1/pp1pppbp/2n2np1/1Bp5/4P3/2N2N2/PPPP1PPP/R1BQ1RK1 w - -
+EO.01*
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/1P2PN2/PB1PBPPP/RN1QK2R b KQ -
+EO.40*
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/1P3NP1/PB1PPPBP/RN1QK2R b KQ -
+EO.48*
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 b - -
+EO.27*
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w - -
+EO.27
+r1bq1rk1/pp1pppbp/2n2np1/8/2PN4/2N1P3/PP2BPPP/R1BQK2R b KQ -
+EO.41*
+r1bq1rk1/pp1pppbp/2n2np1/8/2PN4/2N3P1/PP2PPBP/R1BQ1RK1 b - -
+EO.26
+r1bq1rk1/pp2bppp/2n1p3/2pn4/3PP3/2N2NP1/PP3PBP/R1BQ1RK1 b - -
+TD.02
+r1bq1rk1/pp2bppp/2n2n2/2p1p3/3pP3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+KI.12*
+r1bq1rk1/pp2bppp/2n2n2/2pp2B1/3P4/2N2NP1/PP2PPBP/R2Q1RK1 b - -
+TD.03
+r1bq1rk1/pp2bppp/2n2n2/2pp4/3P4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+TD.04
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 w - -
+KI.15*
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 b - -
+KI.14*
+r1bq1rk1/pp2bppp/2n2n2/4p1B1/2Pp4/3P1NP1/PP3PBP/RN1Q1RK1 b - -
+BI.16*
+r1bq1rk1/pp2bppp/2n5/2pp4/3P4/5NP1/PP2PPBP/R1BQ1RK1 w - -
+TD.01
+r1bq1rk1/pp2bppp/2nn4/2p1p3/3pPP2/3P2P1/PPPNN1BP/R1BQ1RK1 b - -
+KI.01*
+r1bq1rk1/pp2bppp/2nppn2/6B1/3NP3/2N5/PPPQ1PPP/2KR1B1R w - -
+SI.28
+r1bq1rk1/pp2nppp/2nb4/4p3/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 w - -
+BI.36*
+r1bq1rk1/pp2ppb1/2n2npp/2pp4/8/P1NP1NP1/1PP1PPBP/1RBQ1RK1 b - -
+KI.70*
+r1bq1rk1/pp2ppbp/2n2np1/2p5/2P5/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+KI.68*
+r1bq1rk1/pp2ppbp/2n2np1/2p5/2P5/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+KI.68
+r1bq1rk1/pp2ppbp/2n2np1/2p5/N1Pp4/3P1NP1/PP2PPBP/R1BQ1RK1 b - -
+KI.67*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 w - -
+KI.69*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 b - -
+KI.65*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/1P2PN2/PBPPBPPP/RN1Q1RK1 w - -
+QI.09*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/2NP1NP1/PPP1PPBP/R1BQ1RK1 w - -
+KI.72*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/2PP1NP1/PP2PPBP/RNBQ1RK1 w - -
+KI.75*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/P1NP1NP1/1PP1PPBP/R1BQ1RK1 b - -
+KI.71*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/Q7/2PP1NP1/PP2PPBP/RNB2RK1 b - -
+KI.74*
+r1bq1rk1/pp2ppbp/2n2np1/2ppN3/8/1P2P3/PBPPBPPP/RN1Q1RK1 b - -
+QI.10*
+r1bq1rk1/pp2ppbp/2n2np1/3p4/2PP4/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+TD.04*
+r1bq1rk1/pp2ppbp/2n2np1/8/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 w - -
+BI.24*
+r1bq1rk1/pp2ppbp/2n2np1/8/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 b - -
+BI.23*
+r1bq1rk1/pp2ppbp/2n3p1/2pn4/8/2N2NP1/PP1PPPBP/R1BQ1RK1 w - -
+EO.26*
+r1bq1rk1/pp2ppbp/2n3p1/8/2BPP3/4B3/P3NPPP/R2Q1RK1 b - -
+GI.06
+r1bq1rk1/pp2ppbp/2np1np1/8/2BNP3/2N1BP2/PPPQ2PP/R3K2R b KQ -
+SI.18
+r1bq1rk1/pp2ppbp/3p1np1/n1pP4/2P5/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+KI.67
+r1bq1rk1/pp2ppbp/5np1/3p4/2PP4/2N5/PP2BPPP/R1BQ1RK1 b - -
+TD.01*
+r1bq1rk1/pp3pb1/2n2npp/2ppp3/4P3/2PP1NP1/PP1N1PBP/R1BQ1RK1 w - -
+KI.62*
+r1bq1rk1/pp3pb1/2n2npp/2ppp3/4P3/2PP1NP1/PP1N1PBP/R1BQR1K1 b - -
+KI.61*
+r1bq1rk1/pp3pbp/2n2np1/2ppp3/4P3/2PP1NP1/PP1N1PBP/R1BQ1RK1 b - -
+KI.63*
+r1bq1rk1/pp3pbp/2n2np1/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+KI.64*
+r1bq1rk1/pp3pbp/2n2np1/3pp3/2PN4/2N1P3/PP2BPPP/R1BQ1RK1 w - -
+TD.02*
+r1bq1rk1/pp3ppp/2n1pn2/1Bbp4/2P5/4PN2/PP1N1PPP/R1BQ1RK1 b - -
+NI.03*
+r1bq1rk1/pp3ppp/2n1pn2/2pp4/1bPP4/P1NBPN2/1P3PPP/R1BQ1RK1 b - -
+NI.02
+r1bq1rk1/pp3ppp/2n2n2/1Bbp4/8/1P2PN2/P4PPP/RNBQ1RK1 b - -
+NI.04*
+r1bq1rk1/pp3ppp/2nbpn2/1Bpp4/2PP4/4PN2/PP3PPP/RNBQ1RK1 w - -
+NI.05*
+r1bq1rk1/ppp1b1pp/2n5/3npp2/8/P1NPPN2/1PQ2PPP/R1B1KB1R b KQ -
+SI.24*
+r1bq1rk1/ppp1bppp/2n2n2/3pp1B1/8/3P1NP1/PPP1PPBP/RN1Q1RK1 b - -
+PU.01*
+r1bq1rk1/ppp1n1bp/3p2p1/3Ppp1n/1PP1P3/2N2NP1/P3BP1P/R1BQ1RK1 w - -
+KI.04
+r1bq1rk1/ppp1npbp/3p1np1/3Pp3/1PP1P3/2N2N2/P3BPPP/R1BQ1RK1 b - -
+KI.05
+r1bq1rk1/ppp1npbp/3p1np1/3Pp3/2P1P3/2N2N2/PP1BBPPP/R2Q1RK1 b - -
+KI.06
+r1bq1rk1/ppp1npbp/3p1np1/3Pp3/2P1P3/2N5/PP1NBPPP/R1BQ1RK1 b - -
+KI.07
+r1bq1rk1/ppp1npbp/3p1np1/3Pp3/2P1P3/2N5/PP2BPPP/R1BQNRK1 b - -
+KI.03
+r1bq1rk1/ppp1ppbp/2np1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+KI.72
+r1bq1rk1/ppp1ppbp/2np1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+KI.73
+r1bq1rk1/ppp1ppbp/2np1np1/8/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+KI.36
+r1bq1rk1/ppp2pbp/2np1np1/4p3/2P5/2NP1NP1/PP2PPBP/1RBQ1RK1 b - -
+EO.13
+r1bq1rk1/ppp2pbp/2np1np1/4p3/2PPP3/2N1BN2/PP2BPPP/R2Q1RK1 b - -
+KI.08
+r1bq1rk1/ppp2ppp/1n3n2/8/1b1P4/2NB4/PP2NPPP/R1BQK2R b KQ -
+FR.23*
+r1bq1rk1/pppn1pbp/3p1np1/3Pp3/2P1P3/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+KI.12
+r1bq1rk1/pppn1pbp/3p1np1/3Pp3/2P1P3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+KI.16
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+KI.65
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N1BN2/PP2BPPP/R2Q1RK1 b - -
+KI.13
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+KI.14
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQR1K1 b - -
+KI.11
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2NP1/PP3PBP/R1BQ1RK1 b - -
+KI.64
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/2RQKB1R b K -
+QO.11
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QO.12
+r1bq1rk1/pppnn1bp/3p2p1/3Ppp2/2P1P3/2N2P2/PP2B1PP/R1BQNRK1 w - -
+KI.02
+r1bq1rk1/pppnn1bp/3p2p1/3Ppp2/2P1P3/2NN4/PP2BPPP/R1BQ1RK1 w - -
+KI.01
+r1bq1rk1/pppnppbp/3p1np1/8/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+KI.48
+r1bq1rk1/pppp1ppp/2n2n2/4p3/1bP5/2N2NP1/PP1PPPBP/R1BQ1RK1 b - -
+EO.01
+r1bqk1nr/1p3ppp/p1nbp3/1Bpp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 w kq -
+NI.08*
+r1bqk1nr/p4ppp/2p5/2bpp3/8/6P1/PPP1PPBP/RNBQK2R w KQkq -
+GI.05*
+r1bqk1nr/pp1n1ppp/2pb4/3p4/2PPp3/4P3/PP1N1PPP/RNBQKB1R w KQkq -
+FR.17*
+r1bqk1nr/pp1p1pbp/2n1p1p1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+EO.29*
+r1bqk1nr/pp1p1pbp/2n3p1/2p1p3/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+EO.30*
+r1bqk1nr/pp1p1pbp/2n3p1/2p1p3/4P3/2NP2P1/PPP2PBP/R1BQK1NR b KQkq -
+EO.18*
+r1bqk1nr/pp1pppbp/2n3p1/1Bp5/4P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+EO.11*
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P1P3/2N3P1/PP1P1PBP/R1BQK1NR b KQkq -
+EO.30
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N1P1P1/PP1P1PBP/R1BQK1NR b KQkq -
+EO.29
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+EO.28
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR b KQkq -
+EO.31*
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+EO.31
+r1bqk1nr/pp1pppbp/2n3p1/2p5/4P3/5NP1/PPPP1PBP/RNBQK2R b KQkq -
+EO.14*
+r1bqk1nr/pp1pppbp/2n3p1/8/2P5/8/PPN1PPPP/RNBQKB1R b KQkq -
+EO.37*
+r1bqk1nr/pp1pppbp/2n3p1/8/2PN4/2N5/PP2PPPP/R1BQKB1R w KQkq -
+EO.35
+r1bqk1nr/pp1pppbp/2n3p1/8/2PN4/8/PP2PPPP/RNBQKB1R w KQkq -
+EO.38*
+r1bqk1nr/pp1pppbp/2n3p1/8/3N4/6P1/PPP1PP1P/RNBQKB1R w KQkq -
+EO.53*
+r1bqk1nr/pp2bppp/2n5/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+KI.27*
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NP2P1/PPP2PBP/R1BQK1NR w KQkq -
+SI.45
+r1bqk1nr/pp3pbp/2n1p1p1/2pp4/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+KI.78*
+r1bqk1nr/pp3pbp/2n3p1/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+KI.29*
+r1bqk1nr/pp4pp/2n5/4pp2/1bPp4/3P2P1/PP1N1PBP/RNBQK2R b KQkq -
+BI.33*
+r1bqk1nr/pp4pp/2nb4/2p1pp2/2Pp4/3P1NP1/PP2PPBP/RNBQ1RK1 w kq -
+KI.60*
+r1bqk1nr/ppp1ppbp/2np2p1/8/2PPP3/2N5/PP3PPP/R1BQKBNR w KQkq -
+KF.03
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P1P3/2N3P1/PP1P1PBP/R1BQK1NR w KQkq -
+EO.18
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P5/2N1P1P1/PP1PNPBP/R1BQK2R b KQkq -
+EO.17
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P5/2NP2P1/PP2PPBP/1RBQK1NR b Kkq -
+EO.16
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR b KQkq -
+SI.45*
+r1bqk1nr/ppp2ppp/8/2bpn3/8/2P5/PP1NPPPP/R1BQKBNR w KQkq -
+CK.09*
+r1bqk1nr/pppn1pbp/3p2p1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQK2R b KQkq -
+KF.01
+r1bqk1nr/pppnppbp/3p2p1/8/2PPP3/2N5/PP3PPP/R1BQKBNR w KQkq -
+KF.02
+r1bqk1nr/pppp1pbp/2n3p1/4p3/2P5/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+EO.19
+r1bqk1nr/pppp1pbp/2n3p1/4p3/2P5/2N3P1/PP1PPPBP/1RBQK1NR b Kkq -
+EO.15
+r1bqk1nr/pppp1ppp/2n5/2b1p3/1PB1P3/5N2/P1PP1PPP/RNBQK2R b KQkq -
+IG.05
+r1bqk1nr/pppp1ppp/2n5/2b1p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+IG.02
+r1bqk1nr/pppp1ppp/2n5/2b1p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+VG.02*
+r1bqk1nr/pppp1ppp/2n5/2b5/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+SO.05
+r1bqk2r/1p4pp/2nb1n2/p3pp2/2Pp4/P2P2P1/1P1N1PBP/RNBQ1RK1 w kq -
+BI.32*
+r1bqk2r/1pp1bppp/p1np1n2/4p3/B3P3/5N2/PPPP1PPP/RNBQR1K1 w kq -
+RL.16
+r1bqk2r/1pppbppp/p1B2n2/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+RL.14
+r1bqk2r/1pppbppp/p1n2n2/4p3/B2PP3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+RL.15
+r1bqk2r/1pppbppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+RL.13
+r1bqk2r/2p1bppp/p1np1n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQR1K1 w kq -
+RL.19
+r1bqk2r/2ppbppp/p1n2n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQR1K1 b kq -
+RL.17
+r1bqk2r/p4ppp/2pbpn2/2pp4/2P5/2NPPN2/PP3PPP/R1BQK2R b KQkq -
+NI.14*
+r1bqk2r/pp1pnpbp/2n1p1p1/2p5/4P3/2NP2P1/PPP2PBP/R1BQK1NR w KQkq -
+EO.17*
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+EO.28*
+r1bqk2r/pp1pppbp/2n2np1/2p5/4P3/2N3P1/PPPP1PBP/R1BQK1NR w KQkq -
+EO.19*
+r1bqk2r/pp1pppbp/2n2np1/8/2P5/2N5/PPN1PPPP/R1BQKB1R b KQkq -
+EO.36*
+r1bqk2r/pp1pppbp/2n2np1/8/3N4/6P1/PPP1PPBP/RNBQK2R w KQkq -
+EO.51*
+r1bqk2r/pp1pppbp/2n2np1/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+EO.03*
+r1bqk2r/pp2b1pp/2n2n2/2p1pp2/2Pp4/3PPNP1/PP3PBP/RNBQ1RK1 w kq -
+KI.57*
+r1bqk2r/pp2b1pp/2n2n2/2p2p2/2PPp3/3P1NP1/PP3PBP/RNBQ1RK1 w kq -
+KI.56*
+r1bqk2r/pp2b1pp/2n2n2/4pp2/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 b kq -
+BI.29*
+r1bqk2r/pp2b1pp/2n2n2/4ppB1/2Pp4/3P1NP1/PP3PBP/RN1Q1RK1 b kq -
+BI.30*
+r1bqk2r/pp2b1pp/2n5/2pnpp2/8/3P1NP1/PP2PPBP/RNBQ1RK1 w kq -
+KI.59*
+r1bqk2r/pp2bppp/2n1p3/2pn4/8/2N2NP1/PP1PPPBP/R1BQ1RK1 w kq -
+EO.41
+r1bqk2r/pp2bppp/2n2n2/2p1p3/3pP3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+KI.17*
+r1bqk2r/pp2bppp/2n2n2/2p1p3/3pP3/3P1NP1/PPPN1PBP/R1BQ1RK1 b kq -
+KI.16*
+r1bqk2r/pp2bppp/2n2n2/2ppp3/4P3/3P1N2/PPPNBPPP/R1BQK2R w KQkq -
+OI.01*
+r1bqk2r/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 b kq -
+KI.18*
+r1bqk2r/pp2bppp/2n2n2/2ppp3/4P3/3P2P1/PPPN1PBP/R1BQK1NR w KQkq -
+KF.01*
+r1bqk2r/pp2bppp/2n2n2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+KI.19*
+r1bqk2r/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+BI.17*
+r1bqk2r/pp2npbp/2n3p1/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+KI.28*
+r1bqk2r/pp2nppp/2n1p3/2ppP3/3P4/P1P2N2/2P2PPP/R1BQKB1R w KQkq -
+FR.13
+r1bqk2r/pp2nppp/2nb4/1B1p4/8/1N3N2/PPP2PPP/R1BQ1RK1 w kq -
+FR.23
+r1bqk2r/pp2nppp/2nbp3/1Bpp4/2PP4/4PN2/PP3PPP/RNBQ1RK1 b kq -
+NI.09*
+r1bqk2r/pp2ppbp/2n2np1/2pp4/8/2NP1NP1/PPP1PPBP/R1BQ1RK1 b kq -
+KI.73*
+r1bqk2r/pp3ppp/2n1pn2/2bp4/1P6/2P1PN2/P2N1PPP/R1BQKB1R b KQkq -
+SL.09*
+r1bqk2r/pp3ppp/2nbpn2/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQ1RK1 w kq -
+NI.07*
+r1bqk2r/pp3ppp/2nbpn2/1Bpp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 w kq -
+NI.06*
+r1bqk2r/pp3ppp/2nbpn2/3p4/2PN4/2N1P3/PP3PPP/R1BQKB1R w KQkq -
+TD.07*
+r1bqk2r/pp3ppp/2nppn2/2p5/2PP4/2PBPN2/P4PPP/R1BQK2R w KQkq -
+NI.14
+r1bqk2r/ppp1bppp/1nn5/4p3/4P3/P2P1N2/1P2BPPP/RNBQK2R b KQkq -
+SI.11*
+r1bqk2r/ppp1bppp/2n2n2/3pp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+PU.03*
+r1bqk2r/ppp1bppp/2n5/3np3/8/2NPPN2/PP3PPP/R1BQKB1R b KQkq -
+SI.22*
+r1bqk2r/ppp1bppp/2n5/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+SI.10*
+r1bqk2r/ppp1bppp/2n5/3np3/8/P2PPN2/1P3PPP/RNBQKB1R b KQkq -
+SI.23*
+r1bqk2r/ppp1bppp/2n5/3p4/3Pn3/3B1N2/PPP2PPP/RNBQ1RK1 w kq -
+RG.06
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/2NPPN2/PP3PPP/R1BQKB1R b KQkq -
+SI.26*
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+SI.13*
+r1bqk2r/ppp3pp/2nb1n2/3ppp2/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+PU.02*
+r1bqk2r/pppnbppp/3p1n2/4p3/2PPP3/2N2N2/PP2BPPP/R1BQK2R b KQkq -
+OI.01
+r1bqk2r/pppp1ppp/2n2n2/3Np3/1bP5/5NP1/PP1PPP1P/R1BQKB1R b KQkq -
+EO.02
+r1bqk2r/pppp1ppp/2n2n2/4p3/1b1PP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+SO.01
+r1bqk2r/pppp1ppp/2n2n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+KP.03*
+r1bqk2r/pppp1ppp/2n2n2/4p3/1bP5/2N1PN2/PP1P1PPP/R1BQKB1R w KQkq -
+EO.05
+r1bqkb1r/1p1n1ppp/p2ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+SI.06
+r1bqkb1r/1p2pppp/2n2n2/p1Pp4/5B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+SL.04*
+r1bqkb1r/1p3ppp/p1np1n2/1N2p1B1/4P3/2N5/PPP2PPP/R2QKB1R w KQkq -
+SI.36
+r1bqkb1r/1p3ppp/p1nppn2/6B1/3NP3/2N5/PPPQ1PPP/2KR1B1R b kq -
+SI.29
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+RL.12
+r1bqkb1r/1ppp1ppp/p1n5/4p3/B3n3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+RL.27
+r1bqkb1r/2p2ppp/p1p2n2/3p4/2PPp3/2N1P3/PP2NPPP/R1BQK2R b KQkq -
+FR.13*
+r1bqkb1r/2p2ppp/p1p2n2/3p4/2PPp3/4P3/PP2NPPP/RNBQK2R w KQkq -
+FR.12*
+r1bqkb1r/5p1p/p1np4/1p1Npp2/4P3/N7/PPP2PPP/R2QKB1R w KQkq -
+SI.38
+r1bqkb1r/5ppp/p1np1n2/1p2p1B1/4P3/N1N5/PPP2PPP/R2QKB1R w KQkq -
+SI.37
+r1bqkb1r/p2n1ppp/2p1pn2/1p6/2BP4/2N1PN2/PP3PPP/R1BQK2R w KQkq -
+SL.09
+r1bqkb1r/p4ppp/5n2/3pp3/8/4P3/PP3PPP/RNBQKB1R w KQkq -
+TD.08*
+r1bqkb1r/pp1npppp/2n5/8/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+BI.27*
+r1bqkb1r/pp1npppp/2n5/8/2Pp4/B2P1NP1/4PP1P/RN1QKB1R w KQkq -
+BI.40*
+r1bqkb1r/pp1p1ppp/2n1pn2/1Bp5/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+EO.05*
+r1bqkb1r/pp1p1ppp/2n1pn2/1N6/2P5/2N5/PP2PPPP/R1BQKB1R b KQkq -
+EO.33
+r1bqkb1r/pp1p1ppp/2n1pn2/2p5/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+EO.34*
+r1bqkb1r/pp1p1ppp/2n1pn2/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+EO.06*
+r1bqkb1r/pp1p1ppp/2n1pn2/8/2PN4/2N3P1/PP2PP1P/R1BQKB1R b KQkq -
+EO.32
+r1bqkb1r/pp1p1ppp/2n2n2/2p1p3/2P5/1P3N2/P2PPPPP/RNBQKB1R w KQkq -
+EO.43*
+r1bqkb1r/pp1p1ppp/2n2n2/2p1p3/8/1P2PN2/PBPP1PPP/RN1QKB1R b KQkq -
+EO.60*
+r1bqkb1r/pp1p1ppp/2n2n2/4p3/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+SI.35
+r1bqkb1r/pp1ppp1p/2n2np1/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+EO.04*
+r1bqkb1r/pp1ppp1p/5np1/1Bp5/3nP3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+EO.02*
+r1bqkb1r/pp1ppppp/2n2n2/1Bp5/8/4PN2/PPPP1PPP/RNBQK2R b KQkq -
+EO.59*
+r1bqkb1r/pp1ppppp/2n2n2/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+EO.21*
+r1bqkb1r/pp1ppppp/2n2n2/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+EO.09*
+r1bqkb1r/pp1ppppp/2n2n2/8/2PN4/8/PP2PPPP/RNBQKB1R b KQkq -
+EO.42*
+r1bqkb1r/pp1ppppp/2n2n2/8/3N4/6P1/PPP1PP1P/RNBQKB1R b KQkq -
+EO.52*
+r1bqkb1r/pp1ppppp/2n2n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+SI.34
+r1bqkb1r/pp1ppppp/n4n2/2P5/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+RE.18*
+r1bqkb1r/pp2n1pp/2n2p2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+KI.52*
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+NI.16*
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/8/1P2PN2/P1PP1PPP/RNBQK2R w KQkq -
+NI.13*
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+NI.10*
+r1bqkb1r/pp2pp1p/2n2np1/2pp4/4P3/3P1N2/PPPN1PPP/R1BQKB1R w KQkq -
+OI.02*
+r1bqkb1r/pp2pp1p/2n2np1/3p4/2PP4/2N5/PP3PPP/R1BQKBNR w KQkq -
+TD.09*
+r1bqkb1r/pp2pp1p/2n2np1/8/2Pp4/B2P1NP1/4PP1P/RN1QKB1R w KQkq -
+BI.39*
+r1bqkb1r/pp2pp1p/2n3p1/2pn4/8/2N1PN2/PP1P1PPP/R1BQKB1R w KQkq -
+EO.32*
+r1bqkb1r/pp2pppp/2n2n2/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R b KQkq -
+NI.27*
+r1bqkb1r/pp2pppp/2n2n2/1Bpp4/8/1P2PN2/P1PP1PPP/RNBQK2R b KQkq -
+NI.26*
+r1bqkb1r/pp2pppp/2n2n2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+NI.28*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/2PP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+TD.05*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+SL.03*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R b KQkq -
+GI.07*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+EO.08*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/8/3P1NP1/PPP1PPBP/RNBQK2R b KQkq -
+KI.76*
+r1bqkb1r/pp2pppp/2n2n2/3p4/2PP4/8/PP3PPP/RNBQKBNR w KQkq -
+TD.11*
+r1bqkb1r/pp2pppp/2n2n2/3p4/2Pp4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+TD.12*
+r1bqkb1r/pp2pppp/2n5/1Bpn4/8/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+EO.44*
+r1bqkb1r/pp2pppp/2n5/2n5/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+BI.26*
+r1bqkb1r/pp2pppp/2n5/2p5/1n6/2N1PN2/PP1P1PPP/R1BQKB1R w KQkq -
+EO.33*
+r1bqkb1r/pp2pppp/2n5/2pn4/8/2N3P1/PP1PPPBP/R1BQK1NR b KQkq -
+EO.35*
+r1bqkb1r/pp2pppp/2n5/2pn4/8/5NP1/PP1PPPBP/RNBQK2R w KQkq -
+EO.49
+r1bqkb1r/pp2pppp/2np1n2/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+EO.07*
+r1bqkb1r/pp2pppp/2np1n2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R b KQkq -
+SI.27
+r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+SI.25
+r1bqkb1r/pp3pp1/2n2n1p/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+KI.20*
+r1bqkb1r/pp3ppp/2n1p3/2pn4/3P4/2NBPN2/PP3PPP/R1BQK2R b KQkq -
+TD.07
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/2P5/5NP1/PP1PPPBP/RNBQ1RK1 b kq -
+KI.77*
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/2P1PN2/PP3PPP/RNBQKB1R w KQkq -
+SL.08*
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 b kq -
+GI.09*
+r1bqkb1r/pp3ppp/2n1pn2/3p4/2PP4/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+TD.06*
+r1bqkb1r/pp3ppp/2n2n2/2pp4/3P4/2N1PN2/PP3PPP/R1BQKB1R w KQkq -
+TD.06
+r1bqkb1r/pp3ppp/2n2n2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 b kq -
+KI.21*
+r1bqkb1r/pp3ppp/2n2n2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+KI.22*
+r1bqkb1r/pp3ppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQK2R b KQkq -
+BI.20*
+r1bqkb1r/pp3ppp/2n5/2pn4/4N3/4P3/PP1P1PPP/R1BQKBNR b KQkq -
+EO.54*
+r1bqkb1r/pp3ppp/2nppn2/8/2BNP3/2N5/PPP2PPP/R1BQK2R w KQkq -
+SI.26
+r1bqkb1r/pp3ppp/2nppn2/8/3NP3/2N5/PPP1BPPP/R1BQK2R w KQkq -
+SI.22
+r1bqkb1r/pp4pp/2n2n2/2p1pp2/1PPp4/3P1NP1/P3PPBP/RNBQ1RK1 b kq -
+KI.55*
+r1bqkb1r/pp4pp/2n2n2/2p1pp2/2P5/3PBNP1/PP3PBP/RN1Q1RK1 b kq -
+KI.58*
+r1bqkb1r/pp4pp/2n2n2/4pp2/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+BI.31*
+r1bqkb1r/ppn1pppp/2n5/2p5/8/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+EO.36
+r1bqkb1r/ppp2p1p/2n5/3np1p1/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+SI.20*
+r1bqkb1r/ppp2ppp/2n2n2/1B1pp3/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+SO.01*
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/8/3P1NP1/PPP1PPBP/RNBQK2R b KQkq -
+PU.10*
+r1bqkb1r/ppp2ppp/2n5/3np3/4P3/2N2N2/PP1P1PPP/R1BQKB1R b KQkq -
+SI.35*
+r1bqkb1r/ppp2ppp/2n5/3np3/4P3/3P1N2/PP3PPP/RNBQKB1R b KQkq -
+SI.03*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N1P3/PPQP1PPP/R1B1KBNR b KQkq -
+SI.40*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+SI.34*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+EO.03
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2NP1N2/PP2PPPP/R1BQKB1R b KQkq -
+SI.25*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3P1NP1/PP2PP1P/RNBQKB1R b KQkq -
+SI.15*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3PPN2/PP3PPP/RNBQKB1R b KQkq -
+SI.19*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R b KQkq -
+SI.14*
+r1bqkb1r/ppp2ppp/5n2/3Pp3/3n4/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+SO.02*
+r1bqkb1r/ppp2ppp/5n2/3pn3/8/2P5/PP1NPPPP/R1BQKBNR w KQkq -
+CK.08*
+r1bqkb1r/ppp3pp/2n2n2/3ppp2/8/3P1NP1/PPP1PPBP/RNBQ1RK1 b kq -
+PU.06*
+r1bqkb1r/ppp3pp/2n5/3npp2/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+SI.21*
+r1bqkb1r/ppp3pp/2n5/3npp2/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+SI.12*
+r1bqkb1r/pppn1ppp/3p1n2/4p1B1/2PP4/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+OI.03
+r1bqkb1r/pppn1ppp/3p1n2/4p3/2PP4/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+OI.02
+r1bqkb1r/pppn1ppp/5n2/3p4/2PP4/2N5/PP3PPP/R1BQKBNR b KQkq -
+FR.22*
+r1bqkb1r/pppn1ppp/5n2/3p4/2PP4/8/PP3PPP/RNBQKBNR w KQkq -
+FR.21*
+r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+KP.03
+r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+RL.07
+r1bqkb1r/pppp1ppp/2n2n2/3N4/3pP3/5N2/PPP2PPP/R1BQKB1R b KQkq -
+SO.02
+r1bqkb1r/pppp1ppp/2n2n2/4p1N1/2B1P3/8/PPPP1PPP/RNBQK2R b KQkq -
+KP.01
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+IG.01
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N1PN2/PP1P1PPP/R1BQKB1R b KQkq -
+EO.06
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N2NP1/PP1PPP1P/R1BQKB1R b KQkq -
+EO.04
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2NP1N2/PP2PPPP/R1BQKB1R b KQkq -
+EO.07
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+EO.08
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+KP.06*
+r1bqkb1r/pppp1ppp/2n2n2/8/2BpP3/5N2/PPP2PPP/RNBQK2R w KQkq -
+KP.02
+r1bqkb1r/ppppnppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+RL.04
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+RL.11
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+RL.10
+r1bqkbnr/1ppp1ppp/p1B5/4p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+RL.08
+r1bqkbnr/1ppp1ppp/p1n5/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+RL.09
+r1bqkbnr/2p2ppp/p1p5/3p4/2PPp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+FR.11*
+r1bqkbnr/4pppp/p1p5/2pp4/2P5/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+NI.19*
+r1bqkbnr/4pppp/p1p5/2pp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+NI.18*
+r1bqkbnr/p4ppp/2p5/2pp4/8/4PQ2/PPP2PPP/RNB1KB1R w KQkq -
+EO.56*
+r1bqkbnr/p4ppp/2p5/3pp3/8/6P1/PPP1PP1P/RNBQKB1R w KQkq -
+GI.04*
+r1bqkbnr/pp1npppp/2p5/8/2BPN3/8/PPP2PPP/R1BQK1NR b KQkq -
+CK.09
+r1bqkbnr/pp1npppp/2p5/8/3PN3/5N2/PPP2PPP/R1BQKB1R b KQkq -
+CK.08
+r1bqkbnr/pp1p1ppp/2n1p3/4P3/2P1Q3/2N5/PP3PPP/R1B1KBNR b KQkq -
+EO.55
+r1bqkbnr/pp1p1ppp/2n1p3/8/2PN4/8/PP2PPPP/RNBQKB1R w KQkq -
+EO.50
+r1bqkbnr/pp1p1ppp/2n1p3/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+SI.39
+r1bqkbnr/pp1p1ppp/2n5/2p1p3/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+EO.57*
+r1bqkbnr/pp1p1ppp/2n5/2p1p3/8/2P2N2/PP1PPPPP/RNBQKB1R w KQkq -
+EO.61*
+r1bqkbnr/pp1p1ppp/4p3/4n3/2PN4/2N5/PP3PPP/R1BQKB1R w KQkq -
+EO.54
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/2P5/2N1PN2/PP1P1PPP/R1BQKB1R b KQkq -
+EO.34
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+EO.20*
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/2P2N2/PP1P1PPP/RNBQKB1R b KQkq -
+EO.12*
+r1bqkbnr/pp1ppp1p/2n3p1/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+SI.33
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+EO.22*
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+EO.10*
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+SI.31
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+EO.23*
+r1bqkbnr/pp1ppppp/2n5/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+SI.32
+r1bqkbnr/pp2pp1p/2n3p1/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+NI.29*
+r1bqkbnr/pp2pppp/2n5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R b KQkq -
+NI.30*
+r1bqkbnr/pp2pppp/2n5/2pp4/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+TD.10*
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/2P1P3/PP3PPP/RNBQKBNR b KQkq -
+SL.06*
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+QO.16*
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+GI.03*
+r1bqkbnr/pp2pppp/2n5/2pp4/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+HD.05*
+r1bqkbnr/pp2pppp/2n5/2pp4/8/3P1N2/PPP1PPPP/RNBQKB1R w KQkq -
+OI.04*
+r1bqkbnr/pp2pppp/2n5/8/1pPp4/P4N2/3PPPPP/RNBQKB1R w KQkq -
+BI.44*
+r1bqkbnr/pp2pppp/2n5/8/2Pp4/B4NP1/3PPP1P/RN1QKB1R b KQkq -
+BI.41*
+r1bqkbnr/pp3pp1/2n4p/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 b kq -
+KI.30*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+NI.15*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/1P2PN2/P1PP1PPP/RNBQK2R b KQkq -
+NI.12*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 b kq -
+NI.11*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+NI.17*
+r1bqkbnr/pp3ppp/2n5/2p1p3/2Pp4/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+RE.13
+r1bqkbnr/pp3ppp/2n5/2p1p3/2PpP3/3P1N2/PP3PPP/RNBQKB1R w KQkq -
+OI.05*
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+TD.09
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+CK.03*
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/5N2/PPPN1PPP/R1BQKB1R w KQkq -
+FR.22
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/2NP2P1/PPP1PPBP/R1BQK1NR b KQkq -
+KF.03*
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R b KQkq -
+KI.31*
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/3P2P1/PPP1PPBP/RNBQK1NR w KQkq -
+KF.04*
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/3P2P1/PPPNPPBP/R1BQK1NR b KQkq -
+KF.02*
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/5NP1/PPPPPPBP/RNBQ1RK1 b kq -
+KI.32*
+r1bqkbnr/pp4pp/2n2p2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+KI.54*
+r1bqkbnr/pp4pp/2n2p2/2ppp3/8/P2P1NP1/1PP1PPBP/RNBQK2R b KQkq -
+KI.53*
+r1bqkbnr/pp4pp/2n5/5p2/2Ppp3/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+BI.34*
+r1bqkbnr/ppp1pppp/2n5/3p4/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+VO.06
+r1bqkbnr/ppp1pppp/2n5/8/2Pp4/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+OI.08*
+r1bqkbnr/ppp2pp1/6n1/3p3p/8/2P3B1/PP2PPPP/RN1QKBNR w KQkq -
+CK.11*
+r1bqkbnr/ppp2ppp/2n1p3/3p4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+FR.15
+r1bqkbnr/ppp2ppp/2n5/1B1p4/2PPp3/4P3/PP3PPP/RNBQK1NR b KQkq -
+FR.10*
+r1bqkbnr/ppp2ppp/2n5/1B1p4/3Pp3/4P3/PPP2PPP/RNBQK1NR w KQkq -
+FR.09*
+r1bqkbnr/ppp2ppp/2n5/1B1pp3/3P4/4P3/PPP2PPP/RNBQK1NR b KQkq -
+FR.08*
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+CK.05*
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+FR.04*
+r1bqkbnr/ppp2ppp/2n5/3pp3/8/3P1NP1/PPP1PP1P/RNBQKB1R b KQkq -
+PU.07*
+r1bqkbnr/ppp2ppp/2np4/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+RL.02
+r1bqkbnr/ppp2ppp/8/3p4/8/2P2P2/PP2PP1P/RNBQKB1R b KQkq -
+CK.07*
+r1bqkbnr/ppp2ppp/8/3p4/8/2P2P2/PP3PPP/RNBQKB1R b KQkq -
+CK.06*
+r1bqkbnr/ppp2ppp/8/3pn3/5B2/2P5/PP2PPPP/RN1QKBNR b KQkq -
+CK.10*
+r1bqkbnr/ppp2ppp/8/3pn3/8/4P3/PPP2PPP/RNBQKBNR w KQkq -
+FR.07*
+r1bqkbnr/ppp3pp/2n2p2/3pp3/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+PU.04*
+r1bqkbnr/ppp3pp/2n5/3ppp2/8/3P1NP1/PPP1PPBP/RNBQK2R b KQkq -
+PU.05*
+r1bqkbnr/pppn1ppp/8/3p4/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+FR.20*
+r1bqkbnr/pppn1ppp/8/3p4/2PQ4/4P3/PP3PPP/RNB1KBNR b KQkq -
+FR.19*
+r1bqkbnr/pppn1ppp/8/3p4/3Pp3/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+FR.16*
+r1bqkbnr/pppn1ppp/8/3pp3/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+FR.18*
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/2N1P3/PPP2PPP/R1BQKBNR b KQkq -
+FR.15*
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+FR.14*
+r1bqkbnr/pppp1p1p/2n3p1/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+RL.03
+r1bqkbnr/pppp1p1p/2n3p1/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+VG.01*
+r1bqkbnr/pppp1ppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+RL.01
+r1bqkbnr/pppp1ppp/2n5/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+IG.03
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+EO.21
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+EO.20
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+SI.44*
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+KP.06
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2P2N2/PP1P1PPP/RNBQKB1R b KQkq -
+KP.05
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+KP.07
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+VG.04*
+r1bqkbnr/pppp1ppp/2n5/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+SO.04
+r1bqkbnr/pppp1ppp/2n5/8/3Q4/8/PPP1PPPP/RNB1KBNR w KQkq -
+SD.02*
+r1bqkbnr/pppp1ppp/2n5/8/3pP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+SO.06
+r1bqkbnr/pppp1ppp/2n5/8/Q7/8/PPP1PPPP/RNB1KBNR b KQkq -
+SD.01*
+r1bqkbnr/pppp1ppp/8/1B2p3/3nP3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+RL.05
+r1bqkbnr/pppp2pp/2n5/1B2pp2/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+RL.06
+r1bqkbnr/pppp2pp/2n5/4pp2/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+VG.03*
+r1bqkbnr/pppppppp/2n5/8/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+VO.05
+r1bqkbnr/pppppppp/2n5/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+VO.04
+r1bqkbnr/pppppppp/2n5/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.15*
+r1bqnrk1/pp2b1pp/2n2p2/2p1p3/3pPP2/3P2P1/PPPNN1BP/R1BQ1RK1 b - -
+KI.02*
+r1bqnrk1/pp2bppp/2n5/2p1p3/3pP3/3P1NP1/PPP1NPBP/R1BQ1RK1 w - -
+KI.03*
+r1bqr1k1/1p1n1pbp/p2p1np1/2pP4/P3P3/2N5/1P1NBPPP/R1BQ1RK1 w - -
+BI.03
+r1bqr1k1/1p1n1pbp/p2p1np1/2pP4/P3P3/R1N5/1P1NBPPP/2BQ1RK1 b - -
+BI.01
+r1bqr1k1/1p1n1pbp/p2p1np1/2pP4/P3PP2/2N5/1P1NB1PP/R1BQ1RK1 b - -
+BI.02
+r1bqr1k1/1p1n1pbp/p2p1np1/2pP4/P7/2N3P1/1P1NPPBP/R1BQ1RK1 w - -
+BI.22
+r1bqr1k1/p1n2pbp/1p1p1np1/2pP4/P3P3/2N2P2/1P1NB1PP/R1BQ1RK1 w - -
+BI.07
+r1bqr1k1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N2NPP/PP3PB1/R1BQ1RK1 w - -
+KI.61
+r1bqr1k1/pp1n1pbp/3p1np1/2pP4/4P3/2N5/PP1NBPPP/R1BQ1RK1 w - -
+BI.05
+r1bqr1k1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+KI.11*
+r1bqr1k1/pp3pbp/3p1np1/2pPn3/P3P3/2N5/1P1NBPPP/R1BQ1RK1 w - -
+BI.04
+r1bqr1k1/pp3pbp/n2p1np1/2pP4/4P3/2N5/PP1NBPPP/R1BQ1RK1 w - -
+BI.09
+r1bqr1k1/ppbn1pp1/2p2n1p/3pp3/NPP1P3/P2P1N2/2Q1BPPP/R1B2RK1 w - -
+RL.24*
+r1bqr1k1/ppnn1pbp/3p2p1/2pP4/P3P3/2N2P2/1P1NB1PP/R1BQ1RK1 w - -
+BI.08
+r1bqrbk1/pp3ppp/2n2n2/2ppp3/4P3/2PP1NP1/PP1N1PBP/R1BQ1RK1 w - -
+KI.10*
+r1bqrbk1/pp3ppp/2n2n2/2ppp3/P3P3/2PP1NP1/1P1N1PBP/R1BQ1RK1 b - -
+KI.09*
+r1n1kb1r/pp1q2pp/2n1bp2/2ppp3/8/P1NP1NP1/1PP1PPBP/1RBQ1RK1 w kq -
+KI.34*
+r2q1r1k/1p2b1pp/2n2p2/p1n1p3/2Pp2b1/BP1P1NP1/P1N2PBP/1R1QR1K1 w - -
+BI.06*
+r2q1rk1/1bp1bppp/p1np1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+RL.26
+r2q1rk1/1p1n1pbp/p2p1np1/2pP4/P3P3/2N2B1P/1P3PP1/R1BQ1RK1 w - -
+BI.10
+r2q1rk1/1p2bppp/2n2n2/p3p1B1/2Pp2b1/P2P1NP1/1P3PBP/RN1Q1RK1 w - -
+BI.13*
+r2q1rk1/1p2bppp/2n2n2/p3pbB1/2Pp4/P2P1NP1/1P3PBP/RN1Q1RK1 w - -
+BI.12*
+r2q1rk1/1p2bppp/2n2n2/p3pbB1/2Pp4/P2P1NP1/1P3PBP/RN1QR1K1 b - -
+BI.11*
+r2q1rk1/p3nppp/4b3/2bpp3/8/2N3P1/PP2PPBP/R1BQ1RK1 w - -
+GI.06*
+r2q1rk1/pp1bbppp/2n2n2/2p1p3/3pP3/3P1NP1/PPP1NPBP/R1BQ1RK1 w - -
+KI.06*
+r2q1rk1/pp2bppp/2n1bn2/2ppp3/4P3/2NP1NP1/PPP2PBP/R1BQ1RK1 w - -
+KI.08*
+r2q1rk1/pp2bppp/2n1bn2/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+KI.13*
+r2q1rk1/pp2n1pp/2nbbp2/2ppp3/1P6/P1PP1NP1/3NPPBP/R1BQ1RK1 b - -
+KI.46*
+r2q1rk1/pp2ppbp/2n2np1/3p4/2PP2b1/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+TD.03*
+r2q1rk1/ppp2ppp/2nb4/1B6/3P2b1/5N2/P1P2PPP/R1BQ1RK1 w - -
+SO.03*
+r2qk1nr/pp2bppp/2n5/2p1p3/2Pp2b1/3P1NPP/PP2PPB1/RNBQ1RK1 b kq -
+KI.23*
+r2qk1nr/pp2bppp/2n5/2p1p3/2Pp2b1/3PPNP1/PP3PBP/RNBQ1RK1 b kq -
+KI.24*
+r2qk1nr/pp2bppp/2n5/2ppp3/2P3b1/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+KI.25*
+r2qk1nr/pp2bppp/2n5/2ppp3/6b1/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+KI.26*
+r2qk1nr/pp4pp/2nbbp2/2p1p3/1P1pP3/2PP1NP1/P4PBP/RNBQ1RK1 b kq -
+KI.38*
+r2qk1nr/pp4pp/2nbbp2/4p3/3pP3/3P1NP1/PP3PBP/RNBQ1RK1 w kq -
+KI.37*
+r2qk2r/2p2ppp/p1n1b3/1pbpP3/4n3/1BP2N2/PP3PPP/RNBQ1RK1 w kq -
+RL.30
+r2qk2r/pp2b1pp/2n2n2/6N1/2Ppp1b1/1Q4P1/PP3PBP/RNB1R1K1 b kq -
+BI.28*
+r2qk2r/pp2n1pp/2nbbp2/2pp4/2P1p3/PP1P1NP1/4PPBP/RNBQ1RK1 w kq -
+KI.44*
+r2qkb1r/1p1b1ppp/p1nppn2/6B1/3NP3/2N5/PPPQ1PPP/2KR1B1R w kq -
+SI.30
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1B3N2/PPP1QPPP/RNB2RK1 b kq -
+RL.28
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP3PPP/RNBQ1RK1 b kq -
+RL.29
+r2qkb1r/pp1n1ppp/2n5/4p2b/2Pp4/P2P1NPP/1P3PB1/RNBQK2R w KQkq -
+BI.18*
+r2qkb1r/pp1n1ppp/2p1pn2/3p1b2/2P5/1P3NP1/PB1PPPBP/RN1Q1RK1 b kq -
+RE.02
+r2qkb1r/pp1n1ppp/2p1pn2/3p4/2P3b1/1P3NP1/PB1PPPBP/RN1Q1RK1 b kq -
+RE.01
+r2qkb1r/pp2n1pp/2n1bp2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+KI.43*
+r2qkb1r/pp2pppp/2n2n2/2pp4/3P2b1/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+GI.08*
+r2qkb1r/pp2pppp/2n2n2/2pp4/4P1b1/3P1N2/PPPN1PPP/R1BQKB1R w KQkq -
+OI.03*
+r2qkb1r/pp2pppp/2n2n2/8/2Pp2b1/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+BI.25*
+r2qkb1r/pp3ppp/2n1pn2/2pp1b2/2PP4/4PN2/PP2BPPP/RNBQ1RK1 b kq -
+QO.03*
+r2qkb1r/pp3ppp/2n1pn2/2pp1b2/3P4/4PN2/PPP1BPPP/RNBQ1RK1 w kq -
+QO.04*
+r2qkb1r/pp3ppp/2n1pn2/2pp3b/3P4/1P2PN1P/P1P1BPP1/RNBQ1RK1 b kq -
+QO.10*
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 b kq -
+QO.12*
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P4/4PB1P/PPP2PP1/RNBQ1RK1 b kq -
+QO.14*
+r2qkb1r/pp3ppp/2n1pn2/2pp4/Q2P2b1/2P1PN2/PP1N1PPP/R1B1KB1R b KQkq -
+QO.15*
+r2qkb1r/pp3ppp/2n1pn2/3p4/3P4/1P3B1P/P1P2PP1/RNBQ1RK1 b kq -
+QO.08*
+r2qkb1r/pp3ppp/2n1pn2/5b2/2Bp4/4PN2/PP3PPP/RNBQ1RK1 w kq -
+QO.01*
+r2qkb1r/pp3ppp/2n2n2/2Ppp3/1P4b1/2P1PN2/P4PPP/RNBQKB1R b KQkq -
+SL.07*
+r2qkb1r/pp3ppp/2n2n2/4p3/2Pp2b1/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+BI.19*
+r2qkb1r/pp4pp/2n1bn2/2pp4/4pB2/1NN1P3/PPP2PPP/R2QKB1R w KQkq -
+AL.06*
+r2qkb1r/ppp2ppp/1nn1p3/4Pb2/2PP4/2N1BN2/PP4PP/R2QKB1R b KQkq -
+AL.06
+r2qkb1r/ppp2ppp/2n1b3/3np3/8/3P1NP1/PP2PPBP/RNBQK2R b KQkq -
+SI.16*
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+SI.27*
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+SI.04*
+r2qkb1r/ppp2ppp/2n5/4p3/1n2P1b1/P1NP1N2/1P3PPP/R1BQKB1R b KQkq -
+SI.36*
+r2qkb1r/ppp2ppp/n1n5/4p3/1P2P1b1/P1NP1N2/5PPP/R1BQKB1R b KQkq -
+SI.37*
+r2qkb1r/ppp2ppp/n7/4p3/1P1nPP2/P1NP4/5P1P/R1BQKB1R b KQkq -
+SI.38*
+r2qkb1r/ppp3pp/2n1bp2/3np3/8/3P1NP1/PP2PPBP/RNBQK2R w KQkq -
+SI.17*
+r2qkb1r/ppp3pp/2n5/3npp2/1P4b1/P2PPN2/5PPP/RNBQKB1R b KQkq -
+SI.07*
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/P2PPN2/1P1N1PPP/R1BQKB1R b KQkq -
+SI.06*
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/P2PPN2/1P2BPPP/RNBQK2R b KQkq -
+SI.09*
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/P2PPN2/1PQ2PPP/RNB1KB1R b KQkq -
+SI.05*
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/PQ1PPN2/1P3PPP/RNB1KB1R b KQkq -
+SI.08*
+r2qkbnr/pp1nppp1/2p4p/7P/3P4/3Q1NN1/PPP2PP1/R1B1K2R b KQkq -
+CK.12
+r2qkbnr/pp2pppp/2n5/1Bpp4/6b1/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+NI.25*
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+QO.13*
+r2qkbnr/pp2pppp/2n5/3p1b2/3P4/2P5/PP2BPPP/RNBQK1NR b KQkq -
+QO.05*
+r2qkbnr/pp3ppp/2n5/4pb2/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+BI.35*
+r2qkbnr/pp4pp/2n1bp2/2p1p3/3pP3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+KI.41*
+r2qkbnr/pp4pp/2n1bp2/2ppp3/8/1P1P1NP1/P1P1PPBP/RNBQ1RK1 b kq -
+KI.45*
+r2qkbnr/pp4pp/2n1bp2/2ppp3/8/2NP1NP1/PPP1PPBP/R1BQ1RK1 b kq -
+KI.36*
+r2qkbnr/pp4pp/2n1bp2/2ppp3/8/3P1NP1/PPPNPPBP/R1BQ1RK1 b kq -
+KI.48*
+r2qkbnr/pp4pp/2n2p2/2p1p3/2Pp2b1/3P1NP1/PP2PPBP/RNBQ1RK1 w kq -
+KI.50*
+r2qkbnr/pp4pp/2n2p2/2ppp3/6b1/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+KI.51*
+r2qkbnr/pp4pp/2n2p2/4p3/2Pp2b1/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+BI.37*
+r2qkbnr/ppp2ppp/2n5/3pp3/3P2b1/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+FR.06*
+r2qkbnr/ppp2ppp/2n5/3pp3/3P2b1/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+FR.05*
+r2qkbnr/ppp2ppp/2n5/3pp3/6b1/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+PU.09*
+r3k2r/pppq2pp/2n1bp2/2bnp3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w kq -
+SI.18*
+r3kb1r/pp1qn1pp/2n1bp2/2ppp3/4P3/2PP1NP1/PP1N1PBP/R1BQ1RK1 b kq -
+KI.42*
+r3kb1r/pp1qn1pp/2n1bp2/2ppp3/8/P1NP1NP1/1PP1PPBP/1RBQ1RK1 b kq -
+KI.35*
+r3kb1r/pp3ppp/1qn1bn2/3pp1B1/8/6P1/PPPNPPBP/RN1Q1RK1 w kq -
+GI.11*
+r3kb1r/ppq1n1p1/2n1bp2/2ppp2p/8/P1NP1NP1/1PP1PPBP/1RBQ1RK1 w kq -
+KI.33*
+r3kbnr/pp1q2pp/2n1bp2/2p1p3/3pP2N/3P2P1/PPP2PBP/RNBQ1RK1 w kq -
+KI.40*
+r3kbnr/pp1q2pp/2n1bp2/2ppp3/8/P2P1NP1/1PP1PPBP/RNBQ1RK1 w kq -
+KI.47*
+r3kbnr/pp1q2pp/2n1bp2/4p3/3pP3/3P1NP1/PP3PBP/RNBQ1RK1 w kq -
+KI.39*
+r3kbnr/pp1q2pp/2n2p2/2p1p3/2Pp2b1/3PPNP1/PP3PBP/RNBQ1RK1 w kq -
+KI.49*
+r4rk1/pbqnppbp/1pn3p1/2p5/NPPp4/P2P1NP1/4PPBP/1RBQ1RK1 w - -
+KI.66*
+rn1q1rk1/1p3pbp/p2p1np1/2pP2B1/P3P1b1/2N2N2/1P2BPPP/R2Q1RK1 b - -
+BI.13
+rn1q1rk1/1p3pbp/p2p1np1/2pP4/P3P3/2N5/1P1NQPPP/R1B2RK1 b - -
+BI.14
+rn1q1rk1/1p3pbp/p2p1np1/2pP4/P3PBb1/2N2N2/1P2BPPP/R2Q1RK1 b - -
+BI.12
+rn1q1rk1/pb1p1pbp/1p2pnp1/2p5/3P4/1P2PN2/PBP1BPPP/RN1Q1RK1 w - -
+RE.08*
+rn1q1rk1/pb1pbppp/1p2p3/2p5/2PP4/2Q2NP1/PP2PPBP/R1B2RK1 w - -
+QI.13
+rn1q1rk1/pb1pppbp/1p3np1/2p3B1/3P4/2P1PN2/PP1N1PPP/R2QKB1R w KQ -
+RE.01*
+rn1q1rk1/pb1pppbp/1p3np1/2p5/2P5/1P3NP1/PB1PPPBP/RN1Q1RK1 b - -
+EO.47*
+rn1q1rk1/pb1pppbp/1p3np1/2p5/2P5/1P3NP1/PB1PPPBP/RN1Q1RK1 w - -
+EO.47
+rn1q1rk1/pb1pppbp/1p3np1/2p5/3P1B2/2P1PN2/PP1N1PPP/R2QKB1R w KQ -
+RE.02*
+rn1q1rk1/pbp1bpp1/1p2pn1p/3p4/2PP3B/2N1PN2/PP3PPP/2RQKB1R w K -
+QO.09
+rn1q1rk1/pbp1bppp/1p2pn2/3p4/2P5/1P2PNP1/PB1P1PBP/RN1Q1RK1 b - -
+RE.08
+rn1q1rk1/pbppb1pp/1p2p3/5p2/2PP4/2Q2NP1/PP2PPBP/R1B2RK1 w - -
+QI.12
+rn1q1rk1/pbppbppp/1p2p3/8/2PPn3/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+QI.10
+rn1q1rk1/pbppbppp/1p2p3/8/2PPn3/2N2NP1/PPQ1PPBP/R1B2RK1 b - -
+QI.11
+rn1q1rk1/pbppbppp/1p2pn2/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+QI.09
+rn1q1rk1/pbppbppp/1p3n2/3p4/2P5/5NP1/PP2PPBP/RNBQ1RK1 w - -
+QI.08
+rn1q1rk1/pp3pbp/3p1np1/2pP4/4P1b1/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+BI.16
+rn1q1rk1/pp3pbp/3p1np1/2pP4/4PPb1/2N2N2/PP2B1PP/R1BQK2R w KQ -
+BI.30
+rn1q1rk1/pp3pbp/3pbnp1/2p5/2P1PP2/2N2N2/PP4PP/R1BQKB1R w KQ -
+KI.58
+rn1q1rk1/ppp1ppbp/3p1np1/8/3PP1b1/2N2N2/PPP1BPPP/R1BQ1RK1 w - -
+PU.01
+rn1q1rk1/pppnppbp/6p1/8/3PP1b1/1QN1BN2/PP3PPP/R3KB1R b KQ -
+GI.11
+rn1qk2r/pb1pbppp/1p2pn2/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w kq -
+EO.40
+rn1qk2r/pb1pbppp/1p2pn2/8/2PQ4/2N2NP1/PP2PPBP/R1B2RK1 b kq -
+EO.39
+rn1qk2r/pb1pppbp/1p3np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w kq -
+EO.48
+rn1qk2r/pb1pppbp/1p3np1/2p5/3P4/2P2NP1/PP2PPBP/RNBQK2R w KQkq -
+RE.03*
+rn1qk2r/pbppbppp/1p2pn2/8/2PP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+QI.07
+rn1qk2r/pp3ppp/2p1pn2/5b2/PbBP4/2N1PN2/1P3PPP/R1BQ1RK1 b kq -
+SL.05
+rn1qk2r/ppp1bppp/1n1pp3/4P2b/2PP4/5N1P/PP2BPP1/RNBQ1RK1 w kq -
+AL.01
+rn1qkb1r/3ppp1p/b4np1/2pP4/8/2N5/PP2PPPP/R1BQKBNR w KQkq -
+BI.41
+rn1qkb1r/4pp1p/b2p1np1/2pP4/8/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+BI.39
+rn1qkb1r/4pp1p/b2p1np1/2pP4/8/2N5/PP1NPPPP/R1BQKB1R b KQkq -
+BI.40
+rn1qkb1r/4pp1p/b2p1np1/2pP4/8/6P1/PP2PPBP/RNBQK1NR w KQkq -
+BI.42
+rn1qkb1r/p1pp1ppp/bp2pn2/8/2PP4/5NP1/PP2PP1P/RNBQKB1R w KQkq -
+QI.05
+rn1qkb1r/pbpp1ppp/1p2pn2/8/2P1P3/2N2N2/PP1P1PPP/R1BQKB1R w KQkq -
+EO.60
+rn1qkb1r/pbpp1ppp/1p2pn2/8/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+QI.06
+rn1qkb1r/pp2pppp/2p2n2/3p1b2/2P5/5NP1/PP1PPPBP/RNBQK2R w KQkq -
+RE.06
+rn1qkb1r/pp2pppp/2p2n2/3p4/2P3b1/5NP1/PP1PPPBP/RNBQK2R w KQkq -
+RE.05
+rn1qkb1r/pp2pppp/2p2n2/5b2/P1pP4/2N2N2/1P2PPPP/R1BQKB1R w KQkq -
+SL.04
+rn1qkb1r/ppp1pppp/3p4/3nP3/3P2b1/5N2/PPP2PPP/RNBQKB1R w KQkq -
+AL.03
+rn1qkb1r/ppp1pppp/5n2/3p1b2/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+QP.05*
+rn1qkb1r/ppp1pppp/5n2/3p1b2/8/5NP1/PPPPPPBP/RNBQK2R b KQkq -
+QP.03*
+rn1qkb1r/ppp1pppp/5n2/3p4/6b1/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+QP.04*
+rn1qkb1r/ppp1pppp/5n2/3p4/6b1/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+QP.02*
+rn1qkb1r/ppp1pppp/5n2/3p4/6b1/5NP1/PPPPPPBP/RNBQK2R b KQkq -
+QP.01*
+rn1qkb1r/ppp2ppp/3pp3/3nP3/3P2b1/5N2/PPP1BPPP/RNBQK2R w KQkq -
+AL.02
+rn1qkb1r/ppp2ppp/4pn2/8/2BP2b1/4PN2/PP3PPP/RNBQK2R w KQkq -
+QG.06
+rn1qkbnr/pbpp1ppp/1p2p3/8/3PP3/3B4/PPP2PPP/RNBQK1NR w KQkq -
+VO.03
+rn1qkbnr/pbpppppp/1p6/8/3PP3/3B4/PPP2PPP/RNBQK1NR b KQkq -
+VO.02
+rn1qkbnr/pp2pppp/2p3b1/8/3P3P/6N1/PPP2PP1/R1BQKBNR b KQkq -
+CK.11
+rn1qkbnr/pp2pppp/2p5/3pPb2/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+CK.04
+rn1qkbnr/pp2pppp/2p5/5b2/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+CK.10
+rn1qr1k1/1p3pbp/p2p1np1/2pP4/P3PBb1/2N2N2/1P2BPPP/R2Q1RK1 w - -
+BI.11
+rnb1k1nr/pp2ppbp/6p1/q1Pp4/8/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+CA.02*
+rnb1kb1r/1p3ppp/pq1ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+SI.08
+rnb1kb1r/1pq2ppp/p2ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+SI.05
+rnb1kb1r/ppp2ppp/4pq2/8/2PP4/2P5/P4PPP/R1BQKBNR b KQkq -
+EO.56
+rnb1kb1r/ppp2ppp/5n2/3qp3/8/3P4/PP2PPPP/RNBQKBNR w KQkq -
+SI.02*
+rnb1kbnr/pp3ppp/4p3/2pq4/3P4/8/PPPN1PPP/R1BQKBNR w KQkq -
+FR.19
+rnb1kbnr/ppp1pppp/8/3q4/8/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+SD.02
+rnb1kbnr/ppp1pppp/8/q7/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+SD.01
+rnb1r1k1/pp3pbp/1q4p1/2pPP1B1/6n1/2N2N2/PP2B1PP/R2QK2R w KQ -
+BI.28
+rnb2rk1/p1p1qpp1/1p5p/3p4/3P4/5N2/PP2PPPP/2RQKB1R w K -
+QO.06
+rnb2rk1/pp2ppbp/2pp1np1/q7/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+KI.74
+rnb2rk1/ppp1qppp/1b3n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R w KQ -
+RL.28*
+rnbq1rk1/1p1n1pbp/p2p2p1/2pP4/P3PP2/2NB1N2/1P4PP/R1BQK2R b KQ -
+BI.32
+rnbq1rk1/1pp1ppbp/p2p1np1/8/2PPP3/2N1BP2/PP1Q2PP/R3KBNR b KQ -
+KI.47
+rnbq1rk1/2p1bppp/p2p1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+RL.25
+rnbq1rk1/4ppbp/pp1p1np1/2p1P3/2PP4/2NBBP2/PP2N1PP/R2QK2R b KQ -
+KI.44
+rnbq1rk1/p1p1bpp1/1p2pn1p/3p4/2PP3B/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QO.10
+rnbq1rk1/p1p1ppbp/1p1p1np1/8/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+KI.45
+rnbq1rk1/p1p2pp1/1p3b1p/3p4/3P4/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QO.08
+rnbq1rk1/p2pppbp/1p3np1/2p5/3P4/4PN2/PPP1BPPP/RNBQ1RK1 w - -
+RE.09*
+rnbq1rk1/p3ppbp/3p1np1/1ppP4/2P1PP2/2N2N2/PP4PP/R1BQKB1R w KQ -
+KI.55
+rnbq1rk1/p4pbp/2pp1np1/1p1Pp3/2P1P3/2NBBP2/PP4PP/R2QK1NR w KQ -
+KI.38
+rnbq1rk1/p4ppp/1p2pn2/8/1bBP4/2N2N2/PP3PPP/R1BQ1RK1 w - -
+NI.04
+rnbq1rk1/pp1p1ppp/4pn2/2P5/1bP5/2N5/PPQ1PPPP/R1B1KBNR w KQ -
+NI.21
+rnbq1rk1/pp1p1ppp/4pn2/2p5/1bPP4/2NBPN2/PP3PPP/R1BQK2R b KQ -
+NI.07
+rnbq1rk1/pp1pppbp/5np1/2p5/2PP4/2N1PN2/PP3PPP/R1BQKB1R w KQ -
+KI.77
+rnbq1rk1/pp2bpp1/5n1p/2pp4/4p2B/1N1PP3/PPP1BPPP/RN1QK2R b KQ -
+AL.01*
+rnbq1rk1/pp2bppp/4pn2/2pp4/2PP1B2/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QO.03
+rnbq1rk1/pp2ppb1/3p1npp/2pP2B1/2P1P3/2N5/PP2BPPP/R2QK1NR w KQ -
+KI.23
+rnbq1rk1/pp2ppbp/2pp1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+KI.75
+rnbq1rk1/pp2ppbp/3p1np1/2p3B1/2PPP3/2N5/PP2BPPP/R2QK1NR w KQ -
+KI.25
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+KI.69
+rnbq1rk1/pp2ppbp/3p1np1/2pP2B1/2P1P3/2N2P2/PP4PP/R2QKBNR b KQ -
+KI.50
+rnbq1rk1/pp2ppbp/3p1np1/2pP4/2P1P3/2N5/PP3PPP/R1BQKBNR w KQ -
+RE.13*
+rnbq1rk1/pp2ppbp/3p1np1/2pP4/2P1PP2/2NB4/PP4PP/R1BQK1NR b KQ -
+KI.60
+rnbq1rk1/pp2ppbp/3p1np1/8/2PNPP2/2N5/PP2B1PP/R1BQK2R b KQ -
+KI.59
+rnbq1rk1/pp2ppbp/5np1/2Pp4/8/4PN2/PPP1BPPP/RNBQ1RK1 b - -
+CA.05*
+rnbq1rk1/pp2ppbp/5np1/2p5/3P4/1P3N2/PBPPBPPP/RN1Q1RK1 b - -
+QI.08*
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w - -
+GI.02*
+rnbq1rk1/pp2ppbp/5np1/2pp4/5P2/3P1NP1/PPP1P1BP/RNBQ1RK1 b - -
+HD.06*
+rnbq1rk1/pp2ppbp/5np1/2pp4/5P2/3PPN2/PPP1B1PP/RNBQ1RK1 b - -
+HD.01*
+rnbq1rk1/pp2ppbp/5np1/2pp4/5P2/4PN2/PPPPB1PP/RNBQ1RK1 w - -
+HD.02*
+rnbq1rk1/pp2ppbp/5np1/2pp4/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w - -
+KI.79*
+rnbq1rk1/pp3pbp/3p1np1/2pP4/2N5/2N5/PP2PPPP/R1BQKB1R w KQ -
+BI.26
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+BI.17
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4P3/2NB4/PP2NPPP/R1BQ1RK1 b - -
+BI.36
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4PP2/2N2N2/PP4PP/R1BQKB1R w KQ -
+BI.31
+rnbq1rk1/pp3pbp/3p1np1/2pP4/8/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+BI.24
+rnbq1rk1/pp3pbp/3p1np1/2ppP3/2P2P2/2N2N2/PP2B1PP/R1BQK2R b KQ -
+KI.56
+rnbq1rk1/pp3pbp/3p1np1/3Pp3/4P3/2N1BP2/PP1Q2PP/R3KBNR b KQ -
+KI.39
+rnbq1rk1/pp3pbp/3p1np1/3Pp3/4P3/2NBBP2/PP4PP/R2QK1NR b KQ -
+KI.37
+rnbq1rk1/pp3pbp/3ppnp1/2pP2B1/2P1P3/2N2P2/PP1Q2PP/R3KBNR b KQ -
+KI.49
+rnbq1rk1/pp3pbp/3ppnp1/2pP2B1/2P1P3/2N5/PP2BPPP/R2QK1NR w KQ -
+KI.24
+rnbq1rk1/pp3pbp/3ppnp1/2pP4/2P1PP2/2N2N2/PP2B1PP/R1BQK2R b KQ -
+KI.57
+rnbq1rk1/pp3ppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R w KQ -
+RL.29*
+rnbq1rk1/pp3ppp/1bp2n2/4N3/1PBPp3/P1N1B3/2P2PPP/R2QK2R b KQ -
+RL.30*
+rnbq1rk1/pp3ppp/4pn2/2bP4/5B2/2N1PN2/PP3PPP/R2QKB1R b KQ -
+QO.01
+rnbq1rk1/pp3ppp/4pn2/2bp4/2P5/P3PN2/1P3PPP/RNBQKB1R b KQ -
+QG.07*
+rnbq1rk1/pp3ppp/4pn2/2pp4/1bPP4/2NBP3/PP2NPPP/R1BQK2R w KQ -
+NI.09
+rnbq1rk1/pp3ppp/4pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQ1RK1 b - -
+NI.05
+rnbq1rk1/ppp1b1pp/3ppn2/5p2/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+HD.01
+rnbq1rk1/ppp1bpp1/4pn1p/8/2pP3B/2N2N2/PP2PPPP/2RQKB1R w K -
+QO.07
+rnbq1rk1/ppp1bppp/4pn2/3p4/2P5/1P3NP1/P2PPPBP/RNBQ1RK1 b - -
+RE.09
+rnbq1rk1/ppp1bppp/4pn2/3p4/2PP1B2/2N1PN2/PP3PPP/R2QKB1R b KQ -
+QO.04
+rnbq1rk1/ppp1bppp/4pn2/8/2pP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+CA.05
+rnbq1rk1/ppp1p1bp/3p1np1/5p2/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+HD.06
+rnbq1rk1/ppp1ppbp/3p1np1/6B1/2PPP3/2N2P2/PP4PP/R2QKBNR b KQ -
+KI.51
+rnbq1rk1/ppp1ppbp/3p1np1/6B1/2PPP3/2N5/PP2BPPP/R2QK1NR b KQ -
+KI.26
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PP4/2N1P1P1/PP3PBP/R1BQK1NR b KQ -
+KI.78
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PP4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+KI.79
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2N1P/PP3PP1/R1BQKB1R b KQ -
+KI.20
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2N2/PP2BPPP/R1BQK2R b KQ -
+KI.19
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2N2/PP3PPP/R1BQKB1R w KQ -
+KI.21
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2P2/PP2N1PP/R1BQKB1R b KQ -
+KI.52
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N3P1/PP3PBP/R1BQK1NR b KQ -
+KI.29
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N4P/PP3PP1/R1BQKBNR w KQ -
+KI.30
+rnbq1rk1/ppp1ppbp/3p1np1/8/3PPP2/2N2N2/PPP3PP/R1BQKB1R w KQ -
+PU.06
+rnbq1rk1/ppp1ppbp/3p1np1/8/3PPP2/2NB1N2/PPP3PP/R1BQK2R b KQ -
+PU.02
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R w KQ -
+GI.09
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+GI.02
+rnbq1rk1/ppp2pbp/3p1np1/3Pp3/2P1P3/2N1BP2/PP4PP/R2QKBNR b KQ -
+KI.41
+rnbq1rk1/ppp2pbp/3p1np1/3Pp3/2P1P3/2N2N2/PP2BPPP/R1BQK2R b KQ -
+KI.17
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N1BP2/PP2N1PP/R2QKB1R b KQ -
+KI.43
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+KI.15
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+KI.18
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N3P1/PP2NPBP/R1BQK2R b KQ -
+KI.28
+rnbq1rk1/ppp2pbp/3p2p1/3Pp2n/2P1P3/2N1BP2/PP1Q2PP/R3KBNR b KQ -
+KI.40
+rnbq1rk1/ppp2pp1/4pb1p/3p4/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QO.14
+rnbq1rk1/ppp2ppp/3b1n2/3pN3/3P4/2N5/PPP1BPPP/R1BQK2R b KQ -
+RG.06*
+rnbq1rk1/ppp2ppp/4pn2/3p4/1bPP4/2NBPN2/PP3PPP/R1BQK2R b KQ -
+NI.06
+rnbq1rk1/ppp2ppp/4pn2/3p4/1bPP4/P1NBP3/1P3PPP/R1BQK1NR b KQ -
+NI.08
+rnbq1rk1/ppp2ppp/5n2/b2pp3/4P3/P1N2N2/1PPPBPPP/R1BQK2R w KQ -
+RL.15*
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQ -
+NI.10
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQ -
+NI.11
+rnbq1rk1/pppp1ppp/4pn2/8/2PP4/P1Q5/1P2PPPP/R1B1KBNR b KQ -
+NI.20
+rnbq1rk1/pppp1ppp/5n2/4p3/1bP5/2N3P1/PP1PPPBP/R1BQK1NR w KQ -
+EO.11
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1b2N2/1PPPBPPP/R1BQK2R w KQ -
+RL.14*
+rnbq1rk1/pppp1ppp/5n2/b3N3/4P3/P1N5/1PPP1PPP/R1BQKB1R b KQ -
+RL.27*
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPPBPPP/R1BQK2R b KQ -
+RL.13*
+rnbq1rk1/ppppb1pp/4pn2/5p2/2PP4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+HD.02
+rnbq1rk1/ppppppbp/5np1/8/2PPP3/2N5/PP3PPP/R1BQKBNR w KQ -
+KI.32
+rnbqk1nr/pp2bppp/2p5/3p4/3P1B2/2N5/PP2PPPP/R2QKBNR w KQkq -
+QO.05
+rnbqk1nr/pp2ppbp/6p1/2pp4/5P2/2PP1N2/PP2P1PP/RNBQKB1R b KQkq -
+HD.04*
+rnbqk1nr/pp2ppbp/6p1/2pp4/5P2/4PN2/PPPP2PP/RNBQKB1R w KQkq -
+HD.03*
+rnbqk1nr/pp2ppbp/6p1/2pp4/5P2/5NP1/PPPPP1BP/RNBQK2R b KQkq -
+HD.07*
+rnbqk1nr/pp2ppbp/6p1/8/2Pp4/B2P1NP1/4PP1P/RN1QKB1R b KQkq -
+BI.42*
+rnbqk1nr/pp3ppp/4p3/2ppP3/1b1P4/2N5/PPP2PPP/R1BQKBNR w KQkq -
+FR.10
+rnbqk1nr/pp3ppp/4p3/2ppP3/3P4/P1P5/2P2PPP/R1BQKBNR b KQkq -
+FR.11
+rnbqk1nr/ppp1ppbp/3p2p1/8/2PPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+KF.04
+rnbqk1nr/ppp1ppbp/6p1/3p4/5P2/6P1/PPPPP2P/RNBQKBNR w KQkq -
+HD.09*
+rnbqk1nr/ppp2ppp/3b4/3pp3/8/1P2P3/PBPP1PPP/RN1QKBNR b KQkq -
+VO.03*
+rnbqk1nr/ppp2ppp/3b4/3pp3/8/1P6/PBPPPPPP/RN1QKBNR w KQkq -
+VO.02*
+rnbqk1nr/ppp2ppp/4p3/3p4/1b1PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+FR.08
+rnbqk1nr/ppp2ppp/4p3/3pP3/1b1P4/2N5/PPP2PPP/R1BQKBNR b KQkq -
+FR.09
+rnbqk1nr/pppp1ppp/8/2b1p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+IG.04*
+rnbqk1nr/ppppppbp/6p1/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+KF.05
+rnbqk2r/1p2bppp/p2p1n2/4p3/4P3/1NN5/PPP1BPPP/R1BQK2R w KQkq -
+SI.11
+rnbqk2r/1p2bppp/p2ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+SI.09
+rnbqk2r/1p3pb1/p2p1npp/2pP4/4P2B/2N5/PP1N1PPP/R2QKB1R b KQkq -
+BI.18
+rnbqk2r/1pp1ppbp/p2p1np1/8/2PPP3/2N2P2/PP4PP/R1BQKBNR w KQkq -
+KI.53
+rnbqk2r/p1pp1ppp/1p2pn2/8/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQkq -
+NI.13
+rnbqk2r/p1pp1ppp/1p2pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+NI.12
+rnbqk2r/p1pp1ppp/1p2pn2/8/1bPP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+NI.26
+rnbqk2r/p1pp1ppp/5n2/1pb1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+IG.05*
+rnbqk2r/pp1n1pbp/3p2p1/1BpP4/4PP2/2N5/PP4PP/R1BQK1NR w KQkq -
+BI.33
+rnbqk2r/pp1p1ppp/2p2n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQkq -
+RL.11*
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQkq -
+NI.16
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+NI.15
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+NI.22
+rnbqk2r/pp1p1ppp/4pn2/2p5/2PP4/P1P5/4PPPP/R1BQKBNR w KQkq -
+NI.19
+rnbqk2r/pp1p1ppp/4pn2/8/1bPN4/2N5/PP2PPPP/R1BQKB1R w KQkq -
+EO.44
+rnbqk2r/pp1pppbp/5np1/2P5/8/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+RE.10*
+rnbqk2r/pp1pppbp/5np1/2p3B1/3P4/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+RE.05*
+rnbqk2r/pp1pppbp/5np1/2p5/3P1B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+RE.06*
+rnbqk2r/pp1pppbp/5np1/2p5/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+RE.11*
+rnbqk2r/pp1pppbp/5np1/8/2PN4/2N5/PP2PPPP/R1BQKB1R b KQkq -
+EO.49*
+rnbqk2r/pp2nppp/4p3/2ppP3/3P4/P1P2N2/2P2PPP/R1BQKB1R b KQkq -
+FR.12
+rnbqk2r/pp2ppbp/2p2np1/3p4/2P5/1P3NP1/PB1PPPBP/RN1QK2R b KQkq -
+RE.03
+rnbqk2r/pp2ppbp/3p1np1/8/3NP3/2N1B3/PPP2PPP/R2QKB1R w KQkq -
+SI.16
+rnbqk2r/pp2ppbp/3p1np1/8/3NP3/2N1BP2/PPP3PP/R2QKB1R b KQkq -
+SI.17
+rnbqk2r/pp2ppbp/5np1/2Pp4/8/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+CA.03*
+rnbqk2r/pp2ppbp/5np1/2pp4/3P4/4PN2/PPP1BPPP/RNBQK2R w KQkq -
+CA.04*
+rnbqk2r/pp2ppbp/5np1/2pp4/8/1P2PN2/PBPP1PPP/RN1QKB1R w KQkq -
+QI.06*
+rnbqk2r/pp2ppbp/5np1/2pp4/8/1P2PN2/PBPPBPPP/RN1QK2R b KQkq -
+QI.07*
+rnbqk2r/pp3pbp/3p1np1/2pP2B1/4P3/2N2N2/PP3PPP/R2QKB1R b KQkq -
+BI.19
+rnbqk2r/pp3pbp/3p1np1/2pP2B1/4P3/2N2P2/PP4PP/R2QKBNR b KQkq -
+BI.37
+rnbqk2r/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP3PPP/R1BQKB1R w KQkq -
+BI.20
+rnbqk2r/pp3pbp/3p1np1/2pPP3/5P2/2N5/PP4PP/R1BQKBNR b KQkq -
+BI.34
+rnbqk2r/pp3ppp/4pn2/2bp2B1/8/4PN2/PPP2PPP/RN1QKB1R b KQkq -
+QG.06*
+rnbqk2r/ppp1bppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR w KQkq -
+QO.13
+rnbqk2r/ppp1bppp/4pn2/3p2B1/3PP3/2N5/PPP2PPP/R2QKBNR w KQkq -
+FR.06
+rnbqk2r/ppp1bppp/4pn2/3p4/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+CA.04
+rnbqk2r/ppp1bppp/5n2/3p2B1/3Np3/3PP3/PPP2PPP/RN1QKB1R b KQkq -
+AL.02*
+rnbqk2r/ppp1bppp/8/3p4/3Pn3/3B1N2/PPP2PPP/RNBQK2R w KQkq -
+RG.05
+rnbqk2r/ppp1ppbp/3p1np1/8/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+KI.76
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+KI.22
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N2P2/PP4PP/R1BQKBNR b KQkq -
+KI.54
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N5/PP2BPPP/R1BQK1NR b KQkq -
+KI.27
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N5/PP3PPP/R1BQKBNR w KQkq -
+KI.31
+rnbqk2r/ppp1ppbp/3p1np1/8/3PP3/2N2N2/PPP1BPPP/R1BQK2R b KQkq -
+PU.03
+rnbqk2r/ppp1ppbp/3p1np1/8/3PP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+PU.10
+rnbqk2r/ppp1ppbp/3p1np1/8/3PPP2/2N5/PPP3PP/R1BQKBNR w KQkq -
+PU.05
+rnbqk2r/ppp1ppbp/5np1/3p2B1/2PP4/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+GI.08
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/1QN2N2/PP2PPPP/R1B1KB1R b KQkq -
+GI.10
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+GI.07
+rnbqk2r/ppp1ppbp/6p1/3n4/8/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+EO.51
+rnbqk2r/ppp1ppbp/6p1/8/2BPP3/2P5/P4PPP/R1BQK1NR b KQkq -
+GI.05
+rnbqk2r/ppp2ppp/3b1n2/3pN3/3P4/8/PPP1BPPP/RNBQK2R b KQkq -
+RG.05*
+rnbqk2r/ppp2ppp/3b4/3np3/8/P3P3/1P1P1PPP/RNBQKBNR w KQkq -
+SI.42*
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+NI.27
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+NI.23
+rnbqk2r/ppp2ppp/5n2/2bPp3/8/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+KP.02*
+rnbqk2r/pppp1pbp/5np1/4p3/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+EO.14
+rnbqk2r/pppp1ppp/4pn2/6B1/1bPP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+NI.25
+rnbqk2r/pppp1ppp/4pn2/8/1bP5/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+EO.59
+rnbqk2r/pppp1ppp/4pn2/8/1bP5/2N2N2/PPQPPPPP/R1B1KB1R b KQkq -
+EO.58
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR b KQkq -
+NI.17
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+NI.28
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N3P1/PP2PP1P/R1BQKBNR b KQkq -
+NI.29
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+NI.30
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N5/PPQ1PPPP/R1B1KBNR b KQkq -
+NI.24
+rnbqk2r/pppp1ppp/4pn2/8/2PP4/P1P5/4PPPP/R1BQKBNR b KQkq -
+NI.18
+rnbqk2r/pppp1ppp/5n2/2b1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+IG.02*
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+IG.01*
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+IG.03*
+rnbqk2r/pppp1ppp/5n2/3Np3/1b2P3/8/PPPP1PPP/R1BQKBNR b KQkq -
+RL.05*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+RL.07*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+RL.03*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+RL.01*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N5/PPPPNPPP/R1BQKB1R b KQkq -
+RL.04*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2NP4/PPP2PPP/R1BQKBNR b KQkq -
+RL.02*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+RL.06*
+rnbqk2r/pppp1ppp/5n2/4p3/4P3/P1b5/1PPP1PPP/R1BQKBNR w KQkq -
+RL.08*
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R b KQkq -
+RL.12*
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N5/1PPP1PPP/R1BQKBNR w KQkq -
+RL.09*
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR b KQkq -
+RL.10*
+rnbqk2r/pppp1ppp/8/2b1p3/4P1n1/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+KP.01*
+rnbqk2r/ppppp1bp/5np1/5p2/2PP4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+HD.07
+rnbqk2r/ppppppbp/5np1/6B1/3P4/5N2/PPP1PPPP/RN1QKB1R w KQkq -
+QP.01
+rnbqk2r/ppppppbp/5np1/8/3P1B2/5N2/PPP1PPPP/RN1QKB1R w KQkq -
+QP.03
+rnbqkb1r/1p2pppp/p2p1n2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R b KQkq -
+SI.04
+rnbqkb1r/1p2pppp/p2p1n2/8/2BNP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+SI.13
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+SI.10
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+SI.14
+rnbqkb1r/1p2pppp/p2p1n2/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+SI.12
+rnbqkb1r/1p2pppp/p4n2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+QI.04*
+rnbqkb1r/1p3ppp/p2ppn2/8/3NP3/2N5/PPP1BPPP/R1BQK2R w KQkq -
+SI.23
+rnbqkb1r/1p3ppp/p3pn2/2p5/2BP4/4PN2/PP3PPP/RNBQ1RK1 w kq -
+QG.07
+rnbqkb1r/3ppppp/p4n2/1PpP4/8/2N5/PP2PPPP/R1BQKBNR b KQkq -
+BI.44
+rnbqkb1r/3ppppp/p4n2/1PpP4/8/4P3/PP3PPP/RNBQKBNR b KQkq -
+BI.43
+rnbqkb1r/3ppppp/p4n2/1PpP4/8/8/PP2PPPP/RNBQKBNR w KQkq -
+BI.45
+rnbqkb1r/5ppp/p2ppn2/1p4B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+SI.07
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+QI.03
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+QI.02
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/P4N2/1P2PPPP/RNBQKB1R b KQkq -
+QI.04
+rnbqkb1r/p2ppp1p/1p3np1/2p5/3P4/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+RE.04*
+rnbqkb1r/p2ppppp/1p3n2/2p5/2P1P3/2N2N2/PP1P1PPP/R1BQKB1R b KQkq -
+EO.43
+rnbqkb1r/p2ppppp/5n2/1ppP4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+BI.46
+rnbqkb1r/p2ppppp/5n2/1ppP4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+RE.17*
+rnbqkb1r/p4ppp/2p1pn2/1p4B1/2pPP3/2N2N2/PP3PPP/R2QKB1R w KQkq -
+SL.07
+rnbqkb1r/pp1n1ppp/4p3/2ppP3/3P4/2PB4/PP1N1PPP/R1BQK1NR b KQkq -
+FR.17
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+EO.12
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+KP.05*
+rnbqkb1r/pp1p1ppp/4pn2/2pP4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+RE.16*
+rnbqkb1r/pp1p1ppp/4pn2/8/2PN4/6P1/PP2PP1P/RNBQKB1R b KQkq -
+EO.45
+rnbqkb1r/pp1ppp1p/5np1/2p5/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+RE.07*
+rnbqkb1r/pp1ppp1p/5np1/2p5/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+RE.12*
+rnbqkb1r/pp1ppp1p/5np1/2pP4/2P5/8/PP2PPPP/RNBQKBNR b KQkq -
+RE.14*
+rnbqkb1r/pp1ppp1p/5np1/2pP4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+RE.15*
+rnbqkb1r/pp1ppppp/2p2n2/8/2P1P3/2N5/PP1P1PPP/R1BQKBNR b KQkq -
+EO.61
+rnbqkb1r/pp1ppppp/5n2/2P5/8/8/PPP1PPPP/RNBQKBNR b KQkq -
+RE.19*
+rnbqkb1r/pp1ppppp/5n2/2p5/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+OI.06
+rnbqkb1r/pp1ppppp/5n2/2pP4/2P5/8/PP2PPPP/RNBQKBNR b KQkq -
+BI.38
+rnbqkb1r/pp1ppppp/5n2/2pP4/8/2N5/PPP1PPPP/R1BQKBNR b KQkq -
+OI.08
+rnbqkb1r/pp1ppppp/5n2/8/2PN4/8/PP2PPPP/RNBQKB1R b KQkq -
+EO.46
+rnbqkb1r/pp1ppppp/8/3nP3/3p4/2P5/PP3PPP/RNBQKBNR w KQkq -
+SI.47
+rnbqkb1r/pp2p1pp/2pp1n2/5p2/2PP4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+HD.04
+rnbqkb1r/pp2pp1p/2p2p2/8/3P4/8/PPP2PPP/R1BQKBNR w KQkq -
+CK.07
+rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+SI.15
+rnbqkb1r/pp2pp1p/5np1/2pp4/8/BP2PN2/P1PP1PPP/RN1QKB1R b KQkq -
+QI.05*
+rnbqkb1r/pp2pp1p/6p1/2pn4/8/4PN2/PP1P1PPP/RNBQKB1R w KQkq -
+EO.45*
+rnbqkb1r/pp2pppp/2p2n2/3p4/2P5/1P3NP1/P2PPP1P/RNBQKB1R b KQkq -
+RE.04
+rnbqkb1r/pp2pppp/2p2n2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+SL.03
+rnbqkb1r/pp2pppp/5n2/2Pp4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+QG.05*
+rnbqkb1r/pp2pppp/5n2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R b KQkq -
+QI.02*
+rnbqkb1r/pp2pppp/5n2/2pp4/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+QI.01*
+rnbqkb1r/pp2pppp/5n2/3p4/2PP4/2N5/PP3PPP/R1BQKBNR b KQkq -
+CK.03
+rnbqkb1r/pp2pppp/5n2/3p4/3P4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+SL.02*
+rnbqkb1r/pp2pppp/5n2/3p4/3P4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+SL.02
+rnbqkb1r/pp2pppp/8/2pn4/8/2N1P3/PP1P1PPP/R1BQKBNR b KQkq -
+EO.50*
+rnbqkb1r/pp2pppp/8/2pn4/8/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+EO.42
+rnbqkb1r/pp2pppp/8/2pn4/8/2N3P1/PP1PPPBP/R1BQK1NR b KQkq -
+EO.38
+rnbqkb1r/pp2pppp/8/2pn4/8/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+EO.46*
+rnbqkb1r/pp3p1p/3p1np1/2pP2B1/8/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+BI.25
+rnbqkb1r/pp3p1p/3p1np1/2pP4/4PB2/2N5/PP3PPP/R2QKBNR b KQkq -
+BI.35
+rnbqkb1r/pp3p1p/3p1np1/2pP4/8/2N5/PP1NPPPP/R1BQKB1R b KQkq -
+BI.27
+rnbqkb1r/pp3ppp/2p1pn2/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+SL.08
+rnbqkb1r/pp3ppp/2p2p2/8/3P4/8/PPP2PPP/R1BQKBNR w KQkq -
+CK.06
+rnbqkb1r/pp3ppp/3p1n2/2pPp3/2P1P3/2N5/PP3PPP/R1BQKBNR b KQkq -
+OI.05
+rnbqkb1r/pp3ppp/3p1n2/4p3/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+SI.03
+rnbqkb1r/pp3ppp/3ppn2/8/3NP1P1/2N5/PPP2P1P/R1BQKB1R b KQkq -
+SI.20
+rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+SI.19
+rnbqkb1r/pp3ppp/3ppn2/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+SI.21
+rnbqkb1r/pp3ppp/4p3/8/3PP3/5N2/P4PPP/R1BQKB1R b KQkq -
+TD.08
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+QG.08*
+rnbqkb1r/pp3ppp/4pn2/2pP4/3P4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+TD.12
+rnbqkb1r/pp3ppp/4pn2/2pp4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+TD.05
+rnbqkb1r/pp3ppp/4pn2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+QI.03*
+rnbqkb1r/ppn1pppp/8/2p5/8/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+EO.37
+rnbqkb1r/ppp1pp1p/3p1np1/6B1/3PP3/2N5/PPP2PPP/R2QKBNR b KQkq -
+PU.09
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PP3/2N2P2/PPP3PP/R1BQKBNR b KQkq -
+PU.04
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+PU.07
+rnbqkb1r/ppp1pp1p/3p2p1/3nP3/3P4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+AL.04
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+GI.03
+rnbqkb1r/ppp1pp1p/6p1/3n4/8/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+EO.52
+rnbqkb1r/ppp1pp1p/6p1/3n4/8/2N3P1/PP1PPPBP/R1BQK1NR b KQkq -
+EO.53
+rnbqkb1r/ppp1pp1p/6p1/8/3PP3/2P5/P4PPP/R1BQKBNR b KQkq -
+GI.04
+rnbqkb1r/ppp1pppp/1n1P4/8/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+AL.08
+rnbqkb1r/ppp1pppp/1n1p4/4P3/2PP1P2/8/PP4PP/RNBQKBNR b KQkq -
+AL.07
+rnbqkb1r/ppp1pppp/3p1n2/8/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+OI.04
+rnbqkb1r/ppp1pppp/3p1n2/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+PU.08
+rnbqkb1r/ppp1pppp/3p4/3nP3/3P4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+AL.05
+rnbqkb1r/ppp1pppp/5n2/3P4/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+SD.03
+rnbqkb1r/ppp1pppp/5n2/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+QP.06*
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+QG.08
+rnbqkb1r/ppp2ppp/3p1n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+KP.07*
+rnbqkb1r/ppp2ppp/3p4/8/3Pn3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+RG.04
+rnbqkb1r/ppp2ppp/4pn2/3p2B1/3PP3/2N5/PPP2PPP/R2QKBNR b KQkq -
+FR.05
+rnbqkb1r/ppp2ppp/4pn2/3p4/2P1P3/2N5/PP1P1PPP/R1BQKBNR w KQkq -
+EO.57
+rnbqkb1r/ppp2ppp/4pn2/3p4/2P5/5NP1/PP1PPPBP/RNBQK2R b KQkq -
+RE.11
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QO.16
+rnbqkb1r/ppp2ppp/4pn2/3pP3/3P4/8/PPPN1PPP/R1BQKBNR b KQkq -
+FR.16
+rnbqkb1r/ppp2ppp/4pn2/8/2p5/5NP1/PP1PPPBP/RNBQK2R w KQkq -
+RE.10
+rnbqkb1r/ppp2ppp/4pn2/8/2pP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+CA.03
+rnbqkb1r/ppp2ppp/4pn2/8/Q1pP4/6P1/PP2PPBP/RNB1K1NR b KQkq -
+CA.02
+rnbqkb1r/ppp2ppp/5n2/3Pp3/8/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+SO.06*
+rnbqkb1r/ppp2ppp/5n2/3p2B1/3Np3/3P4/PPP1PPPP/RN1QKB1R b KQkq -
+AL.03*
+rnbqkb1r/ppp2ppp/5n2/3p4/3Np3/3P2P1/PPP1PP1P/RNBQKB1R b KQkq -
+AL.04*
+rnbqkb1r/ppp2ppp/5n2/3p4/3Np3/3P4/PPP1PPPP/RNBQKB1R w KQkq -
+AL.05*
+rnbqkb1r/ppp2ppp/5n2/3pN3/4P3/8/PPPP1PPP/RNBQKB1R b KQkq -
+RG.02*
+rnbqkb1r/ppp2ppp/5n2/3pN3/8/3P4/PPP2PPP/RNBQKB1R w KQkq -
+RG.04*
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/3P4/PPP2PPP/RNBQKBNR w KQkq -
+KP.08*
+rnbqkb1r/ppp2ppp/5n2/3pp3/4PP2/2N5/PPPP2PP/R1BQKBNR w KQkq -
+VG.03
+rnbqkb1r/ppp2ppp/8/3np3/2B5/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+SO.05*
+rnbqkb1r/ppp2ppp/8/3np3/8/2N1P3/PP1P1PPP/R1BQKBNR b KQkq -
+SI.39*
+rnbqkb1r/ppp2ppp/8/3np3/8/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+SI.33*
+rnbqkb1r/ppp2ppp/8/3np3/8/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+SI.32*
+rnbqkb1r/ppp2ppp/8/3np3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+SO.04*
+rnbqkb1r/ppp2ppp/8/3np3/8/4P3/PP1P1PPP/RNBQKBNR w KQkq -
+SI.41*
+rnbqkb1r/pppp1ppp/4pn2/6B1/3P4/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+QP.04
+rnbqkb1r/pppp1ppp/4pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+QI.01
+rnbqkb1r/pppp1ppp/4pn2/8/2PP4/6P1/PP2PP1P/RNBQKBNR b KQkq -
+CA.01
+rnbqkb1r/pppp1ppp/4pn2/8/3P1B2/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+QP.05
+rnbqkb1r/pppp1ppp/5n2/4N3/4P3/8/PPPP1PPP/RNBQKB1R b KQkq -
+RG.03
+rnbqkb1r/pppp1ppp/5n2/4p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+VG.02
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+EO.09
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+SI.31*
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+EO.10
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/3P4/PP2PPPP/RNBQKBNR b KQkq -
+SI.01*
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+SI.43*
+rnbqkb1r/pppp1ppp/5n2/4p3/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QG.01
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+VG.01
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+RG.01*
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+RG.01
+rnbqkb1r/pppp1ppp/5n2/4p3/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+KP.09*
+rnbqkb1r/pppp1ppp/5n2/4p3/8/2N5/PPPPPPPP/R1BQKBNR w KQkq -
+VO.05*
+rnbqkb1r/pppp1ppp/8/4P3/6n1/8/PPPPP1PP/RNBQKBNR w KQkq -
+HD.13*
+rnbqkb1r/pppp1ppp/8/4p3/3Pn3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+RG.02
+rnbqkb1r/pppp1ppp/8/4p3/4n3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+RG.03*
+rnbqkb1r/pppp2pp/4pn2/5p2/2PP4/6P1/PP2PPBP/RNBQK1NR b KQkq -
+HD.03
+rnbqkb1r/pppp2pp/5n2/4pP2/6P1/8/PPPP1P1P/RNBQKBNR b KQkq -
+KG.01*
+rnbqkb1r/pppp2pp/5n2/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KG.02*
+rnbqkb1r/ppppp1pp/5n2/5p2/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+HD.05
+rnbqkb1r/ppppp2p/5np1/5p2/2PP4/6P1/PP2PP1P/RNBQKBNR w KQkq -
+HD.08
+rnbqkb1r/pppppp1p/5np1/6B1/3P4/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+QP.02
+rnbqkb1r/pppppp1p/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+GI.01
+rnbqkb1r/pppppp1p/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+KI.80
+rnbqkb1r/pppppppp/5n2/8/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+QP.10*
+rnbqkb1r/pppppppp/5n2/8/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+QP.06
+rnbqkb1r/pppppppp/5n2/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+QP.09*
+rnbqkb1r/pppppppp/5n2/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+QP.07
+rnbqkb1r/pppppppp/5n2/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+AL.10
+rnbqkb1r/pppppppp/5n2/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+QP.11*
+rnbqkb1r/pppppppp/7n/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.16*
+rnbqkb1r/pppppppp/8/3nP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+AL.09
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/3B4/PPP2PPP/RNBQK2R b KQkq -
+SI.42
+rnbqkbnr/1ppppppp/p7/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.14*
+rnbqkbnr/p1pppppp/1p6/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+EO.63
+rnbqkbnr/p1pppppp/1p6/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+VO.01
+rnbqkbnr/p1pppppp/1p6/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.08*
+rnbqkbnr/p1pppppp/8/1p6/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.10*
+rnbqkbnr/pp1p1ppp/2p5/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+SI.46*
+rnbqkbnr/pp1p1ppp/4p3/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+SI.41
+rnbqkbnr/pp1p1ppp/8/2p1p3/4P3/6P1/PPPP1P1P/RNBQKBNR b KQkq -
+EO.62*
+rnbqkbnr/pp1ppp1p/6p1/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+EO.24*
+rnbqkbnr/pp1ppppp/2p5/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+CK.01
+rnbqkbnr/pp1ppppp/2p5/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.12*
+rnbqkbnr/pp1ppppp/8/2p5/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+OI.09
+rnbqkbnr/pp1ppppp/8/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+SI.44
+rnbqkbnr/pp1ppppp/8/2p5/4P3/2P5/PP1P1PPP/RNBQKBNR b KQkq -
+SI.46
+rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+SI.43
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+EO.25*
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+SI.48
+rnbqkbnr/pp1ppppp/8/2p5/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+HD.14*
+rnbqkbnr/pp1ppppp/8/2p5/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+EO.63*
+rnbqkbnr/pp1ppppp/8/2p5/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+QP.10
+rnbqkbnr/pp1ppppp/8/2p5/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+EO.64*
+rnbqkbnr/pp2pp1p/6p1/2pp4/5P2/5NP1/PPPPP2P/RNBQKB1R b KQkq -
+HD.08*
+rnbqkbnr/pp2pp1p/6p1/2pp4/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+CA.01*
+rnbqkbnr/pp2pppp/2p5/3p4/2P5/5NP1/PP1PPP1P/RNBQKB1R b KQkq -
+RE.07
+rnbqkbnr/pp2pppp/2p5/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+SL.01
+rnbqkbnr/pp2pppp/2p5/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+CK.05
+rnbqkbnr/pp2pppp/2p5/3p4/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+CK.02
+rnbqkbnr/pp2pppp/3p4/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+SI.01
+rnbqkbnr/pp2pppp/3p4/8/3QP3/5N2/PPP2PPP/RNB1KB1R b KQkq -
+SI.02
+rnbqkbnr/pp2pppp/8/2Pp4/8/8/PPP1PPPP/RNBQKBNR b KQkq -
+QG.03*
+rnbqkbnr/pp2pppp/8/2p5/1PPp4/5N2/P2PPPPP/RNBQKB1R b KQkq -
+BI.46*
+rnbqkbnr/pp2pppp/8/2p5/2Pp4/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+BI.38*
+rnbqkbnr/pp2pppp/8/2p5/2Pp4/5NP1/PP1PPP1P/RNBQKB1R w KQkq -
+RE.14
+rnbqkbnr/pp2pppp/8/2pp4/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+OI.06*
+rnbqkbnr/pp2pppp/8/2pp4/3P4/2P5/PP2PPPP/RNBQKBNR b KQkq -
+SL.01*
+rnbqkbnr/pp2pppp/8/2pp4/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+QG.02*
+rnbqkbnr/pp2pppp/8/2pp4/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+QG.01*
+rnbqkbnr/pp2pppp/8/2pp4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+HD.10*
+rnbqkbnr/pp2pppp/8/2pp4/8/3P4/PPP1PPPP/RNBQKBNR w KQkq -
+OI.07*
+rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+GI.01*
+rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+KI.80*
+rnbqkbnr/pp2pppp/8/8/1pPp4/P4N2/3PPPPP/RNBQKB1R b KQkq -
+BI.45*
+rnbqkbnr/pp3ppp/2p1p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+SL.06
+rnbqkbnr/pp3ppp/2p5/3P4/3Np3/8/PP1PPPPP/RNBQKB1R b KQkq -
+SI.47*
+rnbqkbnr/pp3ppp/4p3/2pp4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+TD.10
+rnbqkbnr/pp3ppp/4p3/2pp4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+FR.18
+rnbqkbnr/pp3ppp/4p3/8/1pPp4/P4N2/3PPPPP/RNBQKB1R w KQkq -
+BI.43*
+rnbqkbnr/pp3ppp/8/2Ppp3/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+QG.04*
+rnbqkbnr/pp3ppp/8/2pp4/3P4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+TD.11
+rnbqkbnr/pp3ppp/8/2pp4/3P4/5N2/PPPN1PPP/R1BQKB1R b KQkq -
+FR.21
+rnbqkbnr/pp3ppp/8/2pp4/3P4/8/PPPN1PPP/R1BQKBNR w KQkq -
+FR.20
+rnbqkbnr/pp3ppp/8/2pp4/8/1N1p4/PPP1PPPP/RNBQKB1R w KQkq -
+AL.08*
+rnbqkbnr/pp4pp/8/2pp1p2/4p3/1N1P4/PPP1PPPP/RNBQKB1R w KQkq -
+AL.07*
+rnbqkbnr/ppp1pppp/3p4/8/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+OI.07
+rnbqkbnr/ppp1pppp/3p4/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.13*
+rnbqkbnr/ppp1pppp/8/3p4/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+OI.09*
+rnbqkbnr/ppp1pppp/8/3p4/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+QP.08*
+rnbqkbnr/ppp1pppp/8/3p4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+QP.08
+rnbqkbnr/ppp1pppp/8/3p4/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+HD.12*
+rnbqkbnr/ppp1pppp/8/3p4/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+QP.07*
+rnbqkbnr/ppp1pppp/8/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+QP.09
+rnbqkbnr/ppp1pppp/8/3p4/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+QO.17*
+rnbqkbnr/ppp1pppp/8/8/1PPp4/5N2/P2PPPPP/RNBQKB1R b KQkq -
+RE.17
+rnbqkbnr/ppp1pppp/8/8/2Pp4/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+RE.16
+rnbqkbnr/ppp1pppp/8/8/2Pp4/5NP1/PP1PPP1P/RNBQKB1R b KQkq -
+RE.15
+rnbqkbnr/ppp1pppp/8/8/2p5/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+RE.19
+rnbqkbnr/ppp1pppp/8/8/2p5/N4N2/PP1PPPPP/R1BQKB1R b KQkq -
+RE.18
+rnbqkbnr/ppp1pppp/8/8/2pP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+QG.05
+rnbqkbnr/ppp1pppp/8/8/2pP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QG.03
+rnbqkbnr/ppp1pppp/8/8/2pPP3/8/PP3PPP/RNBQKBNR b KQkq -
+QG.04
+rnbqkbnr/ppp2ppp/3p4/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+EO.22
+rnbqkbnr/ppp2ppp/3p4/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+KP.08
+rnbqkbnr/ppp2ppp/3p4/4p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+FR.02*
+rnbqkbnr/ppp2ppp/4p3/3p4/2P5/5NP1/PP1PPP1P/RNBQKB1R b KQkq -
+RE.12
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+FR.04
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/8/PPPN1PPP/R1BQKBNR b KQkq -
+FR.14
+rnbqkbnr/ppp2ppp/4p3/3pP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+FR.03
+rnbqkbnr/ppp2ppp/4p3/8/3PN3/8/PPP2PPP/R1BQKBNR b KQkq -
+FR.07
+rnbqkbnr/ppp2ppp/8/3Pp3/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+KP.04*
+rnbqkbnr/ppp2ppp/8/3p4/3Np3/8/PPPPPPPP/RNBQKB1R w KQkq -
+AL.09*
+rnbqkbnr/ppp2ppp/8/3p4/3Pp3/4P3/PPP2PPP/RNBQKBNR w KQkq -
+FR.03*
+rnbqkbnr/ppp2ppp/8/3p4/3PpB2/2P5/PP2PPPP/RN1QKBNR b KQkq -
+CK.04*
+rnbqkbnr/ppp2ppp/8/3pp3/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QG.02
+rnbqkbnr/ppp2ppp/8/3pp3/3P4/2N5/PPP1PPPP/R1BQKBNR b KQkq -
+VO.06*
+rnbqkbnr/ppp2ppp/8/3pp3/3P4/2P5/PP2PPPP/RNBQKBNR b KQkq -
+CK.02*
+rnbqkbnr/ppp2ppp/8/3pp3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KG.04
+rnbqkbnr/ppp2ppp/8/3pp3/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+HD.11*
+rnbqkbnr/ppp2ppp/8/3pp3/8/3P1N2/PPP1PPPP/RNBQKB1R b KQkq -
+PU.08*
+rnbqkbnr/ppp2ppp/8/3pp3/8/6P1/PPPPPPBP/RNBQK1NR b KQkq -
+KF.05*
+rnbqkbnr/pppp1p1p/6p1/4p3/2P1P3/8/PP1P1PPP/RNBQKBNR w KQkq -
+EO.62
+rnbqkbnr/pppp1p1p/8/6p1/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KG.01
+rnbqkbnr/pppp1ppp/4p3/8/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+FR.02
+rnbqkbnr/pppp1ppp/4p3/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+FR.01
+rnbqkbnr/pppp1ppp/8/4p3/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+IG.04
+rnbqkbnr/pppp1ppp/8/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+EO.23
+rnbqkbnr/pppp1ppp/8/4p3/2P5/6P1/PP1PPP1P/RNBQKBNR b KQkq -
+EO.24
+rnbqkbnr/pppp1ppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+SI.48*
+rnbqkbnr/pppp1ppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+EO.25
+rnbqkbnr/pppp1ppp/8/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+VG.04
+rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+KP.10*
+rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP.10
+rnbqkbnr/pppp1ppp/8/4p3/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+KG.05
+rnbqkbnr/pppp1ppp/8/4p3/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+VO.01*
+rnbqkbnr/pppp1ppp/8/4p3/8/2N5/PPPPPPPP/R1BQKBNR b KQkq -
+VO.04*
+rnbqkbnr/pppp1ppp/8/4p3/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+CK.01*
+rnbqkbnr/pppp1ppp/8/4p3/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+FR.01*
+rnbqkbnr/pppp1ppp/8/4p3/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+AL.10*
+rnbqkbnr/pppp1ppp/8/4p3/8/6P1/PPPPPP1P/RNBQKBNR b KQkq -
+KF.06*
+rnbqkbnr/pppp1ppp/8/4p3/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.17*
+rnbqkbnr/pppp1ppp/8/8/3p4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+SD.03*
+rnbqkbnr/pppp1ppp/8/8/3pP3/8/PPP2PPP/RNBQKBNR w KQkq -
+KP.04
+rnbqkbnr/pppp1ppp/8/8/4Pp2/5N2/PPPP2PP/RNBQKB1R b KQkq -
+KG.02
+rnbqkbnr/pppp1ppp/8/8/4Pp2/8/PPPP2PP/RNBQKBNR w KQkq -
+KG.03
+rnbqkbnr/pppp2pp/8/4pP2/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+KG.03*
+rnbqkbnr/pppp2pp/8/4pp2/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+KG.04*
+rnbqkbnr/pppp2pp/8/4pp2/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+KP.09
+rnbqkbnr/pppp2pp/8/4pp2/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KG.05*
+rnbqkbnr/ppppp1pp/8/5p2/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+HD.14
+rnbqkbnr/ppppp1pp/8/5p2/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+HD.10
+rnbqkbnr/ppppp1pp/8/5p2/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+HD.12
+rnbqkbnr/ppppp1pp/8/5p2/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+HD.11
+rnbqkbnr/ppppp1pp/8/5p2/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.07*
+rnbqkbnr/ppppp1pp/8/6N1/4p3/8/PPPP1PPP/RNBQKB1R b KQkq -
+HD.13
+rnbqkbnr/ppppp2p/6p1/5p2/3P4/6P1/PPP1PPBP/RNBQK1NR b KQkq -
+HD.09
+rnbqkbnr/pppppp1p/6p1/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KF.06
+rnbqkbnr/pppppp1p/6p1/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.09*
+rnbqkbnr/pppppp1p/8/6p1/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.11*
+rnbqkbnr/pppppppp/8/8/1P6/8/P1PPPPPP/RNBQKBNR b KQkq -
+VO.10
+rnbqkbnr/pppppppp/8/8/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+EO.64
+rnbqkbnr/pppppppp/8/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+QO.17
+rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+VO.17
+rnbqkbnr/pppppppp/8/8/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+VO.07
+rnbqkbnr/pppppppp/8/8/6P1/8/PPPPPP1P/RNBQKBNR b KQkq -
+VO.11
+rnbqkbnr/pppppppp/8/8/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+VO.08
+rnbqkbnr/pppppppp/8/8/8/2N5/PPPPPPPP/R1BQKBNR b KQkq -
+VO.15
+rnbqkbnr/pppppppp/8/8/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+VO.12
+rnbqkbnr/pppppppp/8/8/8/3P4/PPP1PPPP/RNBQKBNR b KQkq -
+VO.13
+rnbqkbnr/pppppppp/8/8/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+QP.11
+rnbqkbnr/pppppppp/8/8/8/6P1/PPPPPP1P/RNBQKBNR b KQkq -
+VO.09
+rnbqkbnr/pppppppp/8/8/8/7N/PPPPPPPP/RNBQKB1R b KQkq -
+VO.16
+rnbqkbnr/pppppppp/8/8/8/P7/1PPPPPPP/RNBQKBNR b KQkq -
+VO.14
+rnbqr1k1/1ppp1ppp/1b3n2/p3p3/1P2P3/P1N2N2/2PPBPPP/R1BQ1RK1 w - -
+RL.18*
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N1P/2P1BPP1/R1BQ1RK1 b - -
+RL.22*
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N2/1BP1BPPP/R2Q1RK1 b - -
+RL.26*
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+RL.21*
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P2P1N2/2P1BPPP/RNBQ1RK1 b - -
+RL.25*
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4PP2/2N2N2/PP2B1PP/R1BQK2R w KQ -
+BI.29
+rnbqr1k1/pp3pbp/3p1np1/2pP4/8/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+BI.23
+rnbqr1k1/pp3ppp/1bp2n2/3pp3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+RL.20*
+rnbqr1k1/ppbp1pp1/2p2n1p/4p3/NP2P3/P2P1N2/2P1BPPP/R1BQ1RK1 w - -
+RL.23*
+rnbqr1k1/pppp1ppp/1b3n2/4p3/1P2P3/P1N2N2/2PPBPPP/R1BQK2R w KQ -
+RL.17*
+rnbqr1k1/pppp1ppp/1b3n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQK2R b KQ -
+RL.19*
+rnbqr1k1/pppp1ppp/5n2/b3p3/4P3/P1NP1N2/1PP1BPPP/R1BQK2R b KQ -
+RL.16*
--- /dev/null
+
+You'll find the following files:
+
+fen.doc
+long001.idx
+eco000.idx
+nic000.idx
+changes.txt
+
+long.idx is standard English long name
+eco.idx is the ECO classification scheme
+nic.idx is the NIC classification scheme
+
+Current features:
+
+Include color reversed positions (tagged with a *).
+
+Please do not modify any of these files and then distribute, since I do
+not want multiple versions of these floating around and confusing people.
+If there is something you'd like to see added or changed, please contact
+me so we can do it together and keep everything coherent. The next
+versions planned will hopefully feature *much* greater compression of data,
+and the abilility to recognize a transposition out of one main line and
+into another (there is a difference between very early positions and deep
+main lines).
+
+Chris Long {clong@cnj.digex.net, clong@eden.rutgers.edu}
--- /dev/null
+lasker/data/com_help
--- /dev/null
+/_help/1.1/Thu Jun 6 08:56:54 2002//
+/abuser/1.1/Thu Jun 6 08:56:54 2002//
+/addresses/1.1/Thu Jun 6 08:56:54 2002//
+/adjournments/1.1/Thu Jun 6 08:56:55 2002//
+/adjud_info/1.1/Thu Jun 6 08:56:55 2002//
+/adm-info/1.1/Thu Jun 6 08:56:55 2002//
+/adm-new/1.1/Thu Jun 6 08:56:55 2002//
+/adm_info/1.1/Thu Jun 6 08:56:55 2002//
+/adm_new/1.1/Thu Jun 6 08:56:55 2002//
+/admins/1.1/Thu Jun 6 08:56:55 2002//
+/allobservers/1.1/Thu Jun 6 08:56:55 2002//
+/analysis/1.1/Thu Jun 6 08:56:55 2002//
+/backward/1.1/Thu Jun 6 08:56:55 2002//
+/chan_1/1.1/Thu Jun 6 08:56:55 2002//
+/channel/1.1/Thu Jun 6 08:56:55 2002//
+/clearmessages/1.1/Thu Jun 6 08:56:55 2002//
+/cls/1.1/Thu Jun 6 08:56:55 2002//
+/cls_info/1.1/Thu Jun 6 08:56:55 2002//
+/courtesyabort/1.1/Thu Jun 6 08:56:55 2002//
+/credit/1.1/Thu Jun 6 08:56:55 2002//
+/date/1.1/Thu Jun 6 08:56:55 2002//
+/decline/1.1/Thu Jun 6 08:56:55 2002//
+/draw/1.1/Thu Jun 6 08:56:55 2002//
+/eco/1.1/Thu Jun 6 08:56:55 2002//
+/eggo/1.1/Thu Jun 6 08:56:55 2002//
+/fics-lingo/1.1/Thu Jun 6 08:56:55 2002//
+/fics_lingo/1.1/Thu Jun 6 08:56:55 2002//
+/ficsfaq/1.1/Thu Jun 6 08:56:55 2002//
+/fixes/1.1/Thu Jun 6 08:56:55 2002//
+/ftp-hints/1.1/Thu Jun 6 08:56:55 2002//
+/ftp_hints/1.1/Thu Jun 6 08:56:55 2002//
+/glicko/1.1/Thu Jun 6 08:56:55 2002//
+/gm_game/1.1/Thu Jun 6 08:56:55 2002//
+/goboard/1.1/Thu Jun 6 08:56:55 2002//
+/gonum/1.1/Thu Jun 6 08:56:55 2002//
+/handle/1.1/Thu Jun 6 08:56:55 2002//
+/hrank/1.1/Thu Jun 6 08:56:55 2002//
+/inchannel/1.1/Thu Jun 6 08:56:55 2002//
+/index/1.1/Thu Jun 6 08:56:55 2002//
+/inetchesslib/1.1/Thu Jun 6 08:56:55 2002//
+/intro0/1.1/Thu Jun 6 08:56:55 2002//
+/intro1/1.1/Thu Jun 6 08:56:55 2002//
+/intro2/1.1/Thu Jun 6 08:56:55 2002//
+/intro3/1.1/Thu Jun 6 08:56:55 2002//
+/intro4/1.1/Thu Jun 6 08:56:55 2002//
+/intro5/1.1/Thu Jun 6 08:56:55 2002//
+/intro6/1.1/Thu Jun 6 08:56:55 2002//
+/intro7/1.1/Thu Jun 6 08:56:55 2002//
+/intro_information/1.1/Thu Jun 6 08:56:55 2002//
+/intro_moving/1.1/Thu Jun 6 08:56:55 2002//
+/intro_playing/1.1/Thu Jun 6 08:56:55 2002//
+/intro_settings/1.1/Thu Jun 6 08:56:55 2002//
+/intro_special/1.1/Thu Jun 6 08:56:55 2002//
+/lag/1.1/Thu Jun 6 08:56:55 2002//
+/lecture1/1.1/Thu Jun 6 08:56:55 2002//
+/limits/1.1/Thu Jun 6 08:56:55 2002//
+/lists/1.1/Thu Jun 6 08:56:55 2002//
+/mailmess/1.1/Thu Jun 6 08:56:55 2002//
+/mailmoves/1.1/Thu Jun 6 08:56:55 2002//
+/mailoldmoves/1.1/Thu Jun 6 08:56:55 2002//
+/mailstored/1.1/Thu Jun 6 08:56:55 2002//
+/moretime/1.1/Thu Jun 6 08:56:55 2002//
+/motd.std/1.1/Thu Jun 6 08:56:55 2002//
+/motd_help/1.1/Thu Jun 6 08:56:55 2002//
+/moves/1.1/Thu Jun 6 08:56:55 2002//
+/newrating/1.1/Thu Jun 6 08:56:55 2002//
+/news/1.1/Thu Jun 6 08:56:55 2002//
+/next/1.1/Thu Jun 6 08:56:55 2002//
+/oldmoves/1.1/Thu Jun 6 08:56:55 2002//
+/pause/1.1/Thu Jun 6 08:56:56 2002//
+/pending/1.1/Thu Jun 6 08:56:56 2002//
+/rank/1.1/Thu Jun 6 08:56:56 2002//
+/register/1.1/Thu Jun 6 08:56:56 2002//
+/register.dist/1.1/Thu Jun 6 08:56:56 2002//
+/register.email/1.1/Thu Jun 6 08:56:56 2002//
+/servers/1.1/Thu Jun 6 08:56:56 2002//
+/shout_abuse/1.1/Thu Jun 6 08:56:56 2002//
+/shout_quota/1.1/Thu Jun 6 08:56:56 2002//
+/showlist/1.1/Thu Jun 6 08:56:56 2002//
+/simabort/1.1/Thu Jun 6 08:56:56 2002//
+/simadjourn/1.1/Thu Jun 6 08:56:56 2002//
+/simallabort/1.1/Thu Jun 6 08:56:56 2002//
+/simalladjourn/1.1/Thu Jun 6 08:56:56 2002//
+/simgames/1.1/Thu Jun 6 08:56:56 2002//
+/simmatch/1.1/Thu Jun 6 08:56:56 2002//
+/simnext/1.1/Thu Jun 6 08:56:56 2002//
+/simopen/1.1/Thu Jun 6 08:56:56 2002//
+/simpass/1.1/Thu Jun 6 08:56:56 2002//
+/simprev/1.1/Thu Jun 6 08:56:56 2002//
+/simuls/1.1/Thu Jun 6 08:56:56 2002//
+/soapbox/1.1/Thu Jun 6 08:56:56 2002//
+/sourcecode/1.1/Thu Jun 6 08:56:56 2002//
+/sublist/1.1/Thu Jun 6 08:56:56 2002//
+/switch/1.1/Thu Jun 6 08:56:56 2002//
+/takeback/1.1/Thu Jun 6 08:56:56 2002//
+/teamgames/1.1/Thu Jun 6 08:56:56 2002//
+/todo/1.1/Thu Jun 6 08:56:56 2002//
+/totals/1.1/Thu Jun 6 08:56:56 2002//
+/unalias/1.1/Thu Jun 6 08:56:56 2002//
+/uncensor/1.1/Thu Jun 6 08:56:56 2002//
+/unexamine/1.1/Thu Jun 6 08:56:56 2002//
+/unnotify/1.1/Thu Jun 6 08:56:56 2002//
+/unobserve/1.1/Thu Jun 6 08:56:56 2002//
+/unpause/1.1/Thu Jun 6 08:56:56 2002//
+/uptime/1.1/Thu Jun 6 08:56:56 2002//
+/uscf_faq/1.1/Thu Jun 6 08:56:56 2002//
+/wild/1.1/Thu Jun 6 08:56:56 2002//
+/withdraw/1.1/Thu Jun 6 08:56:56 2002//
+/znotify/1.1/Thu Jun 6 08:56:56 2002//
+/abort/1.2/Fri Jun 21 14:46:28 2002//
+/accept/1.2/Fri Jun 21 14:46:28 2002//
+/addlist/1.2/Fri Jun 21 14:46:28 2002//
+/adjourn/1.2/Fri Jun 21 14:46:28 2002//
+/adjudication/1.2/Fri Jun 21 14:46:28 2002//
+/alias/1.2/Fri Jun 21 14:46:28 2002//
+/assess/1.2/Fri Jun 21 14:46:28 2002//
+/bell/1.2/Fri Jun 21 14:46:28 2002//
+/best/1.2/Fri Jun 21 14:46:28 2002//
+/blitz/1.2/Fri Jun 21 14:46:28 2002//
+/boards/1.2/Fri Jun 21 14:46:28 2002//
+/busy/1.2/Fri Jun 21 14:46:28 2002//
+/censor/1.2/Fri Jun 21 14:46:28 2002//
+/computers/1.2/Fri Jun 21 14:46:28 2002//
+/cshout/1.2/Fri Jun 21 14:46:28 2002//
+/etiquette/1.2/Fri Jun 21 14:46:28 2002//
+/examine/1.2/Fri Jun 21 14:46:28 2002//
+/finger/1.2/Fri Jun 21 14:46:28 2002//
+/flag/1.2/Fri Jun 21 14:46:28 2002//
+/flip/1.2/Fri Jun 21 14:46:28 2002//
+/formula/1.2/Fri Jun 21 14:46:28 2002//
+/forward/1.2/Fri Jun 21 14:46:28 2002//
+/games/1.2/Fri Jun 21 14:46:28 2002//
+/gnotify/1.1/Fri Jun 21 07:02:42 2002//
+/handles/1.2/Fri Jun 21 14:46:28 2002//
+/hbest/1.2/Fri Jun 21 14:46:28 2002//
+/highlight/1.2/Fri Jun 21 14:46:28 2002//
+/history/1.2/Fri Jun 21 14:46:28 2002//
+/interfaces/1.2/Fri Jun 21 14:46:28 2002//
+/intro_basics/1.1/Fri Jun 21 07:02:42 2002//
+/intro_general/1.2/Fri Jun 21 14:46:28 2002//
+/intro_talking/1.2/Fri Jun 21 14:46:28 2002//
+/intro_welcome/1.2/Fri Jun 21 14:46:28 2002//
+/it/1.2/Fri Jun 21 14:46:28 2002//
+/journal/1.1/Fri Jun 21 07:02:42 2002//
+/jsave/1.1/Fri Jun 21 07:02:42 2002//
+/kibitz/1.2/Fri Jun 21 14:46:28 2002//
+/kiblevel/1.1/Fri Jun 21 07:02:42 2002//
+/lightning/1.1/Fri Jun 21 07:02:42 2002//
+/llogons/1.2/Fri Jun 21 14:46:28 2002//
+/logons/1.2/Fri Jun 21 14:46:28 2002//
+/match/1.2/Fri Jun 21 14:46:28 2002//
+/messages/1.2/Fri Jun 21 14:46:28 2002//
+/mexamine/1.2/Fri Jun 21 14:46:28 2002//
+/noplay/1.1/Fri Jun 21 07:02:42 2002//
+/notes/1.1/Fri Jun 21 07:02:42 2002//
+/notify/1.2/Fri Jun 21 14:46:28 2002//
+/observe/1.2/Fri Jun 21 14:46:28 2002//
+/open/1.2/Fri Jun 21 14:46:28 2002//
+/password/1.2/Fri Jun 21 14:46:28 2002//
+/private/1.2/Fri Jun 21 14:46:28 2002//
+/promote/1.2/Fri Jun 21 14:46:28 2002//
+/quit/1.2/Fri Jun 21 14:46:28 2002//
+/ratings/1.2/Fri Jun 21 14:46:28 2002//
+/refresh/1.2/Fri Jun 21 14:46:28 2002//
+/resign/1.2/Fri Jun 21 14:46:28 2002//
+/revert/1.2/Fri Jun 21 14:46:28 2002//
+/say/1.2/Fri Jun 21 14:46:28 2002//
+/set/1.2/Fri Jun 21 14:46:28 2002//
+/shout/1.2/Fri Jun 21 14:46:28 2002//
+/smoves/1.2/Fri Jun 21 14:46:28 2002//
+/sposition/1.2/Fri Jun 21 14:46:28 2002//
+/standard/1.1/Fri Jun 21 07:02:42 2002//
+/statistics/1.2/Fri Jun 21 14:46:28 2002//
+/stored/1.2/Fri Jun 21 14:46:28 2002//
+/style/1.2/Fri Jun 21 14:46:28 2002//
+/tell/1.2/Fri Jun 21 14:46:28 2002//
+/time/1.2/Fri Jun 21 14:46:28 2002//
+/timeseal/1.2/Fri Jun 21 14:46:28 2002//
+/untimed/1.1/Fri Jun 21 07:02:42 2002//
+/variables/1.2/Fri Jun 21 14:46:28 2002//
+/whisper/1.2/Fri Jun 21 14:46:28 2002//
+/who/1.2/Fri Jun 21 14:46:28 2002//
+/xtell/1.2/Fri Jun 21 14:46:28 2002//
+/bname/1.1/Sun Jun 23 07:20:52 2002//
+/bsetup/1.1/Sun Jun 23 07:20:52 2002//
+/clrsquare/1.1/Sun Jun 23 07:20:52 2002//
+/fmessage/1.1/Sun Jun 23 07:20:52 2002//
+/getgi/1.1/Sun Jun 23 07:20:52 2002//
+/getpi/1.1/Sun Jun 23 07:20:52 2002//
+/iset/1.1/Sun Jun 23 07:20:52 2002//
+/jkill/1.1/Sun Jun 23 07:20:52 2002//
+/ltell/1.1/Sun Jun 23 06:44:01 2002//
+/partner/1.1/Sun Jun 23 07:20:52 2002//
+/play/1.1/Sun Jun 23 07:20:52 2002//
+/prefresh/1.1/Sun Jun 23 07:20:52 2002//
+/pstat/1.1/Sun Jun 23 07:20:52 2002//
+/ptell/1.1/Sun Jun 23 07:20:52 2002//
+/ptime/1.1/Sun Jun 23 07:20:52 2002//
+/qtell/1.1/Sun Jun 23 07:20:52 2002//
+/seek/1.1/Sun Jun 23 07:20:52 2002//
+/sought/1.1/Sun Jun 23 07:20:52 2002//
+/toggle/1.1/Sun Jun 23 07:20:52 2002//
+/tomove/1.1/Sun Jun 23 07:20:52 2002//
+/tournset/1.1/Sun Jun 23 07:20:52 2002//
+/unseek/1.1/Sun Jun 23 07:20:52 2002//
+/whenshut/1.1/Sun Jun 23 07:20:52 2002//
+/wname/1.1/Sun Jun 23 07:20:52 2002//
+/help/1.3/Thu Jul 22 07:04:37 2004//
+/remote/1.1/Tue Jul 20 04:47:27 2004//
+/rmatch/1.1/Mon Jul 1 04:11:55 2002//
+D
--- /dev/null
+lasker/data/help
--- /dev/null
+
+_help
+
+Type ... In Order To ...
+------------------ --------------------------------------------------
+help chan_1 learn how to ask someone for help
+help commands list all commands
+help help learn how to read help files
+help intro_general get basic information about the chess server
+help intro_welcome get basic information about the introductory files
+help register learn how to register on this server
+index print a list of categories of help files
+index all list all help files, by categories
+info to list all informational (non-command) help files
+quit exit the chess server and end your session
+set shout off reduce the amount of information on your screen while
+ you read the various help files
+
--- /dev/null
+
+abort
+
+Usage: abort
+
+ The "abort" request is used in two situations during a chess game.
+
+ (1) You wish to abort the game for some reason. "Abort" sends a request to
+your opponent that your game be aborted. Your opponent can accept or decline
+your offer. If a proposal to abort has been sent to you, then typing "abort"
+(or "accept") will accept the offer.
+
+ (2) Your opponent has run out of time and you believe that a problem has
+occured with the connection to the chess server. Rather than "flag" your
+opponent and claim a win on time, you can "abort" the game. (This function is
+the old "courtesyabort" command just made easier to use.) If you are both out
+of time, however, (a) the abort command will be sent as a request, but (b) you
+can "flag" and the result will be a draw.
+
+ An aborted game is canceled; no changes in ratings occur, the game is not
+stored, and it is not listed in history or counted as a completed game in your
+statistics.
+
+See Also: accept decline flag lag pending
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+
+abuser
+
+ The admins maintain a private list of individuals who have abused the chess
+server by intentionally disconnecting in lost positions. If you suspect that
+someone disconnected intentionally, please contact an admin. The admin will
+review the situation. If you are unable to connect with your opponent in
+order to resume your game, you may also want to seek an adjudication.
+
+ If a user has too many stored games, the user may also be placed on the
+abuser list until more of the adjourned games are completed or adjudicated.
+
+ Being on the abuser list has these affects: (a) abusers may have match
+requests automatically declined if the opponent has "!abuser" in the formula,
+and (b) abusers who disconnect while playing a game forfeit the game
+automatically.
+
+See Also: adjudication etiquette formula shout_abuse showlist stored
+variables
+
+[Last modified: September 12, 1995 -- Friar]
+
--- /dev/null
+
+accept
+
+Usage: accept [1-n, all, abort, adjourn, draw, match, pause, player, simul,
+switch, takeback]
+
+ Accepts an offer that has been made to you. If no parameter is given and
+there is only one offer, you accept it. If there is more than one offer
+pending (for example, multiple match offers) you will shown a list of pening
+offers and asked which one to accept. Then you must specify which offer to
+accept. You can either choose the offer by number, or by type (such as draw,
+adjourn, abort, or takeback). "All" accepts all pending offers.
+
+See Also: decline pending match draw adjourn abort takeback
+
+[Last modified: October 9, 1995 -- Friar]
+
--- /dev/null
+
+addlist
+
+Usage: addlist list information
+
+ Adds information to the list in question. There are several kinds of lists
+on the server. Some can only be modified by admins; others can be modified by
+all users. "Sublist" command removes information from a list.
+
+ The standard alias for "addlist" is "+". For example, "addlist notify
+Stravinsky" could be typed as "+notify Stravinsky" instead.
+
+See Also: admins alias showlists sublist
+
+[Last modified: November 26, 1995 -- Friar]
+
--- /dev/null
+
+address
+
+The Internet Chess Servers are services that you can telnet to and use to play
+chess with many other players around the world, both human and machine.
+
+The following is a list of the main servers using a version of FICS:
+
+ A-FICS: ics.onenet.net 5000 (164.58.253.10 5000) Main US server
+ E-FICS: krypton.daimi.aau.dk 5000 (130.225.18.157 5000) Main EURO server
+ D-FICS: dds.hacktic.nl 5000 (193.78.33.69 5000) Dutch server
+ B-FICS: holly.csv.warwick.ac.uk 5000 (137.205.192.12 5000) British server
+ ?-FICS: chess.unix-ag.uni-kl.de 5000 (131.246.89.3 5000) German server
+ M-FICS: wisdom.weizmann.ac.il 5000 (132.76.80.77 5000) Mid-east server
+
+Alternative sites:
+
+ chess.pitt.edu 5000 (136.142.81.40 5000) USA, Pittsburg PA
+ rogue.coe.ohio-state.edu 5000 (128.146.144.12 5000) USA, Columbus, OH
+ getnet.com 4000 (204.157.9.29 4000) USA, Phoenix, AZ
+
+Internet Chess Club (commercial chess server):
+
+ chess.lm.com 5000 (192.231.221.16 5000) USA, Pittsburgh, PA
+
+WWW-servers:
+
+ URL: http://chess.onenet.net/chess/
+
+FTP-servers:
+
+ chess.onenet.net (164.58.253.10)
+ ftp.math.uni-hamburg.de (134.100.220.2)
+ ftp.daimi.aau.dk [for timeseal files for use on Euro FICS]
+
+To connect to a chess server use: "telnet <address> 5000"
+To connect to an ftp server use: "ftp <server>" (Login: ftp, Passwd:
+\ <emailaddr>)
+
--- /dev/null
+
+adjourn
+
+Usage: adjourn
+
+ Sends a request to your opponent that a game be discontinued and saved for
+later play. If a proposal to adjourn is pending for you, then typing adjourn
+(or accept) will accept the offer. If your opponent is out of time, the
+adjourn request is accepted automatically (a courtesy adjournment).
+
+ Games that are adjourned can be resumed later by using the match command
+when your opponent is logged on. They can be resigned even when your opponent
+is not logged on. They can also be adjudicated by an admin (see
+"adjudication" help file). For more information on these options, see the
+"adjournments" help file. Use "stored" to view the list of your adjourned
+games. If you log on and a user with whom you have an adjourned game is also
+on, you will be notified automatically that he/she is logged on.
+
+See Also: accept adjudication adjournments decline match pending resign
+stored
+
+[Last modified: December 17, 1995 -- Friar]
+
--- /dev/null
+
+adjournments
+
+ Adjourned games are stored by the server until one of three things occurs:
+(a) the game is later resumed and completed, (b) one player resigns, or (c)
+the game is adjudicated. Adjourned games can also be examined for purposes of
+analysis. Typed "stored" to view the list of your adjourned games. Games are
+adjourned either by agreement of both players or if a player disconnects
+suddenly; games are not adjourned if the server crashes, however.
+
+
+RESUMING AN ADJOURNED GAME
+
+ Your game can be resumed when your opponent is logged on to the server.
+Type "match opponent_name" to request that you and your opponent continue your
+game. Your opponent can either accept or decline this request.
+
+
+RESIGNING AN ADJOURNED GAME
+
+ Your game can be resigned even when your opponent is not logged on. Type
+"resign opponent_name" to do this. Your opponent will be notified of your
+decision.
+
+
+ADJUDICATION OF AN ADJOURNED GAME
+
+ If you have difficulty resuming your game with your opponent after repeated
+attempts, you can have your game adjudicated by an admin. The "adjudication"
+help file outlines the procedure to follow for requesting an adjudication.
+
+
+EXAMINING AN ADJOURNED GAME
+
+ You can examine an adjourned game using the "examine" command. You will be
+able to analyze possible continuations of the game. For the most part, this
+analysis has the same restrictions as adjournments for over-the-board chess
+games: consultation is permitted. However, when your game resumes, you must
+play without consultation or notes of any kind.
+
+
+See Also: adjourn adjudication examine match resign stored
+
+[Last modified: July 20, 1995 -- Friar]
+
--- /dev/null
+
+adjud_info
+
+RESTRICTED TO ADMINISTRATORS.
+
+ Games should be adjudicated as a win for a player only if the game is an
+obvious (theoretical) win. For example, (a) K+R vs. K, or (b) up a queen in
+the middlegame. You may also grant a win due to time IF (1) the player
+requests a win on this basis and (2) the conditions (namely clocking settings)
+warrant it.
+
+ If the player seeks a draw, then the game should be dead equal in the
+endgame.
+
+ Abort adjudications are appropriate if the game has lasted only a few moves
+and neither player can speak of an advantage: i.e., 1. d4 d5, 2. c4 c6, 3. Nf3
+could be aborted. Games should *not* be aborted if one side has an advantage.
+For example, 1. d4 d5, 2. c4 e6, 3. c5 should *not* be adjudicated as an
+abort, especially if white wants the abort.
+
+ To list games for which adjudications have been requested, type "ahelp
+adjrequests".
+
+See ahelp: adjudicate
+See help: adjudication
+
+[Last modified: July 1, 1995 -- Friar]
+
--- /dev/null
+
+adjudication
+
+ Whenever possible, please finish games that have been adjourned. You should
+attempt to complete the game by messaging your opponents, trying to find times
+to complete the games, and giving them ample opportunity to do so. Users are
+on different time schedules, so patience should be practiced.
+
+ If -- after repeated attempts -- an opponent will not resume his/her game
+with you, you may request an adjudication. You can ask for a game to be
+adjudicated as a win, a draw or to be aborted (you do not need an adjudication
+in order to resign a game; see the "resign" help file). Adjudications are
+made by admins who are skilled at chess. The admin will look at the position
+and decide on a result. Please note that the admin's decision is final. If a
+genuine mistake has been made, the adjudicator would probably like feedback,
+although at that stage nothing may change the result and the changes in
+ratings that may have occurred. Adjudications take time and effort,
+especially on a server with many users, so only ask for an adjudication when
+you absolutely need one.
+
+ To request an adjucation, "message adjudicate <request>", that is, send a
+message to the special Adjudicate account ("Adjudicate" is not the handle of a
+user). In your message for adjudication you should gove the name of your
+opponent and what you think the result should be -- win, draw or abort. For
+example:
+
+ message adjudicate l want my game with DAV to be a draw; neither of us
+ can make progress or gain an advantage.
+
+If you have a certain line of play you will follow in order to preserve the
+win or draw, please mention it.
+
+ An admin will check the account regularly and decide the game. You and your
+opponent will be messaged concerning the result.
+
+
+REMINDERS:
+
+(a) The command "stored" gives a list of your stored (adjourned) games.
+
+(b) "Match [opponent]" is used to continue resumed games.
+
+See also: abuser adjournments match stored
+
+[Last modified: October 17, 1995 -- Friar]
+
--- /dev/null
+
+Information about FICS administrators
+
+ FICS is coordinated by several administrators ("admins") who ensure that
+FICS is working properly and deal with problem situations and cases of abuse
+(see etiquette). Certain commands that regulate FICS can only be used by
+admins.
+
+ The group of admins is small in order to keep things fair and uniform. For
+the moment, FICS has a sufficient number of admins for its needs, so new
+admins are not being added.
+
+ If you have a question, problem situation or concern as a FICS user, feel
+free to contact an admin. They are designated by (*) on "who" lists. To see
+a list of current admins, type "=admin".
+
+ Admins tend to listen to FICS channel 1. To contact several admins at once,
+you can "tell" to channel 1.
+
+See Also: admins etiquette intro0 channel tell who
+
--- /dev/null
+
+adm-new
+
+About becoming an FICS administrator
+
+ Thank you for asking about how someone becomes an FICS administrator
+("admin"). As the "adm-info" help file notes, the number of FICS admins is
+kept small for several reasons. At the moment, we are not accepting
+applications from anyone to be an admin. If additional admins are needed, we
+will contact you.
+
+ In the meantime, the best way for you to help with FICS needs is to monitor
+messages on the various FICS channels and help users who have questions, let
+us know about bugs you find (message to "bug"), and make suggestions about
+improvements you would like to see implemented (message to "suggestion" or to
+"helpfiles"). If you have code you'd like to contribute, contact one of the
+programming admins (see "admins" help file for a listing). Typing "=admin"
+lists the current admins. Typing "in 0" will give a list of admins currently
+logged on.
+
+See Also: admins adm-info
+
+[Last modified: June 11, 1995 -- Friar]
+
--- /dev/null
+
+adm_info
+
+Information about server administrators (admins)
+
+ This chess server is coordinated by several administrators ("admins") who
+ensure that the server is working properly and deal with problem situations
+and cases of abuse (see etiquette and abuser). Certain commands that regulate
+the server can only be used by admins.
+
+ The group of admins is small in order to keep things fair and uniform.
+For the moment, the server has a sufficient number of admins for its needs, so
+new admins are not being added (see adm_new).
+
+ If you have a question, problem situation or concern as a user of this
+server, feel free to contact an admin. For the most part, they are designated
+by (*) on "who" lists. They are also on channel 0 (the admin channel). Type
+"in 0" to see which admins are logged on. To see a current list of all
+admins, type "=admin". The "admins" help file indicates the role each admin
+plays on the server.
+
+ Admins tend to listen to channel 1. To contact several admins at once, you
+can "tell" to channel 1. You can also "message" an admin, especially if you
+need to relay detailed information. Special accounts have been set aside for
+feedback from users; these are listed in the "admins" help file.
+
+See Also: abuser adm_new admins channel etiquette inchannel
+intro_welcome message tell who
+
+[Last modified: September 9, 1995 -- Friar]
+
--- /dev/null
+
+adm_new
+
+About becoming an FICS administrator
+
+ Thank you for asking about how someone becomes an FICS administrator
+("admin"). As the "adm_info" help file notes, the number of FICS admins is
+kept small for several reasons. At the moment, we are not accepting
+applications from anyone to be an admin. If additional admins are needed, we
+will contact you.
+
+ In the meantime, the best way for you to help with FICS needs is to monitor
+messages on the various FICS channels and help users who have questions, let
+us know about bugs you find (message to "bug"), and make suggestions about
+improvements you would like to see implemented (message to "suggestion" or to
+"helpfiles"). If you have code you'd like to contribute, contact one of the
+programming admins (see "admins" help file for a listing). Typing "=admin"
+lists the current admins. Typing "in 0" will give a list of admins currently
+logged on.
+
+See Also: admins adm_info
+
+[Last modified: September 9, 1995 -- Friar]
+
--- /dev/null
+
+admins
+
+ Admins on this server have various functions. Many are here solely for
+programming reasons; when they are logged on, they are often busy and working
+with the server code. Other admins are here for general assistance to users.
+There are also special accounts that make it easy for users to give the admins
+feedback, suggestions and special requests. Here is a breakdown....
+
+Programming admins: cranium Cthulhu DAV foxbat Grimm Hawk hersco
+ loon Mann Shane Sparky
+
+General admins: Clovis equiLibre Friar Len McKeork schert
+ Solid sveshi Sparky Thanatos TheDane
+
+Special admin accounts: adjudicate Bug filter helpfiles Suggestion
+
+
+Note: Admins have been chosen based on some simple but important criteria.
+ Programmer admins obviously are chosen for ability and willingness
+ to volunteer much time and energy toward the GNU-ICS project. In
+ general, however, a good working knowledge of the game itself along
+ with some practicle tournamant experience is quite valuable. Even
+ more valuable is Tournamant directorship experience either on the club
+ or national level. Also of great value is a knowledge of different
+ computers and operating systems and the ability to help new players
+ with setting up interfaces and getting started toward their first
+ game. :-)
+
+ Sparky
+
+[Minor edits: September 19, 1995 -- Friar]
+
+See Also: adjudication adm_info adm_new
+
--- /dev/null
+
+alias
+
+Usage: alias [word [string]]
+
+ Sets up a command alias so that "word" is equivalent to typing "string". If
+"string" is omitted then the current value of "word" is displayed. If both
+parameters are omitted, then all of your aliases are displayed.
+
+ "alias" -- lists all of your aliases
+ "alias word" -- gives your alias for "word"
+ "alias word string" -- creates/updates an alias for you so that typing
+ "word" is equivalent to typing "string"
+
+ Use the "unalias" command to remove an alias.
+
+
+EXAMPLES
+
+ Here are some sample aliases that may be useful to you. They are listed
+here in order to give you some idea of what is possible. Get ideas from other
+users as well.
+
+ fun say Fun game!
+ gg say Good game!
+ gm say Good move!
+ idle set busy is busy. Please 'message' to contact him.
+ mb match @ 5 12
+ mood1 set formula f2 & f4
+ ms match @ 10 10
+ ps who as
+ pw who aw
+ ty say Thank you for the game.
+ w4 match @ 10 10 0 0 wild 4
+ wave it waves to @
+
+
+SYSTEM ALIASES
+
+ There are many system aliases that everyone has by default; you do not need
+to set them up, they are already there. Here is the list:
+
+ a accept . tell .
+ bye quit , tell ,
+ cls help cls ! shout
+ exit quit : it
+ f finger ? help
+ go goboard * kibitz
+ goto goboard + addlist
+ hi history - sublist
+ logout quit # whisper
+ m match
+ more next
+ p who a
+ players who a
+ re refresh
+ saa simallabort
+ sab simabort
+ sadj simadjourn
+ saadj simalladjourn
+ sh shout
+ sn simnext
+ sp simprev
+ t tell
+ v variables
+ vars variables
+ w who
+ znotl znotify
+
+ Other system aliases are added from time to time. The help files for the
+different commands will have the most updated information.
+
+WARNING:
+
+ Becareful to avoid using an alias that can also stand for another command on
+the server. For example, "fg" could be a chess move (for f-pawn X g-pawn), so
+don't have "fg" be an alias. For similar reasons, don't use "t" as an alias
+since it is already assigned as an alias for "tell". For example, avoid using
+"hi" to mean not "history" but something else, like "tell @ Hello there. How
+are you?" If you later "unalias" your "hi" alias, the "hi" system alias for
+"history" may not come back automatically.
+
+SPECIAL NOTES:
+
+ (1) Aliases can use the "@" wildcard symbol and thus save you a lot of
+typing for routine statements or requests. For example, using the "mb" alias,
+you would type "mb Shane" and have the same request sent as if you had typed
+"match Shane 5 12".
+
+ (2) Aliases are not transitive. This sequence of commands ...
+
+ alias foo bar
+ alias bar baz
+
+... will NOT result in "foo" being equivalent to "baz".
+
+ (3) Because of #3, use the full spelling of a command, not an abbreviation,
+when creating an alias. This procedure also ensures that the alias will work
+properly.
+
+ (4) You may not create an alias for the quit command.
+
+
+See Also: unalias [and the various commands themselves, of course]
+
+[Last modified: December 17, 1995 -- Friar]
+
--- /dev/null
+
+allobservers
+
+Usage: allobservers [game,user]
+
+ If a game is specified then all users observing or examining that game are
+displayed. However, if there are no observers for that game, nothing will be
+displayed.
+
+ If no game is specified, then all users observing or examining games in
+progress are displayed. However, if there are no observers or examining for
+ANY game, nothing will be displayed.
+
+ The display will have this format: Game #, Players, Observers. For example:
+
+ Observing 18 [DAV vs. friar]: Thumper, Charity, Shane
+ Examining 29 (scratch): #Friar, loon
+
+For examined games, there are examiners (people changing the position, noted
+by #) and observers.
+
+See Also: examine observe
+
+[Last modified: June 29, 1995 -- Friar]
--- /dev/null
+
+ChessT is a well-experienced annotator using top chess programs and self-
+written software (stressing on the human-side). He is willing to perform
+thorough analysis on openings, middle-games, endgames & combinations. User's
+games & details can be sent to: danymozs@NetVision.net.il Or send as a
+MESSAGE to ChessT. Analysis given on the spot when ChessT is here.
--- /dev/null
+
+assess
+
+Usage: assess [user1 [user2]]
+
+ Displays how ratings will be affected by the possible outcomes of a chess
+match between two users. If both parameters are omitted ("assess") and you
+are playing a game, then the command will display the possible ratings changes
+from your game with your current opponent (if you are not playing a game, you
+will be told that). If only user1 is given ("assess user1"), then the command
+will display the possible ratings changes from a game you would have with
+user1. If both parameters are given ("assess user1 user2"), then the command
+will display possible ratings results of a game between user1 and user2.
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+
+backward
+
+Usage: backward [#]
+
+ This command is used by a person examining a game in order to move backward
+in the sequence of the game's moves. If # is not specified, 1 will be used.
+
+ In the case of a stored game, you may move forward again using the "forward"
+command, but in the case of a new game you will need to move the pieces again.
+
+SPECIAL NOTE: The "revert" command is a way to move backward to the branch
+from the main variation being examined.
+
+See Also: examine forward revert
+
+[Last modified: June 29, 1995 -- Friar]
+
--- /dev/null
+
+bell
+
+Usage: bell
+
+ Toggles your 'bell' variable. Equivalent to "set bell". Having bell on
+affects beeps you may receive from the server or your interface.
+
+See Also: variables
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+
+best
+
+Usage: best [b|s|w]
+
+ Displays the 20 highest-rated players in the three different ratings
+categories: Blitz, Standard and Wild. Computers are in the listing. Use
+"hbest" to see the top 20 humans.
+
+ Using "best" alone will give all three lists. Using one or more of the
+arguments b, s or w is a request to give only the blitz, standard and/or wild
+best lists, respectively. For example, "best bw" will show the top 20 players
+in blitz and wild chess; the top standard players will not be listed.
+
+ Use "rank" and "hrank" in order to see where a given player is ranked.
+
+See Also: hbest hrank rank
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+
+blitz
+
+ There are four types of regular (not wild or bughouse) chess played on this
+chess server: Untimed, Lightning, Blitz and Standard.
+
+ A game is "Blitz" if the expected duration of the game is between 3 and 15
+minutes per player. "Expected duration" is determined by a formula that takes
+into account both the Start time and the Increment (Inc) value. Here is the
+formula:
+
+ Expected duration = (Start + Inc*2/3)
+
+Thus, a Blitz game is one that is expected to last between 3 and 15 minutes
+for each player (or from 10 to 30 minutes combined). Lightning games are
+those with expected durations less than 3 minutes per player, while Standard
+games are those with expected durations more than 15 minutes per player.
+
+ The following table shows the dividing lines between Blitz and Lightning on
+the one hand and Blitz and Standard on the other hand. those two types of
+matches. [Thanks to schwartzeer for the original calculations between Blitz
+and Standard. :) ]
+
+ Slowest Lightning Fastest Blitz Slowest Blitz Fastest Standard
+ ------------------------------------ ------------------------------------
+ Mins Incr Mins Incr Mins Incr Mins Incr
+ ------------------------------------ ------------------------------------
+ 0 4 0 5 0 22 0 23
+ 1 2 1 3 1 20 1 21
+ 2 1 2 2 2 19 2 20
+ -------- 3 0 3 17 3 18
+ 4 16 4 17
+ 5 14 5 15
+ 6 13 6 14
+ 7 11 7 12
+ 8 10 8 11
+ 9 8 9 9
+ 10 7 10 8
+ 11 5 11 6
+ 12 4 12 5
+ 13 2 13 3
+ 14 1 14 2
+ -------- 15 0
+
+ For example, a game with a Start of 2 minutes will be Blitz if the Increment
+is from 2 to 19; but it will be Lightning with an Inc of 0 or 1 and Standard
+if the Inc is 20 or higher.
+
+ You can list logged on users according to their Blitz ratings by typing "who
+b" (by default, ratings in 'who' listings will be blitz unless you specifiy
+otherwise). "Blitz" is also a variable that can be used in formulas in order
+to screen match requests.
+
+See Also: formula lightning match standard untimed who
+
+[Last modified: December 25, 1995 -- Friar]
+
--- /dev/null
+
+bname
+
+Usage: bname <name>
+
+This command sets the black players name shown in the current game you
+are playing or examining.
+
--- /dev/null
+
+boards
+
+Usage: boards [category]
+
+ If category is given then this lists all available boards for that
+category. If the parameter is omitted, then this lists all available
+categories. The current board categories are:
+
+ standard
+ openings
+ wild
+ chessercizes
+ test
+ material-odds
+ misc
+
+ In order to find out what is loaded for one of these categories, type
+"boards <category>". For example, "boards openings" will list the various
+openings you can start a game from.
+
+ In order to start a game from one of these positions, you need to use all of
+the arguments in the match command and also include the board category and the
+specific board you want. For example:
+
+ match red 2 12 0 0 openings ruy-lopez
+
+would request a blitz match with user "red" starting with the "ruy-lopez"
+opening position.
+
+
+SPECIAL NOTE
+
+ At the moment, you cannot access these boards through the examine feature,
+only match.
+
+See Also: match wild
+
+[Last modified: September 22, 1995 -- Friar]
+
--- /dev/null
+
+bsetup
+
+Usage: bsetup [argument]
+
+Summary: Bsetup mode is a special form of the "examine" mode that allows you
+to set up any position you want and then use examine mode to analyze it. The
+standard alias for "bsetup" is "setup".
+
+ENTERING BSETUP MODE
+-------------------
+
+ There are two ways to enter bsetup mode: from scratch and from "examine"
+mode. The difference in the two procedures concerns the start position of the
+board in bsetup mode: empty board versus a board position.
+
+ (a) FROM SCRATCH -- When nothing else is active (that is, you are not
+playing or examining another game), type either "bsetup" or "examine setup".
+The board will be totally empty when you enter bsetup mode; you will have to
+place all of the pieces where you want to have them.
+
+ (b) FROM WITHIN EXAMINE MODE -- Typing "bsetup" during examine mode (namely
+while you are examining a game) places you in "examine bsetup" mode. The move
+list is cleared and a new move list will be established. However, the current
+board position will be used as the starting board position; you can then
+modify that position and arrange the pieces to be where you want them to be.
+
+USING BSETUP MODE
+----------------
+
+ There are several commands you can use in order to create a board position
+and designate which side is going to move next.
+
+ BSETUP CLEAR -- Typing the command "bsetup clear" will give you a new,
+blank, empty board.
+
+ BSETUP START -- Typing the command "bsetup start" will give you the regular
+starting position for a game of chess.
+
+ BSETUP board_category board -- You can load a non-standard board position if
+you want. The chess server has several non-standard boards. They can be
+listed by using the "board" command. For example, "boards openings" will list
+the various openings you can start a game from and "boards wild" will list
+"wild" opening positions. Note: you must first be in bsetup mode in order to
+create a given board position.
+ To create a suicide game, type "bsetup suicide".
+
+ BESETUP FEN position -- You can also set up complete board positions by
+supplying a FEN position. For example:
+
+ bsetup fen rnbqkbnr/pppppppp/8/8/8/3P4/PPP1PPPP/RNBQKBNR
+
+You have to indicate the pieces and blank squares on each rank of the chess
+board, starting with rank 8 (Black's back rank) and going from the a-file to
+the h-file. The '/' mark divides one rank of pieces from another. Letters in
+CAPS mean a White piece (such as 'K' for White King); small letters mean a
+Black piece (such as 'k' for Black King). The numbers (such as 1, 3, 4 and 8)
+refer to the number of *consecutive* blank squares. For example, the fen
+position given above is the one that occurs when White opens the game with
+Pd3. NOTE: You just give the board position, not which side is to move;
+use "tomove" to modify whose move it is.
+
+ Placing pieces -- There are two formats for placing pieces: case sensitive
+and designate color. Either one works. Here is a table of the formats. For
+the "square" portion, enter a square in algebraic notation, such as e4 or h5.
+You can use either "@" or "*" as the special symbol.
+
+ CASE SENSITIVE DESIGNATE COLOR
+
+ Piece White Black White Black
+ ----- -------- -------- --------- ---------
+ king K@square k@square wk@square bk@square
+ queen Q@square q@square wq@square bq@square
+ rook R@square r@square wr@square br@square
+ bishop B@square b@square wb@square bb@square
+ knight N@square n@square wn@square bn@square
+ pawn P@square p@square wp@square bp@square
+
+ Clearing a square -- There are two ways you can clear a square and make it
+empty: either place an 'x' (meaning empty piece) or "clear" the square.
+
+ x@square
+ clrsquare square
+ bsetup clearsquare square
+
+For example, "x@e4", "clrsquare e4" and "bsetup clearsquare e4" would all have
+the same effect: making e4 an open square. NOTE: you do not have to clear a
+square before placing a piece. For example, if there is a Black Queen on e5,
+placing a Black Pawn on e5 will automatically remove the Black Queen.
+
+ BSETUP TOMOVE white|black -- Typing "bsetup tomove white" will have White be
+the player to move next. Typing "bsetup tomove black" will have Black be the
+player to move next. NOTE: You do not need to include the "bsetup" part of
+the command; the "tomove" command works alone once you are in bsetup mode.
+
+ BSETUP wcastle <rights>|bcastle <rights> -- You may also set the castling
+rights for the game. Use "bsetup wcastle <rights>" and "bsetup bcastle
+<rights>" to set the castling rights for White and Black respectively. The
+possible 'rights' are:
+
+ none (no castling)
+ kside (kingside only)
+ qside (queenside only)
+ both (both sides)
+
+When you load a board using bsetup the rights are set up automatically. On a
+cleared board both player's rights are set to 'none'. Therefore if you use a
+ready made board and move the rooks and kings around, you will need to set the
+appropriate castling rights. Castling rights are validated when you exit
+bsetup; if the rights are invalid, you will receive an error message.
+
+ BSETUP EPPOS <file> -- You can indicate whether an "en passant" capture is
+possible, as if a pawn had just been advanced two squares. In this case, you
+need to specify the file of the pawn (a - h). For example, "bsetup eppos c"
+would mean that a pawn on the c-file has just been moved from c7-c5 or from
+c2-c4, depending on the "tomove" setting. NOTE: You need to have a pawn on
+the right square and have the correct player "tomove" in order for the eppos
+command to work; otherwise, you will get an error message.
+
+ RULES -- Lastly! You can also change the rules for the chess game. There
+are different rules for suicide chess, of course ("help suicide_chess"); but
+there are also different castling rules for Fischer Random chess ("help fr")
+and for certain kinds of wild chess ("help wild"). In order to use the
+correct rules, you need to use bsetup to change them.
+
+ bsetup fischer [for Fischer Random chess]
+ bsetup standard [for normal chess -- this is the default]
+ bsetup suicide [for suicide chess]
+ bsetup wild [for wild chess]
+
+
+EXITING BSETUP MODE
+------------------
+
+ BSETUP DONE -- Typing "bsetup done" will exit bsetup mode and start examine
+mode. However, the position will be validated first. For example, the player
+who is not about to move cannot be in check, pawns cannot be on the 1st or 8th
+ranks, each side must have a king, neither side can have more than one king.
+
+ If the position is valid, you will enter examine mode next. If the position
+is invalid, a message will be sent to you and you will remain in bsetup mode.
+
+ UNEXAMINE -- Typing "unexamine" at any point will immediate cancel both
+bsetup and examine modes.
+
+
+SPECIAL NOTES:
+
+(a) Games in bsetup mode will be listed in the "games" display.
+
+(b) Users in bsetup mode will have comments to that effect in their finger
+displays and will have the symbol "#" next to their handles in "who" displays.
+"Tells" to users in bsetup mode will give the feedback that the user is in
+bsetup mode.
+
+(c) You cannot create a position and then play a match with an opponent.
+However, you can examine a game with another user, use "mexamine" to allow the
+other user to move the pieces, and you can alternate moves back and forth as
+if you were playing a game. You will be in examine mode the whole time, of
+course, and the game will not appear in "history" displays.
+
+(d) At present, you cannot use "jsave" in order to save an examined or bsetup
+game to your "journal". This capability is being developed.
+
+(e) A standard alias for "bsetup" is "setup".
+
+(f) You can change the names of the players of the game by using the "wname"
+and "bname" commands.
+
+See also: alias bname board clrsquare examine finger fr games handle
+history journal jsave mexamine suicide_chess tell unexamine who wild
+wname
+
+[Last modified -- October 30, 1997 -- Friar]
--- /dev/null
+
+busy
+
+Usage: set busy string
+
+ Sets your "busy" string. When your busy string is set and people "tell"
+something to you, they will get your busy string as a response. Your busy
+string (if on) will also be displayed right below your name when someone
+"fingers" you. NOTE: Your busy string can be no longer that 45 characters.
+
+Examples of busy strings you might use are:
+ set busy is really busy right now.
+ set busy will be back in 5 minutes.
+ set busy will be idle for a while...
+
+ Typing any command cancels your "busy" status; you don't have to clear it
+yourself.
+
+ It is useful to use an alias for your busy string, if you intend to use it
+frequently. For example:
+ alias idle set busy is away from the keyboard right now
+would set your busy string to "is away from the keyboard right now".
+
+See also: alias finger set tell
+
+[Last modified: October 22, 1995 -- Friar]
+
--- /dev/null
+
+censor
+
+Usage: +|-|= censor [user]
+
+ When a player is on your censor list, you will not hear anything from
+him/her when he/she tells, shouts, matches, kibitzes, whispers and says. When
+users on your censor list send you a direct message using "tell", they will be
+notified of their being on your censor list. Here are the variations of the
+command possible:
+
+ +censor user Add "user" to censor list
+ -censor user Remove "user" from censor list
+ =censor Display your censor list
+
+ Note that "noplay" only filters match requests, not other communications.
+
+See Also: addlist kibitz noplay say shout tell whisper
+
+[Last modified: December 17, 1995 -- Friar]
+
--- /dev/null
+
+chan_1
+
+ Channel 1 is the server help channel. Admins and other helpful,
+knowledgeable users monitor channel 1 and are ready to assist you. It is also
+a general server discussion channel about server issues.
+
+ If you need assistance about something but don't know whom to contact, ask
+your question on channel 1. Here's the procedure:
+
+(1) Type the following lines:
+
+ channel 1 [this will turn channel 1 on for you]
+ tell 1 Can someone help me? [this sends the message to channel 1]
+
+(2) Watch your screen for someone asking you what help you need. You may be
+contacted directly (in a personal tell) or through channel 1 itself (so
+everyone can listen to to the discussion and help out).
+
+(3) If you want to continue talking on channel 1, type:
+
+ tell 1 <message> [everyone on channel 1 will hear you]
+
+(4) When you are done, you can either stay on channel 1, in order to help
+others and/or learn from their questions, or turn off channel 1 by typing:
+
+ channel 1 [this will set channel 1 to off for you]
+
+To see who is listening to channel 1 at any given moment, type "inch 1". A
+list will appear.
+
+See Also: adm-info channel inchannel intro_talking tell
+
+[Last modified: July 18, 1995 -- Friar]
+
--- /dev/null
+
+channel
+
+Usage: channel [0-99]
+
+ Turns the specified channel on and off. If the channel is on, messages sent
+to that channel will appear on your screen. If the channel number is omitted,
+all channels to which you are tuned will be turned off.
+
+ Channel 1 is the general help channel, and of special importance to users.
+The "chan_1" has more details about its use, and gives the general procedure
+for using a channel.
+
+See Also: chan_1 inchannel say tell
+
+-------------------------------------------------------------------------
+List of currently defined channels:
+
+ 0 Admins Only 2 Chess server discussion
+ 1 General Help 3 FICS Programmers' Channel
+
+ 8 Youth Channel 18 The Gambit Channel
+ 20 Forming Team games 21,22 Playing team games
+ 23 Forming SIMULS 46 Forming tournaments (Tomato)
+ 47 Tomato managers
+
+ 32 Movies 35 Music
+ 33 Quacking & Other Duck Topics 36 Mathematics & Physics
+ 34 Sports 37 Philosophy
+
+ 50 General Unlimited Gab 51 The Hormone Channel
+
+ 60 Chess Theory 64 Computer Chess
+ 65 World Chess Championship
+
+ 69 Latin 75 Russian
+ 70 Danish 76 Dutch
+ 71 Scandinavian 77 French
+ 72 German 78 Greek
+ 73 Spanish 79 Icelandic
+ 74 Italian 80 Chinese
+
+ 84 Macintosh Channel
+
+ 90 The STC BUNCH (Players who like 30- to 120-minute Time Controls.)
+ 97 Politics Channel
+ 98 Zippy the Pinhead's Own Channel
+ 99 `The Street Corner Where Nothing Happens'
+-------------------------------------------------------------------------
+
+[Last modified: September 12, 1995 -- Friar]
+
--- /dev/null
+
+clearmessages
+
+Usage: clearmessages [user]
+
+ Clears any message(s) previously messaged to you. If 'user' is omitted, all
+messages will be cleared. If 'user' is included, only the messages from that
+user to you will be cleared.
+
+See Also: messages
+
+[Last modified: June 16, 1995 -- Friar]
+
--- /dev/null
+
+clrsquare
+
+Usage: clrsquare square
+
+ This command is used in "bsetup" mode in order to make a square empty
+(blank). For example, "clrsquare e4" would make square e4 empty. Another way
+to clear a square is by typing "x@square", for example "x@e4".
+
+See Also: bsetup
+
+[Last modified: February 3, 1996 -- Friar]
+
--- /dev/null
+
+cls_info
+
+ Typing "help cls" will clear your screen and set the cursor at the top.
+This command may be useful if you need to clear your screen suddenly for some
+reason (like the boss). Server messages will soon appear again, however.
+
+See Also:
+
+[Last modified: July 11, 1995 -- Friar]
+
--- /dev/null
+
+computers
+
+ Computers may register and play chess matches. However, computers are
+required to be registered so that users can know whether they are playing
+against humans or computers. (Using an unregistered computer is considered to
+be abusive behavior; see etiquette). In order to register a computer,
+contact an admin or use the correct format in the email registration
+procedure. To see a list of computers registered on the server, type
+"=computer". Computers are designated on "who" lists by (C).
+
+See Also: admin etiquette register who
+
+[Last modified: November 26, 1995 -- Friar]
+
--- /dev/null
+Usage: courtesyabort\r
+\r
+ If your opponent's flag has hit zero, this is a one-sided abort\r
+command. It is intended to abort the game if your opponent has gone\r
+net-dead or has terrible lag. It is considered good sportsmanship\r
+to do this rather than claim a win on time when your opponent doesn't\r
+have a fighting chance.\r
+\r
+See Also: flag\r
+\1a
\ No newline at end of file
--- /dev/null
+Credit:
+
+ Michael Moore - Progenitor of the chess server idea and author of
+ the original server. Without him, the chess server
+ might not exist.
+
+ Richard Nash - Original author of FICS.
+
+ Daniel Sleator - Author of AICS and responsible for many of the ideas
+ that makes the chess server as popular as it is.
--- /dev/null
+
+cshout
+
+Usage: cshout message
+LIMITED TO REGISTERED USERS
+
+ This command send a message to all users who are open to hear cshouts. You,
+as the sender, will see displayed the number of users who heard your message.
+
+ NOTE: "Cshout" should be used ONLY for chess-related messages, such as
+questions about chess or announcing being open for certain kinds of chess
+matches. Use "shout" for non-chess messages.
+
+See Also: censor it shout tell variables
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+
+date
+
+Usage: date
+
+ Shows the date and time at the server location as well as Greenwich, England
+(GMT stands for Greenwich Mean Time, a benchmark for converting times from one
+time zone to another).
+
+See Also:
+
+[Last modified: September 9, 1995 -- Friar]
+
--- /dev/null
+
+decline
+
+Usage: decline [1-n, all, abort, adjourn, draw, match, pause, player, simul,
+switch, takeback]
+
+ Decline an offer that has been made to you. If no parameter is given and
+there is only one offer, you decline it. If there is more than one offer (for
+example multiple match offers), then you must specify which offer you want to
+decline. You can decline offers in several ways: by number, by type, all
+offers, or by the player's name making the offer. For example, the command
+"decline match" will decline all pending match offers you have been given.
+The command "decline Shane" will decline the offer made by Shane.
+
+See Also: abort accept adjourn draw match pause pending simul switch
+takeback
+
+[Last modified: June 20, 1995 -- Friar]
+
--- /dev/null
+
+draw
+
+Usage: draw
+
+ Requests a draw from your opponent. A draw means that you neither win nor
+lose your chess match -- the game will be a tie. Ratings are affected,
+however, unless it was an unrated match.
+
+ If your opponent had offered you a draw, then the command draw (or accept)
+would accept the draw offer. To decline a draw offer, either use the decline
+command or make a move instead.
+
+ This command also claims a draw in the case of the 50 move rule or
+3 times repetition. In the case of a draw being requested, the chess server
+will check for these conditions. If one of them is present, the game will be
+drawn even without the opponent accepting the draw.
+
+See also: accept decline
+
+[Last modified: June 11, 1995 -- Friar]
+
--- /dev/null
+
+eco
+
+Usage: eco [game]
+
+ This command displays the category of the opening being played in the game
+requested, whether a game being played or examined.
+
+ eco gives information about the game you are playing
+ eco 2 gives information about game 2
+ eco hawk gives information about the game hawk is playing
+
+ The display includes several kinds of information about the opening being
+played in the game:
+
+ ECO[ ##] Encyclopedia of Chess Openings classification
+ NIC[ ##] New In Chess classification
+ LONG[ ##] Name of opening
+
+The number in the [] is the ## halfmoves used for classifying this game's
+opening according to the data base being used.
+
+ ECO information is also given in a user's "history" display.
+
+See Also: history
+
+[Last modified: August 15, 1995 -- Friar]
+
--- /dev/null
+
+EGGO
+
+ EGGO stands for "Examine Great Games Online". EGGO is an online database
+program that facilitates examining and analyzing great games from players such
+as Fischer, Kasparov, and Karpov. Basically, EGGO allows you to examine a
+game except that the moves come from EGGO's database, not the chess server.
+Currently, EGGO's database contains about 15000 to 20000 games. Type "finger
+EGGO" for more information.
+
+ In order to use EGGO, send EGGO a command; EGGO then processes the command
+and returns the output to you. See below for a list of commands and their
+descriptions.
+
+ EGGO can have only one primary user at a time, meaning only one person at a
+time can select the games to be examined. However, once a game has been
+loaded for examination, other users can paticipate in examining and analyzing
+the game using the "mexamine" and "observe" features of the chess server.
+
+
+STARTING EGGO
+
+ First step, type "observe EGGO". Second step, type "xtell EGGO begin". If
+no other game is being examined, EGGO will make you the examiner -- you will
+then be able to examine a game from EGGO's library. Otherwise, someone else
+is listed as EGGO's main examiner and you will only be able to examine that
+game for the moment. If you want someone else to help examine a game with
+you, use the "mexamine" command. When you are finished examining one game and
+want to examine another, simply use the examine command. Lastly, use the
+unexamine command in order to leave EGGO.
+
+
+EGGO'S COMMANDS (list):
+
+ about examine help revert status
+ begin forward more search who
+
+
+EGGO'S COMMANDS (descriptions):
+
+ ABOUT
+
+ Usage: xtell eggo about
+
+ If someone is already examining an EGGO's game, this command will display
+ information about the game being examined. This command is also useful
+ for knowing EGGO's status. Anyone can use this command.
+
+ BEGIN
+
+ Usage: xtell eggo begin
+
+ If EGGO is not busy, this command starts an EGGO session. If EGGO was
+ already in use, this command will have no effect.
+
+ EXAMINE
+
+ Usage: xtell eggo examine #
+
+ You may use this command after a successful "xtell eggo search" command.
+ For example, "xtell eggo examine 1" will begin examination of game #1 from
+ the search output. You can repeat this command for other games from the
+ search output when you are finished examining your current game. That is,
+ you can type "xtell eggo examine #" for the next game; you do not need to
+ "unexamine" the other game first. (Please do not confuse this use of
+ examine with the normal "examine" command.)
+
+ FORWARD
+
+ Usage: xtell eggo forward [n]
+
+ When you are already examining an EGGO's game, you can go forward 1 or
+ more moves using "xtell EGGO forward [n]". The default value for 'n'
+ is 1. Currently, you cannot go forward more than 20 moves at one time.
+
+ MORE
+
+ Usage: xtell eggo more
+
+ This command allows you view the results of your search command. It will
+ list the next 20 games in the list (if there are any). You must be EGGO's
+ current user to use this command.
+
+ REVERT
+
+ Usage: xtell eggo revert
+
+ After making your own moves when examining an EGGO's game, you can go back
+ to your game's mainline by "xtell eggo revert". (Please do not confuse
+ this command with the normal "revert" command.)
+
+ SEARCH
+
+ Usage: xtell eggo search [player1 {player2} {draw|nodraw}]
+
+ You may use this command after a successful "xtell EGGO begin". The
+ purpose of this command is to search the EGGO game database for games by
+ particular players. "Player1" must be one of the names EGGO recognizes;
+ use the "xtell EGGO who" command to see which names EGGO knows. You can
+ use "draw" and "nodraw" to select a game with a particular result; they
+ are optional.
+
+ "Search" alone without arguments will list the results of your previous
+ search. Here are other examples:
+ xtell eggo search Capablanca
+ xtell eggo search Fischer nodraw
+ xtell eggo search Fischer Spassky
+ xtell eggo search Kasparov Karpov nodraw
+ You can view the results of the search with "xtell EGGO more".
+
+ STATUS
+
+ Usage: xtell eggo status
+
+ This command will display information about EGGO's current status, such as
+ whether EGGO is open or closed, and which game (if any) is being examined.
+
+ WHO
+
+ Usage: xtell eggo who
+
+ This command will list all of the "primary" players known to EGGO. These
+ primary players are used in EGGO's search command. Anyone can use this
+ command whether they are EGGO's current user or not.
+
+
+SPECIAL NOTES:
+
+(a) Since many of the EGGO commands are long, you might want to consider
+creating aliases for the commands you will use a lot (such as "xtell EGGO
+forward"). Suitable aliases will save you a lot of time as you play through
+these games from famous players.
+
+See Also: alias examine mexamine
+
+[Written by Warrior August 18, 1995; last modified: August 21, 1995 -- Friar]
+
--- /dev/null
+
+etiquette
+
+ The goal of FICS is to provide a friendly means for chess enthusiasts to
+play chess games and discuss topics of interest. In order to promote a
+friendly atmosphere, FICS follows simple guidelines and rules of etiquette.
+FICS admins have the authority to warn and (if necessary) sanction users who
+do not follow these guidelines.
+
+
+COMMUNICATIONS
+
+ Please use the various ways of communicating on this server for their
+intended purpose: to foster chess fellowship and companionship.
+
+ Users should refrain from making any statements or engaging in any conduct
+that could be considered abusive, harrassing, offensive or obscene, especially
+with regard to nationality, race, religion or sexual orientation.
+
+ Please avoid having differences of opinion escalate into personal
+confrontations and attacks. Refrain from namecalling and disparaging a user's
+character.
+
+ It is good etiquette to have lengthy discussions about a topic or issue
+using channels rather than shouts. Special topics channels have been created
+for this purpose (the "channel_list" help file lists them). There may be
+times when you are asked to move your discussion to a channel.
+
+ Further examples of abusive communication are given in the "shout_abuse"
+help file.
+
+
+CHESS COMPETITION
+
+ Users should refrain from conduct that ruins the spirit of competition on
+the server. Such misconduct includes:
+
+ (a) intentionally disconnecting in order to avoid losing a chess match
+ -or- to analyze the game and resume playing it later;
+ (b) intentionally losing a chess match in order to inflate another user's
+ rating;
+ (c) using a chess computer to play a match without having the account
+ registered as a computer;
+ (d) registering as a "blindfold" account but using a board while playing
+ (blindfold accounts must use style 9, by the way);
+ (e) letting other people play rated matches using your registered account;
+ (f) giving assistance to a player while he/she is playing a match;
+ (g) receiving assistance from a person, book or computer while you are
+ playing a match;
+ (h) engaging in conduct that interferes with a chess match or a player's
+ being able to concentrate on his/her chess match;
+ (i) intentionally letting your clock run out of time during a chess match
+ rather than resigning or moving in a lost position.
+
+
+PROBLEM SITUATIONS
+
+ Many users have finger notes that explain how they will handle certain
+situations, such as lag and takeback. The issue of transmission lag often
+comes up for discussion. As noted in the "lag" help file, it is not unethical
+to flag your opponent when he/she runs out of time.
+
+ If you suspect that a user is abusing his/her communication privileges
+and/or not following the spirit of competition, feel free to contact an admin
+with details concerning the situation.
+
+See Also: abuser admins blindfold channel channel_list computers handle
+intro_playing intro_talking lag shout_abuse
+
+[Last modified: December 25, 1995 -- Friar]
+
--- /dev/null
+
+examine
+
+Usage: examine [player1 [player2, game_number]
+
+ This command starts a game in the examine mode where you, as the examiner,
+can move the pieces for both white and black, take moves back and analyze side
+variations. You can examine a new game from scratch, a stored (adjourned)
+game, a finished game from "history" or a game in someone's "journal".
+
+
+STARTING EXAMINE MODE
+
+ There are four ways to begin an examine session:
+
+ 1) New Game from Scratch -- "Examine" used alone without any player names
+ begins examine mode for a new game and, in essence, you will be playing
+ yourself. Typing "match your_handle" is also a way to enter examine mode
+ for a new game.
+
+ 2) Stored Games (adjourned) -- "Examine player1" will examine your stored
+ game against player1 (if one exists). "Examine white_player
+ black_player" will examine the stored game (adjourned) between the two
+ players. Example: "examine dav thedane".
+
+ 3) Completed Game from History -- "Examine player1 game_number" will examine
+ that game from player1's "history". Example: "examine theviking 45".
+
+ 4) Game from a Journal -- "Examine player1 game_slot" will examine that game
+ from player1's "journal" (unless the journal is private, namely
+ "jprivate" variable has been set to non-zero). Example: "examine sms B".
+
+
+EXAMINE MODE
+
+ No matter how you start the examine functions, the game will be played from
+the starting position, not the last, stored position.
+
+ While in examine mode, you can move the pieces in order to set up a position
+and/or analyze side variations. There are three special commands you can use
+when examining a stored game:
+
+ forward [#] goes forward # moves (default n=1)
+
+ backward [#] goes backward # moves (default n=1)
+
+ revert goes back to the main variation (the last branch)
+
+For new games, only "backward" works; the other commands have no affect since
+there is no main line stored. Therefore, once you go backward, you will need
+to move the pieces again in order to move forward.
+
+ Lastly, the command "unexamine" leaves the examine mode and ends your
+analysis of the game.
+
+
+GROUP EXAMINE
+
+ Other users can also examine the game you are reviewing. But must you
+decide who these other examiners are. Here are the steps involved:
+
+ (1) The other examiner must first "observe" your game.
+
+ (2) You, as the main examiner, must type "mexamine <user>" in order to give
+ "user" access to the examine mode.
+
+ As long as there is at least one designated examiner of a game, the analysis
+can continue even when the first examiner who started the examine session
+leaves.
+
+ In order to communicate with another examiner of the game, it is best to use
+the "kibitz" command. If you use "whisper", the game's observers but not
+examiners will hear your message.
+
+
+SPECIAL NOTES
+
+(1) Players examining games have a # next to their handles in the (short)
+"who" display, and examined games are listed in both the "games" and
+"allobservers" displays.
+
+(2) "Unexamine" stops your participation in the analysis, and also stops your
+observer status. Other examiners of the game may continue, however, even if
+you started the examine session initially.
+
+(3) Clock times displayed are unimportant, of course, since time is not a
+factor when analyzing games.
+
+
+See Also: allobservers backward forward games history kibitz journal
+match mexamine observe stored unexamine variables whisper who
+
+[Last modified: December 17, 1995 -- Friar]
+
--- /dev/null
+
+ Some people get confused with the words that some people use, so here's an
+explanation of the more common terms and abbreviations.
+
+
+Abbreviation: BRB
+Means: I'll be right back. Person is about to go idle or log off for a few
+ minutes or so..
+
+Abbreviation: BIAS
+Means: Back in a second. (As above)
+
+Abbreviation: ATM
+Means: At the moment.
+
+Abbreviation: IAM
+Means: In a minute.
+
+Abbreviation: IMO
+Means: In my opinion.
+
+Abbreviation: ROTFL
+Means: Rolls on the floor laughing.
+
+Word: wrok
+Means: work - work is a forbidden word :)
+
+Word: Wuah
+Means: greetings - the word muah can also be used with it eg wuah muah!
+
+Word: Thumpa
+Means: greetings
+
+Word: Isbjoern
+Means: Polar bear. A weird concept invented by that master of creativity,
+ TheDane. If someone says this, everyone is meant to repeat it. (It
+ is used to mean greetings). However don't take this literaly, else
+ the server would really slow down. :)
+
+Words: Your plan
+Means: The notes you get when you type finger.
+
+Words: Your finger (notes)
+Means: (As above)
+
+Words: Your notes
+Means: (As above)
+
+Word: Admin
+Means: Administrator or sys-op.
+
+Word: Unreg
+Means: Unregistered - doesn't have an account here.
+
+Word: Muzzle
+Means: Loss of shouting priveledges. You also can't kibitz.
+
+Words: Match someone
+Means: Start a game with someone.
+
+Word: Censor
+Means: Whoever is censored by you can't talk to or match you. You won't see
+ their shouts either.
+
+Word: Filter
+Means: Sites that are filtered cannot have unreg logins from them.
+
+Words: :) :) :) :) :) :)'s at the wonderful wonderful world :)
+Means: Dates back to the 'Court of Queen Eyre' on the old ICS. I think it
+ meant hi everyone.
--- /dev/null
+
+fics_lingo
+
+ Many users on this server use special words and phrases (slang, jargon,
+lingo). Here is an explanation of the more common terms and abbreviations.
+
+
+Admin -- Server administrator or sys-op (systems operator).
+
+ATM -- At the moment.
+
+BIAS -- Back in a second. (similar to brb)
+
+BRB -- I'll be right back. Person is about to go idle or log off for a few
+ minutes or so.
+
+Censor -- Whoever is censored by you can't talk to or match you. You won't
+ see their shouts either.
+
+Filter -- Sites that are filtered cannot have unreg logins from them.
+
+Finger (someone) -- A command used to learn about another user. Also refers
+ to one's notes or "plan". Thus, "finger me" is not meant
+ to be rude. :)
+
+Handle -- Your server name (nickname).
+
+IAM -- In a minute.
+
+IMHO -- In my humble opinion.
+
+IMO -- In my opinion.
+
+Isbjoern -- Polar bear. A weird concept invented by that master of
+ creativity, TheDane. If someone says this, everyone is meant to
+ repeat it. (It is used to mean greetings.) However don't take
+ this literaly, else the server would really slow down. :)
+
+Lag -- Transmission delay, when either the server or the internet slows down.
+
+Match (someone) -- Start a game with someone.
+
+Muzzle -- Loss of shouting privileges. You also can't kibitz.
+
+Notes -- Same as "plan" or "finger" notes.
+
+Plan -- The notes you get when you type "finger".
+
+ROTFL -- Rolls on the floor laughing.
+
+Thumpa -- Greetings!
+
+wrok -- Work [work is a forbidden word :) ]
+
+Wuah -- Greetings! The word muah can also be used with it, e.g., wuah muah!
+
+Unreg -- Unregistered user (doesn't have an account here ... yet).
+
+:) :) :) :) :) :)'s at the wonderful wonderful world :) -- This shout dates
+back to the 'Court of Queen Eyre' on the old ICS. We think it meant "hi
+everyone".
+
+See Also: [the individual commands and help files]
+
+[Last modified: September 9, 1995 -- Friar]
+
--- /dev/null
+FICSFAQ (Frequently Asked Questions)
+
+ The admins at this site can be very busy so, if you find a bug or have
+questions, read this file first:
+
+1> How do I register?
+ Read the "register" help file -- "help register".
+
+2> What is network vs local:
+ It has to do with distributed ratings -- contact an admin if you get this
+ one.
+
+3> Can I have more than one account?
+ Only if for blind/computer/admin/team reasons.
+
+4> Can I register more than one computer?
+ Yes.
+
+5> Can I have more than one person using my email?
+ Yes.
+
+6> Can more than one person share an account for team games?
+ Yes, WEENIES is an example.
+
+7> Can I be an admin?
+ Read the "admin-new" help file -- "help admin-new".
+
+8> Can I help with programming.
+ Ask hawk.
+
+9> Who's programming?
+ Dan/DAV/foxbat/grimm/hawk/Len/Mann/Shane,etc
+ Thanks to Friar for some help files.
+ And Cthulu(clong) for ECO database - coming soon.
+ Thanks to Richard Nash (red) and Michael Moore for the old fics code.
+
+10> Where else can I play FREE chess?
+ ics.onenet.net 5000 helium.daimi.aau.dk 5000
+ pitt.chess.edu 5000 anemone.daimi.aau.dk 5000
+ arapaho.cse.ucsc.edu 5000
+ If you know of more FREE sites tell us.
+
+11> Where do I get an interface from?
+ pub/chess on ftp ics.onenet.net (use anonynous ftp)
+
+12> Where can I get the latest code from.
+ pub/chess/Unix on ftp ics.onenet.net (use anonynous ftp)
+ help files are in the oldest version FICS.tar.gz
+
+13> I don't like admin x. Admin y is treating me badly.
+ See Sparky (onenet) and hawk (helium)
+
+14> Darooha, arcsin and POTZY have come for a peek. What gives?
+ Sometimes people pretend to be them.
+ Do not abuse them if they log on.
+ Our code is GNU - they can use our ideas and code on ICC if they
+ want. Remember who wrote it first.
+
+15> What is ICC?
+ Don't ask -- no free advertising -- you pay $49 for chess there. :)
+
+16> Can I shout about ICC?
+ Yes, sure. Given a choice to pay $49 or $0. I'd take the $0.
+
+17> Should I advertise FICS?
+ Yes do so. Watch you don't get nuked on ICC, though. Do help ads there.
+ Remember, Burger King burgers are free. :)
+
+18> I can't shout!
+ Are you unreg or have you been muzzled?
+
+19> I can't play rated.
+ Have both of you set rated 1?
+ Have you got the network vs local bug.
+
+20> How do I use the -->name thing I see displayed?
+ Use "it" "i" or ":" followed by a message
+
+21> The Hormone channel(51) has been reinstated I notice.
+ Yes, but cleanish language only. This is a family server.
+ Don't say something you wouldn't say in front of someone's kids.
+ But maybe you would :)
+
+22> The board is the wrong way up:
+ Problem flip in style 12 -- old ZIICS and SLICS are affected.
+
+23> Can't promote (xboard).
+ Try e7e8 for a queen.
+
+24> How do I continue a game that was adjourned?
+ "match" the player again, and it will resume the game if the player
+ accepts
+
+25> I can't castle after king takeback.
+ We know.
+
+26> I can castle through check.
+ This has been observed once.
+
+27> Takeback gives wrong lastmove info.
+ A bug.
+
+28> Simuls don't work.
+ They were broken once; they should be okay now.
+
+29> My rating is over/under inflated
+ There may be a bug somewhere.
+
+30> +alias/+censor etc don't work.
+ Try alias/unalias and censor/uncensor for now.
+
+31> I've got an old account here, I can't remember my password.
+ Ask an admin for help -- be ready to verify your email address.
+
+34> Stats gives silly info.
+ We know.
+
+35> Is there any wild?
+ Yes .. and rated, too.
+
+36> Zippy won't shut up, too many shouts.
+ Use censor [name], cshout (sshout on ICC) is coming.
+
+37> How many channels can I be in?
+ As many as you like, don't be in too many though as this takes
+ up file space; do "help channel" for predefined ones.
+
+39> The "who" listing appears staggered.
+ Fixed soon.
+
+40> How do I withdraw a match request?
+ Type "withdraw".
+
+41> I'm getting lag -- what can I do?
+ Either Ctrl C to escape or use adjourn.
+ Otherwise get your opponent to do "moretime #" where # <= 600 seconds.
+
+42> I suddenly got a Connection closed message.
+ 1> There has been a shutdown
+ 2> There has been a crash -- please bear with us.
+ 3> The server dumped you for some reason.
+ 4> You got nuked.
+
+43> How long do shutdowns last and why?
+ About 10 seconds.
+ Sometimes we need to add new code or fix bugs -- please bear with us.
+
+44> I get unprintable characters / delete don't work.
+ Being fixed.
+
+45> How do I get further help?
+ Follow these steps:
+ (a) "channel 1"
+ (b) "tell 1 help me!"
+ (c) When you are done, you can type "channel 1" exit this channel.
+
+46> How do I pause a long file from scrolling?
+ Use ctrl q and ctrl s -- or use your scroll bar.
+ Also, "set height ##" fixes how many lines will be displayed at a time.
+
--- /dev/null
+
+finger
+
+Usage: finger [user]
+
+ Displays information about the given user. If no user is given, then
+your information is displayed. Here is a sample display:
+
+|----------------------------------------------------------------------|
+ Statistics for Aquinas On for: 55 Idle: 0
+ (examining game 9: Plato vs. Aristotle)
+
+ rating RD win loss draw total best
+ Blitz 1910 75.3 28 10 2 40 1936 (01-Jun-95)
+ Standard 1838 92.3 13 6 1 20 1838 (03-Jun-95)
+ Lightning ---- 350.0 0 0 0 0
+ Wild 1876 94.3 15 10 0 25 1903 (05-Jun-95)
+
+ Timeseal: ON
+
+ 1: <text>
+ 2: <text>
+|----------------------------------------------------------------------|
+
+ The user's ratings for each type of chess are displayed, along with the
+Glicko RD (or index of ratings variability), the total results from games
+played, and the best or highest rating for each type. You can also tell (1)
+whether the user is (1) currently logged on and, if so, for how long and
+whether his/she is idle, (2) playing, observing or examining a game and, if
+so, which game it is, and (3) currently running a version of timeseal or not.
+Beneath the ratings are note lines (a user's "plan" or "notes") the user can
+add using the set command.
+
+
+SPECIAL NOTES:
+
+(a) Your e-mail address is automatically displayed to you beneath your ratings
+table; it is NOT displayed to other users -- unless of course you include your
+address as part of your finger notes.
+
+(b) Best ratings and dates are only given *after* you have played 20 games of
+a given type.
+
+(c) If a user has not played rated games of a given type, the rating will be
+indicated as ---- and the RD will be 350.0.
+
+(d) If a user is not logged on, the display will indicate when he/she last
+disconnected and the timeseal section will not appear.
+
+See Also: busy examine glicko notes observe ratings set timeseal
+variables
+
+[Last modified: December 17, 1995 -- Friar]
+
--- /dev/null
+Things I've worked on: (foxbat)
+
+ratings.c 3.10.95 - if 2 0 rated players play a rated game, Rb_S can go
+ negative, which is bad for the sqrt function. added
+ a filter to stop this. Also the pow(x,y) funtion
+ expects floating point args, so changed 10 to 10.0
+
+ratings.c 3.11.95 - added code to increment the number of games played and
+ Rb_total/Rs_total's in the rating_update function.
+
+comproc.c 3.11.95 - in com_match, added filters so the 'rated' variables
+ must match before a match request is issued.
+
+gamedb.c 3.12.95 - if a rated game was drawn, the 'Winner' column in hist
+ and was showing whoever was white, so I changed these 2
+gameproc.c files to show that it was 'Drawn'. also limited the
+ character length of names in history to 9.
+
--- /dev/null
+
+flag
+
+Usage: flag
+
+ This command asks the chess server to check the clock time for you and your
+opponent. The effect of the command depends upon whether one or both of you
+are out of time (chess clock reads zero or negative).
+
+ (i) If your opponent has run out of time but you have time, then "flag"
+will claim the win for you.
+
+ (ii) If both you and your opponent are out of time, then "flag" will claim a
+draw.
+
+ (iii) If your opponent has time left, you will be given an error message by
+the server when you use "flag".
+
+ If your opponent appears to have lost his/her connection or hasn't responded
+in a reasonable amount of time, he/she probably has a systems lag. Use the
+command "abort" to end the game like a good sport and not have your opponent
+lose the game through no fault of his/her own.
+
+SPECIAL NOTES:
+
+(a) Some users have interface programs that automatically flag you when you
+have run out of time. This practice is legal. If you find yourself losing
+many games from being flagged when you have system lags or take longer to
+think about moves, then consider using longer time controls.
+
+(b) If your opponent's clock reads zero (0:00) on your screen, it does not
+*always* mean that your opponent has no time left for the game. The server
+keeps the official times for both players. These times are re-sent after each
+move. Transmission lag or using timeseal may cause the official time to be
+different than the times shown on your screen.
+
+See Also: abort draw lag timeseal
+
+[Last modified: November 26, 1995 -- Friar]
+
--- /dev/null
+
+flip
+
+Usage: flip
+
+ "Flip" toggles the 'flip' variable on and off. When 'flip' is on it causes
+the board display to be reversed -- either from White at bottom to Black at
+bottom, or vice versa. Changing your flip setting may be especially useful
+when observing games or playing team games. Using this command is equivalent
+to "set flip on"/"set flip off". Because the 'flip' variable is affected,
+changes in 'flip' are permanent until you re-set it.
+
+See Also: variables
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+
+fmessage
+
+Usage: fmessage user message_number
+
+ You can forward a "message" you have received to another user by using the
+"fmessage" command. In this way, you can share news with other users without
+having to retype the information each time. Suppose, for example, the third
+message in your message list is something you want Hawk to read. You type
+"fmessage Hawk 3". When you do this, you will receive the feedback that your
+message has been forwarded to that user. When you receive a forwarded
+message, it will be clearly designated as a FORWARDED message from a given
+user.
+
+See Also: message
+
+[Last modified: April 28, 1996 -- Friar]
+
--- /dev/null
+
+formula
+
+Usage: set formula <formula-expression>
+
+
+SUMMARY
+
+ The formula variable filters out match requests. If you have a formula set,
+then any match request not satisfying your formula is automatically declined;
+you will be notified that the offer was made and rejected by your formula. If
+you make an offer that fails a player's formula, you will be given this
+feedback. A user's formula and f-variable settings are displayed using the
+"variables" command. You disable (turn off) your formula by typing "set
+formula". This will, in essence, erase your current formula setting.
+
+ Here are some simple examples, with descriptions in [] brackets:
+
+ blitz [match must be blitz]
+ !wild [match must be non-wild]
+ inc >= 10 [match must have an increment of 10 or higher]
+
+ Create or modify a formula by using the "set" command. For example, "set
+formula blitz". Special variables (f1-f9) can also be established using the
+"set" command; these variables make it easier to modify your formula depending
+upon your mood.
+
+
+CREATING A FORMULA
+
+ (1) Decide whether you will be changing your formula often. If so, think
+about using f-variables to make these changes easier.
+
+ (2) Decide exactly what kinds of filters you want to have, such as type of
+game, time controls, and kinds of opponents.
+
+ (3) Review the available formula operators and pre-defined variables (listed
+below) to see which ones fit your needs.
+
+ (4) Write out your formula and f-variables on paper to make sure that their
+"logic" works.
+
+ (5) Enter the logical expressions for the f-variables and formula using the
+"set" command.
+
+ Changing your f-variables and formula follows the same procedures.
+
+
+FORMULA VARIABLES
+
+ Several variables are allowed in formula settings. Some of these variables
+hold numerical information while others are Boolean (true/false, 1/0). Here
+is a list of allowed variables, where Boolean variables are denoted by "(B)":
+
+ The following variables are allowed in formulas:
+
+ Variable Description
+ ------------ ---------------------------------------------------
+ abuser 1 if opponent is on the abuser list; 0 otherwise (B)
+ assessdraw How many rating points you will gain/lose by drawing a
+ chess match
+ assessloss How many rating points you will lose by losing a chess
+ match
+ assesswin How many rating points you will gain by winning a chess
+ match
+ blitz 1 if match is blitz in type; 0 otherwise (B)
+ computer 1 if opponent is a computer; 0 otherwise (B)
+ inc Increment time for each player
+ lightning 1 if match is lightning in type; 0 otherwise (B)
+ maxtime(n) The maximum time n moves will take for BOTH players
+ (in seconds) [you must supply the 'n' value]
+ mymaxtime(n) The maximum time n moves will take YOU (in seconds)
+ [you must supply the 'n' value]
+ myrating Your rating
+ nonstandard 1 if the game will have different time controls for the
+ two players; 0 otherwise (B)
+ private 1 if game will be private; 0 otherwise (B)
+ rated 1 if game will be rated; 0 otherwise (B)
+ rating Opponent's rating
+ ratingdiff The difference between opponent's rating and your
+ rating [rating - myrating]
+ registered 1 if opponent is a registered user; 0 otherwise (B)
+ standard 1 if game will be standard in type; 0 otherwise (B)
+ timeseal 1 if opponent has timeseal; 0 otherwise (B)
+ time Start time for each player
+ untimed 1 if game will not involve the clock; 0 otherwise (B)
+ wild 1 if game will be wild in type; 0 otherwise (B)
+
+ Also, the word "minutes" is allowed after a number that is not enclosed in
+parentheses (but right now, you must use "1 minutes"; the singular is not
+recognized). The word has the effect of multiplying the previous number by
+60, thus turning minute-values into seconds-values -- important for the
+maxtime and mymaxtime variables. For example, "2 minutes" would yield the
+value of "120".
+
+
+FORMULA OPERATORS
+
+ The following formula operators are allowed; their order of precedence in
+the calculations and evaluations is listed. Sometimes more than one set of
+symbols leads to the same result. When functions in the formula have equal
+precedence, the precedence is from left to right.
+
+ Symbol Function Precedence
+ ------ ------------------------------- ----------
+ ! not; negation 1
+ - minus [as in -20 or -variable] 1
+ * multiplication 2
+ / division 2
+ + addition 3
+ - subtraction 3
+ < less than 4
+ <= less than or equal to [ =< also works] 4
+ > greater than 4
+ >= greater than or equal to [ => also works] 4
+ = equals [ == also works] 5
+ != not equals [ <> also works] 6
+ & and [ && also works as does 'and'] 7
+ | or [ || also works as does 'or'] 8
+
+ Parentheses () are allowed in formulas and function as they do in numerical
+equations: expressions within parentheses are evaluated first. You can use
+the pound sign '#' after your settings to provide comments and reminders to
+yourself. NOTE: The program divides by a fudge factor of .001 instead of
+dividing by 0.
+
+
+USER-DEFINED FORMULA VARIABLES (f-variables)
+
+ F1 through f9 are user-defined formula variables changed by using the "set"
+command. These variables can return either numerical or Boolean results.
+They make it easy to change one part of your formula without retying the whole
+thing, or to adjust your formula depending on your mood. For example, if your
+various f-variables were ...
+
+ f1 rated & time=5 & inc=0 # rated 5 minute games
+ f2 ratingdiff
+ f3 maxtime(40) >= 2*8minutes # at least 8 mins each for 40 moves
+ f4 f2>400 # I want a REAL fight
+ f5 !abuser
+ f6 standard | (ratingdiff<200 & blitz)
+
+... then, depending on your mood, you could type one of the following:
+
+ set formula f1 & f5 # rated 5 min. games only
+ set formula f2 > -100 # long games, decent competition
+ set formula f1 & !f4
+-or- set formula f2 >= 0 | blitz
+
+ You define an f-variable using the "set" command. With respect to the above
+examples, you would type such lines as ...
+
+ set f2 ratingdiff
+ set f4 f2>400 # I want a REAL fight
+ set f5 !abuser
+
+*** Special Note ***
+Be careful how you write the f-variables. Make sure they have the proper
+sequence. For example, f5 can refer to f2 but f5 cannot refer to f8.
+
+
+MAXTIME EXAMPLE
+
+ Using maxtime sets the expected total time for the game. If your formula
+(or f-variable) included the following expression ...
+
+ maxtime(30) <= 10 minutes
+
+... this would allow no more than 10 minutes total time for the first 30 moves
+of the game (5 minutes for each player, or any other combination).
+
+
+CREDITS: Formula program for FICS written by Dave Herscovici (hersco)
+
+
+See Also: assess blitz lightning match timeseal variables
+
+[Last modified: December 17, 1995 -- Friar]
+
--- /dev/null
+
+forward
+
+Usage: forward [#]
+
+ This command is used by a person examining a game in order to move forward
+in the sequence of the game's moves. The # is half_moves. Example: "forward
+40" -- game will go forward 40 half-moves (20 for White and 20 for Black).
+If # is not specified, 1 will be used. If you type "forward 999" the game's
+final position will be displayed.
+
+SPECIAL NOTES
+
+(1) This command does not work for new games, only stored games.
+
+(2) This command works only on the mainline of stored games, not variations
+branching off from the main line or moves continuing a game from a stored
+position.
+
+See Also: backward examine
+
+[Last modified: November 26, 1995 -- Friar]
+
--- /dev/null
+The Internet Chess Library (chess.onenet.net) is an anonymous FTP archive
+containing a large amount of chess information and programs (~200MB).
+
+All of the FICS Graphical interfaces are available there, and much more,
+and access is free. It is available via your favorite Web browser, like
+Netscape or Mosaic (URL: http://chess.onenet.net/chess) or simply ftp
+(file transfer protocol), a very common program available on most Unix
+systems and many others. Web access would be best and most intuitive,
+but instruction for using ftp follow:
+
+-----------------------------------------------------------------------------
+
+The most standard command to initiate an ftp connection to the ICL would
+be (from your host's prompt, not FICS's):
+
+ ftp chess.onenet.net
+ or ftp 164.58.253.10
+
+If this seems to be garbage to your system, you'll need to find out more
+from a local systems administrator.
+
+If you connect to the server, you will be asked for a Username (type
+"anonymous") and a Password (as it will tell you, give your email address).
+Note: chess.onenet.net and caissa.onenet.net are the same machine currently.
+
+ ftp chess.onenet.net
+
+ Connected to chess.onenet.net.
+ 220 caissa.onenet.net FTP server (Version wu-2.4(1) Tue Oct 11 11:29:11 1994)
+ ready
+ Name (your-host.your-domain:your-username): anonymous
+ 331 Guest login ok, send your complete e-mail address as password.
+ Password: your@email.address
+
+In this example, we will go to the DOS directory. All files and directories
+in the current directory can be seen with "dir". "cd" changes directories.
+a "/" separates directory names when specifying directories within
+directories. "help" will give you a list of available commands in ftp.
+
+ cd /pub/chess/DOS
+
+or cd DOS
+
+( users of DELPHI may need to type: cd "DOS" )
+
+"dir" will show you all the files and directories here. There are quite
+a few. We will now transfer the software for ZIICS, a graphical interface
+which runs under DOS on PC's. The "binary" command sets the transfer
+mode to binary type (8 bit, for true binary/executable data). The "get"
+command transfers a file.
+
+ binary
+ get ziics121.exe
+
+If you are done, "quit" will exit you from ftp.
+
+ quit
+
+Now all you need to do is transfer the file to your local PC or workstation,
+assuming you do not have a direct Internet connection or PPP/SLIP. This is
+done most commonly with "kermit" or "zmodem". Check around locally for
+what is available.
+
+Channel 1 is a great place to get help help from people on-line at FICS.
+
+See also: interfaces, addresses
--- /dev/null
+
+ftp_hints
+
+There are many kinds of files for the chess server you may wish to access and
+download to your system. The Internet Chess Library (chess.onenet.net) is an
+anonymous FTP archive containing a large amount of chess information and
+programs (~200MB). (See the "inetchesslib" help file.) Many users of the
+chess server download a graphical interface and timeseal (read the
+"interfaces" and "timeseal" help files).
+
+There are several ways to access and download these files. But first, you
+need to connect to where the files are located. There are two main ways to
+connect: World Wide Web (www) and file transfer protocol (ftp).
+
+WWW access would be best and most intuitive. You can get there using your
+favorite Web browser, like Netscape or Mosaic. The URL address is:
+
+ http://chess.onenet.net/chess
+
+But ftp access is also easy. This file is about ftp procedures for the chess
+server files.
+
+
+FTP FILE TRANSFER
+
+The most standard command to initiate an ftp connection to the files would be
+to initiate a session from your system (not from within the chess server
+itself) and at your host's prompt type:
+
+ ftp chess.onenet.net
+ or ftp 164.58.253.10
+
+[Note: chess.onenet.net and caissa.onenet.net are the same machine currently
+so either address will work for now.]
+
+If the ftp command seems to be garbage to your system, you will need to
+contact your local systems administrator.
+
+If you connect to the file server, you will see this message on your screen:
+
+ Connected to chess.onenet.net.
+ 220 caissa.onenet.net FTP server (Version wu-2.4(1) Tue Oct 11 11:29:11
+ 1994)
+ ready
+ Name (your-host.your-domain:your-username):
+
+Type:
+
+ anonymous
+
+You will then see this message:
+
+ 331 Guest login ok, send your complete e-mail address as password.
+ Password:
+
+Type your email address.
+
+Now you are in and should see the ftp prompt:
+
+ ftp>
+
+
+LOCATING THE FILES YOU NEED
+
+Typing "help" will give you a list of available commands in ftp, but here are
+some basics. All files and directories in the current directory can be seen
+with "dir". Typing "cd" changes directories. A "/" separates directory names
+when specifying directories within directories.
+
+In this example, we will go to the DOS directory. Type:
+
+ cd /pub/chess/DOS
+
+or cd DOS
+
+ (NOTE: users of DELPHI may need to type: cd "DOS")
+
+If you type "dir" you will see all the files and directories in that location.
+There are quite a few.
+
+
+TRANSFERRING A FILE
+
+In order to transfer a file properly from the ftp site to your computer host,
+you need to set the correct transfer mode and use the right commands. The
+files you need for an interface and timeseal need to be transferred using the
+"binary" mode. The "binary" command sets the transfer mode to binary type (8
+bit, for true binary/executable data). Then you need to have the file sent to
+you. The "get" command transfers a file from the ftp site to you.
+
+In this example we will now transfer the software for ZIICS, a graphical
+interface that runs under DOS on PC's. The file name for ZIICS is
+"ziics121.exe". Here is what you would need to type:
+
+ binary
+ get ziics121.exe
+
+If you are done and do not wish to transfer any other files, type "quit" and
+you will exit from ftp.
+
+ quit
+
+If you have a direct internet connection using PPP/SLIP, the file should now
+be in your computer directory and you are ready to work on it.
+
+If yuo do not have a direct connection, what you need to do is transfer the
+file from your computer host to your local PC or workstation. This is done
+most commonly with "kermit" or "zmodem". Check around locally for what is
+available and works best on your system. After using kermit or zmodem, the
+file should then be in your directory for you to work on.
+
+
+FOR FURTHER ASSISTANCE
+
+Channel 1 is a great place to get help from people on-line at this chess
+server. They can help you work through each of these steps. You should also
+read the special help files for interfaces and timeseal; they have further
+details specific to those kinds of files. And you can also contact the server
+admins for help.
+
+See also: admins addresses chan_1 inetchesslib interfaces timeseal
+
+[Last modified: September 9, 1995 -- Friar]
+
--- /dev/null
+
+games
+
+Usage: games [#, word]
+
+ If no parameters are given, "games" lists all the games currently being
+played on the server. The games are listed in order of the ratings of the
+players involved. If a number is supplied as a parameter, only the game
+matching that number is displayed. If a word (or even a single letter) is
+supplied, only games involving players whose handles begin with that word are
+displayed. For example, "games gr" will show all games involving players
+whose handles begin with "gr".
+
+ Here is a sample games display and what the symbols mean:
+------------------------------------------------------------------------------
+25 (Exam. 0 Friar 0 Friar ) [ uu 0 0] W: 1
+28 ++++ TryMe 1737 Jack [ su 30 20] 22:27 - 23:17 (29-30) W: 16
+ 2 2274 OldManII ++++ Peshkin [ bu 2 12] 2:34 - 1:47 (39-39) B: 3
+29 1622 Vman 1609 PopKid [ sr 10 10] 1:14 - 5:10 (21-22) B: 18
+32 1880 Raskapov 1859 RoboDweeb [ br 2 12] 1:04 - 1:26 ( 9-10) B: 34
+ 1 1878 Roberto 1881 baraka [psr 45 30] 30:35 - 34:24 (22-22) W: 21
+
+ 6 games displayed (of 23 in progress)
+------------------------------------------------------------------------------
+
+ Reading from left to right: (i) game number; (ii) rating of user playing
+White; (iii) handle of White, (iv) rating of user playing Black; (v) handle of
+Black; (vi) type of match and time controls, (vii) current clock times for
+both players; (viii) current material strength for both players, (ix) who is
+on move and what move number it will be, and, lastly (x) the number of games
+listed in the display and how many in progress. Ratings are ++++ for
+unregistered players and ---- for registered players who do not have a rating
+in this category. Lastly, any games being examined are displayed.
+
+
+TYPE OF MATCH -- The format will be [Private] | [Category] | [Rated].
+
+ Private -- If a "p" is given, the game is private and not open for
+observation. If not private, the space will be blank. (See the "variables"
+help file.)
+
+ Category -- The possibilities are:
+ b blitz
+ d bughouse
+ l lightning
+ n nonstandard game, such as different time controls for the players
+ s standard
+ u untimed (including simul-matches, simuls)
+ w wild
+
+ Rated -- The possibilities are "r" for rated and "u" for unrated.
+
+
+See Also: blitz examine lightning match simuls standard variables
+untimed
+
+[Last modified: December 19, 1995 -- Friar]
+
--- /dev/null
+
+getgi
+
+Usage: RESTRICTED FOR USE BY TD PROGRAMS
+
+[Last modified: August 1, 1997 -- Friar]
--- /dev/null
+
+getpi
+
+Usage: RESTRICTED FOR USE BY TD PROGRAMS
+
+[Last modified: August 1, 1997 -- Friar]
--- /dev/null
+
+ +-------------------------------------------------+
+ | Vek-splanation of the Glicko Ratings System |
+ +-------------------------------------------------+
+
+As you may have noticed, each FICS player now has a rating and an RD.
+
+RD stands for "ratings deviation".
+
+Why a new system
+----------------
+
+The new system with the RD improves upon the binary categorization that was
+used before on fics and elsewhere, where players with fewer than 20 games were
+labeled"provisional" and others were labeled "established". Instead of two
+separate ratings formulas for the two categories, there is now a single
+formula incorporating the two ratings and the two RD's to find the ratings
+changes for you and your opponent after a game.
+
+What RD represents
+------------------
+
+The Ratings Deviation is used to measure how much a player's current rating
+should be trusted. A high RD indicates that the player may not be competing
+frequently or that the player has not played very many games yet at the
+current rating level. A low RD indicates that the player's rating is fairly
+well established. This is described in more detail below under "RD
+Interpretation".
+
+How RD Affects Ratings Changes
+------------------------------
+
+In general, if your RD is high, then your rating will change a lot each time
+you play. As it gets smaller, the ratings change per game will go down.
+However, your opponent's RD will have the opposite effect, to a smaller
+extent: if his RD is high, then your ratings change will be somewhat smaller
+than it would be otherwise.
+
+A further use of RD's:
+----------------------
+
+Vek asked Mark Glickman the following:
+
+> Given player one with rating r1, error s1,
+> and player two with r2 and s2, do you have a formula for the probability
+> that player 1's "true" rating is greater than player 2's ?
+
+Mark said:
+
+ Yes - it's:
+
+ 1/(1 + 10^(-(r1-r2)f(sqrt(s1^2 + s2^2))/400) )
+
+ where f(s) is [the function applied to RD in Step 2 below].
+
+How RD is Updated
+-----------------
+
+In this system, the RD will decrease somewhat each time you play a game,
+because when you play more games there is a stronger basis for concluding what
+your rating should be. However, if you go for a long time without playing any
+games, your RD will increase to reflect the increased uncertainty in your
+rating due to the passage of time. Also, your RD will decrease more if your
+opponent's rating is similar to yours, and decrease less your opponent's
+rating is much different.
+
+Why Ratings Changes Aren't Balanced
+-----------------------------------
+
+In the other system, except for provisional games, the ratings changes for the
+two players in a game would balance each other out - if A wins 16 points, B
+loses 16 points. That is not the case with this system. Here is the
+explanation I received from Mark Glickman:
+
+ The system does not conserve rating points - and with good
+ reason! Suppose two players both have ratings of 1700,
+ except one has not played in awhile and the other playing
+ constantly. In the former case, the player's rating is not
+ a reliable measure while in the latter case the rating is a fairly
+ reliable measure. Let's say the player with the uncertain rating
+ defeats the player with the precisely measured rating.
+ Then I would claim that the player with the imprecisely
+ measured rating should have his rating increase a fair
+ amount (because we have learned something informative from
+ defeating a player with a precisely measured ability) and
+ the player with the precise rating should have his rating
+ decrease by a very small amount (because losing to a player
+ with an imprecise rating contains little information).
+ That's the intuitive gist of my extension to the Elo system.
+
+ On average, the system will stay roughly constant (by the
+ law of large numbers). In other words, the above scenario
+ in the long run should occur just as often with the
+ imprecisely rated player losing.
+
+Mathematical Interpretation of RD
+---------------------------------
+
+Direct from Mark Glickman:
+
+Each player can be characterized as having a true (but unknown) rating that
+may be thought of as the player's average ability. We never get to know that
+value, partly because we only observe a finite number of games, but also
+because that true rating changes over time as a player's ability changes. But
+we can *estimate* the unknown rating. Rather than restrict oneself to a
+single estimate of the true rating, we can describe our estimate as an
+*interval* of plausible values. The interval is wider if we are less sure
+about the player's unknown true rating, and the interval is narrower if we are
+more sure about the unknown rating. The RD quantifies the uncertainty in
+terms of probability:
+
+The interval formed by Current rating +/- RD contains your true rating with
+probability of about 0.67.
+
+The interval formed by Current rating +/- 2 * RD contains your true rating
+with probability of about 0.95.
+
+The interval formed by Current rating +/- 3 * RD contains your true rating
+with probability of about 0.997.
+
+For those of you who know something about statistics, these are not confidence
+intervals, but are called "central posterior intervals" because the derivation
+came from a "Bayesian" analysis of the problem.
+
+These numbers are found from the cumulative distribution function of the
+normal distribution with mean = current rating, and standard deviation = RD.
+For example, CDF[ N[1600,50], 1550 ] = .159 approximately (that's shorthand
+Mathematica notation.)
+
+The Formulas
+------------
+
+Algorithm to calculate ratings change for a game against a given opponent:
+
+Step 1. Before a game, calculate initial rating and RD for each player.
+
+ a) If no games yet, initial rating assumed to be 1720.
+ Otherwise, use existing rating.
+ (The 1720 is not printed out, however.)
+
+ b) If no RD yet, initial RD assumed to be 350 if you have no games,
+ or 70 if your rating is carried over from ICC.
+ Otherwise, calculate new RD, based on the RD that was obtained
+ after the most recent game played, and on the amount of time (t) that
+ has passed since that game, as follows:
+
+ RD' = Sqrt(RD^2 + c log(1+t))
+
+ where c is a numerical constant chosen so that predictions made
+ according to the ratings from this system will be approximately
+ optimal.
+
+Step 2. Calculate the "attenuating factor" due to your OPPONENT's RD,
+ for use in later steps.
+
+ f = 1/Sqrt(1 + p RD^2)
+
+ Here p is the mathematical constant 3 (ln 10)^2
+ -------------
+ Pi^2 400^2 .
+
+ Note that this is between 0 and 1 - if RD is very big,
+ then f will be closer to 0.
+
+Step 3. r1 <- your rating,
+ r2 <- opponent's rating,
+
+ 1
+ E <- ----------------------
+ -(r1-r2)*f/400 <- it has f(RD) in it!
+ 1 + 10
+
+ This quantity E seems to be treated kind of like a probability.
+
+Step 4. K = q*f
+ --------------------------------------
+ 1/(RD)^2 + q^2 * f^2 * E * (1-E)
+
+ where q is a mathematical constant: q = (ln 10)/400.
+
+Step 5. This is the K factor for the game, so
+
+ Your new rating = (pregame rating) + K * (w - E)
+
+ where w is 1 for a win, .5 for a draw, and 0 for a loss.
+
+Step 6. Your new RD is calculated as
+
+ RD' = 1
+ -------------------------------------------------
+ Sqrt( 1/(RD)^2 + q^2 * f^2 * E * (1-E) ) .
+
+The same steps are done for your opponent.
+
+Further information
+-------------------
+
+A PostScript file containing Mark Glickman's paper discussing this ratings
+system may be obtained via ftp. The ftp site is hustat.harvard.edu, the
+directory is /pub/glickman, and the file is called "glicko.ps". It is
+available at http://hustat.harvard.edu/pub/glickman/glicko.ps.
+
+Credits
+-------
+
+The Glicko Ratings System was invented by Mark Glickman, Ph.D. who is
+currently at the Harvard Statistics Department, and who is bound for Boston
+University.
+
+Vek and Hawk programmed and debugged the new ratings calculations (we may
+still be debugging it). Helpful assistance was given by Surf, and Shane fixed
+a heinous bug that Vek invented.
+
+Vek wrote this helpfile and Mark Glickman made some essential
+corrections and additions.
+
+ Last major update: April 19, 1995.
+ Minor revisions: August 28, 1995 by Friar.
+
--- /dev/null
+
+[Event "ICS game"]
+[Site "krypton"]
+[Date "1995.07.06"]
+[Round "-"]
+[White "GMSeirawan"]
+[Black "GMLarsen"]
+[Result "1/2-1/2"]
+[TimeControl "7200"]
+
+1. d4 Nf6 2. c4 e6 3. Nf3 b6 4. Nc3 Bb7 5. Bg5 Be7 6. e3 c5 7. dxc5 bxc5 8.
+Be2 O-O 9. Qc2 Nc6 10. Rd1 a6 11. O-O Qc7 12. Rd2 Rfd8 13. Rfd1 d6 14. h3
+Rd7 15. Qb1 Rad8 16. Bf4 h6 17. Bg3 Qb6 18. e4 e5 19. Nd5 Nxd5 20. cxd5 Nd4
+21. Nxd4 cxd4 22. Rc2 Rc7 23. Rxc7 Qxc7 24. Rc1 Qb6 25. Bd3 h5 26. f3 Bg5
+27. Rc4 Rc8 28. b3 Be3 29. Kf1 Rxc4 30. bxc4 Qxb1 31. Bxb1 Kf8 32. Bc2 Bc1
+33. Ke2 Ba3 34. f4 f6 35. Ba4 Bc8 36. f5 Kf7 37. Be1 g6 38. fxg6 Kxg6 39.
+Be8 Kg5 40. Bd2 Kh4 41. Be1 1/2-1/2
+
--- /dev/null
+
+gnotify
+
+Usage: +|-|= gnotify [user]
+
+ When a player is on your gnotify list, you will be notified when that player
+begins a game on the server. Here are the possible variations of the command:
+
+ +gnotify user Add "user" to gnotify list
+ -gnotify user Remove "user" from gnotify list
+ =gnotify Display your gnotify list
+
+ Use "gin" variable to be notified regarding all games and when they begin.
+
+See Also: addlist gin variables
+
+[Last modified: October 18, 1995 -- Friar]
+
--- /dev/null
+
+goboard
+
+Usage: goboard player
+
+ This command is used by a person holding a simul match. Play moves to the
+board for the specified player in a simul match. Standard aliases are "go
+player" and "goto player".
+
+See Also: gonum simnext simprev simuls
+
+[Last modified: July 7, 1995 -- Friar]
+
--- /dev/null
+
+gonum
+
+Usage: gonum #
+
+ This command is used by a person holding a simul match. Play will move to
+board number # in the simul match.
+
+See Also: goboard simnext simprev simuls
+
+[Last modified: July 7, 1995 -- Friar]
+
--- /dev/null
+
+handle
+
+ Your server account name is known as your "handle." It is your identity on
+the server. Some users prefer to have handles similar to their real names;
+others do not. The choice is up to you. But whatever you decide to have as
+your handle, please be aware that handles for registered users are permanent.
+Admins do not change handles for registered users except in extreme cases
+(very rare). So please select a handle that you will feel comfortable with
+for a long time.
+
+ No two users can have the same handle, of course. To see which handles have
+already been taken, use the "handles" command.
+
+ Lastly, admins reserve the right to deny your using a particular handle. If
+the handle you want is offensive or might lead to too much confusion among
+users (such as various reserved words or commands), you may be asked to change
+it. Profane and crude handles are not permitted. Unregistered users who
+logon with profane and/or crude handles may be disconnected from the server,
+even without warning. Unregistered users who persist in adopting
+inappropriate handles may be prevented from accessing the server.
+
+See Also: handles register
+
+[Last modified: July 19, 1995 -- Friar]
+
--- /dev/null
+
+handles
+
+Usage: handles [string]
+
+ Displays a list of registered players who have handles matching "string".
+For example, the command "handles e" would display all handles beginning with
+"e". "Handles" can also be used to determine if the player [string] has an
+account on the server. The "handle" help file explains aspects of a server
+handle.
+
+See Also: handle who
+
+[Last modified: October 9, 1995 -- Friar]
+
--- /dev/null
+
+hbest
+
+Usage: hbest [b|s|w]
+
+ Displays the 20 highest-rated human players in the three different ratings
+categories: Blitz, Standard and Wild. Computers are excluded from the
+listing. Use "best" to see the top 20 users, both humans and computers.
+
+ Using "hbest" alone will give all three lists. Using one or more of the
+arguments b, s or w is a request to give only the blitz, standard and/or wild
+best lists, respectively. For example, "best bw" will show the top 20 humans
+in the blitz and wild chess; the top standard players will not be listed.
+
+ Use "hrank" and "rank" to see where a given player is ranked.
+
+See Also: best hrank rank
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+
+help
+
+Usage: help [topic]
+
+ Prints information on the given topic. If topic is omitted, then "help"
+will provide instructions for displaying several, useful help files. Also,
+typing "help commands" will list all commands.
+
+ When you request information about a command, the help file will describe
+the format for the command ("Usage"). Words in square brackets [] designate
+optional variables; including them affects the way your command will be
+processed.
+
+ Some help files are longer than one screen. To continue reading the file,
+type "next" (or its alias "more").
+
+ If you need help while on the server, use channel 1 to contact people who
+can help you (see chan_1 help file).
+
+See Also: chan_1 index intro_information intro_welcome next
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+
+highlight
+
+Usage: set highlight [0-15]
+
+ Highlight is one of the variables you can change with the "set" command.
+When highlight is non-zero and you receive a personal tell, the sender's
+handle will be displayed in a different style thus making the tell more
+obvious on your screen. Other information, such as your location in a ranking
+list or who list, will also be displayed to you in a different style thus
+making it easier to read.
+
+ There are 15 possible styles. However, the way they appear on your screen
+will depend on many factors. Try they out to see which style works best for
+you. "Set highlight 0" turns the highlight to neutral (off).
+
+See Also: rank set tell variables who
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+
+history
+
+Usage: history [user]
+
+ Shows the results of the last 10 or so games that 'user' played. If no
+user handle is specified, your history will be displayed to you. There are
+columns in the history display for the players and their ratings (as
+adjusted by the result of the match), the winner, the type of match
+(blitz/standard, rated/unrated), the type of opening and the date.
+
+
+EXAMPLE
+
+ Here is the history header, a sample line from User 1's history file, and an
+explanation of this line:
+
+ Opponent Type ECO End Date
+23: + 1681 W 1521 User 2 [ br 2 12] A84 Res Fri Apr 21 06:29:12 1995
+
+ Explanation
+ --------------------------------------------------------------------------
+ 23 -- Game number in User 1's history
+ + -- User 1's result; '+' means Won; '-' means Lost; '=' means Draw.
+ 1681 -- User 1's revised rating given the result
+ W -- User 1's color in the match
+ 1521 -- User 2's revised rating given the result
+ br -- Category of game -- 'b' Blitz; 'd' bughouse; 'l' Lightning;
+ 'n' Nonstandard times; 's' Standard; 'u' Untimed; 'w' Wild
+ Rated/unrated --'r' Rated; 'u' Unrated
+ a 'p' in fron of these codes would mean a Private match
+ 2 12 -- The time controls for the match
+ ECO -- The ECO (Encyclopedia of Chess Openings) classification of the
+ opening moves of the match
+ Res -- How the match ended; 'Res' for Resignation; 'Mat' for Mate; 'Fla'
+ for Flag, or time forfeit; 'Agr' for Agreed to a draw; 'Rep' for
+ three-time Repetiion of position (same player to move); 'NM' for
+ Neither player has Material for delivering mate; 'Adj' for result
+ was adjudicated.
+ The date and time of the match are also given.
+
+ Here is how to read this example: User1 (playing White; blitz rating now
+1681) Won (+) against User2 (blitz rating now 1521) in a rated (r) blitz (b)
+match using the time controls of 2 minutes to start and 12 second increments
+on Friday April 21, 1995, at 06:29 hours when User 2 resigned (Res); the type
+of opening (ECO) was A84.
+
+SPECIAL NOTES:
+
+(a) ECO will not be given for games that are "private" (see the variables help
+ file).
+
+(b) Games in history can now be examined.
+
+See Also: adjudication eco examine games match variables
+
+[Last modified: December 19, 1995 -- Friar]
+
--- /dev/null
+
+hrank
+
+Usage: hrank [user [b][s][w]]
+ hrank m-n [b][s][w]
+
+ The first usage shows the ranking of the given user and all human users with
+nearby rankings -- computers will be excluded from the rankings. A second
+argument with one or more of the letters b, s, and/or w asks to show only
+blitz, standard, and/or wild ratings respectively. If no second argument is
+given, rankings for all three types are shown. For example, "rank foo bw"
+shows the blitz and wild ranking of the player whose handle is "foo". If
+'user' is omitted, your rankings will be displayed.
+
+ The second usage shows all human users ranked between the rankings of M and
+N. The optional third argument again limits which ratings are shown. For
+example, "rank 1-30 sw" lists the human users with the highest 30 standard and
+wild ratings. "hbest" lists the top 20 human users in a category.
+
+ The columns are always sorted by blitz, then standard, then wild.
+
+ Currently, all players with at least 20 games of a particular rating type
+are ranked. If you ask for a player's rank and they do not yet have the 20
+games needed to be an active player, the player's current rating will be
+displayed in the table but a line (----) will precede the handle to indicate a
+provisional ranking.
+
+ To include computers in the list, use "rank".
+
+See Also: best hbest rank
+
+[Last modified: June 13, 1995 -- Friar]
+
--- /dev/null
+
+inchannel
+
+Usage: inchannel [0-99]
+
+ Lists all users currently listening to the given channel. If the
+channel number is omitted, then all users listening to all channels
+are displayed. With this listing, you can tell which users will hear
+something you tell a given channel.
+
+See Also: channel tell
+
+[Last modified: June 11, 1995 -- Friar]
+
--- /dev/null
+
+index
+
+Usage: index [topic]
+
+ Prints information on the given topic. If topic is omitted, then "index"
+will list the various topics in the index.
+
+ When you request information about a topic, you will be given a list of
+various commands that relate to that topic as well as information files of
+interest. You can access files on the various commands and information files
+using the "help" command.
+
+ If you need help while on the server, use channel 1 to contact people who
+can help you (see chan_1 help file).
+
+See Also: chan_1 help intro_information intro_welcome
+
+[Last modified: July 20, 1995 -- Friar]
+
--- /dev/null
+The Internet Chess Library -- An anonymous ftp archive at chess.onenet.net
+(this file may be somewhat out of date! :-) )
+
+The chess archive consists of the content of the directory tree contained
+in /pub/chess. At the top level of this tree are a few informational files
+which are briefly described below (the contents of these files will be
+updated from time to time):
+
+ ICS.getting-started
+ This is an old introduction to the ICS (internet chess server).
+ The information will apply somewhat to the current server, but it
+ has changed a great deal since this was written.
+ README
+ This is a file containing a welcome message and a statement of the
+ general purpose and intent of the archive.
+ README.archive-structure
+ This file.
+ README-pictures-of-netchessplayers
+ This tells how you might donate a digitized picture of yourself or
+ a chessplayer you know into the archive.
+ README-where_is_ICS.info
+ This is a 'link' to the file containing the current Internet
+ locations of the main ICS's (currently, one in USA and one in
+ Europe.)
+ README.too
+ This is an informational note related to finding recently uploaded
+ data.
+ chess-FAQ
+ This is the Chess FAQ (Frequently Asked Questions, and answers).
+ gnu-chess-FAQ
+ This is a FAQ for GnuChess, a public domain chess playing program
+ from the GNU (Gnu's Not Unix) project -- part of the Free Software
+ Foundation.
+ ls-lR
+ This is a complete listing of the current contents of the archive,
+ without descriptions. Filenames only. A Index with descriptions
+ is probably not a possibility at this time because of the limited
+ resources of the current maintainer. (Any help on this would be
+ greatly appreciated)
+ where_is_ICS.info
+ This is the info file for the locations of the ICS's.
+ README-where_is_ICS.info is linked to this file.
+
+
+
+The rest of the archive is divided into a number of subdirectories which
+attempt to classify the data somewhat. Below is a listing of directories
+in this archive and what one might expect to find there.
+
+
+/pub/chess/
+ Amiga/ Software and data for/related to Amiga computers.
+ Atari/ Software and data for/related to Atari computers.
+ CBUFF/ Files and data for the CBUFF (ChessBase Utilities
+ File Format) project.
+ Atari/
+ DOS/
+ Macintosh/
+ Unix/
+ data/
+ doc/
+ src/
+ DOS/ Software and data for/related to IBM PC compatible
+ computers running DOS/Windows.
+ Bookup/ Bookup data files. This is a link to the
+ directory:
+ Game-Databases/Bookup/
+ ChessAssistent/ ChessAssistent data files. This is a link to the
+ directory:
+ Game-Databases/ChessAssistent/
+ ChessBase/ ChessBase data files. This is a link to the
+ directory:
+ Game-Databases/ChessBase/
+ NicBase/ NicBase data files. this is a link to the
+ directory:
+ Game-Databases/NicBase/
+ Tools/ Utility programs for DOS. Archiving and
+ compression utilities needed to unpack most of
+ the data in this archive may be found here for
+ DOS.
+ Game-Databases/ This is a directory tree dedicated to Chess game
+ databases in varying formats. Utilities to
+ convert from one format to another may be found
+ in the Tools directory.
+ Bookup/ Bookup database files.
+ ChessAssistent/ ChessAssistent database files.
+ Tools/ Utilities for manipulating/converting ChessAssistent
+ data files. This is a link to the directory:
+ Game-Databases/Tools/ChessAssistent/
+ ChessBase/ ChessBase database files.
+ Tools/ Utilities for manipulating/converting ChessBase
+ data files. This is a link to the directory:
+ Game-Databases/Tools/ChessBase/
+ ChessBase_CBUFF/ ChessBase database files from the CBUFF project.
+ This is a link to the directory: CBUFF/data/
+ NicBase/ NicBase database files.
+ Tools/ Utility programs for manipulating/converting
+ NicBase files. This is a link to the directory:
+ Game-Databases/Tools/NicBase/
+ PGN/ This is the PGN (Portable Game Notation) project
+ directory tree. It contains utilities for the
+ PGN format (including tools for converting
+ between other formats) and game databases in
+ the format. A DOS program for viewing these
+ databases is available.
+ Events/ PGN format data files of events in specific years.
+ 1990/
+ 1993/
+ 1994/
+ MGR/ The MASTER GAME REPOSITORY directory. contains
+ (or soon will) thousands of games in PGN format.
+ Players/ PGN data file of games for specific players:
+ Kasparov, Tal, Fischer, Karpov, Polgar, and
+ others!
+ Tools/ Utilities for PGN data files. Conversion tools
+ and a reader.
+ Tools/ Utility programs for all Databasse formats in the
+ Game-Databases area.
+ ChessAssistent/
+ ChessBase/
+ NicBase/
+ PGN/ This is a link to the directory:
+ Game-Databases/PGN/Tools/
+ HTML/ Hypertext files. For use with Mosaic (WWW)
+ clients. If you don't know what this is, don't
+ worry. It's specific to distributed
+ information over the Internet.
+ ICS_help/ All the help files for the ICS.
+ Macintosh/ Software and data for/related to Macintosh's.
+ NeXT/ Software and data for/related to NeXT computers.
+ PGN/ This is the PGN (Portable Game Notation) project
+ directory tree. It contains utilities for the
+ PGN format (including tools for converting
+ between other formats) and game databases in
+ the format. A DOS program for viewing these
+ databases is available. This is a link to the
+ directory: Game-Databases/PGN/
+ SAN_testsuites/ This is a collection of test positions for testing
+ the problem solving capabilities of chess
+ software. These files are related to the SAN
+ (Standard Algebraic Notation) project, the
+ distribution of which may be obtained in the
+ Unix/ directory. SAN utilities and datafiles
+ use PGN.
+ Unix/ Software and data for/related to Unix OS.
+ X/ Software and data for/related to X-Windows.
+ chessbits/ Archives of the Chessbits Electronic magazine
+ which will probably not come back to life,
+ although an occasional ICS-Newsletter seems to
+ have picked up the slack. These are found in
+ texts/
+ dropoff/ A place to drop things off where no-one but the
+ archive maintainer can get to them. Please
+ accompany anything with a brief note.
+ ics-tourn/ Data and games related to tournaments held on the
+ ICS's.
+ masters/ Collections of games for masters and tournaments
+ in ascii format primarily (some are PGN
+ compatible)
+ matches/
+ WCC_1993/ Games of the World Chess Championships in 1993.
+ Fide men's and women's and the PCA match as well.
+ pictures/ digitized pictures of chess related art and/or
+ chess players both famous and not so famous.
+ projects/ A directory tree for software projects donated to
+ the archive. Not necessarily chess related.
+ metagame/
+ morph/
+ texts/ General texts of materials, analysis and some game
+ scores. A grab-bag of chess related materials.
+ PCA_Qualifiers_1993/
+ uploads/ A directory containing lots of subdirectories for
+ donating materials to the archive. Pick an
+ appropriate directory here for your upload.
+ windows/ Here is where new applications for MSwindows or
+ other brands of windows for the IBM PC reside.
+ This area is new, so many windows applications
+ still are in th DOS directory.
+ xchange/ A place for data/software you want to make
+ available to everyone but which you might not
+ want to place in a 'permanent' area do to it's
+ developmental/experimental nature.
+
+
--- /dev/null
+
+interfaces
+
+ It is possible to play chess matches on the server by typing your moves and
+having board positions displayed in a simple style. However, it is also
+possible to use a graphics interface for making moves and displaying board
+positions. A graphics interface is a software program designed to decode the
+information sent to you by FICS and display board information using stylized
+graphics. It also allows you to make moves by moving pieces on its board
+using a mouse.
+
+ Which graphics interface will work best for you will depend upon the kind
+of computer you are using, and the way you are being connected to the server.
+Many graphics interfaces are available at the main chess ftp site
+(ics.onenet.net). Feel free to ask FICS users about what is working best for
+them, and feel free to examine the files at ics.onenet.net.
+
+ If you use a graphics interface, you will need to select the board style
+that is most appropriate for your software.
+
+See Also: set style variables
+
+
+List of interfaces
+------------------
+
+ Listed in this helpfile are details of graphical interfaces. Often it is
+difficult to play chess using the 'ASCII' boards the server generates. They
+aren't easy to see, and are affected by other information such as shouts. The
+graphical ones give you a proper chess board on which to view your pieces,
+making your chess easier to play.
+
+Here's a summary:
+
+=============================================================================
+Graphical Required Computer Operating Interface Location
+Interface System and Software Program at ICL
+Program Author
+==============================================================================
+ZIICS # DOS, modem Zek pub/chess/DOS
+GIICS DOS, modem LLama pub/chess/DOS
+Monarc DOS, modem *Kevster pub/chess/DOS
+JIICS DOS, VGA, modem, mouse Peluri pub/chess/DOS
+NGIICS DOS, TCP/IP LLama pub/chess/DOS
+Raja # MS Win3, modem and SLIP/PPP Christian pub/chess/Win3
+Gilchess MS Win3, modem Bloodrake pub/chess/Win3
+bludrake MS Win3, modem Bloodrake pub/chess/Win3
+SLICS # MS Win3, TCP/IP dfong pub/chess/Win3
+Toolkit ## MS Win3, TCP/IP and/or modem MaDHaTteR pub/chess/Win3
+WinBoard WinNT or W95, TCP/IP and/or modem mann pub/chess/Win3
+PMICS OS/2, TCP/IP and/or modem woof pub/chess/DOS
+XBoard # Unix, X11R4, TCP/IP and/or modem mann pub/chess/X
+xics Unix, X11R3 , TCP/IP *observer pub/chess/X
+cics TCP/IP and C, ASCII terminal *observer pub/chess/Unix
+NeXTICS NeXT, TCP/IP and/or modem red pub/chess/NeXT
+MacICS Mac *douglas pub/chess/Macintosh
+E-ICS Mac, Modem *douglas pub/chess/Macintosh
+MacICS-TCP Mac, TCP/IP eew pub/chess/Macintosh
+Aics Amiga, TCP/IP and/or modem Christian pub/chess/Amiga
+AmyBoard Amiga, TCP/IP and/or modem JochenW pub/chess/Amiga
+==============================================================================
+
+# Recommended and popular.
+## Not yet working well on FICS.
+* No account on FICS yet.
+
+Note: The handles of the authors may refer to the handles of people at the
+ old Aics. Certain ones may be different people here or non-existent.
+ Most interfaces should work; both the authors and the FICS programmers
+ would like feedback if you have problems with one here.
+
+
+ The listing will explain which interfaces will run on your particular
+set-up and in which directory to find it. It may have comments from the
+users/authors of the interfaces to help you choose.
+
+ If you have any further questions or trouble please contact an admin.
+
+Instructions for getting an interface
+-------------------------------------
+
+ The above graphical interfaces can be found at the anonymous ftp site
+chess.onenet.net (URL: ftp://ftp.onenet.net/) Most come with some
+instructions. :-)
+
+ Pick one, use ftp (read the "ftp_hints" help file for assistance), Netscape
+or some similar software to access it over the Internet, transfer it to your
+local PC system or workstation via your preferred method (zmodem, kermit for
+most non tcp/ip dialup connections), unpack it (most use standard archival
+software or are self-extracting), and set it up. :-)
+
+Comments on interfaces
+----------------------
+
+ This listing will explain the interfaces in a little more detail. Many have
+comments from the users/authors of the interfaces. Also indicated are the
+directories at onenet.net that hold the interfaces.
+
+ If you have any further questions or trouble please contact an admin.
+
+
+PC and compatibles (Using DOS and modem): pub/chess/DOS
+-----------------------------------------
+
+ ZIICS by Zek:
+ A very popular interface for the PC. ZIICS requires a regular modem
+ connection and a graphics adapter (VGA, EGA, CGA or Hercules). In VGA
+ there are several styles of sets from 32 pixels per square to 56 pixels
+ per square (almost fills the screen vertically). You can configure the
+ colors and the functions of the buttons by editing a text file.
+ [comment by Zek]
+
+ GIICS by LLama:
+
+ JIICS by Peluri:
+ You will need VGA and a mouse to use this.
+
+ Monarc by Kevster:
+
+
+PC and compatibles (Using DOS and TCP/IP): pub/chess/DOS
+------------------------------------------
+
+ NGIICS by LLama:
+
+
+PC and compatibles (Using Windows and modem): pub/chess/Win3
+---------------------------------------------
+
+ Raja (elephant) by Christian:
+ Works well with Win95. Noticable speed increase (and its not even 32 bit
+ yet!). Tested with 486-DX4-100. [note from Christian]
+
+ Gilchess by Azorduldu:
+
+ bludrake by Bloodrake:
+
+
+PC and compatibles (Using Windows and TCP/IP): pub/chess/Win3
+----------------------------------------------
+
+ SLICS by dfong:
+
+ Toolkit by MaDHaTteR:
+ Should work here soon.
+
+
+PC and compatibles (Using Windows NT(or 95) and TCP/IP): pub/chess/Win3
+--------------------------------------------------------
+
+ WinBoard by mann:
+ finger mann for the latest details.
+
+
+PC and compatibles (OS/2 PM ): pub/chess/DOS
+------------------------------
+
+ PMICS by woof:
+
+
+Unix (Xwindows): pub/chess/X
+----------------
+
+ XBoard by mann:
+ Certainly the best of the Unix interfaces and still is being supported to
+ work better at FICS. Owners of Unix machines are well advised to get this
+ interface. It is also suitable for use with GNUchess. [comment by DAV]
+ Finger mann for the latest details.
+
+ xics by observer:
+
+
+Unix (vt100 terminal): pub/chess/Unix
+----------------------
+
+ cics by observer:
+
+
+NeXT: pub/chess/NeXT
+-----
+
+ NeXTICS by red:
+
+
+MAC: pub/chess/Macintosh
+----
+
+ MacICS by douglas:
+
+
+MAC (Modem): pub/chess/Macintosh
+------------
+
+ E-ICS by douglas:
+
+
+MAC (TCP\IP): pub/chess/Macintosh
+-------------
+
+ MacTCP by eew:
+
+
+Amiga: pub/chess/Amiga:
+------
+
+ Aics by Christian:
+ Will work with 2.04 Kickstart and should be compatible with newer
+ versions.
+
+ AmyBoard by JochenW:
+
+
+See also: ftp_hints
+
+[Last modified: December 25, 1995 -- Friar]
+
--- /dev/null
+
+intro0
+
+ W E L C O M E
+
+ to the
+
+ F R E E I N T E R N E T C H E S S S E R V E R (FICS)
+
+
+ We have created several information files for users of this chess server.
+The files describe different features of the server and give you some
+suggestions on how these features can help you enjoy internet chess. Here is
+a directory of the information files and what topics each file covers:
+
+ File Topics
+ ------ --------------------------------------------------
+ intro1 General information
+ intro2 Communicating
+ intro3 Displaying information
+ intro4 Setting your preferences
+ intro5 Special functions
+ intro6 Chess matches
+ intro7 Making moves in a chess match
+
+ To read information from one of these files, simply type "help intro#" using
+the appropriate number. If you have questions after reading the files, there
+are several things you can do. (1) Read the help file for a command you have
+a question about; your answer might be there. (2) Contact users, especially
+administrators of the server (known as "admins"); they are very helpful.
+
+ To read a help file, type "help [topic]", without the square brackets,
+however. If the topic is a command, the help file will give you information
+about the format for the command. You can tell that it is a command because
+the first line will describe its format ("Usage"). Words in square brackets
+[] designate optional variables; including them affects the way your command
+will be processed. In many cases, a help file will suggest other help files
+you may want to read.
+
+ Your suggestions about the information files (and help files, too) are
+welcome. Feel free to "message helpfiles" with your comments.
+
+[Last modified: June 16, 1995 -- Friar]
+
--- /dev/null
+
+intro1
+
+GENERAL INFORMATION
+
+ The internet has great capabilities for connecting people from all over
+the world. This chess server is one way for networking individuals who enjoy
+chess. Among other things, the chess server allows users to play chess
+matches against each other, as well as communicate with each other. The chess
+server (computer) is programmed to send players' chess moves and messages to
+the right users. It also keeps track of various information.
+
+ In order to use the features, you need to type various commands. To list
+the various commands, type "help". To get a description of a particular
+command, type "help [command]" -- without the square brackets, of course.
+NOTE: you do not have to type the entire command in order to use it or read
+its help file; typing the first few letters will work in most cases.
+
+ In general, commands do one of four things: (a) send a message to one or
+more users (see intro2), (b) display information to you (see intro3), (c)
+modify one of your settings/features/functions (see intro 4), or (d) have the
+server perform a special function. Certain commands are restricted to server
+administrators ("admins") and cannot be used by regular users.
+
+ New users might want to start off with simple features and gradually learn
+about the other features as you go along. The server allows you to determine
+how various information is sent to you. For example, you can decide how a
+position in a chess game is displayed (see style). You can also set your
+preferences about the types of chess matches you would like to have or types
+of messages you receive from others (see variables).
+
+See Also intro2 intro3 intro4 intro5
+
+[Last modified: June 16, 1995 -- Friar]
+
--- /dev/null
+
+intro2
+
+COMMUNICATING
+
+ Communications among users are of two types: (a) messages, and (b) requests.
+Messages basically involve conversations among users; the server merely
+transmits the messages. Requests are different because they involve the
+server doing something about or during a chess match.
+
+
+MESSAGES
+
+ Suppose you want to say something to one or more users. There are several
+commands you could use:
+
+ command function
+ ------- --------------------------------------------
+ message Send a user a message to be stored, even if the user is
+ not logged on at that time
+ tell Talk to one user, or users on one channel
+ xtell Talk to one user, but allow for a continuing conversation
+ with another user
+ channel Listen to tells sent to a given channel
+ say Talk to the user you are playing chess with (or just
+ played a game with)
+ shout Talk to all users who are open to shouts
+ cshout Talk to all users who are open to shouts; message must be
+ about chess
+ it Special kind of shout
+ kibitz Talk to all players and observers of a specific chess game
+ whisper Talk to all observers of a specific chess game
+ censor Prevents a given user's messages from reaching you
+
+ Read more about these commands in their own help files. But, in general,
+"message" works like an answering machine, "tell" and "say" are like normal
+one-to-one conversations, "shout", "cshout" and "it" are for group talks,
+and "kibitz" and "whisper" are for commenting on a chess match you are
+observing. Please observe chess server etiquette guidelines when using these
+commands.
+
+
+REQUESTS
+
+ Users need to make agreements about the kinds of chess matches they will be
+playing. They also need to make agreements about various situations during
+the play of a chess match. Requests serve as ways to reach agreements as well
+as take the agreed upon action. For example, users need to request the start
+of a chess match. When a match has been agreed upon, the server will start a
+match between those two users. During a match, one player may need to
+adjourn; if an adjournment is agreed upon, the server will stop the match and
+save the game so that it can be resumed later. Read intro6 for more
+information about chess matches and these special requests.
+
+ USEFUL HINT: At times, a lot of messages from various users will come across
+your screen. To help you notice when a user has sent a message or request to
+you personally (rather than to users on FICS), you can set the
+highlight variable to to make them readily apparent (see highlight).
+
+See Also: etiquette intro6 [and the individual commands]
+
+[Last modified: June 16, 1995 -- Friar]
+
--- /dev/null
+
+intro3
+
+DISPLAYING INFORMATION
+
+ There are several commands you can use for displaying general information:
+
+ command information
+ ------- --------------------------------------------
+ help describes a command, displays useful information, or
+ lists all commands and their help file topics alphabetically
+ info lists all help files for non-commands
+ who lists current users
+ games lists current games
+ allobservers lists all users observing a chess game (or games)
+ handle lists registered users with names beginning with a given
+ letter or letters
+ inchannel lists all users who are listening to a given communication
+ channel
+ uptime how long the server has been running since its last startup
+ date current date
+ time current time
+ statistics displays information about server usage
+ llogons lists the last 30 or so logons/logoffs
+ best displays highest ratings achieved for different types of
+ chess matches
+ fixes displays information about recent improvements
+
+Other commands display information about you or another user:
+
+ command information
+ ------- --------------------------------------------
+ finger displays general information about a user
+ history displays information about a user's recent matches
+ stored lists a user's stored games
+ pending lists requests that have been made to and by you but have
+ not yet been declined
+ variables displays a user's current preferences and settings
+ assess displays how you and another user's ratings would change
+ if you were to play a rated chess match
+ logons lists the last 10 or so logons for a user
+
+See Also: [the individual commands]
+
+[Last modified: June 16, 1995 -- Friar]
+
--- /dev/null
+
+intro4
+
+SETTING YOUR PREFERENCES
+
+ Everyone starts out with certain default values and settings, but you may
+change them if you wish. You change settings using the set command; you can
+view your current settings (or those of another user) using the variables
+command.
+
+ Some settings concern what information the server will transmit to you, such
+as communications from other players and notifications about games starting or
+users logging on/off. Other settings concern chess matches, such as your
+default time controls, whether you will hear a bell when a new board
+position is sent to you, whether you will be sent a list of the moves for your
+game automatically when the game is completed (or adjourned), even the format
+used to send you the board position.
+
+ By changing these settings, you can create the kind of atmosphere you would
+like to have. You can change these settings at any time, even during a given
+session. For the most part, changes you make to your settings will be saved
+after you log off and you will not need to change the settings each time you
+log on.
+
+ Your password is also a special setting, although it is never displayed at
+any point. When you register, you are given a logon password. You may change
+your password at any point using the password command.
+
+ Lastly, it is possible for you to create special aliases to save you from
+typing phrases you use often. Instead of typing the whole phrase, all you
+do is type your alias.
+
+See Also: aliases password set variables
+
+[Last modified: June 16, 1995 -- Friar]
+
--- /dev/null
+
+intro5
+
+SPECIAL FUNCTIONS
+
+ There are several commands that perform special functions beyond sending
+messages to other users, displaying information or modifying your settings.
+Here are some useful ones:
+
+ command function
+ ------- --------------------------------------------
+ alias to make typing frequently-used phrases easier
+ mailmoves mails to you the moves of a user's game
+ mailoldmoves mails to you the moves of a user's last game
+ oldmoves allows you to view a user's last game
+ smoves displays moves of a stored game
+ sposition displays the last position of a stored game
+
+More functions will be added as time goes on.
+
+See Also: [the individual commands]
+
+[Last modified: June 16, 1995 -- Friar]
+
--- /dev/null
+
+intro6
+
+CHESS MATCHES
+
+ This chess server's main purpose is to link users who want to play chess.
+Among other things, the server allows you to contact other users about playing
+chess matches, checks to make sure that your moves are legal, keeps track of
+the board position while you play, and updates ratings of players after the
+match.
+
+ The basic way of contacting a user about playing a chess match is by using
+the match command. There is a separate help file for the match command, so we
+will not go into details here. But here is a list of the various commands
+that you may want to learn about (remember that requests are sent to your
+opponent, not to the server, and must be accepted by your opponent in order to
+occur):
+
+ command function
+ ------- --------------------------------------------
+ match request a match with another user
+ abort request that a game be canceled
+ accept accept a request from a user
+ adjourn request that the match be stopped, saved and continued at
+ another time
+ decline decline a request from a user
+ draw request that the chess match be declared a draw
+ flag end the match because your opponent is out of time
+ moves have FICS send you the moves to the match you are playing
+ pause request that the match be suspended temporarily, but not
+ adjourned
+ promote set the kind of piece a pawn will be promoted to when it
+ reaches the back rank
+ refresh display the current board position
+ resign give your opponent the win, and end the match
+ say communicate with your current (last) opponent
+ switch request that you and your opponent change sides (colors)
+ takeback request that one or move moves be taken back (canceled)
+ unpause request that a paused match be resumed
+ withdraw cancel a request you have made
+
+ It is possible to play matches with more than one user simultaneously, much
+like a simultaneous exhibition at many major chess tournaments. If you are
+interested in playing more than one chess game at once, or interested in
+playing against someone with simultaneous matches, read the "simuls" file.
+
+See Also: match simuls [and the individual commands]
+
+[Last modified: June 16, 1995 -- Friar]
+
--- /dev/null
+
+intro7
+
+MAKING MOVES IN A CHESS MATCH
+
+ There are two ways to make chess moves during a match. Many user's have a
+graphics interface. In this case, the user moves the piece on the graphics
+board using the computer mouse, and the interface software translates this
+move into chess notation and sends the move to the server for processing.
+Read the interfaces information file for a few details about graphics
+interfaces.
+
+ If you don't have a graphics interface, you will need to enter your moves
+using a keyboard. In order to do this, you have to know what kind of chess
+notation the server uses. Chess players use one of two different notational
+systems: descriptive and algebraic. The server understands algebraic. (The
+server also understands a computer version of chess notation; see below.)
+
+ In algebraic notation, each square has a unique label. Each rank is
+labeled 1 to 8, with the rank on White's side being 1. Each file is
+labeled a to h, with the file on White's left side being a. So each
+square has a file label and a rank label, with the file listed first. In
+algebraic notation, each chess piece has its own symbol: k = king;
+q = queen; b = bishop; n = knight; r = rook; p = pawn (though the "p" is
+not really used).
+
+ Here is a sample of a match position as displayed in the default style 1.
+For this example, White is at the bottom of the board and Black is at the top.
+Symbols are in capital letters; the * means the piece is Black's.
+
+ ---------------------------------
+ 8 | | *R| | | *R| | *K| |
+ |---+---+---+---+---+---+---+---|
+ 7 | *P| | | *B| *P| *P| *B| *P|
+ |---+---+---+---+---+---+---+---|
+ 6 | | | | | | *N| *P| |
+ |---+---+---+---+---+---+---+---|
+ 5 | *Q| | | *P| | | B | |
+ |---+---+---+---+---+---+---+---|
+ 4 | | | | | | P | | |
+ |---+---+---+---+---+---+---+---|
+ 3 | | | N | B | P | | | |
+ |---+---+---+---+---+---+---+---|
+ 2 | P | P | | | Q | | P | P |
+ |---+---+---+---+---+---+---+---|
+ 1 | | | R | | | R | K | |
+ ---------------------------------
+ a b c d e f g h
+
+ Black's king (*K) is on the g8 square; White's king (K) is on the g1
+square, and so on. It is Black's move. Suppose Black wants to place the
+knight (*N) on the e4 square. The move to enter in algebraic would be Ne4.
+Moving pawns is simpler; you don't use the "p" for the piece and just give
+the square the pawn is moving to. Suppose Black decides to move the pawn
+(*P) on the h7 square to the h6 square. The move to enter would be h6. In
+many board positions, more than one rook, knight or pawn could move to the
+same square. In this case, you have to indicate which of the two pieces you
+want to move. For example, suppose Black has knights on c2 and e2; they could
+both move to d4. To move the knight on c2 to d4 you could type Ncd4, where
+the "c" serves to tell the server which knight to move.
+
+ In algebraic notation, captures are usually denoted by "x". Suppose
+Black wants to capture White's b2 pawn (P) with the rook (R) on b8. Black
+would enter the move Rxb2. However, the server would also understand the
+simple Rb2 and know that a capture is implied. So, for this server, you can
+enter the square the piece will capture on. To make a castle move, use O-O to
+castle on the king's side and O-O-O to castle on the queen's side.
+
+ Many computers want very explicit instructions on how to move pieces.
+This "computer" notation has the following format: square_from-square_to
+
+ For example, in the above board position, moving the Black rook from b8 to
+b2 would be entered b8-b2. Piece symbols are never used; only the squares.
+The server understands computer notation as well.
+
+ In short, to move a piece during a chess match, enter the move. Each
+time you and your opponent make a move, the server updates the board position
+and sends the new position to both you and your opponent. It's that simple!
+
+See Also: interfaces style
+
+[Last modified June 16, 1995 -- Friar]
+
--- /dev/null
+
+intro_basics
+
+ Here is a summary chart for new users of the server with basic commands you
+may want to use as you start to play chess live on the internet.
+
+In order to ... Type ...
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Get assistance or an answer to a question [Step 1] +chan 1
+ [Step 2] tell 1 <text>
+Turn shouts off set shout 0
+Read a help file help file_name
+Select an appropriate graphics interface help interfaces
+Download a graphics interface help ftp_hints
+Talk to just one individual tell user_name <text>
+Challenge a user to a chess match match user_name
+
+See Also (these other help files): help index intro_welcome intro_talking
+
+[Last modified: December 19, 1995 -- Friar]
+
--- /dev/null
+
+intro_general
+
+GENERAL INFORMATION
+
+ The internet has great capabilities for connecting people from all over the
+world. This chess server is one way for networking individuals who enjoy
+chess. Other chess servers (at least those we know about) are listed in the
+"addresses" file. Among other things, a chess server allows users to play
+chess matches against each other, as well as communicate with each other. The
+chess server (computer) is programmed to send players' chess moves and
+messages to the right users. It also keeps track of various information.
+
+ In order to use the features, you need to type various commands. In
+general, commands do one of four things: (a) help you play a chess match (see
+intro_playing), (b) send a message to one or more users (see intro_talking),
+(c) display information to you (see intro_information), (d) modify one of your
+settings, variables or notes (see intro_settings), or (e) have the server
+perform a special function (see intro_special).
+
+ Certain commands are restricted to server administrators ("admins") and
+cannot be used by regular users. Some features are only available for
+registered users. Only registered users can have rated chess games, have
+games stored after adjournment, have "finger" notes, and communicate using
+"shout", "kibitz" and "message" (see "intro_talking" help file). If you
+intend to visit the server often, you will enjoy your visit more as a
+registered user. Registration on this server is by email; type "help
+register" to learn the procedure.
+
+ New users might want to start off with simple features and gradually learn
+about the other functions as they go along. To get a description of a
+particular command, type "help [command]" -- without the square brackets, of
+course. For example, "help match" will give you information about the "match"
+command. NOTE: you do not have to type the entire command in order to use it
+or read its help file; typing the first few letters will work in most cases.
+
+See Also: addresses adm_info finger intro_basics intro_information
+intro_settings intro_special intro_talking notes register
+
+[Last modified: September 28, 1995 -- Friar]
+
--- /dev/null
+
+intro_information
+
+DISPLAYING INFORMATION
+
+ There are several types of information that are available about users, games
+and the server. You can have this information displayed to you by using
+various commands.
+
+
+USER INFORMATION
+
+ command information
+ ------- --------------------------------------------
+ best Displays highest ratings achieved for different types of
+ chess matches (includes computers)
+ finger Displays general information about a user
+ handle Lists registered users with names beginning with a given
+ letter or letters
+ hbest Displays highest ratings achieved for different types of
+ chess matches (excludes computers)
+ history Displays information about a user's recent matches
+ hrank Lists users and ratings within the range of ranks specified
+ (rankings exclude computers)
+ inchannel Lists all users who are listening to a given communication
+ channel
+ rank Lists users and ratings within the range of ranks specified
+ (rankings include computers)
+ stored Lists a user's stored games
+ variables Displays a user's current preferences and settings
+ who Lists current users
+
+
+GAME INFORMATION
+
+ command information
+ ------- --------------------------------------------
+ allobservers Lists all users observing a chess game (or games)
+ assess Displays how you and another user's ratings would change
+ if you were to play a rated chess match
+ eco Displays information about the opening used in the game
+ games Lists current games
+
+
+SERVER INFORMATION
+
+ command information
+ ------- --------------------------------------------
+ date Current date
+ help Describes a command, displays useful information, or
+ lists all commands and their help file topics alphabetically
+ info Lists all "information" help files for non-commands
+ llogons Lists the last 30 or so logons/logoffs
+ logons Lists the last 10 or so logons for a user
+ news Lists recent news items about the server
+ statistics Displays information about server usage
+ time Displays current time at the server site
+ uptime Displays how long the server has been running since its last
+ startup, and various server statistics and parameters
+
+ Also, the "totals" help file gives updated information about registered and
+active users on the server.
+
+See Also: [the individual commands]
+
+[Last modified: July 7, 1995 -- Friar]
+
--- /dev/null
+
+intro_moving
+
+MAKING MOVES IN A CHESS MATCH
+
+ Once you have arranged for a match, you begin playing and moving the pieces
+around. There are two ways to make chess moves during a match. Many user's
+have a graphics interface. In this case, the user moves the piece on the
+graphics board using the computer mouse, and the interface software translates
+this move into chess notation and sends the move to the server for processing.
+Read the interfaces information file for a few details about graphics
+interfaces.
+
+ If you don't have a graphics interface, you will need to enter your moves
+using a keyboard. In order to do this, you have to know what kind of chess
+notation the server uses. Chess players use one of two different notational
+systems: descriptive and algebraic. The server understands algebraic. (The
+server also understands a computer version of chess notation; see below.)
+
+ In algebraic notation, each square has a unique label. Each rank is labeled
+1 to 8, with the rank on White's side being 1. Each file is labeled a to h,
+with the file on White's left side being a. So each square has a file label
+and a rank label, with the file listed first. In algebraic notation, each
+chess piece has its own symbol: k = king; q = queen; b = bishop; n = knight; r
+= rook; p = pawn (though the "p" is not really used).
+
+ Here is a sample of a match position as displayed in the default style 1.
+For this example, White is at the bottom of the board and Black is at the top.
+Symbols are in capital letters; the * means the piece is Black's.
+
+ ---------------------------------
+ 8 | | *R| | | *R| | *K| |
+ |---+---+---+---+---+---+---+---|
+ 7 | *P| | | *B| *P| *P| *B| *P|
+ |---+---+---+---+---+---+---+---|
+ 6 | | | | | | *N| *P| |
+ |---+---+---+---+---+---+---+---|
+ 5 | *Q| | | *P| | | B | |
+ |---+---+---+---+---+---+---+---|
+ 4 | | | | | | P | | |
+ |---+---+---+---+---+---+---+---|
+ 3 | | | N | B | P | | | |
+ |---+---+---+---+---+---+---+---|
+ 2 | P | P | | | Q | | P | P |
+ |---+---+---+---+---+---+---+---|
+ 1 | | | R | | | R | K | |
+ ---------------------------------
+ a b c d e f g h
+
+ Black's king (*K) is on the g8 square; White's king (K) is on the g1
+square, and so on. It is Black's move. Suppose Black wants to place the
+knight (*N) on the e4 square. The move to enter in algebraic would be Ne4.
+Moving pawns is simpler; you don't use the "p" for the piece and just give
+the square the pawn is moving to. Suppose Black decides to move the pawn
+(*P) on the h7 square to the h6 square. The move to enter would be h6. In
+many board positions, more than one rook, knight or pawn could move to the
+same square. In this case, you have to indicate which of the two pieces you
+want to move. For example, suppose Black has knights on c2 and e2; they could
+both move to d4. To move the knight on c2 to d4 you could type Ncd4, where
+the "c" serves to tell the server which knight to move.
+
+ In algebraic notation, captures are usually denoted by "x". Suppose Black
+wants to capture White's b2 pawn (P) with the rook (R) on b8. Black would
+enter the move Rxb2. However, the server would also understand the simple Rb2
+and know that a capture is implied. So, for this server, you can enter the
+square the piece will capture on. To make a castle move, use O-O to castle on
+the king's side and O-O-O to castle on the queen's side.
+
+ Many computers want very explicit instructions on how to move pieces.
+This "computer" notation has the following format: square_from-square_to
+
+ For example, in the above board position, moving the Black rook from b8 to
+b2 would be entered b8-b2. Piece symbols are never used; only the squares.
+The server understands computer notation as well.
+
+ In short, to move a piece during a chess match, enter the move. Each time
+you and your opponent make a move, the server updates the board position and
+sends the new position to both you and your opponent. It's that simple!
+
+See Also: interfaces style
+
+[Last modified: June 16, 1995 -- Friar]
+
--- /dev/null
+
+intro_playing
+
+PLAYING IN CHESS MATCHES
+
+ This chess server's main purpose is to link users who want to play chess.
+Among other things, the server allows you to contact other users about playing
+chess matches, checks to make sure that your moves are legal, keeps track of
+the board position while you play, and updates ratings of players after the
+match.
+
+
+STARTING A MATCH
+
+ The basic way of contacting a user about playing a chess match is by using
+the match command. There is a separate help file for the match command, so we
+will not go into details here. But here is the simplest way to ask another
+user for a match:
+
+ match user_name
+
+The other user will be asked to accept or decline your match request. If the
+user accepts, the server will determine who plays White and Black and will
+notify you that a match has begun with that user. The starting position will
+be sent to you, and play will begin.
+
+
+PLAYING A GAME
+
+ During a chess match, you and your opponent will moves the pieces on the
+board and also issue various commands or requests. The help file
+"intro_moving" explains how to move the pieces on the board. Here is a list
+of other commands and requests you may need to use during a match (remember
+that requests are sent to your opponent, not to the server, and must be
+accepted by your opponent in order to occur):
+
+ command function
+ ------- --------------------------------------------
+ abort request that a game be canceled
+ adjourn request that the match be stopped, saved and continued at
+ another time
+ draw request that the chess match be declared a draw
+ flag end the match because your opponent is out of time
+ moves have FICS send you the moves to the match you are playing
+ pause request that the match be suspended temporarily, but not
+ adjourned
+ promote set the kind of piece a pawn will be promoted to when it
+ reaches the back rank
+ refresh display the current board position
+ resign give your opponent the win, and end the match
+ say communicate with your current (last) opponent
+ switch request that you and your opponent change sides (colors)
+ takeback request that one or move moves be taken back (canceled)
+ unpause request that a paused match be resumed
+ withdraw cancel a request you have made
+
+ It is possible to play matches with more than one user simultaneously, much
+like a simultaneous exhibition at many major chess tournaments. If you are
+interested in playing more than one chess game at once, or interested in
+playing against someone with simultaneous matches, read the "simuls" file.
+
+See Also: accept adjournments decline intro_moving match pending simuls
+[and the individual commands]
+
+[Last modified: July 20, 1995 -- Friar]
+
--- /dev/null
+
+intro_settings
+
+SETTING YOUR PREFERENCES
+
+ Everyone starts out with certain default values and settings, but you may
+change them if you wish. You change settings using the set command; you can
+view your current settings (or those of another user) using the variables
+command.
+
+ Some settings concern what information the server will transmit to you, such
+as communications from other players and notifications about games starting or
+users logging on/off. Other settings concern chess matches, such as your
+default time controls, whether you will hear a bell when a new board
+position is sent to you, whether you will be sent a list of the moves for your
+game automatically when the game is completed (or adjourned), even the format
+used to send you the board position.
+
+ By changing these settings, you can create the kind of atmosphere you would
+like to have. You can change these settings at any time, even during a given
+session. For the most part, changes you make to your settings will be saved
+after you log off and you will not need to change the settings each time you
+log on.
+
+ Your password is also a special setting, although it is never displayed at
+any point. When you register, you are given a logon password. You may change
+your password at any point using the password command.
+
+ Lastly, it is possible for you to create special aliases to save you from
+typing phrases you use often. Instead of typing the whole phrase, all you
+do is type your alias.
+
+See Also: alias password set variables
+
+[Last modified: July 7, 1995 -- Friar]
+
--- /dev/null
+
+intro_special
+
+SPECIAL FUNCTIONS
+
+ There are several commands that perform special functions beyond sending
+messages to other users, displaying information, modifying your settings or
+playing in a chess match. Here are some useful ones:
+
+ command function
+ ------- --------------------------------------------
+ alias to make typing frequently-used phrases easier
+ examine to analyze a game
+ mailmoves mails to you the moves of a user's game
+ mailoldmoves mails to you the moves of a user's last game
+ oldmoves allows you to view a user's last game
+ smoves displays moves of a stored game
+ sposition displays the last position of a stored game
+
+More functions will be added as time goes on.
+
+See Also: [the individual commands]
+
+[Last modified: July 7, 1995 -- Friar]
+
--- /dev/null
+
+intro_talking
+
+COMMUNICATING TO OTHER USERS
+
+ There are several commands you could use for communicating with other users.
+Here is a list, followed by some comparisons.
+
+ command function
+ -------- --------------------------------------------
+ +channel Listen to tells sent to a given channel (-channel to leave a
+ chanel)
+ cshout Talk to all users who are open to shouts; message must be
+ about chess
+ it Special kind of shout
+ kibitz Talk to all players and observers of a specific chess game
+ message Send a user a message to be stored, even if the user is not
+ logged on at that time
+ ptell Talk to your bughouse partner
+ say Talk to the user you are playing chess with (or have just
+ played a game with)
+ shout Talk to all users who are open to shouts
+ tell Talk to one user, or users on one channel
+ whisper Talk to all observers of a specific chess game
+ xtell Talk to one user, but allow for a continuing conversation
+ with another user
+
+ In general, "message" works like an answering machine, " ptell", "tell" and
+"say" are like normal one-to-one conversations, "shout", "cshout", "it" and
+"tell <channel>" are for group talks, and "kibitz" and "whisper" are for
+commenting on a chess match you are observing. Channel 1 is the server help
+channel (see the chan_1 help file).
+
+
+RECEIVING MESSAGES
+
+ In general, you will receive every message sent to all users, to users on
+channels you are listening to, and to you personally. However, you can decide
+not to be open to certain kinds of communications. The "shout" and "tell"
+variables can be set to limit what you will hear (read the intro_settings help
+file). You can also decide not to hear anything from a given user (the
+"censor" command).
+
+ The "message" command is used to send a message to a user and have it
+stored. This command can also be used to read (and re-read) old messages that
+have been sent to you as well as old messages you have sent to other users.
+The "clear" command is used to erase old messages you have received.
+
+
+SPECIAL NOTES
+
+(a) At times, a lot of messages from various users will come across your
+screen. To help you notice when a user has sent a message or request to you
+personally (rather than to all users on the server), you can set the highlight
+variable to to make them readily apparent (see highlight).
+
+(b) Unregistered users (guests) are limited to the "tell" and "xtell"
+commands.
+
+(c) Please observe chess server etiquette guidelines when using these
+commands.
+
+See Also: chan_1 etiquette highlight intro_playing intro_settings
+shout_abuse [and the individual commands of course]
+
+[Last modified: December 19, 1995 -- Friar]
+
--- /dev/null
+
+intro_welcome
+
+ W E L C O M E
+
+ to the
+
+ F R E E I N T E R N E T C H E S S S E R V E R (FICS)
+
+ *** If you are new here and would like to register, ***
+ *** type "help register" to learn about the process. ***
+
+
+ We have created several introductory files for users of this chess server.
+The files describe different features of the server and give you some
+suggestions on how these features can help you enjoy internet chess. Here is
+a directory of the introductory files and what topics each file covers:
+
+ Introductory File Topics Covered
+ ----------------- -------------------------------------
+ intro_basics Basic commands; enough to get started
+ intro_general General information
+ intro_information Displaying information
+ intro_moving Making moves in a chess match
+ intro_playing Playing in chess matches
+ intro_settings Setting your preferences
+ intro_special Special functions
+ intro_talking Communicating to other users
+ register How to register on the server
+
+ In order to read information from one of these files (or any other help
+file), simply type "help file_name" using the appropriate file_name.
+
+ If you have questions after reading a file, there are several things you can
+do. (1) Read the help file for a command you have a question about; your
+answer might be there. Also, help files usually suggest related files you may
+want to read ("See Also"). (2) Contact users, especially administrators of
+the server (known as "admins"); they are very helpful. Users on channel 1 are
+also a great help (see the "chan_1" help file). in order to learn how to
+communicate, type "help intro_talking". Registration on this server is by
+email; type "help register" to learn the procedure.
+
+ Your suggestions about the introductory files (and help files, too) are
+welcome. Feel free to "message helpfiles" with your comments.
+
+See Also: adm_info chan_1 help intro_general intro_talking next
+register
+
+[Last modified: September 22, 1995 -- Friar]
--- /dev/null
+
+iset
+
+Usage: iset ivariable_name [value]
+
+ Ivariables are special variables that interface and bot authors can use to
+modify the output of the FICS server. They shouldn't normally be touched by
+a user and fiddling with them may cause the interface to malfunction (which
+can be reset by logging out then in again). Ivariables are not saved between
+sessions.
+
+Example:
+ iset defprompt 1
+
+ Each ivariable has a separate help file to explain how it is used. Type
+"help iv_<variable>" to read a specific file. For example, to read about the
+graph variable you would type "help iv_graph".
+
+When a ivariable has been modified, you will be informed of the new setting as
+a way of verifying it. Normally an interface should parse out this message so
+that users will not be confused.
+
+See Also: ivariables [and the many 'iv_' files, of course]
+
+[Last modified: August 1, 2000 -- DAV]
+
--- /dev/null
+
+it
+
+Usage: it message
+
+ This command sends a message to all persons open to hear shouts. "It" is
+similar to "shout" in that regard. However, with "it" your chess server name
+(or "handle") is always the first word of the message. Also, the "it" message
+may be preceded by various symbols depending on the chess server being used.
+The symbol string --> is typical. This command has two aliases: "i" and ":".
+
+ Here is an example: if your handle is HANDEL and you type "it thinks FICS
+is great!", users will see the following message displayed --
+
+ --> HANDEL thinks this server is great!
+
+You, as the sender, will see the following --
+
+ (##) HANDEL thinks this server is great!
+
+where ## is the number of users who received the message.
+
+SPECIAL NOTES:
+
+ (a) Use "cshout" rather than "it" for chess-related messages.
+
+ (b) To contact just one user, use "tell".
+
+ (c) If you want to contact a specific group of users, "tell" to a channel.
+
+ (d) "It" and "shout" are similar. Be familiar with their differences.
+
+ (e) Persons who "it" too much, or in less than appropriate ways, may be
+placed on the shout_abuse list. Users on this list may only "shout" a certain
+number of times per minute. To see whether you are on the shout_abuse list,
+or when you are permitted to "it" again, type "it" alone without a message.
+Excessive abuse can lead to heavier restrictions.
+
+ (f) You can decide whether or not to hear an "it" from other users; setting
+the "shout" variable to 0 (zero) filters these from being sent to you.
+
+See Also: alias channel channel_list cshout intro_talking shout
+shout_abuse shout_quota tell variables
+
+[Last modified: December 19, 1995 -- Friar]
+
--- /dev/null
+
+jkill
+
+Usage: jkill slot
+
+ This command will erase a game from your journal. For example: "jkill A"
+will erase the game saves in your journal slot "A".
+
+See Also: jsave journal
+
+[Last modified: February 3, 1996 -- Friar]
+
--- /dev/null
+
+journal
+
+ The journal feature is a way to save games as long as you want to. History
+games, remember, get overwritten as you play more games; only the most recent
+games are saved. The journal feature allows you to save games for a longer
+period of time.
+
+ The journal file for most players has 26 available slots. These slots are
+denoted by the single letters from A to Z. Games in your journal are referred
+to by their letters.
+
+ There are two things you need to know in order to make this feature work for
+you: (i) how to save a game to your journal, and (ii) how to review a game
+from your journal.
+
+
+SAVING A GAME TO A JOURNAL
+--------------------------
+
+ The "jsave" command is used to save games to your journal. Please refer to
+that help file for details
+
+
+SHOWING THE CONTENTS OF A JOURNAL
+---------------------------------
+
+ To read the contents of a journal, type:
+
+ journal [user_name]
+
+If the user_name is omitted, then the contents of your journal will be
+displayed.
+
+ There are several commands you can use in order to display information about
+an individual game: (a) examine; (b) smoves; and (c) mailstored. See those
+help files for further details.
+
+
+PRIVATE JOURNALS
+----------------
+
+ It is possible to hide your journal from other users (except admins) by
+using the 'jprivate' variable:
+
+ set jprivate 1 --- hides your journal
+
+ set jprivate 0 --- allows others to access your journal
+
+
+See also: examine history jsave mailstored smoves variables
+
+[Last modified: December 25, 1995 -- Friar]
+
--- /dev/null
+
+jsave
+
+Usage: jsave [slot] [user_name] [gamenumber]
+
+ This command is used to save games to your journal (see the "journal" help
+file). You can save games from a "history" file or from another journal.
+
+To save from a "history" file
+-----------------------------
+
+ The general format is: jsave slot user_name game_number. For example:
+
+ jsave A Friar 3
+
+ where 'A' is your journal slot; 'Friar' is the handle of the player whose
+ game you want to save -- whether it is your handle or the handle of another
+ player; and '3' is the number of the game from that player's 'history' file.
+
+To save from another journal
+----------------------------
+
+ The general format is: jsave slot user_name slot. For example:
+
+ jsave B Rattlesnake A
+
+ where 'B' is your journal slot, 'Rattlesnake' is the handle of the player
+ whose journal game you want to transfer to your journal; 'A' is that
+ player's journal slot for that game.
+
+Using this journal-transfer feature, you can also relabel your own journal
+entries. For example:
+
+ jsave A your_handle D
+
+will take the journal game in slot 'D' and copy it to journal slot 'A'. At
+the moment, it is not possible to delete a slot (except by overwritting); that
+capability will be added in the future.
+
+See also: history journal
+
+[Last modified: December 25, 1995 -- Friar]
+
--- /dev/null
+
+kibitz
+
+Usage: kibitz message
+LIMITED TO REGISTERED USERS
+
+ Sends your message to all observers AND PLAYERS of a game, with these
+exceptions: (a) users with their kibitz variables set to 0 (off), and (b)
+users who have set a kiblevel. You must be observing or playing a game in
+order to use this command. The standard alias for kibitz is "*".
+
+ In order to listen to kibitzes, you must have your kibitz variable on ("set
+kibitz 1"). If you want to listen to kibitzes only from players of a given
+chess ability or higher, use the kiblevel variable.
+
+ When a kibitz is displayed, the kibitzer's rating will be shown (the higher
+of blitz and standard will be used). However, (a) if the kibitzer has a chess
+master title (GM, IM, FM, NM), this title will be displayed instead of the
+rating; (b) if the kibitzer is an admin on duty, a '*' will be displayed.
+
+
+SPECIAL NOTES:
+
+(a) It is considered bad manners to discuss the game with other observers by
+using kibitz because doing so might assist the players. Instead, use
+"whisper" in order to discuss a game you and others are observing without
+interfering with the play of the game.
+
+(b) If you are observing more than one game at once, using kibitz can be
+tricky. It is possible for the kibitzed message to be sent to another game,
+if the game being observed changes suddenly.
+
+See Also: intro_talking kiblevel observe set variable whisper
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+
+kiblevel
+
+Usage: set kiblevel rating
+
+ When many users are observing and commenting on a game, the kibitzes and
+whispers can be so numerous that following the commentary can be difficult.
+This problem is especially true for special events, such as World Chess
+Championship games. There was therefore a need to cut down on the amount of
+kibitzes and whispers a person might want to receive. A kibitz filter,
+"kiblevel", was created in answer to this problem.
+
+ What the kiblevel variable does is limit the kibitzes and whispers you will
+hear to only users with a certain ability (either a given chess server rating
+or chess master title -- GM, IM, FM, NM). You establish the kiblevel filter
+by using the kiblevel variable and the "set" command. Here are the
+possibilities for kiblevel settings, and their results:
+
+ SAMPLE COMMANDS RESULT
+ ------------------ ------------------------------------------------
+ set kiblevel 9999 Hear kibitzes/whispers only from titled users
+ set kiblevel 2000 Hear kibitzes/whispers from titled users and users
+ with ratings of 2000 or higher
+ set kiblevel 0 Hear all kibitzes/whispers
+
+In terms of a user's rating, the highest rating of blitz/standard is chosen.
+
+ If you want to filter ALL kibitzes, use the "kibitz" variable setting
+instead and type "set kibitz 0".
+
+ Because problems with kibitz/whisper volume only on certain occasions, your
+kiblevel variable is reset back to 0 each time you log in. That way, regular
+games will not be affected by your forgetting to set kiblevel back to a more
+suitable level.
+
+
+SPECIAL NOTES:
+
+(a) Kibitzes made by server admins who are "on duty" (and have their admin
+flag shown, namely a '*' in 'who' listings) are not filtered by this command
+in order to allow for necessary communication in special circumstances.
+
+See Also: kibitz set variable whisper
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+
+lag
+
+ Games over the internet are affected by lag -- the time it takes for the
+electronic transmission of moves and game positions. As a result, some of
+your clock time in a chess match is used up by lag time rather than thinking
+time.
+
+ There are many ways for you to get around this problem with transmission
+lag:
+
+ (a) Play games with a higher increment per move and, in general, longer
+ time controls in general.
+
+ (b) Play unrated games for a while until the lag problem seems to have
+ improved.
+
+ (c) Tell your opponent about your lag. In response, your opponent might
+ do one of several things:
+ (i) Give you more time occasionally.
+ (ii) Turn autoflag off (if they have that feature), or at least
+ decide not to flag you as soon as your time hits 0:00.
+ (iii) Agree to abort your game, and cancel it.
+ (iv) Agree to adjourn your game, and continue it later.
+ (v) Ignore your information and play on as usual (your opponent is
+ under no obligation to give you a break because of lag).
+
+ (d) Use the "timeseal" program if it works for your computer system and
+ configuration. Using timeseal, your clock is not deducted for lag
+ time, just thinking time. Read the "timeseal" help file for details.
+
+NOTE: It is not unethical for someone to flag you when you have lag.
+
+See Also: abort flag match moretime timeseal
+
+[Last modified: September 19, 1995 -- Friar]
+
--- /dev/null
+ The Modern Defence
+
+ by GM Nigel Davies
+
+
+ It was in the late 1970s that I first made the
+ aquaintance of this provocative counter-attacking defence.
+ Under the influence of Raymond Keene, a great many British
+ players were playing it around that time and I decided to
+ jump on the bandwagon. Later on it proved quite difficult to
+ jump off again and play more classical openings, but then
+ that's another story.
+ With his first two moves, 1...g6 and 2...Bg7 Black makes
+ no attempt whatsoever to follow the tried and trusted
+ classical precept of occupying the center. Instead he calmly
+ fianchettoes a bishop and argues the he can attend to things
+ like development later in the game.
+ Some practitioners of the Modern (Colin McNab and David
+ Norwood for example) like to try and close the position up
+ with ...c6 and possible ...d5. But I have my own
+ interpretation involving a fierce counterattack against the
+ d4 square.
+ Above all I want that bishop on g7 to breathe fire, to
+ strike terror along the h8-a1 diagonal. Sometimes I play
+ ...c7-c5, sometimes ...e7-e5, but always something against
+ the d4 square and with that long diagonal in mind.
+ There isn't enough time to show all the ins and outs of
+ this defence, but the following games show my interpretation
+ in action against a variety of White set-ups and how this
+ opening has served me faithfully in some critical games.
+ Amongst my victims with this opening are the likes of Bent
+ Larsen and Viswanathan Anand, but on this occasion I'll show
+ you the real crushes!
+ The first game was played in the last round of the
+ student team Championships in Graz 1981 in which the England
+ team was going for the silver medal....
+
+ Polajzer-Davies
+ Student Team Ch., Graz (Austria), 1981
+
+ 1.d4 g6 2.c4 Bg7 3.Nc3 d6 4.e4
+
+ According to the late Mikhail Botvinnik, setting up the
+ pawns on d4, c4 and e4 is the strongest answer to the Modern
+ Defence. I have usually preferred my `stock' recipe; a
+ counterattack against the d4 square.
+
+ 4...Nc6! 5.Be3 e5! 6.d5 Nce7
+
+ Reaching a kind of King's Indian Defence in which the
+ fact that Black's knight has not been developed on f6 yet
+ means that he can sometimes play ...f7-f5 before bringing it
+ out. White takes immediate measures against this.
+
+ 7.g4 c5 8.h4 Nf6 9.g5 Nh5 10.Be2 Nf4 11.Bf3 0-0 12.Nge2 f5
+ 13.Qd2 Qa5 14.0-0-0 Rb8!!
+
+ One of the best moves I have ever played. The idea,
+ should White play quietly now, is to prise open the
+ queenside with ....b5 followed by ....a6. And there are
+ other points should White capture on f4.
+
+ 15.Nxf4 exf4 16.Bxf4 fxe4 17.Bxd6
+
+ The line which most beautifully illustrates the power of
+ 14...Rb8 is 17.Bxe4 Bxc3 18.bxc3 Rxf4 19.Qxf4 Qxc3+ 20.Kb1
+ (or 20.Bc2 Bf5 21.Rd2 Qa1+) and now 20...b5, opening up the
+ b-file. White, by the way, loses a piece after 17.Nxe4
+ Qxd2+.
+
+ 17...Rxf3! 18.Bxb8 Rxc3+! 19.Kb1
+
+ Or 19.bxc3 Bxc3 20.Qc2 Qa3+ 21.Kb1 Bf5 followed by
+ 22...e3.
+
+ 19...e3 20.fxe3 Bf5+ 21.Ka1 Rc2! 0-1
+
+ White lost on time by he could equally have resigned.
+ 22.Qxa5 is met by 22...Bxb2+ 23.Kb1 Rd2+ followed by mate.
+ I still count this as my most artistic miniature.
+
+ This next game was one of the wins which earned my first
+ Grandmaster norm in Oslo 1988. After a few careless moves in
+ the opening Black develops a murderous attack. White, by the
+ way, is not a patzer. These days he has a rating of around
+ 2500 and is on the verge of becoming a GM.
+
+ Gausel,E-Davies,N
+ Oslo, 1988
+
+ 1.d4 d6 2.e4 g6 3.Nc3 Bg7 4.Bc4 Nc6 5.Be3 Nf6 6.h3
+
+ Preventing 6...Ng4 but losing time for development.
+
+ 6...e5 7.dxe5 Nxe5 8.Bb3 0-0 9.Qd2 b5!
+
+ White's neglect of development allows Black to take the
+ initiative.
+
+ 10.f3 b4 11.Nd5 Nxd5 12.Bxd5 c6 13.Bb3 a5 14.a4 d5
+
+ Blasting open the center before White has got his cing
+ safe. If he had now tried to remedy this with 15.0-0-0
+ there would follow 15...Qf6 and after 16.Bd4 there is
+ 16...c5!, distracting the bishop from the defence of b2.
+
+ 15.exd5 Nc4! 16.Bxc4 Bxb2!
+
+ Suddenly White is in desperate trouble; the threats
+ include 17...Bxa1 and 17...Bc3, not to mention 17...Qh4+.
+
+ 17.Ne2 Qh4+
+
+ Even stronger than capturing the rook on a1, as that will
+ remain a threat.
+
+ 18.Bf2 Qxc4 19.Rb1 Bc3 20.Nxc3 bxc3 21.Qd3 Re8+ 22.Kd1 Qa2!
+ 23.Rc1 Ba6 24.Qxc3 Qxd5+ 25.Qd2 Rad8! 0-1
+
+ The final position shows the true extent of White's
+ misery.
+
+ Engedal,N-Davies N
+ Gausdal Peer-Gynt , 1990
+
+ 1.e4 g6 2.d4 Bg7 3.Nc3 d6 4.f4 Nc6
+
+ I was later to abandon this move after Dragan Velimirovic
+ answered it with 5.Bb5 in a tournament in Vrnjacka Banja in
+ 1991. Since then I have answered the Austrian Attack (4.f4)
+ with 4...e6 followed by ...Ne7, ...Nd7, ...b6 and ...Bb7,
+ obtaining a similar set-up to the game.
+
+ 5.Be3 Nf6 6.Nf3 e6 7.Be2 0-0 8.0-0 Ne7 9.Nd2 b6 10.a4 a6
+ 11.Qe1 c5
+
+ Black's usual way of challenging White's set-up from this
+ structure. Here it proves especially effective because White
+ has plalyed the rather artificial 9.Nd2.
+
+ 12.Qf2 Bb7 13.Bf3 Qc7 14.a5 cxd4 15.Bxd4 b5 16.Bb6 Qc8
+ 17.Rac1 Nd7 18.Bd4
+
+ 18.Be3 was better, as now Black rips apart what is left
+ of White's center.
+
+ 18...e5 19.Be3 f5!
+
+ The opening of the position proves good for Black as his
+ pieces are better placed. Note that White's king also proves
+ weak, a consequence of 4.f4!
+
+ 20.g3 exf4 21.gxf4 b4 22.Nd1 Nf6 23.Qg2 fxe4 24.Nxe4 Nxe4
+ 25.Bxe4 Bxe4 26.Qxe4 Qg4+ 27.Kh1
+
+ 27.Qg2 Qf5 would also have been unpleasant for White.
+
+ 27...Nf5 28.Qxb4
+
+ A suicidal pawn snatch but it is already rather difficult
+ to give White good advice.
+
+ 28...Ng3+! 29.Kg1
+
+ Taking the knight allows 29...Qh3+ followed by 30...Qg3+
+ and 31...Rf5.
+
+ 29...Nxf1+ 30.Kxf1 Qf3+ 31.Kg1 Rae8 32.Qd2 Rxf4! 0-1
+
+ White has had enough. 33.Bxf4 is answered by 33...Re2
+ threatening both mate and the queen.
+
+ For a period of about 10 years I played nothing but the
+ Modern, but in the late 1980s I started to branch out into
+ other openings. Even eating caviar every day can become
+ boring.
+ Yet faced with the prospect of having to win my last
+ round game for a GM norm in a tournament in Budapest, I
+ could hardly answer 1.e4 with 1...e5, after which I would
+ get a boring Four Knights or Ruy Lopez. The only chance was
+ the Modern Defence, and this was it's finest hour.
+
+ Godena,M-Davies,N
+ First Saturday Tournament, Budapest, May 1993
+
+ 1.e4 g6 2.d4 Bg7 3.Nc3 d6 4.Nge2
+
+ The safe way of introducing the fianchetto line for
+ White, as after the immediate 4.g3 there is 4...Nc6 and if
+ 5.Nge2 then 5...Bg4. After the text move I either play the
+ immediate 4...Nc6, or sometimes 4...a6 5.a4 Nc6.
+
+ 4...Nc6 5.Be3 Nf6 6.h3 e5 7.dxe5 Nxe5 8.Ng3 0-0
+
+ The safe way to play it would have been 8...Be6 9.Qd2
+ Nc4, but given that I had to win this game I was not afraid
+ of danger.
+
+ 9.Qd2 Re8 10.0-0-0 b5!?
+
+ A pawn for an open file - not a bad deal with opposite
+ wing castling. If White doesn't capture Black gets the c4
+ square for his knight on e5.
+
+ 11.Bxb5 Bd7 12.Be2
+
+ After 12.f4 my opponent didn't like the look of 12...Bxb5
+ 13.fxe5 Rxe5 14.Bd4 Qe7, which he felt gave me good
+ compensation for the sacrificed exchange. In the post mortem
+ we looked at 12.Ba6!? but then 12...Be6 wasn't clear.
+
+ 12.... Qb8 13.f4 Nc6 14.Bf3 Qb4
+
+ Preparing to move a rook to b8 and threaten mate on b2.
+
+ 15.a3 Qb7 16.e5 Rab8 17.b3
+
+ An alternative way to defend b2 was with 17.Na4, but
+ then Black has 17...dxe5 18.fxe5 Qb5! 19.exf6 Bxf6 20.b3
+ Rxe3 21.Qxd7 Bg5 and if 22.Kb1 then 22...Rxb3+.
+
+ 17...dxe5 18.fxe5 Rxe5 19.Nge4 Qa6!
+
+ It is less good to play this move after a preliminary
+ exchange of knights on e4. Thus 19...Nxe4 20.Nxe4 Qa6 can by
+ met by 21.a4 after which White's defences hold.
+
+ 20.a4?
+
+ The decisive mistake. White should take this opportunity
+ to exchange on f6, as for the time being Black is forced to
+ recapture with the bishop. After Black's next move it
+ becomes possible to take back on f6 with the queen.
+
+ 20...Na5! 21.Nxf6+ Qxf6!
+
+ The point, after which the latent threats along the long
+ h8-a1 diagonal prove decisive. Perhaps White thought that
+ his next move made the capture with the queen impossible,
+ but a serious disappointment is waiting.
+
+ 22.Bd4 Qd6!
+
+ Ouch! Only now did he see that the intended capture of my
+ rook on e5 is met by 23...Qa3+ followed by 24...Nxb3.
+
+ 23.Nb1 Rxb3!
+
+ KAPOW! White must kiss his castled position goodbye.
+
+ 24.Bxe5 Qb6! 0-1
+
+ White has had enough. The threat is 25...Rb1+, the rook
+ is immune to capture because of the knight fork picking up
+ White's queen and after 25.Nc3 there is either 25...Nc4 or
+ 25...Ra3, depending on Black's mood.
+
+ This event was brought to you by Warwick chess club (England)
+
+
--- /dev/null
+
+lightning
+
+ There are four types of regular (not wild or bughouse) chess played on this
+chess server: Untimed, Lightning, Blitz and Standard.
+
+ A game is "Lightning" if the expected duration of the game is 3 minutes or
+less per player. "Expected duration" is determined by a formula that takes
+into account both the Start time and the Increment (Inc) value. Here is the
+formula:
+
+ Expected duration = (Start + Inc*2/3)
+
+ The following table shows the slowest Lightning and fastest Blitz time
+controls, the dividing line if you will between those two types of matches.
+
+ Slowest Lightning Fastest Blitz
+ ------------------------------------
+ Mins Incr Mins Incr
+ ------------------------------------
+ 0 4 0 5
+ 1 2 1 3
+ 2 1 2 2
+ -------- 3 0
+
+ As you can see, Lightning chess is very quick!
+
+ You can list logged on users according to their lightning ratings by typing
+"who L". "Lightning" is also a variable that can be used in formulas in order
+to screen match requests.
+
+See Also: blitz formula match standard untimed who
+
+[Last modified: December 25, 1995 -- Friar]
+
--- /dev/null
+
+limits
+
+Usage: limits
+
+ "Limits" displays the various server limits currently in effect. These
+include maximum numbers of players, channels, channels you can be in, persons
+on your notify list, your aliases, games you are observing, requests pending
+for you, people on your censor list, persons in a simul game, and messages you
+can receive. Also, the minimum number of games that can be active, and the
+shout quota.
+
+See Also: [the various commands and features]
+
+[Last modified: July 7, 1995 -- Friar]
+
--- /dev/null
+
+lists
+
+ The server maintains several lists in order to conduct its business. You
+can use +/-/= to change and view the various lists.
+
+Examples (using the aliases):
+
+ +listname member (Add member to listname -- addlist)
+
+ -listname member (Remove member from listname -- sublist)
+
+ =listname (View the members of listname -- showlist)
+
+ = (View the names of all lists and their status
+ -- showlist)
+
+Certain lists can only be modified by an admin. Other lists are for admin
+viewing only. See showlist help file for details.
+
+See Also: addlist admin showlist sublist
+
+[Last modified: September 2, 1995 -- Friar]
+
--- /dev/null
+
+llogons
+
+Usage: llogons
+
+ Shows the last 30 or so logons and logoffs for the server.
+
+See Also: logons
+
+[Last modified: October 9, 1995 -- Friar]
+
--- /dev/null
+
+logons
+
+Usage: logons [user]
+
+ Shows the last 10 or so logons for the given user. Displayed will be the
+date, time and IP address for your connection. Example: "logons Mozart". If
+"user" is omitted then your last logons are displayed.
+
+See Also: llogons
+
+[Last modified: November 26, 1995 -- Friar]
+
--- /dev/null
+
+lell
+
+Usage: ltell list message
+
+ltell is like xtell but it sends your message to every player on the
+specified list. So for example you could say hello to every computer
+player using:
+ ltell computer hello
--- /dev/null
+
+mailmess
+
+ There are two ways to have your messages mailed to you: (a) all messages
+currently being stored for you, and (b) automatically each time one arrives.
+One method uses a command; the other uses a variable setting. REMINDER: only
+registered users can have stored messages.
+
+
+STORED MESSAGES
+
+ Use the "mailmess" command to send to you at to your e-mail address the
+messages currently being stored for you. In this way you can archive the
+messages on your own computer and then clear the message buffer on the chess
+server. A reduced message buffer makes new messages easier to identify and
+read.
+
+
+AUTOMATICALLY ONE-AT-A-TIME
+
+ When the "mailmess" variable is set to 1, each message you receive from a
+user will be automatically e-mailed to you at your address.
+
+See Also: clearmessages messages register set variables
+
+[Last modified: June 17, 1995 -- Friar]
+
--- /dev/null
+
+mailmoves
+
+Usage: mailmoves
+
+ Mails to you at to your email address the moves to the game you are playing
+or examining.
+
+NOTE: This command concerns games in progress, not games that have been
+completed. For completed games, use "mailstored".
+
+See Also: mailstored smoves
+
+[Last modified: September 14, 1995 -- Friar]
+
--- /dev/null
+
+mailoldmoves
+
+This command has been superceded by an enhanced "mailstored" command. Please
+refer to that help file.
+
+See Also: mailstored smoves
+
+[Last modified: September 14, 1995 -- Friar]
+
--- /dev/null
+
+mailstored
+
+Usage: mailstored player1 {#, player2}
+
+ Mails to you at your email address the moves of player1's game, either game
+# from player1's "history" table or the "stored" (adjourned) game between
+player1 and player2.
+
+ Examples:
+
+ mailstored Hawk 65
+ mailstored Hawk DAV
+
+ Other useful commands: "examine" helps you review the game; "smoves"
+displays the moves; "sposition" displays current game position.
+
+See Also: examine history smoves sposition stored
+
+[Last modified: September 14, 1995 -- Friar]
+
--- /dev/null
+
+match
+
+Usage: match user [rated|unrated] [Start] [Inc] [Black_Start Black_Inc]
+[White|Black] [board_category board]
+
+
+SUMMARY
+~~~~~~~
+ This command allows you to challenge a given user to a game of chess. To
+challenge USER to a match, type "match USER". The type of match being offered
+depends on (a) your variable settings (preferences) and (b) information you
+give in the match request. USER will need to accept or decline the challenge.
+You can cancel a challenge you have made using the "withdraw" command.
+
+
+MATCH VARIABLES
+~~~~~~~~~~~~~~~
+ You can specify the parameters for the match. If no parameters are
+specified, (a) the challenger's variable settings for "rated|unrated", "Start"
+and "Inc" will be used (see "variables"), (b) the clock times will be the same
+for both players, (c) the colors will be chosen by the server, and (d) the
+board_category will be standard. Here are details about each variable of the
+match command.
+
+
+RATED|UNRATED -- Sets whether the match will be rated or unrated. If
+undesignated, the challenger's variable setting for "Rated" will be used. If
+designated, it will override the challenger's "Rated" setting. Example:
+"match user rated".
+
+START and INC -- Determine the clock variables for the match, where Start is
+in minutes and Inc is in seconds. If only 'Start' is given then 'Inc' is
+assumed to be zero (example, "match user 5"). If values are given for Black
+then the challenger will play the White side (example, "match user 5 0 5 0");
+otherwise the side will be chosen "fairly".
+
+WHITE|BLACK -- If a color is given, White or Black (w/b), that will be the
+color of the challenger (example, "match user w").
+
+BOARD_CATEGORY BOARD -- These two parameters must be used together. They
+specify a particular starting position for the game. These parameters can
+only be included when all of the other parameters have also been given. If a
+particular starting position is not supplied, then "standard" and "standard"
+are used (that is, the "regular" starting position for pieces will be used
+with no particular opening). (See the "boards" help file for the categories.)
+
+
+EXAMPLES OF MATCH REQUESTS (challenges):
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+match red
+ Challenges user "red" to a match using your default values for Rated, Start
+ and Inc.
+
+match red 5
+ Challenges user "red" to a match with Start = 5 and Inc = 0 using your
+ default value for Rated.
+
+match red 30 30 u
+ Challenges user "red" to an unrated match using a 30 minute Start time and
+ 30 second Increments per move ("match red 30 30 0 0" would give the same
+ result.)
+
+match red 30 0 15 0 w
+ Challenges user "red" to a non-standard, time-odds match with the challenger
+ playing White and "red" playing Black. White will Start with 30 minutes on
+ the clock, and Black will Start with 15 minutes (note that all four values
+ for the time controls must be given for a match with time odds).
+
+match red 2 12 0 0 openings ruy-lopez
+ Challenges user "red" to a match using the ruy-lopez opening position.
+ (Note that to start from a given board, you must give all four time control
+ values; in this example, you may NOT omit the two zeros.)
+
+match red 2 12 0 0 wild 3
+ Challenges user "red" to a match using the wild 3 starting position.
+ (Again, all four time control values must be given.)
+
+match red 5 12 bughouse
+ Challenges user "red" to a bughouse match, once the bughouse teams have been
+ arranged. The word "wild" does not need to be used.
+
+
+SPECIAL NOTES
+~~~~~~~~~~~~~
+
+(a) COUNTER OFFERS: If you receive a match request from a user and you
+request a match with different time controls, then in essence you (a) decline
+the first request but (b) make a request of your own. If your counter request
+has the same time controls, a game will begin.
+
+(b) RESUMING ADJOURNED GAMES: Use the "match" command to resume an adjourned
+game. Resuming an adjourned game takes precedence over starting a new game.
+The match request, of course, can be declined by your opponent. Adjudications
+of adjourned games are possible.
+
+(c) USING FORMULAS TO FILTER OUT MATCH REQUESTS: Match requests from other
+users can be filtered by using a formula. If a request fails to meet your
+formula, it is declined automatically for you. Also, you will not receive
+challenges from users on your "censor" list.
+
+(d) ALIASES: Using aliases can make it easier to challenge other players to
+matches.
+
+(e) EXAMINE MODE: Matching yourself ("match your_handle") is a way to enter
+examine mode.
+
+(f) MATCH TYPE: It is not possible to request a type of match directly, such
+as "match user blitz". How a match is classified depends upon both the Start
+time and the Inc time. An equation is used to determine whether a match will
+be blitz or standard (see the "blitz" help file). You can, however, request a
+bughouse match directly.
+
+(g) NOPLAY LIST: If you do not want to receive match requests from a
+particular user, place that person on your "noplay" list.
+
+
+See Also: accept adjourn adjudicate alias blitz boards bughouse censor
+decline examine formula intro_playing noplay variables [rated, start,
+inc, etc.] withdraw
+
+[Last modified: December 25, 1995 -- Friar]
+
--- /dev/null
+
+messages
+
+Usage: messages [user [text]]
+LIMITED TO REGISTERED USERS
+
+ This command can do one of four things:
+
+ 1) "Messages" used alone will display all of the stored messages that have
+ been sent to you.
+
+ 2) "Messages user" will display all stored messages from you to that user
+ and from that user to you.
+
+ 3) "Messages #" will display the message numbered # in your list.
+
+ 4) "Messages user text" will send "text" to the user. When you "message"
+ another user, the text of your "message" will be displayed to you for
+ confirmation. If that user is on, he/she will see the message
+ displayed. If the user is not on, he/she will need to use "message" in
+ order to read it.
+
+ Messages will be stored until they are cleared by the recipient. In
+contrast, "tell"s are not stored. When users log on, they are notified if
+they have any stored messages and (if so) how many they have.
+
+See Also: clearmessages tell
+
+[Last modified: December 17, 1995 -- Friar]
+
--- /dev/null
+
+mexamine
+
+Usage: mexamine user
+
+ This command is used by a person examining a game in order to allow other
+users to move the pieces and execute commands in examine mode. The user must
+first be observing the game in order for "mexamine" to work. Here are the
+steps: (1) enter examine mode, (2) have another user "observe" that game, (3)
+"mexamine that_user".
+
+NOTE: As long as there is at least one examiner, the game continues even if
+the first examiner leaves that game.
+
+See Also: examine observe
+
+[Last modified: September 22, 1995 -- Friar]
+
--- /dev/null
+
+moretime
+
+Usage: moretime seconds
+
+ Adds extra time (in seconds) to your opponent's clock when you are playing a
+game. Maximum time you can add -- 600 seconds (if you try to add more than
+600 seconds, only 600 will be added).
+
+ In essence, using the moretime command means that you don't want your
+opponent to worry so much about the time remaining on his/her clock, about
+being flagged, and so on. It is a useful command to use when your opponent
+mentions a problem with transmission lags and you are using an interface
+with the autoflag feature on. You are under no obligation to give your
+opponent more time, of course.
+
+ If you need more time, you can always ask your opponent to add time to your
+clock -- depending on the circumstances and their mood, they might grant your
+request. But if you find that you frequently need more time when you play,
+consider playing with longer time controls.
+
+See Also: abort flag match
+
+[Last modified: June 11, 1995 -- Friar]
+
--- /dev/null
+Got a bug? Message Bug with it. (Not the player Bug on ICC)
+Got a suggestion that could improve this place? Message Suggestion with it.
+
+ The latest FICS distribution is now at the onenet ftp site caissa.onenet.net,
+ as FICS.1.2.18..tar.gz in /pub/chess/Unix.
+
+Like Slower Time Controls? Join THE STC BUNCH! Finger StarCapt for details.
+
+Do 'help register' for info on registration.
+
--- /dev/null
+
+motd_help
+
+ The "motd" information help file -- Message Of The Day -- contains news
+items and other announcements that are displayed when you logon. You can read
+these by typing "help motd". Other news items are on the "news" bulletin
+board.
+
+See Also: news
+
+[Last modified: June 12, 1995 -- Friar]
+
--- /dev/null
+
+moves
+
+Usage: moves [game,user]
+
+ Displays the moves to the specified game. If a game is not specified, moves
+to the game you are playing will be displayed. Command applies only to games
+in progress, not to stored games.
+
+See Also: mailstored smoves
+
+[Last modified: September 14, 1995 -- Friar]
+
--- /dev/null
+ NEW! NEW! NEW! NEW! NEW! NEW! NEW! NEW! NEW! NEW!
+
+ We are proud to introduce you to our completely new rating system!
+
+ --> The Glicko system (developed by Mark E. Glickman) <--
+ --> Assistance/corrections by Dmitry Dakhnovsky <--
+ --> Implemented to FICS by Vek and Hawk <--
+
+
+As you all know, we had a seriously defective rating system, but that
+is now changed after two weeks of hard work.
+
+The previous ratings were bogus and therefore we had to delete them,
+and in order to treat all players equally - we have given them the
+following two choices:
+
+(1) Transfer their ratings and/or stats from ICC. This can be done by
+ leaving me a message FROM ICC (NOTE: I'm called "HawkII"
+ there). This will disable any chance of cheating. Just mention your
+ FICS handle in your message to me.
+
+(2) Some may not want to have their rating transfered from ICC or
+ maybe they dont even have a rating there, then the option is simple:
+ the rating will be reset.
+
+This offer was first published around the 28th of March and will be
+available until the 16th of April. (maybe longer)
+
+
+Every request for ratings transfers must be emailed to me (Hawk) and
+my address is "u940456@daimi.aau.dk". Please use subject line:
+"Request for ratings transfer" and in the body of the message tell
+me your handle on ICC and FICS. (also remember to message me from ICC
+so that I can verify that you are the person you claim to be. NOTE:
+My handle on ICC is "HawkII" )
+
+-Hawk
+
+See Also: glicko, motd
+
+
--- /dev/null
+
+news
+
+Usage: news [#,all]
+
+ The command "news" alone will display the last 10 news items posted to the
+chess server bulletin board, "news #" will display news item #, and "news all"
+will display all news items in the news index. Also, news items and other
+announcements that are part of the opening text when you logon are in the
+"motd" help file (for an explanation of the "motd" information, read the
+"motd_help" help file).
+
+See Also: motd_help
+
+[Last modified: August 20, 1995 -- Friar]
+
--- /dev/null
+
+next
+
+Usage: next
+
+ This command is used to continue the display of a long text file. An alias
+for "next" is "more". How many lines of text you receive at once is
+determined by the "height" variable setting.
+
+See Also: help intro_welcome variables
+
+[Last modified: July 1, 1995 -- Friar]
+
--- /dev/null
+
+noplay
+
+Usage: +|-|= noplay [user]
+
+ When a player is on your noplay list, all match requests from that player
+will be declined automatically. Here are the variations of the command
+possible:
+
+ +noplay user Add "user" to noplay list
+ -noplay user Remove "user" from noplay list
+ =noplay Display your noplay list
+
+ "Censor" will also filter a user's match requests. Use a formula to filter
+match requests of particular types.
+
+See Also: addlist censor formula
+
+[Last modified: December 17, 1995 -- Friar]
+
--- /dev/null
+
+notes
+
+ A registered user has up to 10 lines in their 'finger' display for posting
+information. These lines are known as "finger notes", one's "plan" or just
+"notes". Your 'notes' can be read by all users of the server, so be sure that
+it is information you want to make public. The notes are numbered from 1 to
+10.
+
+ The lines are created, changed and deleted by using the 'set' command. For
+example, "set 1 I love Wild 5!!!" will set your #1 finger note to: "I love
+Wild 5!!!".
+
+See Also: finger set
+
+[Last modified: December 17, 1995 -- Friar]
+
--- /dev/null
+
+notify
+
+Usage: +|-|= notify [user]
+LIMITED TO REGISTERED USERS
+
+ When a user is on your notification list, you will be notified each time
+that user logs onto or leaves the server. Here are the variations of the
+command possible:
+
+ +notify user Add "user" to notify list
+ -notify user Remove "user" from notify list
+ =notify Display your notify list
+
+ Also, when you are on another user's notification list, you will be sent a
+message that your entering the server was noted by that user. If you want to
+be notified each time *any* user logs on or off, use the "pin" variable. Use
+the "znotify" command to see which users currently logged on are on your
+notify list and which have you on their notify lists.
+
+ The size of your notify list is limited (type "limits" to see current size).
+Fortunately, there is a way you can maximize the use of your notify list. The
+solution involves the "notifiedby" variable. If you are on another user's
+notify list and have your "notifiedby" variable set to 1, you will be notified
+by the server when that user logs on/off. It will work the same way as if you
+had that user on your list: you will be *notified by* the other user's list!
+Here's an example:
+
+ Hawk's notify list includes DAV *and* DAV has "notifiedby" set to 1
+
+will have the same effect as ...
+
+ Hawk's notify list includes DAV *and* DAV's list includes Hawk
+
+... except that one notify list entry (namely, DAV on Hawk's list) is doing
+the work of two entries. That is how you can save on the length of your
+'notify' list.
+
+
+See Also: addlist limits variables znotify
+
+[Last modified: November 26, 1995 -- Friar]
+
--- /dev/null
+
+observe
+
+Usage: observe [game,user]
+
+ Puts a game on your observation list. You can give either the game number
+or the user whose game you want to observe. For example, if game #34 is
+KARPOV versus RETI, then "observe 34", "observe RETI" or "observe KARPOV" will
+add this game to your observation list. You can observe more than one game at
+once.
+
+ When you are observing a game, you will receive an updated board position
+and game information each time a move is made. When a game you are observing
+ends, you will be given the result of the game.
+
+ Use the "unobserve" command to remove a game (or even all games) from your
+observation list.
+
+ Use "allobservers" to see who is observing a game (or all games) in
+progress).
+
+
+SPECIAL NOTES
+
+(a) At one point "observe" used alone would remove all games from your
+observation list. This function is now being phased out in favor of the
+"unobserve" command. But be careful while both commands are still valid.
+
+(b) It is possible to observe all simul games being played by the simul
+player by the command "observe simul_player". All of the simul games in
+progress will be added to your observation list. When the last simul game is
+finished, you will be given the result of the simul exhibition.
+
+
+See Also: allobservers games simuls unobserve
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+
+oldmoves
+
+This command has been superceded by an enhanced "smoves" command. Please
+refer to that help file.
+
+See Also: mailstored smoves
+
+[Last modified: September 14, 1995 -- Friar]
+
--- /dev/null
+
+open
+
+Usage: open
+
+ Toggles your 'open' variable open/not open [1/0]. When open is set to 1,
+you are open to receive match requests from other users. When it is set to 0,
+you will not receive match requests from others, but you will be notified that
+such requests have been made to you and ignored automatically.
+
+See Also: match variables
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+
+partner
+
+Usage: partner user_name
+
+ This command is used in order to ask another user to become your partner for
+a bughouse match. The other user will need to accept or decline the offer.
+If the other user accepts the partner offer, the two of you will then be able
+to hold bughouse matches against other partnerships and the two of you can be
+identified using the "bugwho p" command as being available for bughouse
+matches.
+
+ You can only 'partner' users who are open for bughouse partnerships. i.e.,
+have their bugopen variable set to 1. To see which users are available for a
+bughouse partnership, type "bugwho u". If you 'partner' a user, your bugopen
+variable is automatically set to 1.
+
+ If you type "partner" alone, it will cancel any partnership you have, though
+it will not affect your bugopen variable setting.
+
+See Also: accept bughouse bugwho decline pending v_bugopen who
+
+[Last modified: August 5, 1997 -- Friar]
--- /dev/null
+
+password
+
+Usage: password oldpassword newpassword
+LIMITED TO REGISTERED USERS
+
+ Changes your current password on the chess server ("oldpassword") to a new
+password "newpassword". If "oldpassword" is incorrect, then no changes are
+made.
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+
+pause
+
+Usage: pause
+
+ A "pause" requests asks your opponent that the game you are playing be
+paused -- though not adjourned. An accepted pause request has the effect of
+rolling back the clocks to the time of the last move. If your opponent has
+given you a pause request, using the pause command (or accept) will accept the
+request. You may decline a pause request by using the decline command. To
+unpause a game use "unpause".
+
+See Also: accept decline pending unpause
+
+[Last modified: June 20, 1995 -- Friar]
+
--- /dev/null
+
+pending
+
+Usage: pending
+
+ Displays all non-declined, pending offers from other players to you and
+from you to other players.
+
+See also: abort accept adjourn decline draw match takeback
+
+[Last modified: June 11, 1995 -- Friar]
+
--- /dev/null
+
+play
+
+Usage: play [#num | handle]
+
+ The "play" command is how you respond to a user's ad for a chess match. You
+can select an ad either by its ad number ("index number") or by the handle of
+the user who placed the ad. For example, if the ad were displayed as:
+ 4 1563 TheDane 2 8 unrated blitz 0-9999
+you could respond to the ad by typing either (a) "play 4" or (b) "play
+TheDane".
+
+ When you respond to an ad, a check is made that your rating is in the range
+specified by the ad. If the ad asks for a formula check, the user's formula
+is also examined. If you meet these criteria, your response is forwarded to
+the user who placed the ad.
+
+ If the ad calls for auto start, the game begins at once. If the ad calls
+for a manual start, the other user will be notified that you are challenging
+him/her to a match; he/she then can accept or decline your offer to play that
+match.
+
+Special Notes:
+
+(a) If you respond to an an ad and you receive the message "Bad index given;
+no such ad." it probably means that the ad has been removed, either by
+'unseek' or by starting a match.
+
+(b) If you are on the other user's 'noplay' list, your 'play' request will be
+rejected automatically.
+
+(c) (C)omputer accounts cannot accept seeks.
+
+See also: match noplay seek sought unseek
+
+[Last modified: March 2, 1998 -- Friar]
--- /dev/null
+
+prefresh
+
+Usage: prefresh
+
+ This command will display your partner's game during a bughouse match. In
+essence, it is "refresh" for your bughouse partner's game.
+
+See Also: bughouse refresh
+
+[Last modified: December 17, 1995 -- Friar]
+
--- /dev/null
+
+private
+
+Usage: set private [n]
+
+ "Private" is one of the variables you can set. When private is non-zero,
+games you play cannot be observed by other users. If private is 0, other
+users will be able to observe your game -- unless your opponent has private
+non-zero. A private game is designated in "games" and "history" displays by
+the letter "p". Also, if a game is private, the eco category is not displayed
+in the history table.
+
+See Also: eco games history observe variables
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+
+promote
+
+Usage: promote {q,r,b,[kn]}
+
+ Designates the piece that a pawn will be promoted to when it reaches
+the back rank. This is set automatically at the beginning of each game
+to 'q'. The setting can be changed during the game at any point.
+
+SPECIAL NOTE: You must designate how a pawn will be promoted BEFORE it
+reaches the back rank, not afterwards. The current setting will be used when
+the pawn reaches the 8th rank.
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+\r
+pstat\r
+\r
+The command pstat ("player statistics") displays the record one user has in \r
+chess games against another user. Statistics 'pstat' will not include \r
+results prior to FICS version 1.22.0 pstat will only include statistics\r
+from your last 2500 games on the server. In general, this command can be \r
+used wit the following formats:\r
+\r
+ (a) pstat /o User1 -- gives your record against User1\r
+\r
+ (b) pstat User1 /o User2 -- gives the record for User1 against User2\r
+\r
+ For example, the command 'pstat knighttour /o afw' might display the \r
+ following statistics:\r
+\r
+ knighttour's game statistics:\r
+\r
+ Results vs. afw:\r
+ Rated(W-L-D): 10-10-5 Unrated(W-L-D): 8-8-2\r
+\r
+ The counts are always with respect to the FIRST player -- it is the first\r
+player's record against the second player, in this case knighttour's record\r
+against afw. The counts are summed across ALL types of chess matches.\r
+\r
+ (c) For the time being Old statistics can be accessed using the command: \r
+ oldpstat (which is what pstat used to be). The oldpstat command can\r
+ be used in the same format as in examples (a), (b) and (c); without\r
+ the flag /o. \r
+\r
+ For example, the command 'oldpstat toddmf Obliviax" might display the \r
+ following statistics:\r
+\r
+ Record for toddmf vs. Obliviax:\r
+\r
+ wins losses draws\r
+ rated 407 345 68\r
+ unrated 14 6 4\r
+\r
+\r
+Other Notes:\r
+Pstat shows result summaries starting from your latest games and looks \r
+backwards. \r
+\r
+It is now possible to use the 'next' command in conunction with a helpfile and\r
+at the same time use the command 'next stats'.\r
+\r
+-------------------------------------------------------------------------------\r
+\r
+The parameters for pstat in the following usage format:\r
+\r
+ pstat [user] [type of results to show] [how to sort]\r
+\r
+ [user] is the name of the player whose statistics to be viewed\r
+ if a name is missing in this command, it will show your data.\r
+\r
+ [type of results to show] and [how to sort] is based on four sort parameters:\r
+ (opponent, eco code, etime and category/board)\r
+\r
+To specify results to show (ie. only those results/summaries will be shown) \r
+use /o /e /t /b (opponent, eco, (e)time and board/category respectively) \r
+followed by the parameter.(a) eco code is the Encylopedia of chess openings \r
+code which describes which opening took place. It is a letter A-E followed by\r
+a two digit number. \r
+\r
+\r
+1. Sort by ECO: /e\r
+\r
+To see what eco code corresponds to a named opening position - see help eco.\r
+\r
+ (a) pstat /o User1 /e <code>\r
+\r
+ For Example:\r
+\r
+ pstat /o DChessmaster /e B09\r
+\r
+ Your game statistics:\r
+\r
+ Results vs. DChessmaster ECO B09:\r
+ Rated(W-L-D): 2-30-1 Unrated(W-L-D): 0-0-0\r
+\r
+\r
+ (b) pstat User 1 /o User2 /e <code>\r
+\r
+ For Example:\r
+\r
+ pstat Bremen /o DChessmaster /e B09\r
+\r
+ Bremen's game statistics:\r
+\r
+ Results vs. DChessmaster(C) ECO B09:\r
+ Rated(W-L-D): 5-5-1 Unrated(W-L-D): 0-0-0\r
+ \r
+2. Sort by time: /t\r
+\r
+etime is the maximum time 40 moves will take per player. \r
+The formula is: etime = time + 2/3 increment\r
+\r
+ For example: a 5 0 game is etime 5\r
+ a 2 12 game is etime 10\r
+ a 5 8 game is etime 6.7\r
+\r
+Please see help clocks for more details.\r
+This sort command is somewhat difficult, please read carefully.\r
+\r
+Results are grouped together in ranges of time and it's not possible to \r
+specify a decimal number etime. So to request results for 5 8 (etime 6.7) \r
+6.7 should be rounded down to 6.\r
+\r
+In the example above where etime is 6.7; you would have to use etime of 6\r
+\r
+ (a) pstat /t <etime>\r
+\r
+ For Example:\r
+\r
+ pstat /t 5\r
+\r
+ Your game statistics:\r
+\r
+ Results vs. DHessmaster(C) ECO B09:\r
+ Rated(W-L-D): 5-5-1 Unrated(W-L-D): 0-0-0\r
+\r
+ Show me the summary of my games that have etime 5 (covers 5<etime<=6).\r
+\r
+ (b) pstat User2 /t <etime>\r
+\r
+ For Example:\r
+\r
+ pstat volcano /t 6\r
+\r
+ volcano's game statistics:\r
+\r
+ Results etime 6<=etime<7:\r
+ Rated(W-L-D): 14-2-8 Unrated(W-L-D): 0-0-0\r
+\r
+\r
+\r
+\r
+3. Sort by category and board: /b\r
+\r
+Category and board are just like the match command (eg. bughouse, suicide, \r
+wild 5), though the short cut for wild (w/#) does not work and chess is not \r
+recognized. To get normal chess only use blitz, standard, lightning and \r
+untimed as the category. Specify blitz and specifying etime as a non blitz \r
+time control will give undefined results.\r
+\r
+\r
+To group results together /s followed by one or more o,e,t,b is used. \r
+It doesn't make sense to specific a type to show and also have it grouped \r
+together under that type so pstat /o Fred /so is illegal.\r
+\r
+ Examples:\r
+\r
+ pstat /o Fred /se\r
+\r
+ Show my results against Fred by eco code\r
+\r
+ pstat /e C21 /sob\r
+\r
+ Show my results in C21 by opponent and board/category\r
+\r
+\r
+ The following group ranges for etime are used:\r
+\r
+ 0\r
+ 0 < etime < 1\r
+ 1 <= etime < 2\r
+ 2 <= etime < 3\r
+ 3 <= etime < 4\r
+ 4 <= etime < 5\r
+ 5 <= etime < 6\r
+ 6 <= etime < 7\r
+ 7 <= etime < 8\r
+ 8 <= etime < 9\r
+ 9 <= etime < 10\r
+ 10 <= etime < 11\r
+ 11 <= etime < 12\r
+ 12 <= etime < 13\r
+ 13 <= etime < 14\r
+ 14 <= etime < 15\r
+ 15 <= etime < 20\r
+ 20 <= etime < 25\r
+ 25 <= etime < 30\r
+ 30 <= etime < 35\r
+ 35 <= etime < 40\r
+ 40 <= etime < 45\r
+ 45 <= etime < 50\r
+ 50 <= etime < 55\r
+ 55 <= etime < 60\r
+ 60 <= etime < 75\r
+ 75 <= etime < 90\r
+ 90 <= etime < 105\r
+ 105 <= etime < 120\r
+ 120 <= etime < 150\r
+ 150 <= etime < 180\r
+ 180 <= etime\r
+\r
+ \r
+See also: assess eco finger match \r
+ \r
+[Last modified: Dec. 11, 2001 -- MAd]
\ No newline at end of file
--- /dev/null
+
+ptell
+
+Usage: ptell string
+
+ This form of communication is used during a bughouse match. "Ptell" will
+send a message to your partner; no one else will receive it.
+
+See Also: bughouse tell
+
+[Last modified: November 26, 1995 -- Friar]
+
--- /dev/null
+
+ptime
+
+Usage: ptime
+
+ This command is used during a bughouse match in order to display the current
+clock times in your partner's game.
+
+SPECIAL NOTES:
+
+(a) The ptime command is _not_ related to the ptime variable. The ptime
+variable concerns having the current time displayed along with the server
+prompt. See 'help v_ptime' for details.
+
+See Also: bughouse time v_ptime
+
+[Last modified: March 26, 1997 -- Friar]
--- /dev/null
+
+qtell
+
+USAGE: By TD programs, only
+
+ The qtell command is a special channel tell command designed for the TD
+programs that run tournaments on the chess server. This command is not
+available to users or admins.
+
+See Also: tell
+
+[Last modified: October 30, 1997 -- Friar]
--- /dev/null
+
+quit
+
+Usage: quit
+
+ This command exits you from the server. "Bye" and "exit" are default
+aliases for "quit".
+
+SPECIAL NOTE: This command cannot be used if you are in the middle of a chess
+match. If you need to leave during a match, first ask your opponent for an
+adjournment and explain why.
+
+See Also: adjourn alias
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+
+rank
+
+Usage: rank [user [b][s][w]]
+ rank m-n [b][s][w]
+
+ The first usage shows the ranking of the given user and all users with
+nearby rankings. A second argument with one or more of the letters b, s,
+and/or w asks to show only blitz, standard, and/or wild ratings respectively.
+If no second argument is given, rankings for all three types are shown. For
+example, "rank foo bw" shows the blitz and wild ranking of the player whose
+handle is "foo". If 'user' is omitted, your rankings will be displayed.
+
+ The second usage shows all players ranked between the rankings of M and N.
+The optional third argument again limits which ratings are shown. For
+example, "rank 1-30 sw" lists the players with the highest 30 standard and
+wild ratings. "Best" lists the top 20 players in a category.
+
+ The columns are always sorted by blitz, then standard, then wild.
+
+ Currently, all players with at least 20 games of a particular rating type
+are ranked. If you ask for a player's rank and they do not yet have the 20
+games needed to be an active player, the player's current rating will be
+displayed in the table but a line (----) will precede the handle to indicate a
+provisional ranking.
+
+ To omit computers from the list, use "hrank".
+
+See Also: best hbest hrank
+
+[Last modified: June 13, 1995 -- Friar]
+
--- /dev/null
+
+ratings
+
+ Chess ratings serve two purposes: (a) they tell you your relative ability,
+and (b) are useful means for identifying and playing opponents of roughly your
+same ability.
+
+ This server utilizes the Glicko rating system developed by Mark E. Glickman
+(with assistance and corrections by Dmitry Dakhnovsky and server
+implementation by Vek and Hawk). The full explanation of this system is given
+in the "glicko" help file.
+
+ In general, your rating will be adjusted by several factors: (a) the result
+of your game (win, loss, draw), (b) your opponent's rating, (c) the stability
+of your rating, and (d) the stability of your opponent's rating. If you want
+to determine how your rating might change after a match with a given player,
+use the "assess" command.
+
+ At present, there are separate ratings for three kinds of chess: Standard,
+Blitz and Wild. Your current rating is available on your "finger" file. Once
+you have an established rating (20 or more games) in a given type, your
+highest established rating to date will also be displayed. Players with
+established ratings will also have their ratings listed on several ranking
+lists (see the "best", "hbest", "rank" and "hrank" help files).
+
+ By default, the "who" command lists logged on users in order of their
+ratings. This way, you can identify and match players of certain ratings.
+You can also use ratings in your "formula" for filtering out match requests
+from other players. Ratings can also be used to filter out kibitzes and
+whispers by the "kiblevel" variable.
+
+
+TRANSFERRING RATINGS FROM ANOTHER CHESS SERVER
+
+ It is possible to transfer your rating from another chess server to this
+server. Contact an admin concerning which admin should process your request
+since different admins are on different chess servers. In general, you will
+need to email your request to that admin. Please use the subject line
+"Request for ratings transfer" and in the body of the email tell the admin
+your handle(s) on both chess servers. Also be sure to "message" the admin on
+the other server so the admin can verify that you are the person you claim to
+be.
+
+SPECIAL NOTES:
+
+(a) In the case of adjourned games that are resumed, ratings are adjusted by
+the users' ratings at the time the match is resumed rather than the ratings
+they had when the match was started.
+
+See Also: assess best finger formula glicko hbest hrank kiblevel
+message rank who
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+
+refresh
+
+Usage: refresh [game]
+
+ Redisplays the given game position and clock times. If 'game' is omitted,
+then the current game you are playing or observing will be redisplayed. This
+command is especially useful if you are using an ascii board style and it
+scrolls off the screen, or if you want to confirm the current board position
+and/or clock times. (Time can also be confirmed by the "time" command.) The
+alias for "refresh" is "re".
+
+See Also: games style time
+
+[Last modified: November 26, 1995 -- Friar]
+
--- /dev/null
+
+register
+
+ *** ***
+ *** Registration is now automated using email! ***
+ *** ***
+
+
+ To get a registered account on this server, send a message to the following
+address ...
+
+ chess@caissa.onenet.net
+
+... and use as the Subject: "Fics Registration". The text of your message
+should read (please make the appropriate substitutions as indicated by the
+<>'s markers):
+
+ fics_addplayer <handle> "<First M. Last>" <email-address> <human|computer>
+
+**** Be sure to read "help handle" on the server's online help reguarding
+**** handle name policy!
+
+Quotation marks MUST be used around the name field. Do NOT include the <>'s
+markers in your text; they are used above only to indicate where you need to
+place information. If this is a human account, 'human' need not be specified;
+however, 'computer' MUST be used if you are registering a computer on FICS
+(see "computers" help file).
+
+ Here are two examples that would register Sparky with the correct name and
+email information:
+
+ fics_addplayer Sparky "Chris L. Petroff" chris@onenet.net -OR-
+ fics_addplayer Sparky "Chris L. Petroff" chris@onenet.net human
+
+
+SPECIAL NOTES:
+
+(1) PLEASE SELECT YOUR HANDLE CAREFULLY! We do not change handles for
+accounts once they have been created. So choose a handle that you are willing
+to keep. If for some reason the handle you want is already taken, you will be
+notified. To check in advance whether a handle is already being used, use the
+"handles" command. Lastly, your handle must not be offensive! Offensive
+handles will be removed. (See "handle" help file.)
+
+(2) ONLINE REGISTRATION WILL BE LIMITED. Email registration provides
+security for users and reduces mistakes. Contact an admin about registration
+if you have difficulties with email registration or if it is impossible.
+
+(3) Please tell us if you are an FM, IM or GM (master's titles for
+international competition). We can include you on our master's lists.
+
+
+See Also: computers handle handles showlists
+
+[Last modified: July 26, 1995 -- Sparky]
+
--- /dev/null
+To get a registered account, send a message to AdminGuy:
+
+mess AdminGuy fics_addplayer <handle> "<First M. Last>" <email-address>
+
+ NOTE1: quotes have to be around the name field.
+ NOTE2: do not include the <>'s in your mail. They only indicate
+ where you need to place information.
+
+ An example would be like the following, which would register
+ AdminGuy with the correct name and email information.
+
+ Ex: fics_addplayer AdminGuy "I. M. Admin" chris@onenet.net
+
+ Please tell us if you will be playing with a computer (meaning
+ that a COMPUTER is deciding what moves to make), or if you are an
+ FM, IM or GM (master's titles for international competition).
--- /dev/null
+To get a registered account, send mail to:
+
+ (New installations plaese put something here!)
+
+ With the Subject: "Fics Registration"
+
+ Include a line like the following in your mail. Please make the appropriate
+ substitutions inside of the <>'s:
+
+ fics_addplayer <handle> "<First M. Last>" <email-address> <human|computer>
+
+ NOTE1: quotes have to be around the name field.
+ NOTE2: If a human account, human need not be specified.
+ NOTE3: do not include the <>'s in your mail. They only indicate
+ where you need to place information.
+
+ An example would be like the following, which would register
+ Sparky with the correct name and email information.
+
+ Ex: fics_addplayer AdminGuy "I. M. Admin" chris@onenet.net
+ or: fics_addplayer AdminGuy "I. M. Admin" chris@onenet.net human
+
+ Please tell us if you will be playing with a computer (meaning
+ that a COMPUTER is deciding what moves to make), or if you are an
+ FM, IM or GM (master's titles for international competition).
--- /dev/null
+
+remote
+
+Usage: remote USER command
+
+ This command allows you to remotely control another logged in user,
+ if you are in their "remote" list. The player you are controlling
+ will receive a message telling them who issued a command and what
+ command was issued.
+
+ This command is intended to make controlling computer accounts easier.
+
+ To add a player to your remote list use the command:
+ +remote USER
+
+ To remove a player from your remote list use the command:
+ -remote USER
+
+ To see who is in your remote list use the command:
+ =remote
+
+See Also: channel
--- /dev/null
+
+resign
+
+Usage: resign [name]
+
+ Resigns the game you are playing and gives your opponent the win. You will
+then be available for another game.
+
+ It is possible to resign an adjourned game by including your opponent's
+name. For example, "resign Hawk" would resign your adjourned game with Hawk.
+Before you do this, make sure that the game has been stored. When you resign
+an adjourned game, a notification message will be sent to your opponent.
+
+See Also: adjourn intro_playing stored
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+
+revert
+
+Usage: revert
+
+ This command is used by a person examining a game in order to return to the
+main line of the game being examining. The analysis (subvariation line) is
+cancelled.
+
+See Also: examine
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+
+rmatch
+
+RESTRICTED TO TOURNAMENT DIRECTORS
+
+Usage: match user1 user2 <match params>
+
+SUMMARY
+
+This command is used to by tournament directors to start tournament
+matches
--- /dev/null
+
+say
+
+Usage: say message
+
+ Transmits your message to your current opponent if you are playing a
+game. If you are not playing a game, the message is sent to the last
+opponent you had in your current logon session.
+
+ "Say" is an easy form of "tell" as you can see, because you do not need to
+enter the user's name. "Say" differs from "kibitz": both commands send a
+message to your opponent, but "kibitz" also sends the same message to any
+observers of your game and kibitzes can be filtered in various ways.
+
+See Also: intro_talking kibitz kiblevel tell
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+seek
+
+Usage: seek [time inc] [rated|unrated] [white|black] [crazyhouse] [suicide]
+ [wild #] [auto|manual] [formula] [rating-range]
+
+ The "seek" command allows you to post an advertisement for a chess
+game of the specified type. The various parameters of the "seek"
+command are as follows:
+
+ PARAMETER COMMENTS
+ --------- --------
+ time minutes to start with for each player [default: your Time
+ variable setting]
+ inc seconds added to each clock per move [default: your Inc
+ variable setting]
+ rated/unrated type of match; may be abbreviated by "r" and "u"
+ [default: your Rated variable setting]
+ white/black designated colour you will have; may be abbreviated by "w"
+ and "b" [default: no colour specified]
+ crazyhouse see "help crazyhouse" if you are not familiar with this
+ chess variant; may be abreviated by "zh"
+ suicide see "help suicide" if you are not familiar with this
+ chess variant
+ wild # wild chess variant, if any, such as wild 1, wild 2, wild
+ fr, etc.; a shortcut for wild # is w#, but wild fr has no
+ shortcut [default: regular chess]
+ auto/manual indicates whether a game will start automatically when
+ the ad is responded to, or if the person who placed the
+ ad has the option to decline responses; may be
+ abbreviated by "a" and "m" [default: auto start]
+ formula indicates whether your formula will used to screen
+ responses to your ad; may be abbreviated by "f" [default:
+ formula is not checked]
+ rating-range indicates rating qualifications for the opponents, such
+ as 1300-1800 [default: 0000-9999]
+
+Note: If settings for time, inc or rated/unrated are not given, your
+"variables" settings will be used. Example A: if your variables settings have
+Time = 5, Inc = 0, and rated = 0 then typing "seek" would be the same as
+typing "seek 5 0 u". Example B: if your variables settings have Time = 5, Inc
+= 12, then typing "seek 2" would be the same as typing "seek 2 12".
+
+When you place an ad, it will be displayed to users in this general format:
+
+ Hawk(2700) seeking 5 0 rated blitz [white] m ("play 2" to respond)
+
+
+FREQUENTLY ASKED QUESTIONS:
+
+(1) Who will see my ad when it is posted? -- To have your ad displayed
+to a user the moment you make it, the other user must have his/her
+"seek" variable set to 1 and the ad must agree with his/her formula (see
+"help formula"). Otherwise, users can type "sought" to display current
+ads (see "help sought").
+
+(2) How can I see ads displayed? -- There are two ways: (a) type "set
+seek 1" and see ads displayed when they are created (type "set seek 0"
+to cancel these postings; see "help v_seek"); (b) type "sought" to
+display current ads for which are you eligible (see "help sought").
+
+(3) How many ads can I place at once? -- This value is set in the server code
+when it is compiled. To see the current limit for active seek ads, type
+"limits".
+
+(4) How can I see my own ad? -- You need to type "sought all" (see "help
+sought").
+
+(5) How do I withdraw an ad I have placed? -- Use the "unseek" command
+(see "help unseek").
+
+(6) How do I respond to an ad? -- Use the "play" command (see "help
+play").
+
+(7) What happens to my "open" variable when I post an ad or respond to
+an ad? -- Nothing. The value for your "open" variable does not change.
+For example, you can have "open=0" but still place ads and repsond to
+them.
+
+(8) What does the "manual" option do exactly? -- When you place a
+"seek" ad using manual start and a user responds to your ad, you will be
+sent a "match" request. You will then have the option of accepting or
+declining that user's offer to play your advertised match
+
+SPECIAL NOTES:
+
+(a) Users on your 'noplay' list will not be able to respond to your seek ad;
+the 'play' command will be rejected automatically.
+
+(b) (C)omputer accounts can issue seeks, but they cannot answer them.
+
+(i) The server software uses your history (and your opponent's) to determine
+who will get White. Starting from the bottom, for each entry we compare the
+colour you had and the one your opponent had. If they match, we look at the
+next entry. If they don't match we swap them and that is your colour for this
+game. If there are fewer than 10 entries for one player we assume the missing
+colour is the opposite of the one we know about. If they both run out together,
+or all 10 entries match, the colour is randomly chosen.
+
+See also: crazyhouse formula fr history limits match noplay play sought
+ suicide unseek variables v_inc v_open v_seek v_time wild
+
+[Last modified: February 17, 1999 -- pgv]
--- /dev/null
+Usage: servers
+
+ Lists all servers that are known to the main ratings server. Many of the
+machines listed may be out of date or not currently operating, but this
+will give you a place to start looking for a different server.
+
--- /dev/null
+
+set
+
+Usage: set variable_name [value]
+
+ You have a number of predefined variables that control the behavior of your
+account. This command allows you to control those variables and modify their
+settings. Generally, if "value" is omitted, the variable is toggled ON/OFF
+(0/1).
+
+Examples:
+ set shout 0
+ set f4 !private & !computer !abuser
+ set time 10
+ set inc 0
+ set auto 1
+ set style 12
+
+ To see the list of all of variables you can control, type "help variables".
+There are also other special uses of the "set" command, as follows.
+
+BUSY MESSAGE
+
+ If you will be idle for a while, you can have a brief message displayed to
+users when they "tell" you something. Read the "busy" help file for details.
+
+FINGER NOTES
+
+ You can have up to 10 information lines that can be displayed when someone
+uses the "finger" command. These text lines are modified by typing "set n
+<text>" where 'n' can be any integer from 1-10. You can erase one of your
+lines by typing "set n" without any text. (See "notes" help file.)
+
+FORMULA
+
+ You can filter out match requests by setting a formula. Your formula may
+include certain variables you can also set. Read the "formula" help file for
+details.
+
+See Also: busy finger formula notes variables
+
+[Last modified: December 17, 1995 -- Friar]
+
--- /dev/null
+
+shout
+
+Usage: shout message
+LIMITED TO REGISTERED USERS
+
+ Displays your message to all users who are open to hear shouts. Returns
+the number of users who heard your shout. "Shout" has an alias of "!".
+
+ Here is an example: if your handle is HANDEL and you type "shout This server
+is great!", users will see the following message displayed --
+
+ HANDEL shouts: This server is great!
+
+You, as the sender, will see the following --
+
+ (##) HANDEL shouts: This server is great!
+
+where ## is the number of users who received the message.
+
+ All users have a set shout quota, a limit on how many shouts can be made
+within a given period of time. Further details are given in the "shout_quota"
+help file.
+
+
+SPECIAL NOTES:
+
+ (a) Use "cshout" rather than "shout" for chess-related messages.
+
+ (b) To contact just one user, use "tell".
+
+ (c) If you want to contact a specific group of users, "tell" to a channel.
+
+ (d) "It" and "shout" are similar. Be familiar with their differences.
+
+ (e) Persons who "shout" in less than appropriate ways, may be placed on the
+shout_abuse list or given other sanctions (such as "muzzle").
+
+ (f) You can decide whether or not to hear a "shout" from other users;
+setting the "shout" variable to 0 (zero) filters these from being sent to you
+("set shout off" or "set shout 0").
+
+See Also: channel cshout intro_talking it shout_abuse shout_quota tell
+variables
+
+[Last modified: October 17, 1995 -- Friar]
+
--- /dev/null
+
+shout_abuse
+
+ This help file is to give some guidance on the accepted use of shouting.
+Breaking these guidelines may result in sanctions, such as a quota on your
+shouts or even worse muzzling (your shouting privileges revoked). REMEMBER:
+some people use text boards but still have shout on, which means that
+unnecessary shouts scroll their screen unnecessarily.
+
+THINGS THAT ANNOY OTHERS -- hence shout quotas or other sanctions:
+
+ Saying the same or similar things several times in a row. For example:
+
+ --> DAV is here.
+ --> DAV is here.
+ --> DAV greets all.
+ --> DAV is here.
+
+ Annoying others by imitating system messages. For example:
+
+ --> DAV has left a message for you.
+ --> DAV tells you: hi how are you?
+
+ Talking about something that should be in a channel -- after warnings.
+ The channel help file ("help channel") gives a list of all pre-defined
+ channels.
+
+ Also too much hugging and kissing -- except for login/out greetings; use
+ channel 51 for that please -- but keep the language clean!
+
+ Cursing and cussing others on shouts (including don't play xxx for yyy
+ reason).
+
+ Shouting far too often, lengthy shouts (e.g., ASCII pictures) beyond about
+ five or so lines).
+
+ Holding two person conversations on shout.
+
+ Anything else an admin sees fit.
+
+
+
+THINGS THAT ARE FORBIDDEN -- hence muzzle or (worse) a ban from FICS:
+
+ Swearing, in general or at others.
+
+ Discriminatory remarks -- see help etiquette.
+
+ Constant shout abuse.
+
+ Anything else an admin sees fit.
+
+
+ NOTE: any sanctions that are made against you are likely to be recorded,
+so punishment may be incremental for a second offence. A bad comment
+file is also likely to get you barred from privileges that may occur
+time to time, including the possibility of adminship.
+
+ DAV 05/12/95
+
+See Also: abuser etiquette handle shout_quota
+
+[Slight edits by Friar; last modified July 19, 1995]
+
--- /dev/null
+
+shout_quota
+
+ In order to encourage users to hold conversations in channels rather than
+with "shouts" the server has a shout quota. A shout quota limits the
+frequency of a user's shouts (including "it"-type shouts). For normal
+purposes, the standard shout quota is not a limitation.
+
+ Imposing more strict shout quotas is a sanction for cases of shout abuse.
+
+ If you type "shout" or "it" alone without any message, you will be informed
+about your current shout status: either (a) you may shout now, or (b) the time
+when you may next make a shout.
+
+See Also: channel etiquette intro_talking it shout shout_abuse
+
+[Last modified: August 28, 1995 -- Friar]
+
--- /dev/null
+
+showlist
+
+Usage: showlist [list_name]
+
+ This command lists the handles of users on a given list. The server
+maintains various special lists, such as the handles of admins and
+grandmasters on the server. To display the names of available lists, type
+"showlist". Each list will either be READ ONLY, meaning you can display the
+listing, or SECRET, meaning only admins can display the listing. The alias
+for "showlist" is "=". For example, "=admin" will list the handles of the
+server admins and "=computers" will list computers that have accounts on the
+server.
+
+See Also: addlist admins lists sublist
+
+[Last modified: September 2, 1995 -- Friar]
+
--- /dev/null
+
+simabort
+
+Usage: simabort
+
+ Used by a player engaged in simultaneous chess matches. Aborts the current
+board. Use this command if the player you are playing is obnoxious or taking
+too long to make the next move. Don't use it if you are losing, though.
+
+ The standard alias for simabort is "sa".
+
+See Also: simadjourn simallabort simmatch simpass simuls
+
+[Last modified: June 16, 1995 -- Friar]
+
--- /dev/null
+
+simadjourn
+
+Usage: simadjourn
+
+ Used by a player engaged in simultaneous chess matches. Adjourns the
+current board. Use this command in special circumstances, such as your
+opponent not being able to finish due to time constraints. Please don't use
+this command if you are losing, of course.
+
+ To continue your game, use the simmatch command.
+
+ The standard alias for simadjourn is "sadj".
+
+See Also: simabort simadjourn simalladjourn simmatch simpass simuls
+
+[Last modified: June 16, 1995 -- Friar]
+
--- /dev/null
+
+simallabort
+
+Usage: simallabort
+
+ Used by a player engaged in simultaneous chess matches. Aborts all boards
+still in progress.
+
+ The standard alias for simallabort is "saa".
+
+See Also: simabort simadjourn simalladjourn simmatch simpass simuls
+
+[Last modified: June 16, 1995 -- Friar]
+
--- /dev/null
+
+simalladjourn
+
+Usage: simalladjourn
+
+ Used by a player engaged in simultaneous chess matches. Adjourns all boards
+in progress. Use this command in special circumstances, such as your not
+being able to finish due to time constraints. Please don't use this command
+if you are losing, of course.
+
+ To continue your game(s), use the simmatch command.
+
+ The standard alias for simalladjourn is "saadj".
+
+See Also: simabort simadjourn simallabort simmatch simpass simuls
+
+[Last modified: June 16, 1995 -- Friar]
+
--- /dev/null
+
+simgames
+
+Usage: simgames [player]
+
+ Shows the number of active boards the player is playing in a simul. If no
+parameter is specified, the number of boards you are playing will be
+displayed.
+
+See Also: simmatch simuls
+
+[Last modified: July 7, 1995 -- Friar]
+
--- /dev/null
+
+simmatch
+
+Usage: simmatch player
+
+ Requests a simul match with the given player. That player must have
+his/her "simopen" flag on in order to accept simul requests. Once a match
+has started, you will be informed where in line you are. You will play
+BLACK.
+
+ Simmatch can also be used to restart an adjourned simul match, or untimed
+games in simul form.
+
+See Also: simadjourn simalladjourn simopen simuls
+
+[Last modified: June 16, 1995 -- Friar]
+
--- /dev/null
+
+simnext
+
+Usage: simnext
+
+ Used by a player engaged in simultaneous chess matches. Use simnext to
+move to the next game in the rotation so that you can make your next move
+in that game. An alias for "simnext" is "sn".
+
+ To go to a specific board, use "goboard" or "gonum".
+
+See Also: goboard gonum simuls simmatch simprev
+
+[Last modified: June 16, 1995 -- Friar]
+
--- /dev/null
+
+simopen
+
+Usage: simopen
+
+ Toggles your 'simopen' variable 0/1. Equivalent to "set simopen". If
+simopen is 1, then you are open to play more than one chess game at a time:
+have a simultaneous chess exhibition. More details are in the "simuls" help
+file.
+
+See Also: simuls variables
+
+[Last modified: June 22, 1995 -- Friar]
+
--- /dev/null
+
+simpass
+
+Usage: simpass
+
+ This command is upen by an opponent of a simul player. Use this command if
+you are not ready to move when the simul giver gets to your board and you wish
+more time for considering yuor move. You have 3 passes per match, then you
+must move or risk having your game be aborted.
+
+See Also: simabort simuls
+
+[Last modified: July 7, 1995 -- Friar]
+
--- /dev/null
+
+simprev
+
+Usage: simprev
+
+ Used by a player engaged in simultaneous chess matches. Use simprev to
+move to the previous game in the rotation so that you can make your next move
+in that game. An alias for "simnext" is "sp".
+
+ To go to a specific board, use "goboard" or "gonum".
+
+See Also: goboard gonum simnext simuls
+
+[Last modified: June 16, 1995 -- Friar]
+
--- /dev/null
+
+simuls
+
+ "Simuls" = simultaneous chess matches; playing more than one opponent at a
+time. It is possible to play more than one opponent simultaneously on the
+chess server. Below are sections for Starting a Simul and for Joining a
+Simul.
+
+
+STARTING A SIMUL
+
+ In order to play more than one chess match simultaneously you need to do the
+following:
+
+1. Turn on your simopen flag with "simopen". Announce your simul conditions
+ on shout and cshout enough to get the word out, but not so much as to annoy
+ users.
+
+2. Other users must then challenge you with "simmatch".
+
+3. Accept or reject the challenges as they come in. You play WHITE in all
+ games.
+
+4. When you are satisfied that you have started the number of games that you
+ can handle, turn off your simopen flag. You can see how many games you
+ are playing with "simgames".
+
+5. You can then start making moves on the board. The "simnext" command moves
+ you to the next board; "simprev" moves you to the previous board. You
+ will focus on one game at a time, going in a particular order.
+
+6. If you are bothered by how long a player is taking to make the next move,
+ you can abort that game with "simabort". You are in control of these
+ limits since the games are untimed.
+
+7. When all matches you are playing are complete, you will get your results.
+
+Various commands you can use while running a simul include: goboard, gonum,
+simabort, simadjourn, simallabort, simalladjourn, simnext, simopen and
+simprev.
+
+
+JOINING A SIMUL
+
+ In order to play against a user who is open for playing simultaneous
+matches, here is what you do:
+
+1. Using the "simmatch" command, challenge the person you will be playing.
+ If the challenge is accepted, you will play BLACK.
+
+2. You will be informed when the simul player is coming to your board. You
+ should be prepared to move either before or shortly after that player
+ arrives at your board. If you do not move within a reasonable time
+ period, your game could be aborted.
+
+3. It is impolite to offer a draw unless that player is at your board. It
+ could very easily confuse the simul player if offers come in from
+ different users at once.
+
+4. If your game ends early, you may want to turn on your ginform flag so
+ that you can see the final result of the simul games. You can also
+ observe the games; when the last game is over, you get the results.
+
+
+OBSERVING A SIMUL
+
+ You can observe all games in a simul once they have started by typing
+"observe simul_player". All of the simul_player's simul games will be added
+to your observation list. As the simul_player moves from board to board, so
+will you. When the last game has ended, you will see the final results from
+the simul games.
+
+See Also: observe set simmatch simgames [and other commands given above]
+
+[Last modified: August 15, 1995 -- Friar]
+
--- /dev/null
+
+smoves
+
+Usage: smoves player1 {#, player2, journal_slot}
+
+ Displays the moves of player1's game. You must designate either game # from
+player1's "history" table, player2 from player1's "stored" (adjourned) games,
+or a game from the user's journal.
+
+ Examples:
+
+ smoves Hawk 65 [for a history game]
+ smoves Hawk DAV [for a stored game]
+ smoves Hawk K [for a journal game]
+
+ Other useful commands: (a) "examine" helps you review the game; (b)
+"mailstored" mails moves to you; (c) "sposition" displays current game
+position.
+
+See Also: examine history journal mailstored sposition stored
+
+[Last modified: December 17, 1995 -- Friar]
+
--- /dev/null
+
+Soapbox
+
+ It is my hope that the source code to quality chess server software
+will be available to the internet community for free. It could be the
+FICS, the ICS, or some other new software, it doesn't matter.
+
+ When Michael Moore started the chess server years ago, it was his
+intention to provide free access to it to everyone. He distributed the
+server code freely in the hope that server sites might spring up and
+flourish. Unfortunately, the situation exists today where one small
+group of people have hoarded the source code and refuse to allow
+any alternate servers start. I hope that my efforts in re-writing
+a public domain server has the effect to improve the server, both in
+substance and in administration.
+
+ If the FICS catches on and replaces the ICS (unlikely), then we win. If
+the ICS is released as source code to the public and the FICS dies, then
+we win. If the FICS and ICS go on coexisting perhaps someday sharing the
+same ratings server, we win.
+
+ The only way we lose is if the status-quo is maintained and the only
+source of internet chess is controlled by a few individuals.
+
+Richard Nash
+
+SoapboxII (The revenge of soapbox! :) )
+
+ Since then, ICS went free and we all lived (almost) happily, however
+ICS became ICC and wanted to charge $49 to play chess.
+ Now, I understand that the ICC code had lots of work put into it and its
+writer deserves something. However in the spirit of how ICS was set up, I
+and others feel asking for donations would be better and no pay or else
+attitute.
+ So, a band of programmers and ex-admins of ICC got together to rewrite
+the out of date FICS code and this is what you are using now.
+ FICS is free. Enjoy it.
+
+ Dan,DAV,foxbat,friar,grimm,hawk,loon,mann,Shane,Sparky et al.
--- /dev/null
+
+sought
+
+Usage: sought [all]
+
+ The "sought" command can be used in two ways: (a) typing "sought all" will
+display all current ads including your own; (b) typing "sought" alone will
+display only those current ads for which you are eligible based on any formula
+you might have (default). An example output is as follows:
+
+ 0 1900 Hawk blitz 5 0 rated 1800-2000 f
+ 1 1700 Friar wild7 2 12 unrated [white] 0-9999
+ 4 1500 loon standard 5 0 unrated 0-9999 m
+
+The various columns have this information:
+
+ Ad index number
+ Player's rating
+ Player's handle
+ Type of chess match
+ Time at start
+ Increment per move
+ Rated/unrated
+ Color (if specified)
+ Rating range
+ Auto start/manual start and whether formula will be checked
+
+See also: formula match play seek unseek
+
+[Last modified: February 5, 1998 -- Friar]
--- /dev/null
+
+sourcecode
+
+ You can get a version of the code via anonymous ftp to 'ics.onenet.net' in
+the directory /pub/chess/Unix.
+
+ If you make any changes to the code that you would like to see incorporated
+into future releases, please mail them to u940456@daimi.aau.dk. I'm hoping
+that the FICS community will help improve and debug this server.
+
+See Also:
+
+[Last modified: June 15, 1995 -- Friar]
+
--- /dev/null
+
+sposition
+
+Usage: sposition player1 player2
+
+ Displays the position of the stored game between player1 and player2. This
+command only displays the game position; use "examine" for analysis.
+
+See Also: examine smoves stored
+
+[Last modified: December 25, 1995 -- Friar]
+
--- /dev/null
+
+standard
+
+ There are four types of regular (not wild or bughouse) chess played on this
+chess server: Untimed, Lightning, Blitz and Standard.
+
+ A game is "Standard" if the expected duration of the game is 15 minutes or
+more. "Expected duration" is determined by a formula that takes into account
+both the Start time and the Increment (Inc) value. Here is the formula:
+
+ Expected duration = (Start + Inc*2/3)
+
+ The following table shows the slowest Blitz and fastest Standard time
+controls, the dividing line if you will between those two types of matches.
+[Thanks to schwartzeer for the calculations. :) ]
+
+ Slowest Blitz Fastest Standard
+ ------------------------------------
+ Mins Incr Mins Incr
+ ------------------------------------
+ 0 22 0 23
+ 1 20 1 21
+ 2 19 2 20
+ 3 17 3 18
+ 4 16 4 17
+ 5 14 5 15
+ 6 13 6 14
+ 7 11 7 12
+ 8 10 8 11
+ 9 8 9 9
+ 10 7 10 8
+ 11 5 11 6
+ 12 4 12 5
+ 13 2 13 3
+ 14 1 14 2
+ -------- 15 0
+
+ As you can see, not every game with more minutes to start is Standard and
+not every game with few minutes to start is Blitz.
+
+ You can list logged on users according to their Standard ratings by typing
+"who s". "Standard" is also a variable that can be used in formulas in order
+to screen match requests.
+
+See Also: blitz formula lightning match who
+
+[Last modified: December 25, 1995 -- Friar]
+
--- /dev/null
+
+statistics
+
+Usage: statistics
+
+ Displays some statistics on all the players together. For each type of
+rated chess, the table gives (a) the average rating, (b) the standard
+deviation (or variability) of the ratings, and (c) the number of rated players
+(including provisional ratings).
+
+See Also: totals uptime
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+
+stored
+
+Usage: stored [user]
+
+ Displays all of the stored games of 'user' or of yourself if 'user' is
+omitted. Adjourned games are stored (but not games lost due to a server
+crash). To resume an adjourned game, have both players logged on the server
+and use the "match" command.
+
+ Several other commands involve stored games. "Examine" allows you to review
+and analyze a game. "Mailstored" mails the moves to you. "Sposition" will
+display the last position of the game. "Smoves" will display the moves of
+the game. You can also have an adjourned game adjudicated by an admin (see
+the "adjudication" help file).
+
+
+SPECIAL NOTES:
+
+(a) Users who have too many stored games may be placed on the abuser list.
+Having up to 10 stored games is fine, but many more games beyond that will
+raise concerns. Please complete your adjourned games in a reasonable time or
+ask for an adjudication.
+
+(b) It is possible to resign one of your stored games, even when your
+opponent is not logged on.
+
+See Also: abuser adjourn adjudication examine mailstored match resign
+smoves sposition
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+
+style
+
+Usage: style n
+
+ Sets your 'style' variable to n. Equivalent to "set style n". This command
+allows you to choose among the various board display options.
+
+ 1. Standard ICS board in ascii format (default)
+ 2. USA-Today Sports Center-style board
+ 3. Experimental vt-100 ANSI board for dark backgrounds
+ 4. Experimental vt-100 ANSI board for light backgrounds
+ 5. Style suggested by ajpierce@med.unc.edu
+ 6. Email Board suggested by Thomas Fought (tlf@rsch.oclc.org)
+ 7. Miniature board
+ 8. ICS interface maker board -- raw data dump
+ 9. last 2 moves only (previous non-verbose mode)
+10. Alternate raw dump
+11. Same as 8, but with verbose moves ("P/e3-e4", instead of "e4")
+12. Similar to style 10.
+13. Displays board in color for SGI machines -- white versus purple pieces
+ with purple and black squares (for b/w monitors it would display as bold
+ and regular).
+
+ Some graphics interfaces work only with specific board styles. Determine
+which one is best for your set up.
+
+ Suggestions on different styles are always welcome.
+
+See Also: interfaces variables
+
+[Last modified: November 26, 1995 -- Friar]
+
--- /dev/null
+
+sublist
+
+Usage: sublist <list> <information>
+
+ Removes information from the list in question. There are several kinds of
+lists on the server. Some can only be modified by admins; others can be
+modified by all users. "Addlist" command adds information to a list.
+
+ The standard alias for "sublist" is "-".
+
+See Also: addlist admins alias lists
+
+[Last modified: June 15, 1995 -- Friar]
+
--- /dev/null
+
+switch
+
+Usage: switch
+
+ Requests to switch sides with your opponent. Switching sides can only be
+done before the first move of a rated game, or anytime during an unrated game.
+Your opponent can "accept" or "decline".
+
+See Also: accept decline
+
+[Last modified: June 12, 1995 -- Friar]
+
--- /dev/null
+
+takeback
+
+Usage: takeback [n]
+
+ Requests a takeback of 'n' half-moves in the current game. If 'n' is
+omitted then 1 is assumed. A "half-move" is defined as a move by one
+player. To request that the last move made be changed (whether you were
+the one to move last or your opponent moved last), you would request
+"takeback". If you wanted to change the last move made as well as the move
+prior to that, request "takeback 2".
+
+ Here's an example: suppose you are playing White and your opponent has
+just placed a piece on a square where it can be easily captured, and you
+capture it. Your opponent might realize the weak move he/she made and
+request "takeback 2" so that he/she doesn't lose material so easily. If
+you wish, you can accept the "takeback 2" request and continue the game
+from the previous position in the game. Both moves would be reversed, and
+it would be Black's move to make.
+
+See Also: accept
+
+[Last modified: June 14, 1995 -- Friar]
+
--- /dev/null
+
+teamgames
+
+ A team game is a game played between two teams, each consisting of more than
+one player. It is also possible to have a team playing against one person or
+a computer. The procedures are simple: (a) set up the teams, (b) appoint one
+person from each team as captain, (c) have the two captains match each other
+using very long time controls, usually unrated, (d) have two separate channels
+for the teams to use for their consultations, (e) have team members observe
+the game and consult about moves, (f) have the captain play the move for
+his/her team ... and play continues along those lines.
+
+ To start a team game, it is best to have the players use three channels. At
+the moment Channels 20, 21 and 22 are primarily for this purpose. To start
+with, all the participants turn on one channel (Channel 20) to enable
+communication about team formation. The other two channels are for the two
+teams. Players of one team turn on the their channel but not the other. Then
+the players on each team select a captain.
+
+ Actually, there are many ways to form teams. One way is to let the players
+join a channel randomly, another is to agree to two captains first and let
+them pick their teams in turn. There is no set rule that must be followed.
+
+ A game is started by the two captains playing each other. Then every
+participant observes that game. Players can suggest moves using the
+appropriate channels. They can adopt a democracy and vote before making
+moves, or they can opt for dictatorship where the captain can decide on the
+move, taking advice from the think tank. Any form of decision making is
+possible, provided the team has agreed to it beforehand.
+
+ Typically, it takes much longer to play a team game than a game between
+individuals, because a lot of discussion is going on. Hence a longer time
+control and longer increment are recommended. Several minutes per move is not
+uncommon -- and even that time can go quickly.
+
+
+WHY TEAM GAMES?
+
+ Playing team games is a good way to learn because you are involved in a
+position and can hear different views on it. Some people play mainly
+positionally and some prefer sharp combinations. It is enlightening to see
+how widely different analyses can come out from the same position. Moreover,
+you can learn more about openings with which you are unfamiliar.
+
+ Team games are also fun. During the consultation, it is typical that
+players talk and make jokes. It helps develop friendly relationships among
+users. In fact, even the process of forming teams can be fun.
+
+REMEMBER: Chess on this server is for fun. So please don't flame. Sometimes
+even a team can overlook something and play a bad move. In that case, just
+take it easy. Try to work as a team and fight back from behind. Bitter words
+do nobody any good.
+
+See also: channel observe tell
+
+[Last modified: June 20, 1995 -- Friar]
+
--- /dev/null
+
+tell
+
+Usage: tell user message
+
+ "Tell" transmits your message to the user specified. The server gives you
+some feedback that the message has been sent. You will also be told whether
+the user is playing a game currently, or is not even logged on at the moment.
+"t" is an alias for "tell".
+
+ As a shortcut, you can use "." as an alias for "tell user" when you want to
+send another message to the last person you told. That way you can keep
+conversations going easily.
+
+ When you receive a "tell" it will appear like this:
+ <User> tells you: <message>
+
+ The 'user' can also be a channel number in order to send a message to a grou
+of users having that channel activated. In this case, you as sender will see
+the following display after sending your message: (# -> (##)) where # is the
+channel number and ## is the number of people on that channel that received
+your message.
+
+ As a shortcut, you can use "," as an alias for "tell #" and your message
+will be sent to the last channel you gave in a "tell" command. (Compare to
+"xtell" command.)
+
+
+SPECIAL NOTES
+
+ (a) The server remembers both the last user to whom and the last channel to
+which you have told something. For this reason, "." and "," are separate
+aliases and do not interfere with each other.
+
+ (b) A special command, "say", can be used for communicating with an opponent
+during or directly following a chess game.
+
+ (c) Another special command, "message", sends a message to a user so that it
+can be stored for future use.
+
+ (d) You can decide whether or not to hear a "tell" from unregistered users;
+setting the "tell" variable to 0 (zero) filters these from being sent to you.
+
+
+See Also: alias channel intro_talking message say variables xtell
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+
+time
+
+Usage: time [game,user]
+
+ Shows the updated time remaining in the specific game for the players
+involved. If no game is specified, the clock readings for your current game
+will be shown. Revised clock times are also given as part of the "refresh"
+command; however, "time" will always show negative times whereas "refresh"
+will only list negative times if the interface handles them that way.
+
+See Also: refresh
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+
+timeseal
+
+WHAT IS TIMESEAL?!
+
+ Timeseal is a program that has been developed to improve chess on internet.
+Netlag often causes players to lose valuable seconds or even minutes on their
+chess clocks. Transmission time is counted against you, unless the chess
+server can tell exactly when information is transmitted. What timeseal does
+is record your thinking time, so that transmission time is not counted against
+you. Timeseal will not prevent netlag but it makes the games fairer when lag
+occurs.
+
+HOW DO I USE TIMESEAL?!
+
+ What you need to do is get a version of timeseal working on the computer
+that connects you to the chess server. The timeseal program will work as a
+relay station, and will keep track of transimission times.
+
+ The following versions of timeseal are currently available (as of December
+17, 1995):
+
+ AIX-3.2-RISC-SOCKS
+ AIX-3.2-RISC
+ BSD386-1.0-i386
+ BSDOS-2.0-i386
+ HP-UX-A.09.05-9000.705
+ HP-UX-B.09.03-9000.42E
+ IRIX-4.0.5H.IP12-mips
+ IRIX-5.3-IP22-mips
+ IRIX64.6.0.1.IP21.mips
+ Linux-1.2.9-SOCKS
+ Linux-1.2.9-i586
+ OSF1-V3.0-alpha
+ SCO-3.2-i386
+ SunOS-4.1.4-sun4c
+ SunOS-5.4-386
+ SunOS-5.4-sun4d
+ TW-SunOS-TW2.0.1-twin2
+ ULTRIX-4.3-RISC
+ Windows-Winsock (file is called tmsl11j.zip)
+
+To see if anyone of these may fit the hardware you are using, do "uname -a" in
+your unix shell and see which unix system you have operating. Then, determine
+whether you need one of the special Windows or SOCKS versions.
+
+
+TO DOWNLOAD TIMESEAL
+
+Follow these directions:
+
+(1) Login to your unix/inet provider. (VAX/VMS not supported yet). Type
+ "uname -a" and remember the output. You will need this output to figure
+ out which version of timeseal will work on your system.
+
+(2) Type "ftp 164.58.253.10" which will get you to the onenet ftp site. When
+ you are asked for a login ID type: "ftp" or "anonymous". When you are
+ asked for a password, type your email address.
+
+(3) Type "cd pub/chess/timeseal" (in order to get to the correct
+ onenet directory) and type "dir" (in order to see which versions of
+ timeseal are currently available). Compare the available timeseal
+ versions to the type of unix operating system you have.
+
+(4) When you have found the timeseal version that will work on your system,
+ type "bin" (for "binary" transmission format) and then type "get
+ filename" (where "filename" is the name of the version from the
+ directory).
+
+(5) Wait for the ftp file transmission to complete, then type "quit". The
+ file should now be in your current directory -- probably the home dir.
+
+(6) Type "gunzip filename", "chmod 700 filename", and "mv filename timeseal".
+ These various commands make the timeseal program available on your
+ operating system. NOTE: There are times when using "chmod 700 filename"
+ does not work on your system. In this case, try "chmod 755 filename".
+
+ Here is an example after you have ftp'd the version called
+ timeseal.ULTRIX-4.3-RISC.gz:
+
+ gunzip timeseal.ULTRIX-4.3-RISC.gz
+ chmod 700 timeseal.ULTRIX-4.3-RISC
+ mv timeseal.ULTRIX-4.3-RISC timeseal
+
+Now you are ready ... to go to the next step. ;-)
+
+
+TO RUN TIMESEAL WITH YOUR INTERFACE
+
+ There are different procedures depending on which interface/system you are
+using. If you use Xwindows +Xboard / xics, then go to A); if you have winsock,
+then go to B); otherwise go to C).
+
+A) For Xwindows users, there are two methods (listed in order of preference).
+Whichever approach you use, make sure that xboard and timeseal are in the same
+directory. Use one or the other -- NOT BOTH!
+
+ (1) Use this command (it is the more direct, simpler approach):
+
+ ./xboard -ics -icshost 164.58.253.10 -telnet -telnetProgram timeseal
+
+ (2) Executing "./timeseal 164.58.253.10 5000 -p xxxx &" causes timeseal
+ to bind itself to port xxxx and wait for a connection to the chess
+ server. Then you can start xboard / xics like this (remember to
+ exchange xxxx with a valid port number, like 5500, 5501, whatever you
+ like):
+
+ ./xboard -ics -icshost localhost -icsport xxxx
+ ./xics localhost xxxx
+
+ You MUST use the string "localhost". Do NOT write the chess server
+ host because then timeseal will not be on. "localhost" is a perfectly
+ valid address since it's aliased to 127.0.0.1 (loopback) which always
+ means the machine you are using.
+
+B) There are two steps: INSTALL and USE:
+
+ INSTALL: Move the file tmseal.exe to the same directory as your client
+ program. Create a program manager icon for TMSEAL, using the normal
+ methods. (Select File|New from the program manager menu; click on New
+ Program Item, then in the dialog set the Directory field to the same
+ directory as above; set the command line to TMSEAL; you may check the Run
+ Minimized checkbox if you wish.)
+
+ USE: Double-click on the TMSEAL icon before beginning your FICS session.
+ Then, in your client program, connect to "localhost" instead of the usual
+ "chess.onenet.net". Soon the usual logon messages will appear. Errors
+ if any will show up in the TMSEAL window.
+
+C) For other users (no xboard, no winsock) such as ziics, jiics, E-ICS, etc:
+
+ Modify your interface configuration to replace the normal telnet command
+ with: "./timeseal 164.58.253.10 5000".
+
+
+DONE!
+
+Questions? Ask channel 1 or an admin.
+
+
+See Also: chan_1 ftp_hints interface lag
+
+[Written by Hawk, August 15, 1995; last modified: December 17, 1995 -- Friar]
+
--- /dev/null
+ 1. When your opponent puts you in check, it isn't noted in the last move.
+ 2. When you takeback, your opponent should be told to type "takeback" to
+ accept.
+ 3. Implement examine mode for history games.
+ 4. typing "match foo" without parameters should make a counteroffer to
+ foo with your own default parameters instead of accepting foo's offer.
+
--- /dev/null
+
+toggle
+
+Usage: toggle list information
+
+Toggles information in a list. If the 'information' is already in the
+specified list then it is removed, otherwise it is added.
+
--- /dev/null
+
+tomove
+
+Usage: tomove white|black
+
+ This command is used while in "bsetup" mode in order to designate which side
+will move next when you exit from bsetup mode. For example, "tomove white"
+means that it will be White's move next.
+
+See Also: bsetup
+
+[Last modified: February 3, 1996 -- Friar]
+
--- /dev/null
+*** Total players: 7606
+Active in last week: 3241
+Active in last day: 1748
+
+Counted at Tue Sep 19 16:00:00 CDT 1995 [Updated hourly]
--- /dev/null
+
+tournset
+
+Usage: tournset user 0|1
+USE RESTRICTED TO TD PROGRAMS
+
+ The tournset command is used by Tournament Director (TD) programs that are
+running tournaments. It is used to set your tourney variable to ON (1) when
+you have joined a tournament and to OFF (0) when the tournament is over.
+
+See also: v_tourney
+
+[Last modified: February 10, 1997 -- Friar]
+
--- /dev/null
+
+unalias
+
+Usage: unalias word
+
+ Removes your personal alias for 'word'. This alias will no longer be in
+use. This command will not, however, remove default aliases.
+
+See Also: alias
+
+[Last modified: June 20, 1995 -- Friar]
+
--- /dev/null
+
+uncensor
+
+Usage: uncensor [user]
+
+ Removes 'user' from your censor list. If 'user' is omitted then the
+entire list is cleared.
+
+See Also: censor intro2
+
+[Last modified: June 20, 1995 -- Friar]
+
--- /dev/null
+
+unexamine
+
+Usage: unexamine
+
+ This command is used to stop examining a game. "Unexamine" stops your
+participation in the analysis, and also stops your observer status. The other
+examiners and observers may continue, however, even if you set up the examine
+to begin with.
+
+See Also: allobservers examine observe
+
+[Last modified: June 29, 1995 -- Friar]
+
--- /dev/null
+
+unnotify
+
+Usage: notify [user]
+
+ Removes user from your notification list. If no user is specified, the
+command will remove *all* users from your notification list.
+
+See Also: notify znotify
+
+[Last modified: June 20, 1995 -- Friar]
+
--- /dev/null
+
+unobserve
+
+Usage: unobserve [game,user]
+
+ Removes a game from your observation list. You can give either the game
+number or the user whose game you want to unobserve.
+
+ For example, if you are observing game #34, KARPOV versus RETI, then
+"unobserve 34", "unobserve RETI" or "unobserve KARPOV" will remove this game
+from your observation list.
+
+ "Unobserve" used alone removes ALL GAMES from your observation list.
+
+See Also: allobservers games observe
+
+[Last modified: June 11, 1995 -- Friar]
+
--- /dev/null
+
+unpause
+
+Usage: unpause
+
+ Restarts the clocks on a paused game and resumes play. You do not need your
+opponent's consent to restart the game clock. However, it would be good
+etiquette to announce that the game is resuming, and ensure that your opponent
+is ready.
+
+See Also: pause
+
+[Last modified: June 20, 1995 -- Friar]
+
--- /dev/null
+
+unseek
+
+Usage: unseek [#]
+
+ Typing "unseek" alone will cancel *all* of your current ads for chess
+matches. Typing "unseek #" will cancel ad #, where the # is the ad index
+number from the display "sought all".
+
+See also: seek sought
+
+[Last modified: August 18, 1996 -- Friar]
+
--- /dev/null
+
+untimed
+
+ There are four types of regular (not wild or bughouse) chess played on this
+chess server: Untimed, Lightning, Blitz and Standard.
+
+ A game is "Untimed" if the clocks will not be used when playing the game.
+In this case, both the Start and the Increment are 0. For example, "match
+friar 0 0" would request an untimed game against Friar. The clocks in an
+untimed game will not move (though interfaces may handle this in different
+ways). Also, "flag" will not work since the times will never be below 0
+seconds. Lastly, Untimed games are always unrated.
+
+See Also: blitz lightning match standard
+
+[Last modified: December 17, 1995 -- Friar]
+
--- /dev/null
+
+uptime
+
+Usage: uptime
+
+ Displays some server statistics, such as how long the server has been in
+continuous operation, the number of current players and games, the highest
+number of players and games, and the maximum number of players who can be
+logged on.
+
+See Also: games statistics totals who
+
+[Last modified: July 7, 1995 -- Friar]
+
--- /dev/null
+
+USCF FAQ
+"Frequently Asked Questions About the United States Chess Federation"
+
+NOTE: FICS is not affiliated with USCF in any way. This
+help file is intended solely as a public service to FICS users and to
+promote chess. The text was written by FICS users and sanctioned by USCF.
+Neither USCF or FICS take any responsibility for the accuracy of the
+information contained in this file.
+
+--> What is USCF?
+
+ USCF stands for the United States Chess Federation. USCF is the
+national chess organization for the United States. Its purpose is to
+promote chess (see the USCF Mission Statement in another FICS help file,
+"uscf_mis"). USCF sponsors various kinds of chess tournaments, promotes
+chess in public schools and prisons, represents US interests in
+international chess organizations, and offers discounts on chess books and
+equipment. USCF is composed of over 82,000 individual members and 2100
+local and state organizations (known as "affiliates").
+
+--> Are there other national chess organizations?
+
+ Yes. USCF is the main organization for over-the-board (OTB) play.
+They also sponsor correspondence ("postal") chess and Quick Chess (games
+with faster time controls) but other organizations have national
+importance in these two areas as well. Information about these other
+organizations may be placed on FICS at a later date.
+
+--> What are the benefits for joining USCF?
+
+ Well, every member has a different reason for joining. The benefits
+of membership include:
+
+ * Chance to play in numerous chess tournaments and have national
+ ratings in OTB and postal chess
+ * Cash prizes in tournaments
+ * A monthly magazine, "Chess Life" ("SchoolMates" for younger
+ members).
+ * Discounts for chess equipment and books.
+
+--> Tell me about the tournaments.
+
+ There are two main groups: Over-the-board (OTB) and Postal. In OTB
+tournaments you play against other opponents face-to-face. In Postal
+tournaments you play by mail and exchange moves, usually on postcards.
+Membership is necessary to play in a USCF tournament (there are some
+exceptions, but these are rare) and entry fees are charged. A complete
+listing of upcoming OTB tournaments all across the United States should be
+available on FICS sometime in July.
+
+--> What are OTB tournaments like?
+
+ Most tournaments take one or two days over the weekend for maybe half
+a dozen games, though major national tournaments may last a week or two
+and involve many games. A tournament may have anywhere from a dozen to
+600 or even a thousand players.
+ Tournaments generally have different playing "sections" or groups of
+players based on their national ratings. You only play opponents within
+your own section. For example, a large tournament might have these five
+sections: Open, U2000, U1600, U1200, and Scholastic. Any USCF member can
+play in the Open section, only those with a USCF rating under 2000 can
+play in U2000, only those below 1600 can play in the U1600 section, only
+those below 1200 can play in U1200 and only high school or younger
+students can play in the Scholastic. (A high school student with a USCF
+rating of 1300, for example, could choose to play in the Open, U2000,
+U1600 or Scholastic sections, but not in U1200.) The different sections
+allow players of similar strength to compete for prizes.
+ Tournament games can last anywhere from one or two hours up to four or
+five hours, depending on the time control of the tournament. There are
+some Quick Chess tournaments with time controls of only 10 or 30 minutes
+per player per game. Tournament time controls are very different than
+those used on FICS, so learn the details before playing in a tournament.
+ Tournaments generally offer cash prizes (!!), with the exception being
+the Scholastic tournaments which prefer to give out trophies instead.
+Most tournaments offer prizes within each section (1st, 2nd and 3rd for
+example) as well as other prizes by ratings categories (for example, the
+U2000 section may have a prize for the best scoring U1800 player).
+ Chess tournaments, organized by the local USCF affiliates (especially
+state organizations and clubs) are held weekly all across the United
+States. Each tournament varies considerably in style, size, prize fund
+and difficulty. Information about USCF sanctioned tournaments is printed
+monthly in "Chess Life." We also hope to make such information available
+on FICS. We suggest you visit a tournament in your local area and catch
+the excitement!
+
+--> What if I want to play in an OTB tournament but never have before?
+
+ If you're unsure how tournaments run, it may be helpful to visit one
+or two before playing. Almost all tournaments allow and encourage
+spectators.
+ You need to become aware of tournament rules and etiquette. If you
+are in a tournament you will need to know when the rounds start, where the
+pairings (lists of who plays who) are posted, how to find your opponent,
+where to mark the result of your game, what the time controls are, how to
+use a chess clock, how to take notation (it is usually required to record
+the moves of your games), etc.
+ Most tournaments require that you bring your own equipment, but don't
+worry if you don't have a regulation set and clock. Most of your
+opponents will, and there should be unused sets you can borrow any given
+round. If you decide to play in more tournaments, you really should
+acquire regulation equipment.
+ All of this can seem very intimidating to a new player, but if you
+show up early, you should have plenty of time to ask the tournament
+director, or other players, to explain the whole process. It may be
+helpful to obtain a copy of the US Chess Federation's Official Rules of
+Chess (4th ed) (available from USCF).
+ For your first tournament, either mail your entry fee in advance or
+pay it in person at the tournament site. In either case, get there early
+to familiarize yourself with the rooms, the tournament organizers, and
+have a chance to ask questions.
+ Lastly, remember to just have fun and play some good chess. Most
+people do not score very well in their first tournament, but some do win
+prizes (larger tournaments generally offer a few prizes for unrated
+players).
+
+--> What's postal chess all about?
+
+ Basically, you play by mail. Your opponent could be from anywhere in
+the United States, or even overseas. Generally, you play against
+opponents in a small section (4-7 players) with roughly your same level of
+ability, though there are also Open tournaments. Each player is required
+to make a certain number of moves in a 30-day period (not including the
+time it takes for the mail to get through). In examining your next move,
+you may consult with books and articles and take notes, but you may not
+have computers or humans analyze your games while they are in progress.
+Each game may take as long as a year, sometimes longer, but you play
+several games simultaneously. You can even have rated matches against
+opponents of your own choosing. Some tournaments offer cash prizes;
+others offer certificates to the section winners. Information about
+postal chess is given each month in "Chess Life."
+ Many people who are too busy to play OTB tournaments regularly, or
+even at all, find that postal chess matches their schedules perfectly.
+They can analyze moves during lunch, in the evenings, stalled on the
+highway during rush hour, or whenever they have a few minutes free. The
+time controls mean a move need not be sent off the day after it is
+received, and the players can therefore analyze positions at their
+leisure.
+
+--> Tell me more about "Chess Life"?
+
+ "Chess Life" is USCF's official magazine. It has numerous articles
+for players of all abilities, quizzes, ways to test your abilities,
+annotated games from recent tournaments across the world, stories on chess
+personalities and chess-related news. "Chess Life" prints advance
+information on many upcoming chess tournaments in the US as well as postal
+chess. It also has catalog supplements several times each year with
+information on discounts on chess-related products, including books,
+pieces, boards, computers and computer software. Companies selling chess
+productes often advertise in "Chess Life" as well.
+
+--> Tell me more about the affiliates?
+
+ An affiliate is simply a local chess club associated with USCF.
+Almost every major city in the United States has an affiliate. Many
+universities and other organizations sponsor one as well. Currently there
+are just over 2000 affiliates scattered across the nation.
+ Each club is different, but most generally hold informal meetings a
+few times per month, where the club members can get together and play
+games, discuss openings, study grandmaster games, eat doughnuts, or
+whatever. Clubs are a great way to become involved in chess, and you
+normally do not need a USCF membership to join one.
+ Affiliates often sponsor USCF tournaments, some of which are open only
+to the club's members. This depends on each individual affiliate, though.
+ You can write to USCF at the address below and request a list of
+affiliates in your area.
+
+--> Where do I get more information on USCF?
+
+ Well, "Dogma" on FICS would be more than willing to talk to you about
+USCF and playing in a tournament. There are other USCFers on FICS, too,
+and you can ask them for their opinions. You can also go directy to the
+source and call USCF at ... 1-800-388-KING ... and ask them to send you
+membership information, etc.
+ USCF provides free pamphlets on a variety of subjects, available on
+request. These include, but are not limited to, pamphlets describing the
+rules, how to take notation, what constitutes official equipment, etc.
+Call or write USCF for more information.
+
+--> How do I become a USCF member?
+
+ There are several ways. You can join at virtually any tournament,
+call the above phone number and pay with a credit card, or send your
+membership fee directly to USCF at:
+ 186 Route 9W
+ New Windsor, NY 12553
+ It may be possible to obtain a slight discount by buying your USCF
+membership through an affiliate, or as part of tournament registration
+fees; however, this depends on each individual affiliate and tournament.
+
+--> What is the membership fee?
+
+ The regular, one year membership fee is $40, of which $21 is the
+subscription to "Chess Life". Youth memberships (age 19 and under) cost
+$15 for one year. Senior memberships (65 and older) are $30 per year.
+ Scholastic memberships cost $10 per year (generally for elementary
+students, but available for age 19 and under). A scholastic membership is not
+necessary to play in scholastic tournaments; a youth membership would work
+just as well. However, Scholastic membership receive "School Mates", a
+bi-monthly magazine for the beginning player, rather than the monthly "Chess
+Life".
+ All of the above membership types receive full membership benefits,
+including "Chess Life". Again, the major difference between "Youth" members
+and "Scholastic" members is that youth members receive "Chess Life" while
+scholastic members receive "School Mates".
+ Discounts are available for junior, family, blind, and prison memberships.
+Discounts are also given for longer memberships (for example a two-year
+membership); life memberships are also available.
+
+--> Is USCF membership worth it?
+
+ If you are an avid chess player who wants to play in tournaments and
+have national ratings for OTB and/or postal chess, wants to keep up on the
+chess scene, or just wants to help promote chess in the United States, the
+answer is ... YES!!! Whether you have time for tournament chess, postal
+or both, a membership in USCF helps make you a stronger chess player while
+also bringing you into contact with other chess players world-wide. You
+can play chess all your life, with family, friends, and fellow tournament
+players. Chess is a sport that can give you lifelong satisfaction, and
+USCF gives you a great opportunity to learn, play, and make new friends
+along the way. :)
+
--- /dev/null
+
+variables
+
+Usage: variables [user]
+
+ This command will display the variables of the given user. If no user is
+given then your variable settings will be displayed. Here are the variables
+that will be displayed.
+
+VARIABLE INFORMATION
+
+ Name Function
+ ---- --------
+ automail If non-zero, the moves of your games will be mailed to you
+ upon completion; your e-mail address will be used (make sure it
+ is correct; if not, contact an admin).
+ bell If non-zero, a ^G or bell will be sent when a board update
+ is done. In most cases, you will hear a beep.
+ cshout If non-zero, you will hear cshouts. If zero, you will not.
+ f1-f9 Special variables for the formula.
+ flip If is non-zero, rotates the board the opposite way (for
+ example, instead of White at the bottom, Black will be at the
+ bottom).
+ formula The formula used to filter match requests, that is, decline
+ them automatically.
+ gin If non-zero, you will be notified when games begin or end.
+ height Sets the number of lines of text you will receive before a
+ [next] break occurs; usually the screen height.
+ highlight If non-zero, player's names who tell you stuff will be
+ highlighted.
+ jprivate If non-zero, the user's journal cannot be read by others. If
+ zero, it is open to be read by other users.
+ kibitz If non-zero, you will hear kibitz's from observers of your
+ games.
+ kiblevel Limits kibitzes and whispers you will receive to users who have
+ the given rating or higher. Value is reset to 0 when you
+ logout.
+ language Selects a help file in this language, if available. The default
+ is English. Spanish is also available.
+ mailmess If non-zero, messages to you will be mailed to your e-mail
+ address automatically.
+ notifiedby If non-zero, you will be notified by the server when users
+ having you on their notify lists log on/off. If zero, you will
+ not receive such notifications. Use of notifiedby can cut down
+ on the size of notify lists (see "notify" help file for
+ details).
+ open If non-zero, you are willing to accept match requests. If
+ zero, you will not receive match requests.
+ pin If non-zero, you will be informed when any user connects to or
+ disconnects from the server.
+ pgn If non-zero, mails games to you in PGN format. If zero,
+ regular, column format will be used.
+ private If non-zero, then all games you play will be private regardless
+ of your opponent's 'private' variable; no observers will be
+ permitted.
+ prompt This string will be your prompt. Use 'set prompt' to restore
+ the system default. (Caution: some graphics interfaces may need
+ certain prompts in order to work correctly.)
+ rated If zero, your game will not be rated.
+ If non-zero, and all of these conditions hold, then your game
+ will be rated:
+ 1: Your opponent's rated variable is non-zero
+ 2: The time controls for the game qualify as a rated game
+ 3: There are no time-odds
+ 4: The game started position is standard.
+ ropen If zero, you will only be open to match requests from users who
+ have the same setting for "rated". If non-zero, you will
+ receive other requests as well.
+ shout If non-zero, you will hear shouts. If zero, you will not.
+ simopen If non-zero, you are willing to accept simul requests. This
+ variable is always set to 0 when you log in.
+ style The style of board to use.
+ tell If non-zero, you will hear tell's and say's from unregistered
+ users. If zero, you will not.
+ width Sets the width of your display (from 32 to 240).
+ 1-10 This sets your information that is displayed when someone
+ fingers you. You can set these 'notes' to an arbitrary string
+ of length 100. You can display information in ten slots,
+ numbered 1-10.
+
+See Also: bell cshout finger flip formula highlight journal kibitz
+kiblevel notes private set shout simuls style tell
+
+[Last modified: December 25, 1995 -- Friar]
+
--- /dev/null
+
+whenshut
+
+Usage: whenshut
+
+ Using this command will display the time when a shutdown will occur. If
+there is no shutdown of the server scheduled, the message displayed will be
+"No shutdown currently in progress".
+
+See Also:
+
+[Last modified: November 26, 1995 -- Friar]
+
--- /dev/null
+
+whisper
+
+Usage: whisper message
+LIMITED TO REGISTERED USERS
+
+ Sends your message to all the observers of a game but NOT to the players.
+For this reason, using whisper (rather than kibitz) is a more polite way of
+discussing a game with other observers without having your message heard by
+the two players. (Only users with a 'kiblevel' variable setting might not
+receive your message.) You must be observing or playing a game in order to
+use this command. The standard alias for "whisper" is '#'.
+
+See Also: alias censor kibitz kiblevel variable
+
+[Last modified: December 17, 1995 -- Friar]
+
--- /dev/null
+
+who
+
+Usage: who [o][r][f][a][R][U][s][b][L][A][l][t][v][n][1-3][B]
+
+ Displays a list of users who are connected to the server according to the
+parameters you give. Typing "who" alone, without any arguments, will list all
+users according to their blitz ratings.
+
+USERS TO DISPLAY
+ o: Only open players.
+ r: Only players for rated matches.
+ f: Only free players (not playing a game).
+ a: Only available players (open & free).
+ R: Only registered players.
+ U: Only unregistered players.
+ #: Only the top (1), middle (2) or lower (3) third of users.
+ B: Only users with bughouse partners set.
+
+ORDER OF DISPLAY
+ s: Standard rating.
+ b: Blitz rating.
+ L: Lightning rating.
+ A: Lists players alphabetically.
+ l: Same as above but without rating/game info. [lower case "L"]
+
+FORMAT OF DISPLAY
+ t: Terse.
+ v: Verbose.
+ n: Win-loss record.
+
+ For example, "who aRsA" would display an alphabetical listing (A) of
+registered players (R) who are available for matches (a) along with their
+ratings from games using standard time controls (s). NOTE: both the capital
+letters and the order of the options are important, but you *may* use spaces
+between the various letters.
+
+
+THE REGULAR (terse) DISPLAY
+
+ The following table is an example of what the "who" request will display.
+(Only a portion of a much larger listing is given here.)
+
+2255^OldManII(C) 1879 Chopin 1625:Flash 1251:Juan
+2163 Heringer 1838^asu 1612 Lesiege ---- Jerard
+2099^AmacaballoFat 1799^Kael 1587:Boutros ----:Tomato(TD)
+2084^Torr 1783:GARP 1572^chessnut ++++:arc
+2074:loon(*) 1774:grimm 1556#jethro ++++^ASESINO
+2072 death(FM) 1760:Tsang 1555.billard ++++.beto
+
+ The format is <rating> <status> <handle>.
+
+Rating: Only one set of ratings are displayed -- the default is blitz unless
+ another rating is requested. The entry ---- means this user is registered
+ but does not have a rating for this type of chess. The entry ++++ means
+ that the user is unregistered and thus has no rating.
+
+Status codes:
+ ^ involved in a game
+ ~ running a simul match
+ : not open for a match
+ # examining a game
+ . inactive for 5 minutes or longer
+ not busy
+
+Special handle codes:
+ * admin
+ B blindfold account
+ C computer account
+ T team account
+ TD Tournament Director program
+ FM/IM/GM titles for international chess masters
+
+
+THE VERBOSE DISPLAY
+
+ The following table shows sample entries from a "who v" request -- where the
+"v" means "verbose" style of the "who" command. A complete display, of
+course, would be rather long ... one line for each user logged on who fits the
+parameters of the who request..
+
+ +---------------------------------------------------------------+
+ | User Standard Blitz On for Idle |
+ +---------------------------------------------------------------+
+ | 22 OldManII 2172 2256 4:09 |
+ | 40 u Torr ---- 2084 14 |
+ | X loon 2015 2074 11 |
+ | 35 Chopin ---- 1879 4 |
+ | Xu Juan 1336 1251 20 19 |
+ | 4 U ASESINO ++++ ++++ 18 |
+ | |
+ | 95 Players Displayed |
+ +---------------------------------------------------------------+
+
+Going from left to right in the display:
+
+ ## -- the number of the game the user is playing
+ X -- not open for games
+ u -- open for unrated games only
+ U -- unregistered player
+ <name> -- the player's "handle"
+ Standard rating -- the player's rating from standard games
+ Blitz rating -- the player's rating from blitz games
+ On for -- (in hours/minutes) how long the player has been on
+ Idle -- (in hours/minutes) how the player has been idle
+ Players Displayed -- the number of current users fitting the who request
+
+
+THE WIN-LOSS RECORD DISPLAY
+
+ The format for the win-loss record display is simple. Here is an example:
+
+Name Stand win loss draw Blitz win loss draw idle
+---------------- ----- ------------- ----- ------------- ----
+<user> ---- 0 0 0 2018 92 56 26 10
+
+ The order is again by blitz, unless specified otherwise. This information
+is also available on an individual basis by using the "finger" command.
+
+
+See Also: blindfold blitz bughouse computers examine finger
+intro_information observe ratings team
+
+[Last modified: December 25, 1995 -- Friar]
+
--- /dev/null
+
+wild
+
+ Wild is a little different than the other categories of boards in that
+the starting positions are non-standard. Because wild games are fundamentally
+different than regular chess, they are rated separately from blitz and
+standard chess games. The wild ratings, however, do not take into account the
+time controls; all wild games are rated on the same basis.
+
+ Here are the major variations of wild that are rated:
+
+Style 1: In this variant both sides have the same set of pieces as in normal
+chess. The white king starts on d1 or e1 and the black king starts on d8 or
+e8, and the rooks are in their usual positions. Bishops are always on
+opposite colors. Subject to these constraints the position of the pieces on
+their first ranks is random. Castling is done similarly to normal chess: o-o-
+o indicates long castling and o-o short castling.
+
+Style 2: In this variant the usual set of pieces is arranged randomly on the
+first and eighth ranks, with the constraint that Black's arrangement is always
+a mirror image of White's. Castling is not allowed.
+
+Style 3: In this variant the set of pieces is randomly chosen (subject to the
+constraint that there is one king of each color). It is quite possible to get
+more than the normal number of a given piece, such as three rooks or two
+queens. The pieces are placed on the first rank behind the pawns, the
+position of Black's pieces mirrors White's placement, and castling is not
+allowed.
+
+Style 4: In this variant a random set of pieces is generated. These pieces
+are placed randomly for White and Black behind the rank of pawns, subject to
+the constraint that the bishops must be balanced.
+
+Style 5: In this variant, each player has the usual set of pieces. However,
+they are placed in a very unusal position. Pawns start on their 7th rank
+rather than their 2nd rank! They are, therefore, one move away from becoming
+queens. The pieces are placed on their 8th rank rather than the 1st rank.
+When the game starts, it will look like the board is upside down, with White's
+pieces starting on Black's side of the board, and vice versa. But don't let
+this fool you.
+
+See Also: boards match
+
+[Last modified: September 11, 1995 -- Friar]
+
--- /dev/null
+
+withdraw
+
+Usage: withdraw [1-n, all, abort, adjourn, draw, match, pause, player, simul,
+switch, takeback]
+
+ Withdraws an offer that you have made to another user. If no parameter is
+given and there is only one offer, the withdraw command with rescind your
+offer. If you have more than one offer pending (for example multiple match
+offers) then you must specify which offer you want to withdraw. You can
+choose the offer by number, by type, all offers, or by the player's name to
+whom you have made the offer. For example, the command "withdraw match" will
+decline all pending match offers you have made. The command "withdraw Shane"
+will withdraw the offer you made to Shane.
+
+NOTE: Several types of requests are withdrawn automatically in certain
+situations. For example, if you have made a match request to user2 but then
+accept a match request from user1, FICS starts your match with user1 and
+withdraws your offer to user2; user2 is notified that you have started another
+match.
+
+See Also: abort accept adjourn draw match pause pending simul switch
+takeback
+
+[Last modified: June 20, 1995 -- Friar]
+
--- /dev/null
+
+wname
+
+Usage: bname <name>
+
+This command sets the white players name shown in the current game you
+are playing or examining.
+
--- /dev/null
+
+xtell
+
+Usage: xtell user message
+
+ The "xtell" command sends a message to a user, just like "tell" does.
+However, "xtell" will not alter the setting for who-you-told-last. A "tell"
+sends a message *and* resets the who-you-told-last variable to a new user.
+The "xtell" command will leave this setting intact, meaning that you can still
+use the "." alias to "tell" to a person you are having a conversation with.
+The "xtell" command allows for a brief comment to someone while you are having
+a longer chat with someone else.
+
+SPECIAL NOTES:
+
+(a) Xtell works only with tells to players, not to channels.
+
+See Also: alias tell
+
+[Last modified: October 8, 1995 -- Friar]
+
--- /dev/null
+
+znotify
+
+Usage: znotify
+
+ Lists all users currently logged on who: (a) are on your notify list, and
+(b) have you on their notify lists. Two separate lists are displayed. See
+the notify command and notifiedby variable for information about what being on
+these lists means. An alias for "znotify" is "znotl".
+
+See Also: alias notify unnotify variables
+
+[Last modified July 1, 1995 -- Friar]
+
--- /dev/null
+/logout/1.1/Mon Jun 10 08:05:27 2002//
+/logout.fancy/1.1/Mon Jun 10 08:05:27 2002//
+/motd/1.1/Mon Jun 10 08:05:27 2002//
+/unregistered/1.1/Mon Jun 10 08:05:27 2002//
+/welcome/1.2/Wed Jun 12 01:04:05 2002//
+/login/1.2/Sat Jun 29 00:06:13 2002//
+/admotd/1.3/Mon Jul 1 01:36:40 2002//
+D
--- /dev/null
+lasker/data/messages
--- /dev/null
+
+This is the admin message of the day
+
+ Admin command helpfiles are shown by ahelp. Try 'ahelp commands' for
+ a list of administrative commands.
+__________________________________________________________________________
--- /dev/null
+
+If you are not a registered player enter the login name "guest"
--- /dev/null
+
+Thank you for using a Free (GNU) Internet Chess server.
+
--- /dev/null
+
+ .::.
+ _()_ _::_
+ _O _/____\_ _/____\_ _O
+ _ _ _ ^^__ / //\ \ / \ / / //\ ^^__ _ _ _
+| || || | / - \_ { } \____/ \____/ { } / - \_ | || || |
+|_______|<| __< \___/ (____) (____) \___/ <| __< |_______|
+\__ ___ /<| \ (___) | | | | (___) <| \ \__ ___ /
+ |___|_| <| _ \ |_| |__| |__| _|_| <|_ \ |___|_|
+ |_|(_)| <|__(_)_\ /(_)\ /(_) \ (_) \ (_) \ <(_)____\ (_)|___|
+ |_(___) _|(___)_ ((___)) ((___)_) (___)__) (___)__) (___)__|_(___)_|_|
+(_ _|_|_)(_ _|_|_ )( _|_|_ )(__|_|_ _) _|_|____)_|_|____)_|_|_ ___)|_|_____)
+/_(_____)/_(_____)\/(_____)\/(_____)_\(_____)__(_____)__(_____)__(_____)___\
+ /_____\ /_____\ /_____\ /_____\ /_____\ /_____\ /_____\ /_____\
+
+ (Logout screen by Alefith)
+
+Thank you for using a Free (GNU) Internet Chess server.
+
--- /dev/null
+__________________________________________________________________________
+Do 'help' for a list of the commands that are available.
+Do 'help admins' for admin information, "=admin" for a list of all admins.
+Do 'help ficsfaq' for answers to frequently asked questions.
+__________________________________________________________________________
+
--- /dev/null
+
+Newcomers:
+ type 'help intro0' for a gentle introduction.
+ type 'help register' to get a registered account.
+ Foul or abusive named guests may be 'nuked' without warning!!
--- /dev/null
+
+ _ __ __ __
+ | | / /__ / /________ ____ ___ ___ / /_____
+ | | /| / / _ \/ / ___/ __ \/ __ `__ \/ _ \ / __/ __ \
+ | |/ |/ / __/ / /__/ /_/ / / / / / / __/ / /_/ /_/ /
+ |__/|__/\___/_/\___/\____/_/ /_/ /_/\___/ \__/\____/
+ ^^__ _ _ _
+ / - \_ | || || |
+ <| __< YOUR CHESS SERVER NAME HERE |_______|
+ <| \ \__ ___ /
+ <| \ |___|_|
+ <|______\ |_|___|
+ _|____|_ |___|_|
+ (________) (_______)
+ /________\ /_______\
+
+
--- /dev/null
+/newratings_data/1.1/Thu Jun 6 08:56:56 2002//
+D
--- /dev/null
+lasker/data/stats
--- /dev/null
+/abort/1.1/Sun Jun 23 07:29:41 2002//
+/accept/1.1/Sun Jun 23 07:29:41 2002//
+/acheckhelp/1.1/Sun Jun 23 07:51:16 2002//
+/aconfig/1.1/Sun Jun 23 07:51:16 2002//
+/addcomment/1.1/Sun Jun 23 07:29:41 2002//
+/addlist/1.1/Sun Jun 23 07:29:41 2002//
+/addplayer/1.1/Sun Jun 23 07:29:41 2002//
+/adjourn/1.1/Sun Jun 23 07:29:41 2002//
+/adjudicate/1.1/Sun Jun 23 07:29:41 2002//
+/admin/1.1/Sun Jun 23 07:29:41 2002//
+/adump/1.1/Sun Jun 23 07:51:16 2002//
+/ahelp/1.1/Sun Jun 23 07:29:41 2002//
+/alias/1.1/Sun Jun 23 07:29:41 2002//
+/allobservers/1.1/Sun Jun 23 07:29:41 2002//
+/anews/1.1/Sun Jun 23 07:29:41 2002//
+/announce/1.1/Sun Jun 23 07:29:41 2002//
+/annunreg/1.1/Sun Jun 23 07:29:41 2002//
+/areload/1.1/Sun Jun 23 07:51:16 2002//
+/asetadmin/1.1/Sun Jun 23 07:29:41 2002//
+/asetblitz/1.1/Sun Jun 23 07:29:41 2002//
+/asetbughouse/1.1/Sun Jun 23 07:29:41 2002//
+/asetclock/1.1/Sun Jun 23 07:29:41 2002//
+/asetemail/1.1/Sun Jun 23 07:29:41 2002//
+/asethandle/1.1/Sun Jun 23 07:29:41 2002//
+/asetlight/1.1/Sun Jun 23 07:29:41 2002//
+/asetmaxplayer/1.1/Sun Jun 23 07:29:41 2002//
+/asetpasswd/1.1/Sun Jun 23 07:29:41 2002//
+/asetrealname/1.1/Sun Jun 23 07:29:41 2002//
+/asetstd/1.1/Sun Jun 23 07:29:41 2002//
+/asetsuicide/1.1/Sun Jun 23 07:29:41 2002//
+/asetv/1.1/Sun Jun 23 07:29:41 2002//
+/asetwild/1.1/Sun Jun 23 07:29:41 2002//
+/assess/1.1/Sun Jun 23 07:29:41 2002//
+/backward/1.1/Sun Jun 23 07:29:41 2002//
+/bell/1.1/Sun Jun 23 07:29:41 2002//
+/best/1.1/Sun Jun 23 07:29:41 2002//
+/bname/1.1/Sun Jun 23 07:29:41 2002//
+/boards/1.1/Sun Jun 23 07:29:41 2002//
+/bsetup/1.1/Sun Jun 23 07:29:41 2002//
+/bugwho/1.1/Sun Jun 23 07:29:41 2002//
+/canewsf/1.1/Sun Jun 23 07:29:41 2002//
+/canewsi/1.1/Sun Jun 23 07:29:41 2002//
+/cbest/1.1/Sun Jun 23 07:29:41 2002//
+/chkgame/1.1/Sun Jun 23 07:29:41 2002//
+/chkip/1.1/Sun Jun 23 07:29:41 2002//
+/chkpl/1.1/Sun Jun 23 07:29:41 2002//
+/chksc/1.1/Sun Jun 23 07:29:41 2002//
+/chkts/1.1/Sun Jun 23 07:29:41 2002//
+/clearmessages/1.1/Sun Jun 23 07:29:41 2002//
+/clrsquare/1.1/Sun Jun 23 07:29:41 2002//
+/cnewsf/1.1/Sun Jun 23 07:29:41 2002//
+/cnewsi/1.1/Sun Jun 23 07:29:41 2002//
+/copygame/1.1/Sun Jun 23 07:29:41 2002//
+/crank/1.1/Sun Jun 23 07:29:41 2002//
+/cshout/1.1/Sun Jun 23 07:29:41 2002//
+/date/1.1/Sun Jun 23 07:29:41 2002//
+/decline/1.1/Sun Jun 23 07:29:41 2002//
+/draw/1.1/Sun Jun 23 07:29:41 2002//
+/eco/1.1/Sun Jun 23 07:29:41 2002//
+/examine/1.1/Sun Jun 23 07:29:41 2002//
+/finger/1.1/Sun Jun 23 07:29:41 2002//
+/flag/1.1/Sun Jun 23 07:29:41 2002//
+/flip/1.1/Sun Jun 23 07:29:41 2002//
+/fmessage/1.1/Sun Jun 23 07:29:41 2002//
+/follow/1.1/Sun Jun 23 07:29:41 2002//
+/forward/1.1/Sun Jun 23 07:29:41 2002//
+/ftell/1.1/Sun Jun 23 07:29:41 2002//
+/games/1.1/Sun Jun 23 07:29:41 2002//
+/getgi/1.1/Sun Jun 23 07:51:16 2002//
+/getpi/1.1/Sun Jun 23 07:51:16 2002//
+/ginfo/1.1/Sun Jun 23 07:29:41 2002//
+/goboard/1.1/Sun Jun 23 07:29:41 2002//
+/handles/1.1/Sun Jun 23 07:29:41 2002//
+/hbest/1.1/Sun Jun 23 07:29:41 2002//
+/help/1.1/Sun Jun 23 07:29:42 2002//
+/hideinfo/1.1/Sun Jun 23 07:29:42 2002//
+/history/1.1/Sun Jun 23 07:29:42 2002//
+/hrank/1.1/Sun Jun 23 07:29:42 2002//
+/inchannel/1.1/Sun Jun 23 07:29:42 2002//
+/info/1.1/Sun Jun 23 07:29:42 2002//
+/iset/1.1/Sun Jun 23 07:51:16 2002//
+/it/1.1/Sun Jun 23 07:29:42 2002//
+/jkill/1.1/Sun Jun 23 07:29:42 2002//
+/journal/1.1/Sun Jun 23 07:29:42 2002//
+/jsave/1.1/Sun Jun 23 07:29:42 2002//
+/kibitz/1.1/Sun Jun 23 07:29:42 2002//
+/limits/1.1/Sun Jun 23 07:29:42 2002//
+/llogons/1.1/Sun Jun 23 07:29:42 2002//
+/logons/1.1/Sun Jun 23 07:29:42 2002//
+/ltell/1.1/Sun Jun 23 07:51:16 2002//
+/mailhelp/1.1/Sun Jun 23 07:29:42 2002//
+/mailmess/1.1/Sun Jun 23 07:29:42 2002//
+/mailmoves/1.1/Sun Jun 23 07:29:42 2002//
+/mailoldmoves/1.1/Sun Jun 23 07:29:42 2002//
+/mailstored/1.1/Sun Jun 23 07:29:42 2002//
+/match/1.1/Sun Jun 23 07:29:42 2002//
+/messages/1.1/Sun Jun 23 07:29:42 2002//
+/mexamine/1.1/Sun Jun 23 07:29:42 2002//
+/moretime/1.1/Sun Jun 23 07:29:42 2002//
+/moves/1.1/Sun Jun 23 07:29:42 2002//
+/news/1.1/Sun Jun 23 07:29:42 2002//
+/next/1.1/Sun Jun 23 07:29:42 2002//
+/nuke/1.1/Sun Jun 23 07:29:42 2002//
+/observe/1.1/Sun Jun 23 07:29:42 2002//
+/oldmoves/1.1/Sun Jun 23 07:29:42 2002//
+/oldpstat/1.1/Sun Jun 23 07:29:42 2002//
+/open/1.1/Sun Jun 23 07:29:42 2002//
+/partner/1.1/Sun Jun 23 07:29:42 2002//
+/password/1.1/Sun Jun 23 07:29:42 2002//
+/pause/1.1/Sun Jun 23 07:29:42 2002//
+/pending/1.1/Sun Jun 23 07:29:42 2002//
+/pfollow/1.1/Sun Jun 23 07:29:42 2002//
+/play/1.1/Sun Jun 23 07:29:42 2002//
+/pobserve/1.1/Sun Jun 23 07:29:42 2002//
+/pose/1.1/Sun Jun 23 07:29:42 2002//
+/prefresh/1.1/Sun Jun 23 07:29:42 2002//
+/primary/1.1/Sun Jun 23 07:29:42 2002//
+/promote/1.1/Sun Jun 23 07:29:42 2002//
+/pstat/1.1/Sun Jun 23 07:51:16 2002//
+/ptell/1.1/Sun Jun 23 07:29:42 2002//
+/ptime/1.1/Sun Jun 23 07:29:42 2002//
+/qtell/1.1/Sun Jun 23 07:51:16 2002//
+/quit/1.1/Sun Jun 23 07:29:42 2002//
+/quota/1.1/Sun Jun 23 07:29:42 2002//
+/raisedead/1.1/Sun Jun 23 07:29:42 2002//
+/rank/1.1/Sun Jun 23 07:29:42 2002//
+/refresh/1.1/Sun Jun 23 07:29:42 2002//
+/rematch/1.1/Sun Jun 23 07:29:42 2002//
+/remplayer/1.1/Sun Jun 23 07:29:42 2002//
+/rerank/1.1/Sun Jun 23 07:29:42 2002//
+/resign/1.1/Sun Jun 23 07:29:42 2002//
+/resume/1.1/Sun Jun 23 07:29:42 2002//
+/revert/1.1/Sun Jun 23 07:29:42 2002//
+/say/1.1/Sun Jun 23 07:29:42 2002//
+/seek/1.1/Sun Jun 23 07:29:42 2002//
+/set/1.1/Sun Jun 23 07:29:42 2002//
+/shout/1.1/Sun Jun 23 07:29:42 2002//
+/showcomment/1.1/Sun Jun 23 07:29:42 2002//
+/showlist/1.1/Sun Jun 23 07:29:42 2002//
+/shutdown/1.1/Sun Jun 23 07:29:42 2002//
+/simabort/1.1/Sun Jun 23 07:29:42 2002//
+/simadjourn/1.1/Sun Jun 23 07:29:42 2002//
+/simallabort/1.1/Sun Jun 23 07:29:42 2002//
+/simalladjourn/1.1/Sun Jun 23 07:29:42 2002//
+/simgames/1.1/Sun Jun 23 07:29:42 2002//
+/simmatch/1.1/Sun Jun 23 07:29:42 2002//
+/simnext/1.1/Sun Jun 23 07:29:42 2002//
+/simopen/1.1/Sun Jun 23 07:29:42 2002//
+/simpass/1.1/Sun Jun 23 07:29:42 2002//
+/simprev/1.1/Sun Jun 23 07:29:42 2002//
+/smoves/1.1/Sun Jun 23 07:29:42 2002//
+/smposition/1.1/Sun Jun 23 07:29:42 2002//
+/sought/1.1/Sun Jun 23 07:29:42 2002//
+/sposition/1.1/Sun Jun 23 07:29:42 2002//
+/statistics/1.1/Sun Jun 23 07:29:42 2002//
+/stored/1.1/Sun Jun 23 07:29:42 2002//
+/style/1.1/Sun Jun 23 07:29:42 2002//
+/sublist/1.1/Sun Jun 23 07:29:42 2002//
+/summon/1.1/Sun Jun 23 07:29:42 2002//
+/switch/1.1/Sun Jun 23 07:29:42 2002//
+/takeback/1.1/Sun Jun 23 07:29:42 2002//
+/tell/1.1/Sun Jun 23 07:29:42 2002//
+/time/1.1/Sun Jun 23 07:29:42 2002//
+/toggle/1.1/Sun Jun 23 07:51:16 2002//
+/tomove/1.1/Sun Jun 23 07:29:42 2002//
+/tournset/1.1/Sun Jun 23 07:51:16 2002//
+/unalias/1.1/Sun Jun 23 07:29:42 2002//
+/unexamine/1.1/Sun Jun 23 07:29:42 2002//
+/unobserve/1.1/Sun Jun 23 07:29:42 2002//
+/unpause/1.1/Sun Jun 23 07:29:42 2002//
+/unseek/1.1/Sun Jun 23 07:29:42 2002//
+/uptime/1.1/Sun Jun 23 07:29:42 2002//
+/ustat/1.1/Sun Jun 23 07:29:42 2002//
+/variables/1.1/Sun Jun 23 07:29:42 2002//
+/whenshut/1.1/Sun Jun 23 07:29:42 2002//
+/whisper/1.1/Sun Jun 23 07:29:42 2002//
+/who/1.1/Sun Jun 23 07:29:42 2002//
+/withdraw/1.1/Sun Jun 23 07:29:42 2002//
+/wname/1.1/Sun Jun 23 07:29:42 2002//
+/xkibitz/1.1/Sun Jun 23 07:29:42 2002//
+/xtell/1.1/Sun Jun 23 07:29:42 2002//
+/xwhisper/1.1/Sun Jun 23 07:29:42 2002//
+/znotify/1.1/Sun Jun 23 07:29:42 2002//
+/canewsd/1.1/Mon Jun 24 11:13:01 2002//
+/canewse/1.1/Mon Jun 24 11:13:01 2002//
+/canewsp/1.1/Mon Jun 24 11:13:01 2002//
+/canewst/1.1/Mon Jun 24 11:13:01 2002//
+/cnewsd/1.1/Mon Jun 24 11:13:01 2002//
+/cnewse/1.1/Mon Jun 24 11:13:01 2002//
+/cnewsp/1.1/Mon Jun 24 11:13:01 2002//
+/cnewst/1.1/Mon Jun 24 11:13:01 2002//
+/rmatch/1.1/Mon Jul 1 04:11:59 2002//
+D
--- /dev/null
+lasker/data/usage
--- /dev/null
+Command: abort
+Purpose: to request that the game be cancelled
+Usage: abort
+Examples: abort
--- /dev/null
+Command: accept
+Purpose: agree to an offer made by a user or opponent
+Usage: accept [1-n, all, abort, adjourn, draw, match, pause, player,
+ simul, switch, takeback]
+Examples: accept; accept 2; accept draw; accept Shane
--- /dev/null
+ Command: acheckhelp
+ Purpose: check for missing help and usage files
+ Usage: acheckhelp
--- /dev/null
+ Command: aconfig
+ Purpose: display or change a server config option
+ Usage: aconfig; aconfig <variable> <value>
+ Example: aconfig IDLE_TIMEOUT 7200
--- /dev/null
+ Command: addcomment
+ Purpose: place comment in a user's player file
+ Usage: addcomment user comment
+ Examples: addcomment friar warned about misusing channel 1 ... again!
--- /dev/null
+Command: addlist
+Purpose: add information to a list
+Usage: addlist list information
+Alt: +list information
+Examples: addlist noplay Friar; +noplay Friar
--- /dev/null
+ Command: addplayer
+ Purpose: create an account for a user
+ Usage: addplayer playername emailaddress realname
+ Examples: addplayer ColinPapa sms@babyville.net First M. Last
--- /dev/null
+Command: adjourn
+Purpose: to request an adjournment of a game; courtesy_adjourn when
+ opponent is out of time and may have lag problems
+Usage: adjourn
+Examples: adjourn
--- /dev/null
+ Command: adjudicate
+ Purpose: make a decision about a game's result
+ Usage: adjudicate white_player black_player abort|draw|white|black
+ Examples: adjudicate Hawk Sparky draw; adjudicate Hawk Sparky white;
+ adjudicate Hawk Sparky black; adjudicate Hawk Sparky abort
--- /dev/null
+ Command: admin
+ Purpose: toggles your admin symbol (*) on/off
+ Usage: admin
+ Examples: admin
--- /dev/null
+ Command: adump
+ Purpose: dump internal state of server
+ Usage: adump
+
--- /dev/null
+ Command: ahelp
+ Purpose: prints special admin help files
+ Usage: ahelp [topic]
+ Examples: ahelp; ahelp ban
--- /dev/null
+Command: alias
+Purpose: set/edit personal command alias; review alias or all aliases
+Usage: alias [word [string]]
+Examples: alias; alias t1; alias t1 tell 1 @
--- /dev/null
+Command: allobservers
+Purpose: list users currently observing games on the server
+Usage: allobservers [game,user]
+Examples: allobservers; allobservers 43; allobservers Hawk
--- /dev/null
+Command: anews
+Purpose: display anews entries _or_ details about an anews entry
+Usage: anews [all|#[-#]]
+Examples: anews; anews all; anews 27; anews 50-65
--- /dev/null
+ Command: announce
+ Purpose: broadcast message to all users logged on
+ Usage: announce message
+ Examples: announce Type "observe 45" for the world championship game.
--- /dev/null
+ Command: annunreg
+ Purpose: broadcast message to all unregistered users logged on
+ Usage: annunreg message
+ Examples: annunreg Type "help register" for information on how to register.
--- /dev/null
+ Command: areload
+ Purpose: reload server code while running
+ Usage: areload
--- /dev/null
+ Command: asetadmin
+ Purpose: sets admin level of a user (certain restrictions apply)
+ Usage: asetadmin user adminlevel
+ Examples: asetadmin Sparky 10
--- /dev/null
+ Command: asetblitz
+ Purpose: modify the items for a user's blitz finger information
+ Usage: asetblitz user rating wins losses draws RD
+ Examples: asetblitz friar 1209 23 151 0 39.4
--- /dev/null
+ Command: asetbughouse
+ Purpose: modify the items for a user's bughouse finger information
+ Usage: asetbughouse user rating wins losses draws RD
+ Examples: asetbughouse friar 1209 23 151 0 39.4
--- /dev/null
+Command: asetclock
+Purpose: modify the clock time for a user playing a game
+Usage: asetclock <name> hours:minutes:seconds
+Example: asetclock friar 1:05:15
--- /dev/null
+ Command: asetemail
+ Purpose: change the email address of a user
+ Usage: asetemail user [address]
+ Examples: asetemail mlong; asetemail mlong nick@unix.univ.edu
--- /dev/null
+ Command: asethandle
+ Purpose: change the handle of a user
+ Usage: asethandle oldname newname
+ Examples: asethandle StupidName BetterName
--- /dev/null
+ Command: asetlight
+ Purpose: modify the items for a user's lightning finger information
+ Usage: asetlight user rating wins losses draws RD
+ Examples: asetlight friar 1209 23 151 0 39.4
--- /dev/null
+ Command: asetmaxplayer
+ Purpose: changes level at which logons will be restricted
+ Usage: asetmaxplayer level
+ Examples: asetmaxplayer 250
--- /dev/null
+ Command: asetpasswd
+ Purpose: change the password of a user
+ Usage: asetpasswd user {password,*}
+ Examples: asetpasswd Hawk uhwidhl; asetpasswd Friar *
--- /dev/null
+ Command: asetrealname
+ Purpose: change the real name of a user
+ Usage: asetrealname user newname
+ Examples: asetrealname DAV A. W. Kin
--- /dev/null
+ Command: asetstd
+ Purpose: modify the items for a user's standard finger information
+ Usage: asetstd user rating wins losses draws RD
+ Examples: asetstd friar 1209 23 151 0 39.4
--- /dev/null
+ Command: asetsuicide
+ Purpose: modify the items for a user's suicide chess finger information
+ Usage: asetsuicide user rating wins losses draws RD
+ Examples: asetsuicide friar 1209 23 151 0 39.4
--- /dev/null
+ Command: asetv
+ Purpose: change's a user's variable settings for them
+ Usage: asetv user instruction
+ Examples: asetv DAV shout 0; asetv Computer open 0
--- /dev/null
+ Command: asetwild
+ Purpose: modify the items for a user's wild finger information
+ Usage: asetwild user rating wins losses draws RD
+ Examples: asetwild friar 1209 23 151 0 39.4
--- /dev/null
+Command: assess
+Purpose: calculate expected changes to ratings from a chess match
+Usage: assess [game# | user1 [user2
+ [lightning|blitz|standard|suicide|wild]]]
+Examples: assess; assess 23; assess Sparky; assess DAV Thanatos;
+ assess DAV Thanatos standard
--- /dev/null
+Command: backward
+Purpose: move backward in the game sequence as you examine a game
+Usage: backward [#] [default: 1]
+Examples: backward; backward 2
--- /dev/null
+Command: bell
+Purpose: toggles your 'bell' variable on/off (1/0)
+Usage: bell
+Examples: bell
--- /dev/null
+Command: best
+Purpose: list the 20 highest rated players in the ratings categories
+Usage: best [b|s|l|w|B|S] [default: bsl]
+Examples: best; best s
--- /dev/null
+Command: bname
+Purpose: change name of Black player in an examined or setup game
+Usage: bname [string]
+Examples: bname; bname Kotov
--- /dev/null
+Command: boards
+Purpose: list available positions for starting a game
+Usage: boards [category]
+Examples: boards; boards openings
--- /dev/null
+Command: bsetup
+Purpose: begin bsetup mode and execute special bsetup commands
+Usage: bsetup [command]
+Examples: bsetup; bsetup wild 5; bsetup start; bsetup clear; bsetup done
--- /dev/null
+Command: bugwho
+Purpose: lists current bughouse games, partnerships and available partners
+Usage: bugwho [g|p|u]
+Examples: bugwho; bugwho g; bugwho pu
--- /dev/null
+ Command: canewsd
+ Purpose: delete last line of an admin news item
+ Usage: canewsd #
+ Examples: canewsd 180
--- /dev/null
+ Command: canewse
+ Purpose: change expiry of an admin news item
+ Usage: canewse # expiry
+ Examples: canewse 180 2
--- /dev/null
+ Command: canewsf
+ Purpose: changes information for an anews item
+ Usage: canewsf # text
+ Examples: canewsf 25 Users should contact admins for help registering.
--- /dev/null
+ Command: canewsi
+ Purpose: creates an anews item
+ Usage: canewsi headline
+ Examples: canewsi New registration procedures!
--- /dev/null
+ Command: canewsp
+ Purpose: change poster of an admin news item
+ Usage: canewsp #
+ Examples: canewsp 180
--- /dev/null
+ Command: canewst
+ Purpose: change title of an admin news item
+ Usage: canewst # title
+ Examples: canewst 180 Hello everyone!
--- /dev/null
+Command: cbest
+Purpose: displays 20 highest-rated computer players by chess category
+Usage: cbest [b|s|l|w|B|S] [default: bsl]
+Examples: cbest; cbest s
--- /dev/null
+ Command: chkgame
+ Purpose: displays information about a current game
+ Usage: chkgame game#|handle
+ Examples: chkgame 56; chkgame TheDane
--- /dev/null
+ Command: chkip
+ Purpose: display logged users from a given IP address
+ Usage: chkip ip_address|handle
+ Examples: chkip 129.46.4.2; chkip 129*; chkip guest45
--- /dev/null
+
+chkpl
+ Command: chkpl
+ Purpose: check server information about a user
+ Usage: chkpl handle|parray#
+ Examples: chkpl schert; chkpl 20
--- /dev/null
+ Command: chksc
+ Purpose: display which user is in which socket
+ Usage: chksc n
+ Examples: chksc 3
--- /dev/null
+ Command: chkts
+ Purpose: displays all current users who are using timeseal
+ Usage: chkts
+ Examples: chkts
--- /dev/null
+Command: clearmessages
+Purpose: delete one or more stored messages from your message file
+Usage: clearmessages user|#|m-n|* [* will clear all messages]
+Examples: clearmessages Solid; clearmessages 8; clearmessages 3-7;
+ clearmessages *
--- /dev/null
+Command: clrsquare
+Purpose: used in setup mode in order to empty a square (make it blank)
+Usage: clrsquare square
+Examples: clrsquare e4; clrsquare h6
--- /dev/null
+ Command: cnewsd
+ Purpose: delete last line of a regular news item
+ Usage: cnewsd #
+ Examples: cnewsd 180
--- /dev/null
+ Command: cnewse
+ Purpose: change expiry of a regular news item
+ Usage: cnewse # expiry
+ Examples: cnewse 180 2
--- /dev/null
+ Command: cnewsf
+ Purpose: change details of a regular news item
+ Usage: cnewsf # message
+ Examples: cnewsf 180 New interface available. Finger "author".
--- /dev/null
+ Command: cnewsi
+ Purpose: create a regular news item
+ Usage: cnewsi headline
+ Examples: cnewsi New timeseal versions done!
--- /dev/null
+ Command: cnewsp
+ Purpose: change poster of a regular news item
+ Usage: cnewsp #
+ Examples: cnewsp 180
--- /dev/null
+ Command: cnewst
+ Purpose: change title of a regular news item
+ Usage: cnewst # title
+ Examples: cnewst 180 Hello everyone!
--- /dev/null
+Command: copygame
+Purpose: copy a game so that it can be examined
+Usage: copygame [user_name|number|o]
+Examples: copygame Sparky; copygame 7; copygame o; copygame
--- /dev/null
+Command: crank
+Purpose: displays rank (excluding computer accounts) for a player or
+ range of players
+Usage: crank [user [b][s][l][w][B][S]] -OR- crank m-n [b][s][l][w][B][S]
+ -OR- crank m [b][s][l][w][B][S]] [default: bsl]
+Examples: crank; crank 50-100; crank 1800; crank s; crank cyee bs
--- /dev/null
+Command: cshout
+Purpose: send message to users who are open to receive cshouts
+Usage: cshout message
+Examples: cshout Anyone for 2 5 rated?
--- /dev/null
+Command: date
+Purpose: lists both local date/time at the server and GMT date/time
+Usage: date
+Examples: date
--- /dev/null
+Command: decline
+Purpose: decline (turn down) an offer made to you by a user
+Usage: decline [1-n, t all, abort, adjourn, draw, match, pause, player,
+ simul, switch, takeback]
+Examples: decline; decline 2; decline draw; decline cyee
--- /dev/null
+Command: draw
+Purpose: requests (or accepts) a draw offer; it may include a move
+Usage: draw [move]
+Examples: draw; draw Kf7
--- /dev/null
+Command: eco
+Purpose: display the type of opening used in the chess game
+Usage: eco [game, name, e <eco code>, n <nic code>]
+Examples: eco; eco 23; eco Clovis; eco e A5; eco n FR.04
--- /dev/null
+Command: examine
+Purpose: start or review a game under examination mode
+Usage: examine [player1 [player2, game_number, journal_slot] _or_
+ examine b board category
+Examples: examine; examine river; examine TheDane sms; examine McKeork 7;
+ examine loon F; examine b wild 5
--- /dev/null
+Command: finger
+Purpose: display ratings and/or notes about yourself or another user
+Usage: finger [user] [/[b][s][l][w][B][S]] [r][n]
+Examples: finger; finger TheViking; finger TheViking r; finger TheViking n;
+ finger TheViking /wS r
--- /dev/null
+Command: flag
+Purpose: claim a win when your opponent has run out of time
+Usage: flag
+Examples: flag
--- /dev/null
+Command: flip
+Purpose: toggles board display between White-at-bottom and White-at-top
+Usage: flip
+Examples: flip
--- /dev/null
+Command: fmessage
+Purpose: forward a message to a user
+Usage: fmessages user message_# [use # from your message list]
+Examples: fmessage DAV 3
--- /dev/null
+Command: follow
+Purpose: Automatically observe all of a user's games, or cancel this function.
+Usage: follow user; follow
+Examples: follow Binford; follow
--- /dev/null
+Command: forward
+Purpose: move forward in a sequence of moves in a game being examined
+Usage: forward [#] [default: 1]
+Examples: forward; forward 2
--- /dev/null
+Command: ftell
+Purpose: forward tells to channel 0, or cancel this function
+Usage: ftell user_name; ftell
+Examples: ftell idiotUser; ftell
--- /dev/null
+Command: games
+Purpose: display information about games currently in progress
+Usage: games [#, /[bBelsSuw], string] [default: all games]
+Examples: games; games 23; games sv; games sveshi; games /B; games /lw
--- /dev/null
+Command: getgi
+Purpose: used by TD programs only
--- /dev/null
+Command: getpi
+Purpose: used by TD programs only
--- /dev/null
+Command: ginfo
+Purpose: display information about a game being played or examined
+Usage: ginfo name|number
+Examples: ginfo 23; ginfo Clovis
--- /dev/null
+Command: goboard
+Purpose: in a simul match, move to a given player's board
+Usage: goboard player|#
+Examples: goboard Shaughn; goboard 7
--- /dev/null
+Command: handles
+Purpose: lists registered handles beginning with a certain string
+Usage: handles [string]
+Examples: handles; handles g
--- /dev/null
+Command: hbest
+Purpose: displays 20 highest-rated human players by chess category
+Usage: hbest [b|s|l|w|B|S] [default: bsl]
+Examples: hbest; hbest s
--- /dev/null
+Command: help
+Purpose: read a help file
+Usage: help [string]
+Examples: help; help match
--- /dev/null
+ Command: hideinfo
+ Purpose: change from admin to regular display of information
+ Usage: hideinfo
+ Examples: hideinfo
--- /dev/null
+Command: history
+Purpose: displays results of your or another user's recent games
+Usage: history [user]
+Examples: history; history Rattlesnake
--- /dev/null
+Command: hrank
+Purpose: displays rank (excluding computer accounts) for a player or
+ range of players
+Usage: hrank [user [b][s][l][w][B][S]] -OR- hrank m-n [b][s][l][w][B][S]
+ -OR- hrank m [b][s][l][w][B][S]] [default: bsl]
+Examples: hrank; hrank 50-100; hrank 1800; hrank s; hrank cyee bs
--- /dev/null
+Command: inchannel
+Purpose: lists the channels a user is in, or who is in a given channel, or
+ all users in a range of chanels, or all users in all channels
+Usage: inchannel [user|m[-n]]
+Examples: inchannel; inchannel Solid; inchannel 1; inchannel 90-95
--- /dev/null
+Command: info
+Purpose: list the information (non-command) help files
+Usage: info
+Examples: info
--- /dev/null
+Command: iset
+Purpose: set a interface variable
+Usage: iset variable_name [value]
--- /dev/null
+Command: it
+Purpose: send message to users open to receive shouts
+Usage: it message
+Examples: it thinks internet chess is wonderful!
--- /dev/null
+Command: jkill
+Purpose: erase games from your journal
+Usage: jkill slot
+Examples: jkill A; jkill L
--- /dev/null
+Command: journal
+Purpose: display contents of a journal
+Usage: journal [handle]
+Examples: journal; journal DAV
--- /dev/null
+Command: jsave
+Purpose: save games to your journal
+Usage: jsave slot [game_number | user_name [game_number | journal_slot |
+ user_name]]
+Examples: jsave A; jsave D 34; jsave F Friar 3; jsave C Sparky L;
+ jsave J jross bozky
--- /dev/null
+Command: kibitz
+Purpose: send message to all players and observers of a chess match
+Usage: kibitz message
+Examples: kibitz What about Bxc6???
--- /dev/null
+Command: limits
+Purpose: display current server limits and settings
+Usage: limits
+Examples: limits
--- /dev/null
+Command: llogons
+Purpose: lists recent logons and logoffs for the server
+Usage: llogons
+Examples: llogons
--- /dev/null
+Command: logons
+Purpose: lists recent logons/logoffs for the user
+Usage: logons [user]
+Examples: logons; logons Friar
--- /dev/null
+Command: ltell
+Purpose: send a message to a list of users
+Usage: ltell list message
+Examples: ltell computer hello to all our silicon buddies
--- /dev/null
+Command: mailhelp
+Purpose: email a help file to you (or show files that can be emailed)
+Usage: mailhelp [filename]
+Examples: mailhelp; mailhelp intro_welcome
--- /dev/null
+Command: mailmess
+Purpose: email 1 or more of your your stored messages to you
+Usage: mailmess [user|#|#-#]
+Examples: mailmess; mailmess fpawn; mailmess 4; mailmess 7-11
--- /dev/null
+Command: mailmoves
+Purpose: email to you the moves for current game you are involved with
+Usage: mailmoves
+Examples: mailmoves
--- /dev/null
+Command: mailoldmoves
+Purpose: email to you the moves from a completed game
+Usage: mailoldmoves [user]
+Examples: mailoldmoves; mailoldmoves loon
+[NOTE: mailstored is a better command to use]
--- /dev/null
+Command: mailstored
+Purpose: email a stored, history or journal game to you
+Usage: mailstored player1 [#, player2, journal_slot]
+Examples: mailstored Len; mailstored Len 87; mailstored Len fpawn;
+ mailstored Len K
--- /dev/null
+Command: match
+Purpose: challenge a user to a chess match
+Usage: match user [rated|unrated] [Time] [Inc] [Black_Start Black_Inc]
+ [White|Black] [board_category board]
+Examples: match foxbat; match Marsalis 2 15 u
--- /dev/null
+Command: messages
+Purpose: display 1 or more stored messages -OR- send a message to a user
+Usage: messages [user [text]|#|m-n]
+Examples: messages; messages Shane; messages Ramius Thanks for your help!;
+ messages 13; messages 2-9
--- /dev/null
+Command: mexamine
+Purpose: allow another user to examine a game with you
+Usage: mexamine user
+Examples: mexamine connex
--- /dev/null
+Command: moretime
+Purpose: add more seconds to your opponent's clock
+Usage: moretime seconds
+Examples: moretime 90
--- /dev/null
+Command: moves
+Purpose: displays moves to a current game
+Usage: moves [game,user]
+Examples: moves; moves 56; moves Cthulhu
--- /dev/null
+Command: news
+Purpose: list recent news items -OR- display details of a news item
+Usage: news [all|#[-#]]
+Examples: news; news all; news 11; news 35-50
--- /dev/null
+Command: next
+Purpose: display further information from a long text file
+Usage: next
+Examples: next
--- /dev/null
+ Command: nuke
+ Purpose: force a user to disconnect from the server
+ Usage: nuke user
+ Examples: nuke BadUser
--- /dev/null
+Command: observe
+Purpose: add (or remove) a game from your observation list (toggles ON/OFF)
+Usage: observe game|user
+Examples: observe 34; observe GMAnand
--- /dev/null
+Command: oldmoves
+Purpose: display moves of the user's last played chess match
+Usage: oldmoves [user]
+Examples: oldmoves; oldmoves TheDane
+[NOTE: smoves is a better command to use]
--- /dev/null
+Command: pstat
+Purpose: display previous results between two users
+Usage: pstat [user1 [user2]]
+Examples: pstat; pstat Sparky; pstat DAV Thanatos;
--- /dev/null
+Command: open
+Purpose: toggles your open variable on/off (1/0)
+Usage: open
+Examples: open
--- /dev/null
+Command: partner
+Purpose: ask a user to be your bughouse partner; remove partner setting
+Usage: partner handle; partner
+Examples: partner Rattlesnake; partner
--- /dev/null
+Command: password
+Purpose: change your current server password to a new password
+Usage: password oldpassword newpassword
+Examples: password old new
--- /dev/null
+Command: pause
+Purpose: requests (or accepts) a pause during a chess match
+Usage: pause
+Examples: pause
--- /dev/null
+Command: pending
+Purpose: lists all your non-declined offers from and made to users
+Usage: pending
+Examples: pending
--- /dev/null
+Command: pfollow
+Purpose: Automatically observe all of a user's partner's bughouse games.
+Usage: pfollow user; pfollow
+Examples: pfollow Binford; pfollow
--- /dev/null
+Command: play\r
+Purpose: respond to an ad (from 'sought' display)\r
+Usage: play index_#|handle\r
+Examples: play 5; play Rattlesnake\r
--- /dev/null
+Command: pobserve
+Purpose: observe bughouse games of a user's partner
+Usage: pobserve user
+Examples: pobserve GMAnand
--- /dev/null
+ Command: pose
+ Purpose: execute a command on behalf of a user
+ Usage: pose user command
+ Examples: pose Friar tell 0 Huzzah!
--- /dev/null
+Command: prefresh
+Purpose: refresh (display) your bughouse partner's game
+Usage: prefresh
+Examples: prefresh
--- /dev/null
+Command: primary
+Purpose: designate which game is 'primary' for purposes of observation
+Usage: primary name|#
+Examples: primary DAV; primary 21
--- /dev/null
+Command: promote
+Purpose: set the piece a pawn will be promoted to at the back rank
+Usage: promote {q,r,b,[kn], ki}
+Examples: promote q; promote b
--- /dev/null
+Command: pstat
+Purpose: show game stats between two players
+Usage: pstat <user>; pstat <user1> <user2>
+Examples: pstat knighttour; pstat freddy knighttour
--- /dev/null
+Command: ptell
+Purpose: send a message to your bughouse partner
+Usage: ptell string
+Examples: ptell Can you get me a pawn?
--- /dev/null
+Command: ptime
+Purpose: display the clock times in your bughouse partner's game
+Usage: ptime
+Examples: ptime
--- /dev/null
+Command: qtell
+Purpose: used by TD programs only
--- /dev/null
+Command: quit
+Purpose: exit the server (when you are not playing a match)
+Usage: quit
+Examples: quit
--- /dev/null
+ Command: quota
+ Purpose: sets number of seconds in the shout quota
+ Usage: quota n
+ Examples: quota 30
--- /dev/null
+ Command: raisedead
+ Purpose: restores an account that had been removed using "remplayer"
+ Usage: raisedead oldname [newname]
+ Examples: raisedead Anibus; raisedead Xman Xwoman
--- /dev/null
+Command: rank
+Purpose: display rank for user, rating or range of users by rank
+Usage: rank [user [b][s][l][w][B][S]] -OR- rank m-n [b][s][l][w][B][S] -OR-
+ rank m [b][s][l][w][B][S]] [default: bsl]
+Examples: rank; rank zippy; rank 50-100; rank 1800; rank sB
--- /dev/null
+Command: refresh
+Purpose: display the position and time of a game you are involved with
+Usage: refresh [game|name]
+Examples: refresh; refresh 45; refresh IanO
--- /dev/null
+Command: rematch
+Purpose: challenge your last opponent to a game of the same type
+Usage: rematch [string]
+Examples: rematch; rematch w5; rematch misc little_game
--- /dev/null
+ Command: remplayer
+ Purpose: remove an account completely
+ Usage: remplayer name
+ Examples: remplayer ByeByeUser
--- /dev/null
+ Command: rerank
+ Purpose: reset a user's rank if there has been an error
+ Usage: rerank user
+ Examples: rerank DAV
--- /dev/null
+Command: resign
+Purpose: give your opponent the win in your current (or stored) game
+Usage: resign [name]
+Examples: resign; resign Sparky
--- /dev/null
+Command: resume
+Purpose: challenge all online users of your adjourned games
+Usage: resume
+Examples: resume
--- /dev/null
+Command: revert
+Purpose: return to the mainline of a chess game being examined (analyzed)
+Usage: revert
+Examples: revert
--- /dev/null
+Command: rmatch
+Purpose: allows tournament directors to start matches
+Usage: rmatch user1 user2 <match params>
--- /dev/null
+Command: say
+Purpose: sends a message to your current or most recent opponent
+Usage: say message
+Examples: say I have terrible lag right now <sigh>.
--- /dev/null
+Command: seek
+Purpose: place an ad for a chess match
+Usage: seek [time inc] [rated|unrated] [white|black] [w#] [auto|manual]
+ [formula] [rating-range]
+Examples: seek; seek 5; seek 5 0; seek r; seek w5; seek 2 12 u m; seek f;
+ seek 1600-1800 m f; seek 10 25 r b w5 m f 2000-9999
--- /dev/null
+Command: set
+Purpose: fix a value of a variable or line in your finger notes
+Usage: set variable_name [value]
+Examples: set shout 0; set time 5; set inc 0; set formula !wild && rated;
+ set 1 G'day! I'm Mark from Perth, Australia.
--- /dev/null
+Command: shout
+Purpose: send message to all users open to receive shouts
+Usage: shout message
+Examples: shout Time to go! Bye-bye!!!
--- /dev/null
+ Command: showcomment
+ Purpose: display the comments in a user's file
+ Usage: showcomment user
+ Examples: showcomment Rattlesnake
--- /dev/null
+Command: showlist
+Purpose: display users who are on special lists
+Usage: showlist [list_name]
+Alt: =[list_name]
+Examples: showlist; =; showlist computer; =computer
--- /dev/null
+ Command: shutdown
+ Purpose: shutdown the server (disconnect it)
+ Usage: shutdown [now,cancel,time] [comment]
+ Examples: shutdown now; shutdown cancel; shutdown 60; shutdown 600 In
+ order to fix bugs that were causing crashes.
--- /dev/null
+Command: simabort
+Purpose: used in simuls to request (or accept) an abort of a game
+Usage: simabort
+Examples: simabort
--- /dev/null
+Command: simadjourn
+Purpose: used in simuls to request (or accept) an adjournment of a game
+Usage: simadjourn
+Examples: simadjourn
--- /dev/null
+Command: simallabort
+Purpose: used in simuls to abort all games in progress
+Usage: simallabort
+Examples: simallabort
--- /dev/null
+Command: simalladjourn
+Purpose: used in simuls to adjourn all games in progress
+Usage: simalladjourn
+Examples: simalladjourn
--- /dev/null
+Command: simgames
+Purpose: display the number of simul games you or another user are in
+Usage: simgames [player]
+Examples: simgames; simgames river
--- /dev/null
+Command: simmatch
+Purpose: used to request a game in a simul event
+Usage: simmatch player
+Examples: simmatch connex
--- /dev/null
+Command: simnext
+Purpose: used in simuls to move to the next board in the simul
+Usage: simnext
+Examples: simnext
--- /dev/null
+Command: simopen
+Purpose: sets yourself open to receive simul challenges
+Usage: simopen
+Examples: simopen
--- /dev/null
+Command: simpass
+Purpose: used in simuls to pass when the simul player reaches your board
+Usage: simpass
+Examples: simpass
--- /dev/null
+Command: simprev
+Purpose: used in simuls to move to the previous board
+Usage: simprev
+Examples: simprev
--- /dev/null
+Command: smoves
+Purpose: display the moves of a stored, history or journal game
+Usage: smoves UserA [#, UserB, journal_slot]
+Examples: smoves TheDane; smoves TheDane 87; smoves TheDane bozky;
+ smoves TheDane J
--- /dev/null
+Command: smposition
+Purpose: display both position and moves for a stored, history or journal
+ game
+Usage: smposition user_a [user_b|history#|journal_slot]
+Examples: smposition Len; smposition Len Loon; smposition Len 86;
+ smposition Len B
--- /dev/null
+Command: sought
+Purpose: display ads that users have made
+Usage: sought [all]
+Examples: sought; sought all
--- /dev/null
+Command: sposition
+Purpose: display position for a stored, history or journal game
+Usage: sposition user_a [user_b|history#|journal_slot]
+Examples: sposition Len; sposition Len Loon; sposition Len 86;
+ sposition Len B
--- /dev/null
+Command: statistics
+Purpose: display summary information about ratings of server players
+Usage: statistics
+Examples: statistics
--- /dev/null
+Command: stored
+Purpose: list your or another user's stored (adjourned) games
+Usage: stored [user]
+Examples: stored; stored Marsalis
--- /dev/null
+Command: style
+Purpose: set the style variable for the board display
+Usage: style n
+Examples: style 12
--- /dev/null
+Command: sublist
+Purpose: removes information from the given list
+Usage: sublist list information
+Alt: -list information
+Examples: sublist notify Friar; -notify Friar
--- /dev/null
+ Command: summon
+ Purpose: give special notice that you want a user to contact you NOW!
+ Usage: summon player
+ Examples: summon Ramius
--- /dev/null
+Command: switch
+Purpose: requests (or accepts) switching sides with your opponent
+Usage: switch
+Examples: switch
--- /dev/null
+Command: takeback
+Purpose: requests (or accepts) taking back one or more moves in a game
+Usage: takeback [n] [default: 1]
+Examples: takeback; takeback 2
--- /dev/null
+Command: tell
+Purpose: send a message to an individual user or to a channel
+Usage: tell user|channel_number message
+Examples: tell Loon Why is the sky blue? tell 24 Anyone for bughouse?
--- /dev/null
+Command: time
+Purpose: displays the current clock time for a game in progress
+Usage: time [game, user]
+Examples: time; time 45; time Hawk
--- /dev/null
+Command: toggle
+Purpose: add/removes information on a list
+Usage: toggle list information
+Examples: toggle follow Tridge
--- /dev/null
+Command: tomove
+Purpose: used in setup mode in order to designate which side will move next
+Usage: tomove white|black
+Examples: tomove white; tomove black
--- /dev/null
+Command: tournset
+Purpose: used by TD programs only
--- /dev/null
+Command: unalias
+Purpose: removes a personal alias you had created previously
+Usage: unalias word
+Examples: unalias chal; unalias t1
--- /dev/null
+Command: unexamine
+Purpose: stop your examination of a game
+Usage: unexamine
+Examples: unexamine
--- /dev/null
+Command: unobserve
+Purpose: remove a game (or all games) from your observation list
+Usage: unobserve [game,user]
+Examples: unobserve 25; unobserve GMKasparov; unobserve (removes all games)
--- /dev/null
+Command: unpause
+Purpose: requests that the clocks for a paused game be restarted
+Usage: unpause
+Examples: unpause
--- /dev/null
+Command: unseek
+Purpose: cancel one or all ads you have placed for chess matches
+Usage: unseek [index_#]
+Examples: unseek; unseek 7
--- /dev/null
+Command: uptime
+Purpose: displays some server statistics, such as time in operation
+Usage: uptime
+Examples: uptime
--- /dev/null
+Command: ustat
+Purpose: display server statistics for last 24 hour period
+Usage: ustat
+Examples: ustat
--- /dev/null
+Command: variables
+Purpose: display the variable settings for yourself or another user
+Usage: variables [user]
+Examples: variables; variables McKeork
--- /dev/null
+Command: whenshut
+Purpose: display whether a shutdown is in progress and, if so, when it will
+ occur
+Usage: whenshut
+Examples: whenshut
--- /dev/null
+Command: whisper
+Purpose: send a message to observers of a game but NOT to the players
+Usage: whisper message
+Examples: whisper But why can't White just take the pawn?!
--- /dev/null
+Command: who
+Purpose: lists all or a subset of current users on the server
+Usage: who [o][r][f][a][R][U][s][b][w][L][S][A][l][t][v][n][#i#j][B]
+Examples: who; who 19; who s; who a; who B; who as; who asA; who a15
--- /dev/null
+Command: withdraw
+Purpose: remove an offer you had previously made to another user
+Usage: withdraw [1-n, t all, abort, adjourn, draw, match, pause, player,
+ simul, switch, takeback]
+Examples: withdraw 3; withdraw pause; withdraw Shaughn
--- /dev/null
+Command: wname
+Purpose: change name of White player in an examined or setup game
+Usage: wname [string]
+Examples: wname; wname Kotov
--- /dev/null
+Command: xkibitz
+Purpose: send a message to a game, regardless of 'primary' setting
+Usage: xkibitz name|# message
+Examples: xkibitz sms Nb4 works; xkibitz 34 Dead draw now.
--- /dev/null
+Command: xtell
+Purpose: send a message to a user or to a channel, but not affect current
+ "tell" setting
+Usage: xtell user|# message
+Examples: xtell sms Thanks for your help!; xtell 24 Partner up!
--- /dev/null
+Command: xwhisper
+Purpose: send a message to observers of a game, regardless of 'primary'
+ setting
+Usage: xwhisper name|# message
+Examples: xwhisper sms Nb4 works; xkibitz 34 Dead draw now.
--- /dev/null
+Command: znotify
+Purpose: display current users on your notify list, and users for whom you
+ are on their notify lists, with idle times (unless supressed)
+Usage: znotify [n]
+Examples: znotify; znotify n
--- /dev/null
+This is the credits file from Dan's original lasker release.
+
+For more credits please see http://chess.samba.org/ and the CVS logs
+
+ Andrew Tridgell
+ chess@tridgell.net
+
+
+---------------------
+A brief credits file. The first part are people I'd like to thank,
+and the second part are messages that have to be placed here
+for legal reasons.
+
+I would like to thank Michael Moore for starting the
+chess server many moons ago. I don't know where he
+is today, but his legacy is all of these chess servers
+(chessd, FICS, ICC, chess.net)
+
+Thanks to Richard Nash. Mr. Nash wrote
+most of my original code, and without him who knows
+where the state of Internet Chess would be.
+
+I'd also like to thank the people who contributed to the ICS
+code that Nash authored. This includes all developers from the
+years that Nash's code has been around.
+
+I'll specifically thank the FICS contributors. Without FICS,
+this project wouldn't exist today. Much thanks to David Flynn (DAV).
+He still doesn't support chessd, but perhaps one day he will.
+
+Poul-Henning Kamp and Mark Murray. Their code developed for FreeBSD
+was used in the password handling routines in chessd. I owe you a beer, phk.
+
+And of the chessd project:
+
+Chaz Randles - Emotional support, countless design discussions, consulting.
+
+Hristo Doichev - Letting me know that I was doing the right thing with going
+ forward with chessd. Various programming work.
+
+Gian-Carlo Pascutto - Being with me the entire way, both mentally and
+ with help with testing and programming.
+
+Vance Ray - Letting me know how I could use a real database server for
+ managing the players, games, etc. This is unimplemented,
+ but I'm looking into writing it myself (or, preferred) having
+ someone implement this.
+
+Brent D. Rockwood - Contributing the chessd logo. He also may takeover as
+ the webmaster in the future :) (Wink, wink, nudge, nudge)
+
+
+Thanks to everyone who help made chessd possible!
+-Dan Papasian
+bugg@bugg.strangled.net
+
+
+And, for legal reasons:
+
+Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
--- /dev/null
+/README_Nash/1.1/Thu Jun 6 08:56:53 2002//
+/CREDITS/1.3/Fri Jun 21 14:46:28 2002//
+/Changelog/1.2/Fri Jun 21 14:46:28 2002//
+/README_LEGAL/1.2/Fri Jun 21 14:46:29 2002//
+D
--- /dev/null
+lasker/doc
--- /dev/null
+This file contains change various change log information from earlier
+versions of this project. The current change information is held in
+CVS and can be accessed at http://chess.samba.org/
+
+
+
+------------
+
+
+New to 0.2:
+
+-Seek/sought/play support. Play around with these,
+they aren't documented yet (nor is the interface fully defined)
+
+-Improved build process/install target
+
+-Various other fixes and improvements too minor
+ to be listed here.
+
+
+------------
+
+Versions up to 1.2.16 and between 1.2.23 and 1.3.2 are approximate.
+Information on changes may not be exact or complete.
+
+1.6.4 Bughouse ratings, more feedback messages, new assess display,
+ fixed a problem with increasing game numbers.
+
+1.6.2 News bug fixed (Marsalis), caused crash and corrupted index file.
+ ECO brought back (Sparky), bug fixed for use with scratch games
+ (uninitialized moveList caused crash). Examine can now
+ be used to load board positions (Sparky). Works with
+ scratch games also.
+
+1.6.1 News rewritten (Marsalis), Much faster code. Some crash
+ protection code (writing player files after every 'set'
+ command for example) has been supressed for speed.
+ Bug in new playerfile code fixed (sanity checks added to
+ avoid crashes).
+
+1.6 Playerfile formats completely recoded (DAV) new and old
+ formats recognized. New format is written always. The
+ new format has expanded functionallity, more compact form,
+ and much faster processing.
+
+1.5.2 Ghosts hopefully killed; no more timeseal sitting;
+ Oldmoves implementation changes; game structure shrunk.
+ fics_hostname now takes it's contents from SERVER_NAME,
+ which should nwo be a DNS resolvable hostname.
+ fics_addplayer new account message modernized to include
+ brief instructions on how to connect to the server and
+ and warn about the use of anauthorzied duplicate accounts.
+ both adminproc.c and fics_addplayer modified.
+
+1.5.1 Fixes in journal commands, some bughouse bugs.
+
+1.5.0 Journals allowed. Some fixes for NULL v. NULL games.
+
+1.4.0 Initial bughouse version.
+
+1.3.3 clearing and showing individual messages.
+
+1.3.2 fixes to open file bugs;
+ clearing and showing messages from a particular player.
+
+1.3.1 kibitz level; tell/whisper bugs and similar fixed;
+ noplay and gnotify lists.
+
+1.3.0 new admin structure for coordination, responding to suggestions, etc;
+ got rid of annoyingly large version numbers :-).
+
+1.2.23-1.2.24 ???
+
+1.2.22 Examining of history games supported.
+
+1.2.21 Language variable; can't refresh private games;
+ Got rid of "You are not observing" message when you are observing.
+ New news interface; cnewsi, cnewsf, and news show on startup.
+ Percent of life stats.
+
+1.2.20 New help interface; index command.
+
+1.2.19 Examine mode (without history game support)
+ ECO and NIC codes now supported for history games and for
+ interactive reporting on games in process.
+ PGN format now supported for email of game scores.
+ Direct sendmail support provided with the SENDMAILPROG
+ definition in config.h, which overrides any MAILPROGRAM
+ definition. Provides for more reliable and efficient operation
+ under heavy load.
+
+1.2.18 variable mailmess: mails messages to you.
+ messages give the user feedback on what was sent.
+ simul commands simallabort, simadjourn, simalladjourn
+ (aliases saa sadj saadj)
+ simabort given alias sa
+ cshout and it prompts fixed
+ it gives better feedback
+ can restart simuls (or untimed games in simul form) with simmatch
+ game format reduced in size
+1.2.17 asetpasswd now sends mail to the player telling him the new
+ password.
+ extra info in up for admins
+ annunreg seen by all admins
+ hostinfo and lock removed as was fics_delplayer, fics_mailproc
+ and mail_proc.
+ see messages from one person, clear messages from a person
+ More simul bug fixes.
+ simprev (alias sp), goboard (alias go, goto), gonum commands.
+ allow admin to reset RD; ratings may be set with 0 games played.
+1.2.16 Many simul bugs fixed, one fatal bug corrected which caused
+ a crash during a simul.
+ unobserve command.
+ MAILPROGRAM replaced by "sendmail -t" and appropriate "To:"
+ and subject headers. This should help with blank mail
+ message problem. mailhelp and mailsource still depend on MAILPROGRAM
+ stuff added for SUN5 compilation
+ best info shown in who
+1.2.15 Simul bug fixed - losing connection led to a crash
+ adjudicate written (forcedraw, forcewin, forceres commands removed)
+ hostinfo removed from addplayer
+1.2.14 Simul code made operational.
+ games list ordered.
+ tally code disabled
+1.2.13 forcedraw, forcewin, forceres commands
+ asetv command replaces pose
+1.2.12 bug fixes.
+ pose weakened.
+1.2.11 First stable version of FICS. unnotify and unalias had big problems
+ that led to crashes and corrupt player files.
+ siteinfo removed - caused infinite lag
+ mailmess
+1.2.10 bug fixes, max length enforced in alias to stop a crash.
+1.2.9 autoboot out code added.
+1.2.8 aliases fixed, @ added, can alias system commands
+ flagging without material claims a draw, not a win.
+1.2.7 filter list operational.
+ multicol.c used to drop 2048 bytes
+1.2.6 rank and best, makerank
+ time for next shout shown.
+ bug fix to timelog
+ login/logouts logged
+ addcomment and showcomment
+1.2.5 Summon written.
+ ban list
+ (TD) in who
+ board styles fixed
+ shout quotas, it and shout modified
+ admin command to toggle (*)
+ fixes to up
+ admins can observe anything
+1.2.4 td list
+ qtell, getpi, commands for TD
+ asetblitz, asetstd
+ news,anews
+ wild chess made rated, best shows wild, new file
+ asetwild
+ next
+ SGI compilation possible.
+1.2.3 lists
+ (FM) (GM) (IM) (C) shown in who
+ raisedead given a second argument to rename a player
+ ahelp, info written
+ help files split into help and info
+ shutdown fixed
+1.2.2 internal version
+1.2.1 bug fixes.
+ admin gods can only use pose.
+ siteinfo shown
+1.2 notifiedby flag
+ remplayer, asethandle, raisedead written
+ nuke improved
+ query disabled
+1.1 who bug fixed - caused a crash if more than 10 players on.
+ ++++ shown in who for unreg players
+ early version of nuke.
+ (*) shown if level 10 admin
+ level 60 given title Assistant superuser.
+ who A, who l, who U, who R
+ Look of announce and other stuff improved.
+1.0 Original Nash code.
+-----------------------------------------------------------------------------
+Here is a more stable, hopefully more portable release of the
+FICS source code with many features added.
+
+People who have helped improve this from previous releases
+(March 1st 1995 onward) include (FICS names):
+DAV, foxbat, grimm, Hawk, hersco, loon, mann, Shane, Sparky, vek
+SORRY if you feel you should have been on this list but were forgotten.
+
+And Most thanks to red (Richard Nash) for the original code!
+ And Micheal Moore for the original idea of an ICS.
+
+-- Uploaded by Shane Hudson (Shane on FICS).
+Thanks to everyone for their support of FICS.
+
--- /dev/null
+This file contains various license headers that have been used in
+FICS. The code is now under the GNU General Public License (which is
+what the original code was first released under) but at various times
+parts of the code have been released under different licenses. I list
+them here for completeness.
+
+
+--------------------------------------------------------------------------
+fics - An internet chess server.
+
+ Copyright (C) 1993 Richard V. Nash
+
+ 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 2 of the License, or
+ 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.
+
+
+You may also contact the author(s) at
+ Richard Nash: email - nash@visus.com
+ phone - (412)-488-3600
+
+--------------------------------------------------------------------------
+
+
+/**
+ * Copyright (c) 1993 Richard V. Nash.
+ * Copyright (c) 2000 Dan Papasian. All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+--------------------------------------------------------------------------
--- /dev/null
+From nash@nomos.com Tue May 30 07:56:37 1995
+Content-Type: text/plain
+Mime-Version: 1.0 (NeXT Mail 3.3 v118.2)
+From: "Richard V. Nash" <nash@nomos.com>
+Date: Tue, 30 May 95 08:52:10 -0400
+To: danke%daimi.aau.dk.kris%dgate.org.chess%onenet.net.romeo@dcs.warwick.ac.uk
+Subject: Please remove nash@nomos.com and visus.com from help files
+Content-Length: 1130
+Status: RO
+X-Lines: 25
+
+Hello Chess Server Administrators,
+
+ I, nash@nomos.com, am getting dozens of emails everyday inquiring about
+chess servers. I would like to stop this. Could you please remove any
+reference to nash@nomos.com or nash@visus.com from the help files associated
+with FICS. This is in both your running systems and versions of the code that
+is being passed around or placed in ftp'able directories.
+
+ There are also references to ftp.visus.com in help files. These should also
+be removed.
+
+ Could you also pass this message along to anybody that you know who may
+have a copy of FICS but who I've missed on my search for FICS's.
+
+ That said, thanks to all of you for taking the FICS code and making it a
+success! I'm so happy that my work to keep chess servers available and free
+did not fail.
+
+Rich
+-----------------------+---------------------------+
+| Richard V. Nash | NOMOS Corporation |
+| nash@nomos.com | Suite 400 |
+| Tel. (412)-934-5477 | 2591 Wexford-Bayne Road |
+| Fax. (412)-934-5488 | Sewickley, PA 15143 |
++----------------------+---------------------------+
+
--- /dev/null
+D/history////
--- /dev/null
+lasker/games
--- /dev/null
+lasker/games/history
--- /dev/null
+/start_chessd/1.1/Wed Jun 12 02:45:24 2002//
+/spool_sendmail/1.2/Thu Jul 22 07:04:40 2004//
+D
--- /dev/null
+lasker/scripts
--- /dev/null
+#!/bin/sh
+# simple mail spool handler for chessd
+# Andrew Tridgell <tridge@chess.samba.org>
+
+shopt -s nullglob
+
+cd $HOME/chessd || exit 1
+
+(
+while :; do
+ for f in spool/mail.*; do
+ if /usr/lib/sendmail -t < $f; then
+ /bin/rm -f $f
+ fi
+ done
+ sleep 60
+done
+) >> spool.log 2>&1
--- /dev/null
+#!/bin/sh
+# a simple shell script to keep chessd running
+# Andrew Tridgell <tridge@chess.samba.org>
+
+cd $HOME/chessd || exit 1
+
+(
+ while :; do
+ $HOME/bin/chessd -p 5000 -T $HOME/bin/timeseal_decoder -R $HOME/chessd -f
+ sleep 10
+ done
+) >> chessd.log 2>&1
--- /dev/null
+.autoheaders
+Makefile
+autoconfig.h
+chessd
+chessd_addplayer
+config.cache
+config.log
+config.status
+makerank
+proto.h
+vers.c
--- /dev/null
+/comproc.h/1.4/Wed Jun 12 11:05:51 2002//
+/crypt-md5.c/1.3/Wed Jun 12 10:11:35 2002//
+/crypt-md5c.c/1.4/Wed Jun 12 11:05:51 2002//
+/crypt-misc.c/1.3/Wed Jun 12 10:11:35 2002//
+/crypt.c/1.3/Wed Jun 12 10:11:35 2002//
+/journal.h/1.2/Wed Jun 12 10:11:35 2002//
+/md5.h/1.3/Wed Jun 12 11:05:51 2002//
+/mkproto.awk/1.1/Wed Jun 12 10:12:03 2002//
+/vers.h/1.2/Tue Jun 11 09:18:18 2002//
+D/tdb////
+/install-sh/1.1/Fri Jun 14 02:30:58 2002//
+/.cvsignore/1.4/Fri Jun 21 14:46:29 2002//
+/command.h/1.9/Fri Jun 21 14:46:29 2002//
+/formula.h/1.5/Fri Jun 21 14:46:29 2002//
+/gameproc.h/1.4/Fri Jun 21 14:46:29 2002//
+/gics.h/1.6/Fri Jun 21 14:46:29 2002//
+/iset.h/1.1/Fri Jun 21 07:57:19 2002//
+/matchproc.h/1.4/Fri Jun 21 14:46:29 2002//
+/movecheck.h/1.5/Fri Jun 21 14:46:29 2002//
+/multicol.h/1.5/Fri Jun 21 14:46:29 2002//
+/obsproc.h/1.4/Fri Jun 21 14:46:29 2002//
+/ratings.h/1.5/Fri Jun 21 14:46:29 2002//
+/utils.h/1.7/Fri Jun 21 14:46:29 2002//
+/variable.h/1.5/Fri Jun 21 14:46:29 2002//
+D/parsers////
+/ficsmain.h/1.8/Sat Jun 22 05:58:18 2002//
+/formula.c/1.11/Sat Jun 22 05:58:18 2002//
+/multicol.c/1.6/Sat Jun 22 05:58:18 2002//
+/acconfig.h/1.4/Sun Jun 23 08:20:09 2002//
+/autoconfig.h.in/1.3/Sun Jun 23 08:20:09 2002//
+/board.h/1.9/Sun Jun 23 08:20:09 2002//
+/common.h/1.17/Sun Jun 23 08:20:09 2002//
+/configure/1.8/Sun Jun 23 08:20:09 2002//
+/configure.in/1.10/Sun Jun 23 08:20:09 2002//
+/gamedb.h/1.18/Sun Jun 23 08:20:09 2002//
+/gamedb_old.c/1.2/Sun Jun 23 08:20:09 2002//
+/pending.h/1.11/Sun Jun 23 08:20:09 2002//
+/talkproc.h/1.6/Sun Jun 23 08:20:09 2002//
+/eco.c/1.15/Sat Jun 29 00:06:15 2002//
+/fics_addplayer.c/1.13/Sat Jun 29 00:06:15 2002//
+/follow.c/1.2/Sat Jun 29 00:06:15 2002//
+/gics.c/1.15/Sat Jun 29 00:06:15 2002//
+/globals.h/1.11/Sat Jun 29 00:06:15 2002//
+/includes.h/1.13/Sat Jun 29 00:06:15 2002//
+/iset.c/1.4/Sat Jun 29 00:06:15 2002//
+/makerank.c/1.10/Sat Jun 29 00:06:15 2002//
+/malloc.h/1.4/Sat Jun 29 00:06:15 2002//
+/network.h/1.16/Sat Jun 29 00:06:15 2002//
+/news.h/1.1/Sun Jun 23 22:40:42 2002//
+/newvers.sh/1.5/Sat Jun 29 00:06:15 2002//
+/obsproc.c/1.19/Sat Jun 29 00:06:15 2002//
+/pending.c/1.13/Sat Jun 29 00:06:15 2002//
+/playerdb.c/1.32/Sat Jun 29 00:06:15 2002//
+/playerdb_old.c/1.4/Sat Jun 29 00:06:15 2002//
+/ratings.c/1.17/Sat Jun 29 00:06:15 2002//
+/reload.c/1.8/Sat Jun 29 00:06:15 2002//
+/seekproc.c/1.18/Sat Jun 29 00:06:15 2002//
+/setup.c/1.8/Sat Jun 29 00:06:15 2002//
+/shutdown.c/1.12/Sat Jun 29 00:06:15 2002//
+/talkproc.c/1.15/Sat Jun 29 00:06:15 2002//
+/board.c/1.15/Mon Jul 1 01:36:41 2002//
+/config.h/1.14/Mon Jul 1 01:36:42 2002//
+/ficsmain.c/1.17/Mon Jul 1 01:36:42 2002//
+/help.c/1.8/Mon Jul 1 01:36:42 2002//
+/timeseal.c/1.11/Mon Jul 1 01:36:42 2002//
+/Makefile.in/1.29/Thu Jul 22 07:04:40 2004//
+/adminproc.c/1.22/Thu Jul 22 07:04:40 2004//
+/algcheck.c/1.13/Thu Jul 22 07:04:40 2004//
+/command.c/1.52/Thu Jul 22 07:04:40 2004//
+/command_list.h/1.36/Thu Jul 22 07:04:40 2004//
+/comproc.c/1.35/Thu Jul 22 07:04:40 2004//
+/config.c/1.13/Thu Jul 22 07:04:40 2004//
+/findstatic.pl/1.2/Thu Jul 22 07:04:40 2004//
+/gamedb.c/1.34/Thu Jul 22 07:04:40 2004//
+/gameproc.c/1.24/Thu Jul 22 07:04:40 2004//
+/lists.c/1.20/Thu Jul 22 07:04:40 2004//
+/lists.h/1.10/Thu Jul 22 07:04:40 2004//
+/malloc.c/1.13/Thu Jul 22 07:04:40 2004//
+/matchproc.c/1.17/Thu Jul 22 07:04:40 2004//
+/movecheck.c/1.14/Thu Jul 22 07:04:40 2004//
+/network.c/1.20/Thu Jul 22 07:04:40 2004//
+/news.c/1.9/Thu Jul 22 07:04:40 2004//
+/playerdb.h/1.21/Thu Jul 22 07:04:40 2004//
+/utils.c/1.36/Thu Jul 22 07:04:40 2004//
+/variable.c/1.17/Thu Jul 22 07:04:40 2004//
--- /dev/null
+lasker/src
--- /dev/null
+##
+## fics - An internet chess server.
+## Copyright (C) 1993 Richard V. Nash
+## Copyright (C) 2000 Dan Papasian. All rights reserved.
+##
+## This program is free software; you can redistribute it and/or modify
+## it under any terms you see fit as long as this message, the
+## copyright message, and the disclaimer below remain intact.
+##
+##
+## 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.
+##
+##
+## This is the Makefile template; see machine dependant config.h for
+## more configuration options.
+
+
+SHELL = /bin/sh
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CHESSD_CFLAGS = @CHESSD_CFLAGS@
+CC=@CC@
+
+##
+## Where to install FICS
+##
+PREFIX = @prefix@
+exec_prefix = @exec_prefix@
+bindir = ${exec_prefix}/bin
+
+PICFLAG = -fPIC
+DYNEXP=-rdynamic
+
+##
+## Binaries and Options to use
+##
+CFLAGS += $(PICFLAG) -Wall @CFLAGS@ -DTDB_STANDALONE ${CHESSD_CFLAGS} -I${srcdir} -I${srcdir}/tdb
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+LIBS = @LIBS@ -lm
+LNFLAGS = @LDFLAGS@ ${LIBS}
+CHESSDDIR = ${PREFIX}/chessd
+
+TDB_SRC = tdb/tdb.c tdb/spinlock.c
+
+GEN_SRCS=adminproc.c algcheck.c board.c command.c talkproc.c comproc.c \
+ formula.c gamedb.c gamedb_old.c gameproc.c config.c \
+ lists.c malloc.c reload.c follow.c help.c news.c \
+ movecheck.c multicol.c network.c playerdb.c playerdb_old.c ratings.c \
+ utils.c variable.c vers.c eco.c matchproc.c \
+ obsproc.c pending.c gics.c setup.c shutdown.c seekproc.c \
+ parsers/parser.c parsers/genparser.c iset.c \
+ crypt.c crypt-md5.c crypt-md5c.c crypt-misc.c timeseal.c $(TDB_SRC)
+
+SRCS=$(GEN_SRCS) fics_addplayer.c ficsmain.c makerank.c
+
+OBJS=$(GEN_SRCS:.c=.o)
+
+VERSION=./newvers.sh
+
+ALL= chessd chessd.so chessd_addplayer makerank
+
+all: ${ALL}
+
+.autoheaders: proto.h parsers/parse_info.h
+ touch .autoheaders
+
+chessd: .autoheaders ficsmain.o
+ $(CC) $(DYNEXP) $(CFLAGS) $(LNFLAGS) -o chessd ficsmain.o $(LIBS)
+
+chessd.so: .autoheaders $(OBJS)
+ $(CC) -shared -o chessd.so $(OBJS)
+
+chessd_addplayer: .autoheaders fics_addplayer.o $(OBJS)
+ $(CC) fics_addplayer.o $(CFLAGS) $(OBJS) $(LNFLAGS) -o chessd_addplayer $(LIBS)
+
+makerank: .autoheaders makerank.o
+ $(CC) makerank.o $(OBJS) -o makerank $(LIBS)
+
+vers.c:
+ ${VERSION}
+
+depend:
+ makedepend -- ${CFLAGS} ${MAKEDEPMORECFLAGS} -- ${SRCS}
+
+proto.h: $(GEN_SRCS)
+ awk -f mkproto.awk $(GEN_SRCS) > proto.h
+
+parsers/parse_info.h: $(shell /bin/ls *.h | sed s/proto.h//g)
+ parsers/genstruct.pl -o parsers/parse_info.h $(CC) -E $(CFLAGS) includes.h
+
+clean:
+ rm -f *.o $(OBJS) ${ALL} *~ vers.c proto.h parsers/parse_info.h .autoheaders
+
+distclean: clean
+ rm -rf Makefile autoconfig.h config.status config.cache config.log
+
+# useful dependency
+command.o: command_list.h
+
+parsers/parser.o: parsers/parse_info.h
+
+# this is needed to handle compilers that insist on putting code in the current
+# directory with -c
+.c.o:
+ $(CC) -c $(CFLAGS) -o $*.o $*.c
+
+install: $(ALL)
+ install -d -m0755 ${CHESSDDIR}
+ install -d -m0755 ${CHESSDDIR}/bin
+ install -d -m0755 ${CHESSDDIR}/lib
+ install -m0755 chessd ${CHESSDDIR}/bin
+ install -m0755 chessd.so ${CHESSDDIR}/lib
+ install -m0755 makerank ${CHESSDDIR}/bin
+ install -m0755 chessd_addplayer ${CHESSDDIR}/bin
+ install -d -m0755 ${CHESSDDIR}/players
+ install -d -m0755 ${CHESSDDIR}/spool
+ install -d -m0755 ${CHESSDDIR}/data/admin
+ install -d -m0755 ${CHESSDDIR}/data/book
+ install -d -m0755 ${CHESSDDIR}/data/help
+ install -d -m0755 ${CHESSDDIR}/data/usage
+ install -d -m0755 ${CHESSDDIR}/data/messages
+ install -d -m0755 ${CHESSDDIR}/data/stats
+ install -d -m0755 ${CHESSDDIR}/data/boards/wild
+ install -d -m0755 ${CHESSDDIR}/games/history
+ install -d -m0755 ${CHESSDDIR}/games/journal
+ install -d -m0755 ${CHESSDDIR}/games/adjourned
+ install -d -m0755 ${CHESSDDIR}/data/stats/player_data
+ cp -u ${srcdir}/../data/admin/[a-z]* ${CHESSDDIR}/data/admin
+ cp -u ${srcdir}/../data/book/[a-z]* ${CHESSDDIR}/data/book
+ cp -u ${srcdir}/../data/help/[a-z]* ${CHESSDDIR}/data/help
+ cp -u ${srcdir}/../data/usage/[a-z]* ${CHESSDDIR}/data/usage
+ cp -u ${srcdir}/../data/messages/[a-z]* ${CHESSDDIR}/data/messages
+ perl -e 'mkdir("${CHESSDDIR}/players/$$_",0755) for ("a".."z")'
+ perl -e 'mkdir("${CHESSDDIR}/games/history/$$_",0755) for ("0".."99")'
+ perl -e 'mkdir("${CHESSDDIR}/games/journal/$$_",0755) for ("a".."z")'
+ perl -e 'mkdir("${CHESSDDIR}/data/stats/player_data/$$_",0755) for ("a".."z")'
+ perl -e 'mkdir("${CHESSDDIR}/games/adjourned/$$_",0755) for ("a".."z")'
+
+etags:
+ etags *.[ch] */*.[ch]
+
+findglobal:
+ nm $(OBJS) | grep ' C '
+ nm $(OBJS) | grep ' D '
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+/*
+ * This file contains descriptive text for the C preprocessor macros
+ * that are missing in the original acconfig.h of the autoconf
+ * distribution, but used in the configure.in of the FICS distribution.
+ *
+ * It is used *only* by the autoheader program contained in the
+ * autoconf distribution.
+ *
+ *
+ * Leave the following blank line there!! Autoheader needs it.
+ */
+
+/* Define this to be the return value of the time() function. */
+#undef time_t
+
+/* Undefine, if your compiler doesn't support prototypes */
+#undef HAVE_PROTOTYPES
+
+/* Define, if you have a statfs() function which fills a struct
+ statfs, declared in sys/vfs.h. (NeXTStep) */
+#undef HAVE_STATFS_FILLING_STRUCT_STATFS
+
+/* Define, if you have a statfs() function which fills a struct
+ fs_data, declared in sys/mount.h. (Ultrix) */
+#undef HAVE_STATFS_FILLING_STRUCT_FS_DATA
+
+/* Define, if you have crypt() and it is declared in either
+ crypt.h or unistd.h. */
+#undef HAVE_CRYPT_DECLARED
+
+/* Define this to be tv_usec, if your struct rusage has
+ a member ru_utime.tv_usec.
+ Define this to be tv_nsec, if your struct rusage has
+ a member ru_utime.tv_nsec. */
+#undef TV_USEC
+
+#undef HAVE_DLOPEN
+
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+/**
+ *
+ * adminproc.c - All administrative commands and related functions
+ *
+ */
+
+#include "includes.h"
+
+#define PASSLEN 4
+
+
+/*
+ check that a player has sufficient rights for an operation
+*/
+int check_admin(int p, unsigned level)
+{
+ struct player *pp = &player_globals.parray[p];
+ /* gods and head admins always get what they want */
+ if (pp->adminLevel >= ADMIN_GOD ||
+ player_ishead(p)) {
+ return 1;
+ }
+ return pp->adminLevel >= level;
+}
+
+/*
+ check that player p1 can do an admin operation on player p2
+*/
+static int check_admin2(int p1, int p2)
+{
+ return check_admin(p1, player_globals.parray[p2].adminLevel+1);
+}
+
+/*
+ * adjudicate
+ *
+ * Usage: adjudicate white_player black_player result
+ *
+ * Adjudicates a saved (stored) game between white_player and black_player.
+ * The result is one of: abort, draw, white, black. "Abort" cancels the game
+ * (no win, loss or draw), "white" gives white_player the win, "black" gives
+ * black_player the win, and "draw" gives a draw.
+ */
+int com_adjudicate(int p, param_list param)
+{
+ int wp, wconnected, bp, bconnected, g, inprogress, confused = 0;
+
+ if (!FindPlayer(p, param[0].val.word, &wp, &wconnected))
+ return COM_OK;
+ if (!FindPlayer(p, param[1].val.word, &bp, &bconnected)) {
+ if (!wconnected)
+ player_remove(wp);
+ return COM_OK;
+ }
+
+ inprogress = ((player_globals.parray[wp].game >=0) &&(player_globals.parray[wp].opponent == bp));
+
+ if (inprogress) {
+ g = player_globals.parray[wp].game;
+ } else {
+ g = game_new();
+ if (game_read(g, wp, bp) < 0) {
+ confused = 1;
+ pprintf(p, "There is no stored game %s vs. %s\n", player_globals.parray[wp].name, player_globals.parray[bp].name);
+ } else {
+ game_globals.garray[g].white = wp;
+ game_globals.garray[g].black = bp;
+ }
+ }
+ if (!confused) {
+ if (strstr("abort", param[2].val.word) != NULL) {
+ game_ended(g, WHITE, END_ADJABORT);
+
+ pcommand(p, "message %s Your game \"%s vs. %s\" has been aborted.",
+ player_globals.parray[wp].name, player_globals.parray[wp].name, player_globals.parray[bp].name);
+
+ pcommand(p, "message %s Your game \"%s vs. %s\" has been aborted.",
+ player_globals.parray[bp].name, player_globals.parray[wp].name, player_globals.parray[bp].name);
+ } else if (strstr("draw", param[2].val.word) != NULL) {
+ game_ended(g, WHITE, END_ADJDRAW);
+
+ pcommand(p, "message %s Your game \"%s vs. %s\" has been adjudicated "
+ "as a draw", player_globals.parray[wp].name, player_globals.parray[wp].name, player_globals.parray[bp].name);
+
+ pcommand(p, "message %s Your game \"%s vs. %s\" has been adjudicated "
+ "as a draw", player_globals.parray[bp].name, player_globals.parray[wp].name, player_globals.parray[bp].name);
+ } else if (strstr("white", param[2].val.word) != NULL) {
+ game_ended(g, WHITE, END_ADJWIN);
+
+ pcommand(p, "message %s Your game \"%s vs. %s\" has been adjudicated "
+ "as a win", player_globals.parray[wp].name, player_globals.parray[wp].name, player_globals.parray[bp].name);
+
+ pcommand(p, "message %s Your game \"%s vs. %s\" has been adjudicated "
+ "as a loss", player_globals.parray[bp].name, player_globals.parray[wp].name, player_globals.parray[bp].name);
+ } else if (strstr("black", param[2].val.word) != NULL) {
+ game_ended(g, BLACK, END_ADJWIN);
+ pcommand(p, "message %s Your game \"%s vs. %s\" has been adjudicated "
+ "as a loss", player_globals.parray[wp].name, player_globals.parray[wp].name, player_globals.parray[bp].name);
+
+ pcommand(p, "message %s Your game \"%s vs. %s\" has been adjudicated "
+ "as a win", player_globals.parray[bp].name, player_globals.parray[wp].name, player_globals.parray[bp].name);
+ } else {
+ confused = 1;
+ pprintf(p, "Result must be one of: abort draw white black\n");
+ }
+ }
+ if (!confused) {
+ pprintf(p, "Game adjudicated.\n");
+ if (!inprogress) {
+ game_delete(wp, bp);
+ } else {
+ return (COM_OK);
+ }
+ }
+ game_remove(g);
+ if (!wconnected)
+ player_remove(wp);
+ if (!bconnected)
+ player_remove(bp);
+ return COM_OK;
+}
+
+
+/*
+ * remplayer
+ *
+ * Usage: remplayer name
+ *
+ * Removes an account. A copy of its files are saved under .rem.* which can
+ * be found in the appropriate directory (useful in case of an accident).
+ *
+ * The account's details, messages, games and logons are all saved as
+ * 'zombie' files. These zombie accounts are not listed in handles or
+ * totals.
+ */
+int com_remplayer(int p, param_list param)
+{
+ char *player = param[0].val.word;
+ char playerlower[MAX_LOGIN_NAME];
+ int p1, lookup;
+
+ strcpy(playerlower, player);
+ stolower(playerlower);
+ p1 = player_new();
+ lookup = player_read(p1, playerlower);
+ if (!lookup) {
+ if (!check_admin2(p, p1)) {
+ pprintf(p, "You can't remove an admin with a level higher than or equal to yourself.\n");
+ player_remove(p1);
+ return COM_OK;
+ }
+ }
+ player_remove(p1);
+ if (lookup) {
+ pprintf(p, "No player by the name %s is registered.\n", player);
+ return COM_OK;
+ }
+ if (player_find_bylogin(playerlower) >= 0) {
+ pprintf(p, "A player by that name is logged in.\n");
+ return COM_OK;
+ }
+ if (!player_kill(playerlower)) {
+ pprintf(p, "Player %s removed.\n", player);
+ UpdateRank(TYPE_BLITZ, NULL, NULL, player);
+ UpdateRank(TYPE_STAND, NULL, NULL, player);
+ UpdateRank(TYPE_WILD, NULL, NULL, player);
+ } else {
+ pprintf(p, "Remplayer failed.\n");
+ }
+ return COM_OK;
+}
+
+/*
+ * raisedead
+ *
+ * Usage: raisedead oldname [newname]
+ *
+ * Restores an account that has been previously removed using "remplayer".
+ * The zombie files from which it came are removed. Under most
+ * circumstances, you restore the account to the same handle it had
+ * before (oldname). However, in some circumstances you may need to
+ * restore the account to a different handle, in which case you include
+ * "newname" as the new handle. After "raisedead", you may need to use the
+ * "asetpasswd" command to get the player started again as a registered
+ * user, especially if the account had been locked
+ * by setting the password to *.
+ */
+int com_raisedead(int p, param_list param)
+{
+ char *player = param[0].val.word;
+ char *newplayer = (param[1].type == TYPE_NULL ? player : param[1].val.word);
+ char playerlower[MAX_LOGIN_NAME], newplayerlower[MAX_LOGIN_NAME];
+ char plrFile[MAX_FILENAME_SIZE];
+
+ int p2, lookup;
+
+ strcpy(playerlower, player);
+ stolower(playerlower);
+ strcpy(newplayerlower, newplayer);
+ stolower(newplayerlower);
+
+ /* First make sure we have a player to raise. */
+ sprintf (plrFile, "%s/%c/.rem.%s", PLAYER_DIR, playerlower[0], playerlower);
+ if (!file_exists (plrFile)) {
+ pprintf(p, "No deleted player %s.\n", player);
+ return COM_OK;
+ }
+
+ /* Now check for registered player. */
+ sprintf (plrFile, "%s/%c/%s", PLAYER_DIR, newplayerlower[0], newplayerlower);
+ if (file_exists (plrFile)) {
+ pprintf(p, "A player named %s is already registered.\n", newplayerlower);
+ pprintf(p, "Obtain a new handle for the dead person.\n");
+ pprintf(p, "Then use raisedead [oldname] [newname].\n");
+ return COM_OK;
+ }
+
+ /* Don't raise over a logged in user. */
+ if (player_find_bylogin(newplayerlower) >= 0) {
+ pprintf(p, "A player named %s is logged in.\n", newplayerlower);
+ pprintf(p, "Can't raise until that person leaves.\n");
+ return COM_OK;
+ }
+
+ /* OK, ready to go. */
+ if (!player_reincarn(playerlower, newplayerlower)) {
+ if (param[1].type == TYPE_WORD)
+ pprintf(p, "Player %s reincarnated to %s.\n", player, newplayer);
+ else
+ pprintf(p, "Player %s raised.\n", player);
+ p2 = player_new();
+ if (!(lookup = player_read(p2, newplayerlower))) {
+ if (param[1].type == TYPE_WORD) {
+ free(player_globals.parray[p2].name);
+ player_globals.parray[p2].name = strdup(newplayer);
+ player_save(p2);
+ }
+ if (player_globals.parray[p2].s_stats.rating > 0)
+ UpdateRank(TYPE_STAND, newplayer, &player_globals.parray[p2].s_stats, newplayer);
+ if (player_globals.parray[p2].b_stats.rating > 0)
+ UpdateRank(TYPE_BLITZ, newplayer, &player_globals.parray[p2].b_stats, newplayer);
+ if (player_globals.parray[p2].w_stats.rating > 0)
+ UpdateRank(TYPE_WILD, newplayer, &player_globals.parray[p2].w_stats, newplayer);
+ }
+ player_remove(p2);
+ } else {
+ pprintf(p, "Raisedead failed.\n");
+ }
+ return COM_OK;
+#if 0
+ if (param[1].type == TYPE_NULL) {
+ if (!player_raise(playerlower)) {
+ pprintf(p, "Player %s raised from dead.\n", player);
+
+ p1 = player_new();
+ if (!(lookup = player_read(p1, playerlower))) {
+ if (player_globals.parray[p1].s_stats.rating > 0)
+ UpdateRank(TYPE_STAND, player, &player_globals.parray[p1].s_stats, player);
+ if (player_globals.parray[p1].b_stats.rating > 0)
+ UpdateRank(TYPE_BLITZ, player, &player_globals.parray[p1].b_stats, player);
+ if (player_globals.parray[p1].w_stats.rating > 0)
+ UpdateRank(TYPE_WILD, player, &player_globals.parray[p1].w_stats, player);
+ }
+ player_remove(p1);
+ } else {
+ pprintf(p, "Raisedead failed.\n");
+ }
+ return COM_OK;
+ } else {
+ if (player_find_bylogin(newplayerlower) >= 0) {
+ pprintf(p, "A player by the requested name is logged in.\n");
+ pprintf(p, "Can't reincarnate until they leave.\n");
+ return COM_OK;
+ }
+ p2 = player_new();
+ lookup = player_read(p2, newplayerlower);
+ player_remove(p2);
+ if (!lookup) {
+ pprintf(p, "A player by the name %s is already registered.\n", player);
+ pprintf(p, "Obtain another new handle for the dead person.\n");
+ return COM_OK;
+ }
+ if (!player_reincarn(playerlower, newplayerlower)) {
+ pprintf(p, "Player %s reincarnated to %s.\n", player, newplayer);
+ p2 = player_new();
+ if (!(lookup = player_read(p2, newplayerlower))) {
+ free(player_globals.parray[p2].name);
+ player_globals.parray[p2].name = strdup(newplayer);
+ player_save(p2);
+ if (player_globals.parray[p2].s_stats.rating > 0)
+ UpdateRank(TYPE_STAND, newplayer, &player_globals.parray[p2].s_stats, newplayer);
+ if (player_globals.parray[p2].b_stats.rating > 0)
+ UpdateRank(TYPE_BLITZ, newplayer, &player_globals.parray[p2].b_stats, newplayer);
+ if (player_globals.parray[p2].w_stats.rating > 0)
+ UpdateRank(TYPE_WILD, newplayer, &player_globals.parray[p2].w_stats, newplayer);
+ }
+ player_remove(p2);
+ } else {
+ pprintf(p, "Raisedead failed.\n");
+ }
+ }
+ return COM_OK;
+#endif
+}
+
+/*
+ * addplayer
+ *
+ * Usage: addplayer playername emailaddress realname
+ *
+ * Adds a local player to the server with the handle of "playername". For
+ * example:
+ *
+ * addplayer Hawk u940456@daimi.aau.dk Henrik Gram
+ */
+int com_addplayer(int p, param_list param)
+{
+ char text[2048];
+ char *newplayer = param[0].val.word;
+ char *newname = param[2].val.string;
+ char *newemail = param[1].val.word;
+ char password[PASSLEN + 1];
+ char newplayerlower[MAX_LOGIN_NAME];
+ char salt[3];
+ int p1, lookup;
+ int i;
+
+ if (strlen(newplayer) >= MAX_LOGIN_NAME) {
+ pprintf(p, "Player name is too long\n");
+ return COM_OK;
+ }
+ if (strlen(newplayer) < 3) {
+ pprintf(p, "Player name is too short\n");
+ return COM_OK;
+ }
+ if (!alphastring(newplayer)) {
+ pprintf(p, "Illegal characters in player name. Only A-Za-z allowed.\n");
+ return COM_OK;
+ }
+ strcpy(newplayerlower, newplayer);
+ stolower(newplayerlower);
+ p1 = player_new();
+ lookup = player_read(p1, newplayerlower);
+ if (!lookup) {
+ pprintf(p, "A player by the name %s is already registered.\n", newplayerlower);
+ player_remove(p1);
+ return COM_OK;
+ }
+ player_globals.parray[p1].name = strdup(newplayer);
+ player_globals.parray[p1].login = strdup(newplayerlower);
+ player_globals.parray[p1].fullName = strdup(newname);
+ player_globals.parray[p1].emailAddress = strdup(newemail);
+ if (strcmp(newemail, "none")) {
+ for (i = 0; i < PASSLEN; i++) {
+ password[i] = 'a' + random() % 26;
+ }
+ password[i] = '\0';
+ salt[0] = 'a' + random() % 26;
+ salt[1] = 'a' + random() % 26;
+ salt[2] = '\0';
+ player_globals.parray[p1].passwd = strdup(chessd_crypt(password, salt));
+ } else {
+ password[0] = '\0';
+ player_globals.parray[p1].passwd = strdup(password);
+ }
+ PFlagON(p1, PFLAG_REG);
+/* player_globals.parray[p1].network_player = 0; */
+ PFlagON(p1, PFLAG_RATED);
+ player_add_comment(p, p1, "Player added by addplayer.");
+ player_save(p1);
+ player_remove(p1);
+ pprintf(p, "Added: >%s< >%s< >%s< >%s<\n", newplayer, newname, newemail, password);
+ if (strcmp(newemail, "none")) {
+/*
+ sprintf(text, "\nYou have been added as a local player.\n\nLogin Name: "
+ "%s\nFull Name: %s\nEmail Address: %s\nInitial Password: "
+ "%s\n\nIf any of this information is incorrect, please "
+ "contact the administrator\nto get it corrected.\n\n"
+ "Please write down your password.\n\nRegards,\n\nThe FICS admins\n",
+ newplayer, newname, newemail, password);
+*/
+
+ sprintf(text, "\nYour player account has been created.\n\n"
+ "Login Name: %s\nFull Name: %s\nEmail Address: %s\nInitial Password: %s\n\n"
+ "If any of this information is incorrect, please contact the administrator\n"
+ "to get it corrected.\n\n"
+ "You may change your password with the password command on the the server.\n"
+ "\nPlease be advised that if this is an unauthorized duplicate account for\n"
+ "you, by using it you take the risk of being banned from accessing this\n"
+ "chess server.\n\n"
+ "Regards,\n\nThe FICS admins\n",
+ newplayer, newname, newemail, password);
+
+ mail_string_to_address(newemail, "FICS Account Created", text);
+ if ((p1 = player_find_part_login(newplayer)) >= 0) {
+ pprintf_prompt(p1, "\n\nYou are now registered! Confirmation together with\npassword is sent to your email address.\n\n");
+ player_read(p1, newplayer);
+ return COM_OK;
+ }
+ return COM_OK;
+ } else {
+ if ((p1 = player_find_part_login(newplayer)) >= 0) {
+ pprintf_prompt(p1, "\n\nYou are now registered! Your have NO password!\n\n");
+ player_read(p1, newplayer);
+ return COM_OK;
+ }
+ }
+ return COM_OK;
+}
+
+int com_pose(int p, param_list param)
+{
+ int p1;
+
+ if ((p1 = player_find_part_login(param[0].val.word)) < 0) {
+ pprintf(p, "%s is not logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ if (!check_admin2(p, p1)) {
+ pprintf(p, "You can only pose as players below your adminlevel.\n");
+ return COM_OK;
+ }
+ pprintf(p, "Command issued as %s\n", player_globals.parray[p1].name);
+ pcommand(p1, "%s\n", param[1].val.string);
+ return COM_OK;
+}
+
+/*
+ * asetv
+ *
+ * Usage: asetv user instructions
+ *
+ * This command executes "set" instructions as if they had been made by the
+ * user indicated. For example, "asetv DAV shout 0" would set DAV's shout
+ * variable to 0.
+ */
+int com_asetv(int p, param_list param)
+{
+ int p1;
+
+ if ((p1 = player_find_part_login(param[0].val.word)) < 0) {
+ pprintf(p, "%s is not logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ if (!check_admin2(p, p1)) {
+ pprintf(p, "You can only aset players below your adminlevel.\n");
+ return COM_OK;
+ }
+ pprintf(p, "Command issued as %s\n", player_globals.parray[p1].name);
+ pcommand(p1, "set %s\n", param[1].val.string);
+ return COM_OK;
+}
+
+/*
+ * announce
+ *
+ * Usage: announce message
+ *
+ * Broadcasts your message to all logged on users. Announcements reach all
+ * users and cannot be censored in any way (such as by "set shout 0").
+ */
+int com_announce(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1;
+ int count = 0;
+
+ if (!printablestring(param[0].val.string)) {
+ pprintf(p, "Your message contains some unprintable character(s).\n");
+ return COM_OK;
+ }
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (p1 == p)
+ continue;
+ if (player_globals.parray[p1].status != PLAYER_PROMPT)
+ continue;
+ count++;
+ pprintf_prompt(p1, "\n\n **ANNOUNCEMENT** from %s: %s\n\n", pp->name, param[0].val.string);
+ }
+ pprintf(p, "\n(%d) **ANNOUNCEMENT** from %s: %s\n\n", count, pp->name, param[0].val.string);
+ return COM_OK;
+}
+
+/*
+ * annunreg
+ *
+ * Usage: annunreg message
+ *
+ * Broadcasts your message to all logged on unregistered users, and admins,
+ * too. Announcements reach all unregistered users and admins and cannot be
+ * censored in any way (such as by "set shout 0").
+ */
+int com_annunreg(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1;
+ int count = 0;
+
+ if (!printablestring(param[0].val.string)) {
+ pprintf(p, "Your message contains some unprintable character(s).\n");
+ return COM_OK;
+ }
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (p1 == p) continue;
+ if (player_globals.parray[p1].status != PLAYER_PROMPT) continue;
+ if (CheckPFlag(p1, PFLAG_REG)
+ && !check_admin(p1, ADMIN_ADMIN))
+ continue;
+ count++;
+ pprintf_prompt(p1, "\n\n **UNREG ANNOUNCEMENT** from %s: %s\n\n",
+ pp->name, param[0].val.string);
+ }
+ pprintf(p, "\n(%d) **UNREG ANNOUNCEMENT** from %s: %s\n\n",
+ count, pp->name, param[0].val.string);
+ return COM_OK;
+}
+
+/*
+ * asetpasswd
+ *
+ * Usage: asetpasswd player {password,*}
+ *
+ * This command sets the password of the player to the password given.
+ * If '*' is specified then the player's account is locked, and no password
+ * will work until a new one is set by asetpasswd.
+ *
+ * If the player is connected, he is told of the new password and the name
+ * of the admin who changed it, or likewise of his account status. An
+ * email message is mailed to the player's email address as well.
+ */
+int com_asetpasswd(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1, connected;
+ char subject[400], text[10100];
+ char salt[3];
+
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+
+ if (!check_admin2(p, p1)) {
+ pprintf(p, "You can only set password for players below your adminlevel.\n");
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ if (!CheckPFlag(p1, PFLAG_REG)) {
+ pprintf(p, "You cannot set the password of an unregistered player!\n");
+ return COM_OK;
+ }
+ if (player_globals.parray[p1].passwd)
+ free(player_globals.parray[p1].passwd);
+ if (param[1].val.word[0] == '*') {
+ player_globals.parray[p1].passwd = strdup(param[1].val.word);
+ pprintf(p, "Account %s locked!\n", player_globals.parray[p1].name);
+ sprintf(text, "Password of %s is now useless. Your account at our"
+ " FICS has been locked.\n", player_globals.parray[p1].name);
+ pprintf(p, "Please leave a comment to explain why %s's account"
+ " was locked.\n", player_globals.parray[p1].name);
+ pcommand(p, "addcomment %s Account locked.\n", player_globals.parray[p1].name);
+ } else {
+ salt[0] = 'a' + random() % 26;
+ salt[1] = 'a' + random() % 26;
+ salt[2] = '\0';
+ player_globals.parray[p1].passwd = strdup(chessd_crypt(param[1].val.word, salt));
+ sprintf(text, "Password of %s changed to \"%s\".\n", player_globals.parray[p1].name, param[1].val.word);
+ pprintf(p, "%s", text);
+ }
+ if (param[1].val.word[0] == '*') {
+ sprintf(subject, "CHESSD: %s has locked your account.", pp->name);
+ if (connected)
+ pprintf_prompt(p1, "\n%s\n", subject);
+ } else {
+ sprintf(subject, "CHESSD: %s has changed your password.", pp->name);
+ if (connected)
+ pprintf_prompt(p1, "\n%s\n", subject);
+ }
+ mail_string_to_address(player_globals.parray[p1].emailAddress, subject, text);
+ player_save(p1);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+/*
+ * asetemail
+ *
+ * Usage: asetemail player [address]
+ *
+ * Sets the email address of the player to the address given. If the
+ * address is omited, then the player's email address is cleared. The
+ * person's email address is revealed to them when they use the "finger"
+ * command, but no other users -- except admins -- will have another
+ * player's email address displayed.
+ */
+int com_asetemail(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1, connected;
+ char *oldemail;
+
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+
+ if (!check_admin2(p, p1)) {
+ pprintf(p, "You can only set email addr for players below your adminlevel.\n");
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ if (player_globals.parray[p1].emailAddress) {
+ oldemail = strdup(player_globals.parray[p1].emailAddress);
+ free(player_globals.parray[p1].emailAddress);
+ } else {
+ oldemail = strdup("");
+ }
+
+ if (param[1].type == TYPE_NULL) {
+ player_globals.parray[p1].emailAddress = NULL;
+ pprintf(p, "Email address for %s removed\n", player_globals.parray[p1].name);
+ pcommand(p, "addcomment %s Email address removed.\n", player_globals.parray[p1].name);
+
+ } else {
+ player_globals.parray[p1].emailAddress = strdup(param[1].val.word);
+ pprintf(p, "Email address of %s changed to \"%s\".\n", player_globals.parray[p1].name, param[1].val.word);
+ pcommand(p, "addcomment %s Email address changed from %s to %s.\n", player_globals.parray[p1].name, oldemail, player_globals.parray[p1].emailAddress);
+ }
+ free(oldemail);
+ player_save(p1);
+ if (connected) {
+ if (param[1].type == TYPE_NULL) {
+ pprintf_prompt(p1, "\n\n%s has removed your email address.\n\n", pp->name);
+ } else {
+ pprintf_prompt(p1, "\n\n%s has changed your email address.\n\n", pp->name);
+ }
+ } else {
+ player_remove(p1);
+ }
+ return COM_OK;
+}
+
+/*
+ * asetrealname
+ *
+ * Usage: asetrealname user newname
+ *
+ * This command sets the user's real name (as displayed to admins on finger
+ * notes) to "newname".
+ */
+int com_asetrealname(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1, connected;
+
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+
+ if (!check_admin2(p, p1)) {
+ pprintf(p, "You can only set real names for players below your adminlevel.\n");
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ if (player_globals.parray[p1].fullName)
+ free(player_globals.parray[p1].fullName);
+ if (param[1].type == TYPE_NULL) {
+ player_globals.parray[p1].fullName = NULL;
+ pprintf(p, "Real name for %s removed\n", player_globals.parray[p1].name);
+ } else {
+ player_globals.parray[p1].fullName = strdup(param[1].val.word);
+ pprintf(p, "Real name of %s changed to \"%s\".\n", player_globals.parray[p1].name, param[1].val.word);
+ }
+ player_save(p1);
+ if (connected) {
+ if (param[1].type == TYPE_NULL) {
+ pprintf_prompt(p1, "\n\n%s has removed your real name.\n\n", pp->name);
+ } else {
+ pprintf_prompt(p1, "\n\n%s has changed your real name.\n\n", pp->name);
+ }
+ } else {
+ player_remove(p1);
+ }
+ return COM_OK;
+}
+
+/*
+ * asethandle
+ *
+ * Usage: asethandle oldname newname
+ *
+ * This command changes the handle of the player from oldname to
+ * newname. The various player information, messages, logins, comments
+ * and games should be automatically transferred to the new account.
+ */
+int com_asethandle(int p, param_list param)
+{
+ char *player = param[0].val.word;
+ char *newplayer = param[1].val.word;
+ char playerlower[MAX_LOGIN_NAME], newplayerlower[MAX_LOGIN_NAME];
+ int p1;
+
+ strcpy(playerlower, player);
+ stolower(playerlower);
+ strcpy(newplayerlower, newplayer);
+ stolower(newplayerlower);
+ if (player_find_bylogin(playerlower) >= 0) {
+ pprintf(p, "A player by that name is logged in.\n");
+ return COM_OK;
+ }
+ if (player_find_bylogin(newplayerlower) >= 0) {
+ pprintf(p, "A player by that new name is logged in.\n");
+ return COM_OK;
+ }
+ p1 = player_new();
+ if (player_read(p1, playerlower)) {
+ pprintf(p, "No player by the name %s is registered.\n", player);
+ player_remove(p1);
+ return COM_OK;
+ } else {
+ if (!check_admin2(p, p1)) {
+ pprintf(p, "You can't set handles for an admin with a level higher than or equal to yourself.\n");
+ player_remove(p1);
+ return COM_OK;
+ }
+ }
+ player_remove(p1);
+
+ p1 = player_new();
+ if ((!player_read(p1, newplayerlower)) && (strcmp(playerlower, newplayerlower))) {
+ pprintf(p, "Sorry that handle is already taken.\n");
+ player_remove(p1);
+ return COM_OK;
+ }
+ player_remove(p1);
+
+ if ((!player_rename(playerlower, newplayerlower)) && (!player_read(p1, newplayerlower))) {
+ pprintf(p, "Player %s renamed to %s.\n", player, newplayer);
+ free(player_globals.parray[p1].name);
+ player_globals.parray[p1].name = strdup(newplayer);
+ player_save(p1);
+ if (player_globals.parray[p1].s_stats.rating > 0)
+ UpdateRank(TYPE_STAND, newplayer, &player_globals.parray[p1].s_stats, player);
+ if (player_globals.parray[p1].b_stats.rating > 0)
+ UpdateRank(TYPE_BLITZ, newplayer, &player_globals.parray[p1].b_stats, player);
+ if (player_globals.parray[p1].w_stats.rating > 0)
+ UpdateRank(TYPE_WILD, newplayer, &player_globals.parray[p1].w_stats, player);
+ } else {
+ pprintf(p, "Asethandle failed.\n");
+ }
+ player_remove(p1);
+ return COM_OK;
+}
+
+/*
+ * asetadmin
+ *
+ * Usage: asetadmin player AdminLevel
+ *
+ * Sets the admin level of the player with the following restrictions.
+ * 1. You can only set the admin level of players lower than yourself.
+ * 2. You can only set the admin level to a level that is lower than
+ * yourself.
+ */
+int com_asetadmin(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1, connected, oldlevel;
+
+ if (!FindPlayer(p, param[0].val.word,&p1, &connected))
+ return COM_OK;
+
+ if (!check_admin2(p, p1)) {
+ pprintf(p, "You can only set adminlevel for players below your adminlevel.\n");
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ if (!strcmp(player_globals.parray[p1].login, pp->login)) {
+ pprintf(p, "You can't change your own adminlevel.\n");
+ return COM_OK;
+ }
+ if (!check_admin(p, param[1].val.integer+1)) {
+ pprintf(p, "You can't promote someone to or above your adminlevel.\n");
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ oldlevel = player_globals.parray[p1].adminLevel;
+ player_globals.parray[p1].adminLevel = param[1].val.integer;
+ pprintf(p, "Admin level of %s set to %d.\n", player_globals.parray[p1].name, player_globals.parray[p1].adminLevel);
+ player_save(p1);
+ if (connected) {
+ pprintf_prompt(p1, "\n\n%s has set your admin level to %d.\n\n", pp->name, player_globals.parray[p1].adminLevel);
+ } else {
+ player_remove(p1);
+ }
+ return COM_OK;
+}
+
+static void SetRating(int p1, param_list param, struct statistics *s)
+{
+ s->rating = param[1].val.integer;
+ if (s->ltime == 0L)
+ s->sterr = 70.0;
+
+ if (param[2].type == TYPE_INT) {
+ s->win = param[2].val.integer;
+ if (param[3].type == TYPE_INT) {
+ s->los = param[3].val.integer;
+ if (param[4].type == TYPE_INT) {
+ s->dra = param[4].val.integer;
+ if (param[5].type == TYPE_INT) {
+ s->sterr = (double) param[5].val.integer;
+ }
+ }
+ }
+ }
+ s->num = s->win + s->los + s->dra;
+ if (s->num == 0) {
+ s->ltime = 0L;
+#if 0
+ s->dra = 1;
+ s->num = 1;
+#endif
+ } else {
+ s->ltime = time(0);
+ }
+}
+
+/*
+ * asetblitz
+ *
+ * Usage: asetblitz handle rating won lost drew RD
+ *
+ * This command allows admins to set a user's statistics for Blitz games.
+ * The parameters are self-explanatory: rating, # of wins, # of losses,
+ * # of draws, and ratings deviation.
+ */
+int com_asetblitz(int p, param_list param)
+{
+ int p1, connected;
+
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+
+ if (CheckPFlag(p1, PFLAG_REG)) {
+ SetRating(p1, param, &player_globals.parray[p1].b_stats);
+ player_save(p1);
+ UpdateRank(TYPE_BLITZ, player_globals.parray[p1].name, &player_globals.parray[p1].b_stats,
+ player_globals.parray[p1].name);
+ } else
+ pprintf(p, "%s is unregistered. Can't modify rating.\n", player_globals.parray[p1].name);
+
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+/*
+ * asetwild
+ *
+ * Usage: asetwild handle rating won lost drew RD
+ *
+ * This command allows admins to set a user's statistics for Wild games.
+ * The parameters are self-explanatory: rating, # of wins, # of losses,
+ * # of draws, and ratings deviation.
+ */
+int com_asetwild(int p, param_list param)
+{
+ int p1, connected;
+
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+
+ if (CheckPFlag(p1, PFLAG_REG)) {
+ SetRating(p1, param, &player_globals.parray[p1].w_stats);
+ player_save(p1);
+ UpdateRank(TYPE_WILD, player_globals.parray[p1].name, &player_globals.parray[p1].w_stats,
+ player_globals.parray[p1].name);
+ pprintf(p, "Wild rating for %s modified.\n", player_globals.parray[p1].name);
+ } else
+ pprintf(p, "%s is unregistered. Can't modify rating.\n", player_globals.parray[p1].name);
+
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+/*
+ * asetstd
+ *
+ * Usage: asetstd handle rating won lost drew RD
+ *
+ * This command allows admins to set a user's statistics for Standard games.
+ * The parameters are self-explanatory: rating, # of wins, # of losses, # of
+ * draws, and ratings deviation.
+ */
+int com_asetstd(int p, param_list param)
+{
+ int p1, connected;
+
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+
+ if (CheckPFlag(p1, PFLAG_REG)) {
+ SetRating(p1, param, &player_globals.parray[p1].s_stats);
+ player_save(p1);
+ UpdateRank(TYPE_STAND, player_globals.parray[p1].name, &player_globals.parray[p1].s_stats,
+ player_globals.parray[p1].name);
+ pprintf(p, "Standard rating for %s modified.\n", player_globals.parray[p1].name);
+ } else
+ pprintf(p, "%s is unregistered. Can't modify rating.\n", player_globals.parray[p1].name);
+
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+/*
+ * asetlight
+ *
+ * Usage: asetlight handle rating won lost drew RD
+ *
+ * This command allows admins to set a user's statistics for Lightning games.
+ * The parameters are self-explanatory: rating, # of wins, # of losses, # of
+ * draws, and ratings deviation.
+ */
+int com_asetlight(int p, param_list param)
+{
+ int p1, connected;
+
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+
+ if (CheckPFlag(p1, PFLAG_REG)) {
+ SetRating(p1, param, &player_globals.parray[p1].l_stats);
+ player_save(p1);
+ pprintf(p, "Lightning rating for %s modified.\n", player_globals.parray[p1].name);
+ } else
+ pprintf(p, "%s is unregistered. Can't modify rating.\n", player_globals.parray[p1].name);
+
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+/*
+ * asetbug
+ *
+ * Usage: asetbug handle rating won lost drew RD
+ *
+ * This command allows admins to set a user's statistics for Bughouse
+ * games. The parameters are self-explanatory: rating, # of wins,
+ * # of losses, # of draws, and ratings deviation.
+ */
+int com_asetbug(int p, param_list param)
+{
+ int p1, connected;
+
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+
+ if (CheckPFlag(p1, PFLAG_REG)) {
+ SetRating(p1, param, &player_globals.parray[p1].bug_stats);
+ player_save(p1);
+ pprintf(p, "Bughouse rating for %s modified.\n", player_globals.parray[p1].name);
+ } else
+ pprintf(p, "%s is unregistered. Can't modify rating.\n", player_globals.parray[p1].name);
+
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+/* ftell
+ *
+ * Usage: ftell user
+ *
+ * This command forwards all further conversation between an admin and a
+ * user to all those listening in channel 0.
+ * It is unset as soon as the user logs off or ftell is typed without a
+ * parameter.
+ */
+
+int com_ftell(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1;
+ char command[1024];
+
+ if (param[0].type == TYPE_WORD) {
+
+ if ((p1 = player_find_part_login(param[0].val.word)) < 0) {
+ pprintf(p, "%s isn't logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+
+ if (p1 == p) {
+ pprintf (p, "Nobody wants to listen to you talking to yourself! :-)\n");
+ return COM_OK;
+ }
+
+ if (pp->ftell != -1) {
+ sprintf (command, "tell 0 I will no longer be forwarding the conversation between *%s* and myself.", player_globals.parray[pp->ftell].name);
+ pcommand (p,command);
+ }
+
+ sprintf (command, "tell 0 I will be forwarding the conversation between *%s* and myself to channel 0.", player_globals.parray[p1].name);
+ pcommand (p,command);
+
+ pp->ftell = p1;
+ return COM_OK_NOPROMPT;
+
+ } else {
+
+ if (pp->ftell != -1) {
+
+ pprintf (p,"Stopping the forwarding of the conservation with %s.\n",
+ player_globals.parray[pp->ftell].name);
+ pcommand (p,"tell 0 I will no longer be forwarding the conversation between *%s* and myself.",
+ player_globals.parray[pp->ftell].name);
+
+ pp->ftell = -1;
+ return COM_OK_NOPROMPT;
+ } else
+ pprintf (p,"You were not forwarding a conversation.\n");
+ }
+
+ return COM_OK;
+}
+
+/*
+ * nuke
+ *
+ * Usage: nuke user
+ *
+ * This command disconnects the user from the server. The user is informed
+ * that she/he has been nuked by the admin named and a comment is
+ * automatically placed in the user's files (if she/he is a registered
+ * user, of course).
+ */
+int com_nuke(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1, fd;
+
+ if ((p1 = player_find_part_login(param[0].val.word)) < 0) {
+ pprintf(p, "%s isn't logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+
+ if (!check_admin2(p, p1)) {
+ pprintf(p, "You need a higher adminlevel to nuke %s!\n", param[0].val.word);
+ return COM_OK;
+ }
+
+ pprintf(p, "Nuking: %s\n", param[0].val.word);
+ pprintf(p, "Please leave a comment explaining why %s was nuked.\n", player_globals.parray[p1].name);
+ pprintf(p1, "\n\n**** You have been kicked out by %s! ****\n\n", pp->name);
+ pcommand(p, "addcomment %s Nuked\n", player_globals.parray[p1].name);
+ fd = player_globals.parray[p1].socket;
+ process_disconnection(fd);
+ net_close_connection(fd);
+ return COM_OK;
+}
+
+/*
+ * summon
+ *
+ * Usage: summon player
+ *
+ * This command gives a beep and a message to the player indicating that you
+ * want to talk with him/her. The command is useful for waking someone up,
+ * for example a sleepy admin or an ignorant player.
+ */
+int com_summon(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1;
+
+ if ((p1 = player_find_part_login(param[0].val.word)) < 0) {
+ pprintf(p, "%s isn't logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+
+ pprintf(p1, "\a\n");
+ pprintf_highlight(p1, "%s", pp->name);
+ pprintf_prompt(p1, " needs to talk with you. Use tell %s <message> to reply.\a\n", pp->name);
+ pprintf(p, "Summoning sent to %s.\n", player_globals.parray[p1].name);
+ return COM_OK;
+}
+
+/*
+ * addcomment
+ *
+ * Usage: addcomment user comment
+ *
+ * Places "comment" in the user's comments. If a user has comments, the
+ * number of comments is indicated to admins using the "finger" command.
+ * The comments themselves are displayed by the "showcomments" command.
+ */
+int com_addcomment(int p, param_list param)
+{
+ int p1, connected;
+
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+
+ if (player_add_comment(p, p1, param[1].val.string)) {
+ pprintf(p, "Error adding comment!\n");
+ } else {
+ pprintf(p, "Comment added for %s.\n", player_globals.parray[p1].name);
+ player_save(p1);
+ }
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+/*
+ * showcomment
+ *
+ * Usage: showcomment user
+ *
+ * This command will display all of the comments added to the user's account.
+ */
+int com_showcomment(int p, param_list param)
+{
+ int p1, connected;
+
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+ player_show_comments(p, p1);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+/*
+ * admin
+ *
+ * Usage: admin
+ *
+ * This command toggles your admin symbol (*) on/off. This symbol appears
+ * in who listings.
+ */
+int com_admin(int p, param_list param)
+{
+ TogglePFlag(p, PFLAG_ADMINLIGHT);
+ if (CheckPFlag(p, PFLAG_ADMINLIGHT)) {
+ pprintf(p, "Admin mode (*) is now shown.\n");
+ } else {
+ pprintf(p, "Admin mode (*) is now not shown.\n");
+ }
+ return COM_OK;
+}
+
+int com_hideinfo(int p, param_list param)
+{
+ TogglePFlag(p, PFLAG_HIDEINFO);
+
+ if (CheckPFlag(p, PFLAG_HIDEINFO))
+ pprintf(p, "Private user information now not shown.\n");
+ else
+ pprintf(p, "Private user information now shown.\n");
+
+ return COM_OK;
+}
+
+/*
+ * quota
+ *
+ * Usage: quota [n]
+ *
+ * The command sets the number of seconds (n) for the shout quota, which
+ * affects only those persons on the shout quota list. If no parameter
+ * (n) is given, the current setting is displayed.
+ */
+int com_quota(int p, param_list param)
+{
+ if (param[0].type == TYPE_NULL) {
+ pprintf(p, "The current shout quota is 2 shouts per %d seconds.\n", seek_globals.quota_time);
+ return COM_OK;
+ }
+ seek_globals.quota_time = param[0].val.integer;
+ pprintf(p, "The shout quota is now 2 shouts per %d seconds.\n", seek_globals.quota_time);
+ return COM_OK;
+}
+
+
+/*
+ force a server reload
+*/
+int com_areload(int p, param_list param)
+{
+ extern unsigned chessd_reload_flag;
+
+ chessd_reload_flag = 1;
+
+ pprintf(p, "Server reload started\n");
+
+ return COM_OK;
+}
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+
+#include "includes.h"
+
+/* Well, lets see if I can list the possibilities
+ * Piece moves
+ * Ne4
+ * Nxe4
+ * Nce4
+ * Ncxe4
+ * R2f3
+ * R2xf3
+ * Special pawn moves
+ * e4
+ * ed
+ * exd
+ * exd5
+ * ed5
+ * Drop moves (bughouse, board edit)
+ * P@f7 P*f7
+ * #f7 #Nf7
+ * (o-o, o-o-o) Castling is handled earlier, so don't worry about that
+ * Of course any of these can have a + or ++ or = string on the end, just
+ * cut that off.
+ */
+
+/* f - file
+ * r - rank
+ * p - piece
+ * x - x
+ * @ - drop character (bughouse)
+ */
+static char *alg_list[] = {
+ "fxfr", "pxfr", /* These two get confused in case of bishop */
+ "ffr", "pfr", /* These two get confused in case of bishop */
+ "pffr",
+ "pfxfr",
+ "prfr",
+ "prxfr",
+ "fr",
+ "ff",
+ "fxf",
+ "p@fr",
+ "#fr",
+ "#pfr",
+ NULL
+};
+
+#define ALG_UNKNOWN -1
+
+static int get_move_info(const char *str, int *piece, int *ff, int *fr, int *tf, int *tr, int *bishconfusion)
+{
+ char tmp[1024];
+ char *s;
+ int i, j, len;
+ char c;
+ int matchVal = -1;
+ int lpiece, lff, lfr, ltf, ltr;
+
+ *bishconfusion = 0;
+ strlcpy(tmp, str, sizeof(tmp));
+ if ((s = strchr(tmp, '+'))) { /* Cut off any check marks */
+ *s = '\0';
+ }
+ if ((s = strchr(tmp, '='))) { /* Cut off any promotion marks */
+ *s = '\0';
+ }
+ if ((s = strchr(tmp, '#'))) { /* Cut off any 'mates' marks */
+ *s = '\0';
+ }
+ *piece = *ff = *fr = *tf = *tr = ALG_UNKNOWN;
+ len = strlen(tmp);
+ for (i = 0; alg_list[i]; i++) {
+ lpiece = lff = lfr = ltf = ltr = ALG_UNKNOWN;
+ if (strlen(alg_list[i]) != len)
+ continue;
+ for (j = len - 1; j >= 0; j--) {
+ switch (alg_list[i][j]) {
+ case 'f':
+ if ((tmp[j] < 'a') || (tmp[j] > 'h'))
+ goto nomatch;
+ if (ltf == ALG_UNKNOWN)
+ ltf = tmp[j] - 'a';
+ else
+ lff = tmp[j] - 'a';
+ break;
+ case 'r':
+ if ((tmp[j] < '1') || (tmp[j] > '8'))
+ goto nomatch;
+ if (ltr == ALG_UNKNOWN)
+ ltr = tmp[j] - '1';
+ else
+ lfr = tmp[j] - '1';
+ break;
+ case 'p':
+ if (isupper(tmp[j]))
+ c = tolower(tmp[j]);
+ else
+ c = tmp[j];
+ if (c == 'k')
+ lpiece = KING;
+ else if (c == 'q')
+ lpiece = QUEEN;
+ else if (c == 'r')
+ lpiece = ROOK;
+ else if (c == 'b')
+ lpiece = BISHOP;
+ else if (c == 'n')
+ lpiece = KNIGHT;
+ else if (c == 'p')
+ lpiece = PAWN;
+ else
+ goto nomatch;
+ break;
+ case 'x':
+ if ((tmp[j] != 'x') && (tmp[j] != 'X'))
+ goto nomatch;
+ break;
+ case '@':
+ if (tmp[j] != '@' && tmp[j] != '*')
+ goto nomatch;
+ lff = lfr = ALG_DROP;
+ break;
+ case '#':
+ if (tmp[j] != '#')
+ goto nomatch;
+ lff = lfr = ALG_DROP;
+ break;
+ default:
+ d_printf( "Unknown character in algebraic parsing\n");
+ break;
+ }
+ }
+ if (lpiece == ALG_UNKNOWN)
+ lpiece = PAWN;
+ if (lpiece == PAWN && (lfr == ALG_UNKNOWN)) { /* ffr or ff */
+ if (lff != ALG_UNKNOWN) {
+ if (lff == ltf)
+ goto nomatch;
+ if ((lff - ltf != 1) && (ltf - lff != 1))
+ goto nomatch;
+ }
+ }
+ *piece = lpiece; /* We have a match */
+ *tf = ltf;
+ *tr = ltr;
+ *ff = lff;
+ *fr = lfr;
+ if (matchVal != -1) {
+ /* We have two matches, it must be that Bxc4 vs. bxc4 problem */
+ /* Or it could be the Bc4 vs bc4 problem */
+ *bishconfusion = 1;
+ }
+ matchVal = i;
+nomatch:;
+ }
+ if (matchVal != -1)
+ return MS_ALG;
+ else
+ return MS_NOTMOVE;
+}
+
+int alg_is_move(const char *mstr)
+{
+ int piece=0, ff=0, fr=0, tf=0, tr=0, bc=0;
+
+ return get_move_info(mstr, &piece, &ff, &fr, &tf, &tr, &bc);
+}
+
+/* add any promotion qualifier from a move string */
+static void add_promotion(struct game_state_t *gs, const char *mstr, struct move_t * mt)
+{
+ char *s;
+ int piece;
+ s = strchr(mstr, '=');
+ if (s == NULL) {
+ return;
+ }
+
+ if (piecetype(gs->board[mt->fromFile][mt->fromRank]) != PAWN) {
+ return;
+ }
+ if (mt->toRank != 7 && mt->toRank != 0) {
+ return;
+ }
+
+ switch (tolower(s[1])) {
+ case 'q':
+ piece = QUEEN;
+ break;
+ case 'r':
+ piece = ROOK;
+ break;
+ case 'b':
+ piece = BISHOP;
+ break;
+ case 'n':
+ piece = KNIGHT;
+ break;
+ default:
+ return;
+ }
+
+ mt->piecePromotionTo = piece | colorval(gs->board[mt->fromFile][mt->fromRank]);
+}
+
+/* We already know it is algebraic, get the move squares */
+int alg_parse_move(char *mstr, struct game_state_t * gs, struct move_t * mt)
+{
+ int f=0, r=0, tmpr=0, posf=0, posr=0, posr2=0;
+ int piece=0, ff=0, fr=0, tf=0, tr=0, bc=0;
+
+ if (get_move_info(mstr, &piece, &ff, &fr, &tf, &tr, &bc) != MS_ALG) {
+ d_printf( "CHESSD: Shouldn't try to algebraicly parse non-algabraic move string.\n");
+ return MOVE_ILLEGAL;
+ }
+ /* Resolve ambiguities in to-ness */
+ if (tf == ALG_UNKNOWN) {
+ d_printf("Ambiguous %s(%d)\n", __FUNCTION__, __LINE__);
+ return MOVE_AMBIGUOUS; /* Must always know to file */
+ }
+ if (tr == ALG_UNKNOWN) {
+ posr = posr2 = ALG_UNKNOWN;
+ if (piece != PAWN) {
+ d_printf("Ambiguous %s(%d)\n", __FUNCTION__, __LINE__);
+ return MOVE_AMBIGUOUS;
+ }
+ if (ff == ALG_UNKNOWN) {
+ d_printf("Ambiguous %s(%d)\n", __FUNCTION__, __LINE__);
+ return MOVE_AMBIGUOUS;
+ }
+ /* Need to find pawn on ff that can take to tf and fill in ranks */
+ for (InitPieceLoop(gs->board, &f, &r, gs->onMove);
+ NextPieceLoop(gs->board, &f, &r, gs->onMove);) {
+ if ((ff != ALG_UNKNOWN) && (ff != f))
+ continue;
+ if (piecetype(gs->board[f][r]) != piece)
+ continue;
+ if (gs->onMove == WHITE) {
+ tmpr = r + 1;
+ } else {
+ tmpr = r - 1;
+ }
+/* if ((gs->board[tf][tmpr] == NOPIECE) ||
+ (iscolor(gs->board[tf][tmpr], gs->onMove))) continue;*/
+/* patch from Soso, added by Sparky 3/16/95 */
+ if (gs->board[tf][tmpr] == NOPIECE) {
+ if ((gs->ep_possible[((gs->onMove == WHITE) ? 0 : 1)][ff]) != (tf - ff))
+ continue;
+ } else {
+ if (iscolor(gs->board[tf][tmpr], gs->onMove))
+ continue;
+ }
+
+ if (legal_andcheck_move(gs, f, r, tf, tmpr)) {
+ if ((posr != ALG_UNKNOWN) && (posr2 != ALG_UNKNOWN)) {
+ d_printf("Ambiguous %s(%d)\n", __FUNCTION__, __LINE__);
+ return MOVE_AMBIGUOUS;
+ }
+ posr = tmpr;
+ posr2 = r;
+ }
+ }
+ tr = posr;
+ fr = posr2;
+ } else if (bc) { /* Could be bxc4 or Bxc4, tr is known */
+ ff = ALG_UNKNOWN;
+ fr = ALG_UNKNOWN;
+ for (InitPieceLoop(gs->board, &f, &r, gs->onMove);
+ NextPieceLoop(gs->board, &f, &r, gs->onMove);) {
+ if ((piecetype(gs->board[f][r]) != PAWN) && (piecetype(gs->board[f][r]) != BISHOP)) {
+ continue;
+ }
+ if (legal_andcheck_move(gs, f, r, tf, tr)) {
+ if ((piecetype(gs->board[f][r]) == PAWN) && (f != 1)) {
+ continue;
+ }
+
+ /* if its a lowercase 'b' then prefer the pawn move if there is one */
+ if ((ff != ALG_UNKNOWN) && (fr != ALG_UNKNOWN) &&
+ piecetype(gs->board[f][r]) == PAWN && mstr[0] == 'b') {
+ ff = f;
+ fr = r;
+ continue;
+ }
+
+ if ((ff != ALG_UNKNOWN) && (fr != ALG_UNKNOWN) &&
+ piecetype(gs->board[ff][fr]) == PAWN && mstr[0] == 'b') {
+ continue;
+ }
+
+ if ((ff != ALG_UNKNOWN) && (fr != ALG_UNKNOWN)) {
+ d_printf("Ambiguous %s(%d) mstr=%s\n", __FUNCTION__, __LINE__, mstr);
+ return (MOVE_AMBIGUOUS);
+ }
+ ff = f;
+ fr = r;
+ }
+ }
+ } else { /* The from position is unknown */
+ posf = ALG_UNKNOWN;
+ posr = ALG_UNKNOWN;
+ if ((ff == ALG_UNKNOWN) || (fr == ALG_UNKNOWN)) {
+ /* Need to find a piece that can go to tf, tr */
+ for (InitPieceLoop(gs->board, &f, &r, gs->onMove);
+ NextPieceLoop(gs->board, &f, &r, gs->onMove);) {
+ if ((ff != ALG_UNKNOWN) && (ff != f))
+ continue;
+ if ((fr != ALG_UNKNOWN) && (fr != r))
+ continue;
+ if (piecetype(gs->board[f][r]) != piece)
+ continue;
+ if (legal_andcheck_move(gs, f, r, tf, tr)) {
+ if ((posf != ALG_UNKNOWN) && (posr != ALG_UNKNOWN)) {
+ d_printf("Ambiguous %s(%d)\n", __FUNCTION__, __LINE__);
+ return MOVE_AMBIGUOUS;
+ }
+ posf = f;
+ posr = r;
+ }
+ }
+ } else if (ff == ALG_DROP) {
+ if (legal_andcheck_move(gs, ALG_DROP, piece, tf, tr)) {
+ posf = ALG_DROP;
+ posr = piece;
+ }
+ }
+ ff = posf;
+ fr = posr;
+ }
+ if ((tf == ALG_UNKNOWN) || (tr == ALG_UNKNOWN) ||
+ (ff == ALG_UNKNOWN) || (fr == ALG_UNKNOWN))
+ return MOVE_ILLEGAL;
+ mt->fromFile = ff;
+ mt->fromRank = fr;
+ mt->toFile = tf;
+ mt->toRank = tr;
+
+ add_promotion(gs, mstr, mt);
+
+ return MOVE_OK;
+}
+
+/* A assumes the move has yet to be made on the board */
+
+/* Soso: rewrote alg_unparse function.
+ * Algebraic deparser - sets the mStr variable with move description
+ * in short notation. Used in last move report and in 'moves' command.
+ */
+
+char *alg_unparse(struct game_state_t * gs, struct move_t * mt)
+{
+ static char mStr[20];
+ char tmp[20];
+ int piece, f, r;
+ int ambig, r_ambig, f_ambig;
+ struct game_state_t fakeMove;
+
+ if (mt->fromFile == ALG_DROP) {
+ piece = mt->fromRank;
+ } else {
+ piece = piecetype(gs->board[mt->fromFile][mt->fromRank]);
+ }
+
+ if ((piece == KING) && ((mt->fromFile == 4) && (mt->toFile == 6))) {
+ strcpy(mStr, "O-O");
+ goto check;
+ }
+ if ((piece == KING) && ((mt->fromFile == 4) && (mt->toFile == 2))) {
+ strcpy(mStr, "O-O-O");
+ goto check;
+ }
+ strcpy(mStr, "");
+ switch (piece) {
+ case PAWN:
+ if (mt->fromFile == ALG_DROP) {
+ strcpy(mStr,"P");
+ } else if (mt->fromFile != mt->toFile) {
+ sprintf(tmp, "%c", mt->fromFile + 'a');
+ strcpy(mStr, tmp);
+ }
+ break;
+ case KNIGHT:
+ strcpy(mStr, "N");
+ break;
+ case BISHOP:
+ strcpy(mStr, "B");
+ break;
+ case ROOK:
+ strcpy(mStr, "R");
+ break;
+ case QUEEN:
+ strcpy(mStr, "Q");
+ break;
+ case KING:
+ strcpy(mStr, "K");
+ break;
+ default:
+ strcpy(mStr, "");
+ break;
+ }
+
+ if (mt->fromFile == ALG_DROP) {
+ strcat(mStr, "@");
+ } else {
+ /* Checks for ambiguity in short notation ( Ncb3, R8e8 or so) */
+ if (piece != PAWN) {
+ ambig = r_ambig = f_ambig = 0;
+ for (r = 0; r < 8; r++)
+ for (f = 0; f < 8; f++) {
+ if ((gs->board[f][r] != NOPIECE) && iscolor(gs->board[f][r], gs->onMove)
+ && (piecetype(gs->board[f][r]) == piece) &&
+ ((f != mt->fromFile) || (r != mt->fromRank))) {
+ if (legal_move(gs, f, r, mt->toFile, mt->toRank)) {
+ fakeMove = *gs;
+ fakeMove.board[f][r] = NOPIECE;
+ fakeMove.board[mt->toFile][mt->toRank] = piece | gs->onMove;
+ fakeMove.onMove = CToggle(fakeMove.onMove);
+ gs->onMove = CToggle(gs->onMove);
+
+#if 0
+ d_printf("possible move %c%d%c%d against %c%d%c%d\n",
+ 'a' + f, r+1,
+ 'a' + mt->toFile, mt->toRank+1,
+ 'a' + mt->fromFile, mt->fromRank+1,
+ 'a' + mt->toFile, mt->toRank+1);
+#endif
+
+ if (!in_check(&fakeMove)) {
+ ambig++;
+ if (f == mt->fromFile) {
+ ambig++;
+ f_ambig++;
+ }
+ if (r == mt->fromRank) {
+ ambig++;
+ r_ambig++;
+ }
+ }
+ gs->onMove = CToggle(gs->onMove);
+ }
+ }
+ }
+ if (ambig > 0) {
+ /* Ambiguity in short notation, need to add file,rank or _both_ in
+ notation */
+ if (f_ambig == 0) {
+ sprintf(tmp, "%c", mt->fromFile + 'a');
+ strcat(mStr, tmp);
+ } else if (r_ambig == 0) {
+ sprintf(tmp, "%d", mt->fromRank + 1);
+ strcat(mStr, tmp);
+ } else {
+ sprintf(tmp, "%c%d", mt->fromFile + 'a', mt->fromRank + 1);
+ strcat(mStr, tmp);
+ }
+ }
+ }
+ if ((gs->board[mt->toFile][mt->toRank] != NOPIECE) ||
+ ((piece == PAWN) && (mt->fromFile != mt->toFile))) {
+ strcat(mStr, "x");
+ }
+ }
+ sprintf(tmp, "%c%d", mt->toFile + 'a', mt->toRank + 1);
+ strcat(mStr, tmp);
+
+ if ((piece == PAWN) && (mt->piecePromotionTo != NOPIECE)) {
+ strcat(mStr, "="); /* = before promoting piece */
+ switch (piecetype(mt->piecePromotionTo)) {
+ case KNIGHT:
+ strcat(mStr, "N");
+ break;
+ case BISHOP:
+ strcat(mStr, "B");
+ break;
+ case ROOK:
+ strcat(mStr, "R");
+ break;
+ case QUEEN:
+ strcat(mStr, "Q");
+ break;
+ default:
+ break;
+ }
+ }
+check:;
+ fakeMove = *gs;
+ execute_move(&fakeMove, mt, 0);
+ fakeMove.onMove = CToggle(fakeMove.onMove);
+ if (in_check(&fakeMove)) {
+ strcat(mStr, "+");
+ }
+ return mStr;
+}
--- /dev/null
+/* autoconfig.h.in. Generated automatically from configure.in by autoheader. */
+
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define if you don't have vprintf but do have _doprnt. */
+#undef HAVE_DOPRNT
+
+/* Define if you have the strftime function. */
+#undef HAVE_STRFTIME
+
+/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define if you have the vprintf function. */
+#undef HAVE_VPRINTF
+
+/* Define if you have the wait3 system call. */
+#undef HAVE_WAIT3
+
+/* Define as the return type of signal handlers (int or void). */
+#undef RETSIGTYPE
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+#undef size_t
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define if your <sys/time.h> declares struct tm. */
+#undef TM_IN_SYS_TIME
+
+#undef HAVE_DLOPEN
+
+/* Define if you have the dlopen function. */
+#undef HAVE_DLOPEN
+
+/* Define if you have the dprintf function. */
+#undef HAVE_DPRINTF
+
+/* Define if you have the gethostname function. */
+#undef HAVE_GETHOSTNAME
+
+/* Define if you have the gettimeofday function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define if you have the select function. */
+#undef HAVE_SELECT
+
+/* Define if you have the socket function. */
+#undef HAVE_SOCKET
+
+/* Define if you have the strcspn function. */
+#undef HAVE_STRCSPN
+
+/* Define if you have the strdup function. */
+#undef HAVE_STRDUP
+
+/* Define if you have the strlcat function. */
+#undef HAVE_STRLCAT
+
+/* Define if you have the strlcpy function. */
+#undef HAVE_STRLCPY
+
+/* Define if you have the strnlen function. */
+#undef HAVE_STRNLEN
+
+/* Define if you have the strstr function. */
+#undef HAVE_STRSTR
+
+/* Define if you have the <dirent.h> header file. */
+#undef HAVE_DIRENT_H
+
+/* Define if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define if you have the <ndir.h> header file. */
+#undef HAVE_NDIR_H
+
+/* Define if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define if you have the <sys/dir.h> header file. */
+#undef HAVE_SYS_DIR_H
+
+/* Define if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define if you have the <sys/ioctl.h> header file. */
+#undef HAVE_SYS_IOCTL_H
+
+/* Define if you have the <sys/md5.h> header file. */
+#undef HAVE_SYS_MD5_H
+
+/* Define if you have the <sys/ndir.h> header file. */
+#undef HAVE_SYS_NDIR_H
+
+/* Define if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define if you have the m library (-lm). */
+#undef HAVE_LIBM
+
+/* */
+#undef HAVE_COMPAR_FN_T
+
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+
+
+#include "includes.h"
+
+
+const char *wpstring[] = {" ", "P", "N", "B", "R", "Q", "K"};
+static const char *bpstring[] = {" ", "p", "n", "b", "r", "q", "k"};
+
+static int pieceValues[7] = {0, 1, 3, 3, 5, 9, 0};
+
+static const int mach_type = (1<<7) | (1<<8) | (1<<9) | (1<<10) | (1<<11);
+#define IsMachineStyle(n) (((1<<(n)) & mach_type) != 0)
+
+static char bstring[MAX_BOARD_STRING_LEGTH];
+
+static int board_read_file(char *category, char *gname, struct game_state_t *gs);
+static void wild_update(int style);
+
+static int style1(struct game_state_t *b, struct move_t *ml);
+static int style2(struct game_state_t *b, struct move_t *ml);
+static int style3(struct game_state_t *b, struct move_t *ml);
+static int style4(struct game_state_t *b, struct move_t *ml);
+static int style5(struct game_state_t *b, struct move_t *ml);
+static int style6(struct game_state_t *b, struct move_t *ml);
+static int style7(struct game_state_t *b, struct move_t *ml);
+static int style8(struct game_state_t *b, struct move_t *ml);
+static int style9(struct game_state_t *b, struct move_t *ml);
+static int style10(struct game_state_t *b, struct move_t *ml);
+static int style11(struct game_state_t *b, struct move_t *ml);
+static int style12(struct game_state_t *b, struct move_t *ml);
+static int style13(struct game_state_t *b, struct move_t *ml);
+
+static int (*styleFuncs[MAX_STYLES])() = {
+ style1,
+ style2,
+ style3,
+ style4,
+ style5,
+ style6,
+ style7,
+ style8,
+ style9,
+ style10,
+ style11,
+ style12,
+ style13
+};
+
+
+static void reset_board_vars(struct game_state_t *gs)
+{
+ int f,r;
+
+ for (f = 0; f < 2; f++) {
+ for (r = 0; r < 8; r++)
+ gs->ep_possible[f][r] = 0;
+ for (r = PAWN; r <= QUEEN; r++)
+ gs->holding[f][r-PAWN] = 0;
+ }
+ gs->wkmoved = gs->wqrmoved = gs->wkrmoved = 0;
+ gs->bkmoved = gs->bqrmoved = gs->bkrmoved = 0;
+ gs->onMove = WHITE;
+ gs->moveNum = 1;
+ gs->lastIrreversable = -1;
+ gs->gameNum = -1;
+}
+
+void board_clear(struct game_state_t *gs)
+{
+ int f,r;
+
+ for (f = 0; f < 8; f++)
+ for (r = 0; r < 8; r++)
+ gs->board[f][r] = NOPIECE;
+ reset_board_vars(gs);
+}
+
+void board_standard(struct game_state_t *gs)
+{
+ int f,r;
+
+ for (f = 0; f < 8; f++)
+ for (r = 2; r < 6; r++)
+ gs->board[f][r] = NOPIECE;
+ for (f = 0; f < 8; f++)
+ gs->board[f][1] = W_PAWN;
+ for (f = 0; f < 8; f++)
+ gs->board[f][6] = B_PAWN;
+ gs->board[0][0] = W_ROOK;
+ gs->board[1][0] = W_KNIGHT;
+ gs->board[2][0] = W_BISHOP;
+ gs->board[3][0] = W_QUEEN;
+ gs->board[4][0] = W_KING;
+ gs->board[5][0] = W_BISHOP;
+ gs->board[6][0] = W_KNIGHT;
+ gs->board[7][0] = W_ROOK;
+ gs->board[0][7] = B_ROOK;
+ gs->board[1][7] = B_KNIGHT;
+ gs->board[2][7] = B_BISHOP;
+ gs->board[3][7] = B_QUEEN;
+ gs->board[4][7] = B_KING;
+ gs->board[5][7] = B_BISHOP;
+ gs->board[6][7] = B_KNIGHT;
+ gs->board[7][7] = B_ROOK;
+ reset_board_vars(gs);
+}
+
+int board_init(int g,struct game_state_t *b, char *category, char *board)
+{
+ int retval = 0;
+ int wval;
+
+ if (!category || !board || !category[0] || !board[0])
+ /* accounts for bughouse too */
+ board_standard(b);
+ else {
+ if (!strcmp(category, "wild")) {
+ if (sscanf(board, "%d", &wval) == 1 && wval >= 1 && wval <= 4)
+ wild_update(wval);
+ }
+ retval = board_read_file(category, board, b);
+ }
+ MakeFENpos(g, game_globals.garray[g].FENstartPos);
+ return retval;
+}
+
+void board_calc_strength(struct game_state_t *b, int *ws, int *bs)
+{
+ int r, f;
+ int *p;
+
+ *ws = *bs = 0;
+ for (f = 0; f < 8; f++) {
+ for (r = 0; r < 8; r++) {
+ if (colorval(b->board[r][f]) == WHITE)
+ p = ws;
+ else
+ p = bs;
+ *p += pieceValues[piecetype(b->board[r][f])];
+ }
+ }
+ for (r = PAWN; r <= QUEEN; r++) {
+ *ws += b->holding[0][r-1] * pieceValues[r];
+ *bs += b->holding[1][r-1] * pieceValues[r];
+ }
+}
+
+static char *holding_str(int *holding)
+{
+ static char tmp[30];
+ int p,i,j;
+
+ i = 0;
+ for (p = PAWN; p <= QUEEN; p++) {
+ for (j = 0; j < holding[p-1]; j++) {
+ tmp[i++] = wpstring[p][0];
+ }
+ }
+ tmp[i] = '\0';
+ return tmp;
+}
+
+static char *append_holding_machine(char *buf, int g, int c, int p)
+{
+ struct game_state_t *gs = &game_globals.garray[g].game_state;
+ char tmp[50];
+
+ sprintf(tmp, "<b1> game %d white [%s] black [", g+1, holding_str(gs->holding[0]));
+ strcat(tmp, holding_str(gs->holding[1]));
+ strcat(buf, tmp);
+ if (p) {
+ sprintf(tmp, "] <- %c%s\n", "WB"[c], wpstring[p]);
+ strcat(buf, tmp);
+ } else
+ strcat(buf, "]\n");
+ return buf;
+}
+
+static char *append_holding_display(char *buf, struct game_state_t *gs, int white)
+{
+ if (white)
+ strcat(buf, "White holding: [");
+ else
+ strcat(buf, "Black holding: [");
+ strcat(buf, holding_str(gs->holding[white ? 0 : 1]));
+ strcat(buf, "]\n");
+ return buf;
+}
+
+void update_holding(int g, int pieceCaptured)
+{
+ int p = piecetype(pieceCaptured);
+ int c = colorval(pieceCaptured);
+ struct game_state_t *gs = &game_globals.garray[g].game_state;
+ int pp, pl;
+ char tmp1[80], tmp2[80];
+
+ if (c == WHITE) {
+ c = 0;
+ pp = game_globals.garray[g].white;
+ } else {
+ c = 1;
+ pp = game_globals.garray[g].black;
+ }
+ gs->holding[c][p-1]++;
+ tmp1[0] = '\0';
+ append_holding_machine(tmp1, g, c, p);
+ sprintf(tmp2, "Game %d %s received: %s -> [%s]\n", g+1,
+ player_globals.parray[pp].name, wpstring[p], holding_str(gs->holding[c]));
+ for (pl = 0; pl < player_globals.p_num; pl++) {
+ if (player_globals.parray[pl].status == PLAYER_EMPTY)
+ continue;
+ if (player_is_observe(pl, g) || (player_globals.parray[pl].game == g)) {
+ pprintf_prompt(pl, IsMachineStyle(player_globals.parray[pl].style) ? tmp1 : tmp2);
+ }
+ }
+}
+
+
+/* Globals used for each board */
+static int wTime, bTime;
+static int orient;
+static int forPlayer;
+static int myTurn; /* 1 = my turn, 0 = observe, -1 = other turn */
+ /* 2 = examiner, -2 = observing examiner */
+ /* -3 = just send position (spos/refresh) */
+
+char *board_to_string(char *wn, char *bn,
+ int wt, int bt,
+ struct game_state_t *b, struct move_t *ml, int style,
+ int orientation, int relation,
+ int p)
+{
+ int bh = (b->gameNum >= 0 && game_globals.garray[b->gameNum].link >= 0);
+ orient = orientation;
+ myTurn = relation;
+
+ wTime = 0;
+ bTime = 0;
+
+ /* when examining we calculate times based on the time left when the
+ move happened, not current time */
+ if (game_globals.garray[b->gameNum].status == GAME_EXAMINE) {
+ unsigned nhm = game_globals.garray[b->gameNum].numHalfMoves;
+ if (nhm > 0) {
+ wTime = ml[nhm - 1].wTime;
+ bTime = ml[nhm - 1].bTime;
+ } else {
+ wTime = game_globals.garray[b->gameNum].wInitTime;
+ bTime = game_globals.garray[b->gameNum].bInitTime;
+ }
+ }
+
+ /* cope with old stored games */
+ if (wTime == 0) wTime = wt;
+ if (bTime == 0) bTime = bt;
+
+ forPlayer = p;
+ if ((style < 0) || (style >= MAX_STYLES))
+ return NULL;
+
+ if (style != 11) { /* game header */
+ sprintf(bstring, "Game %d (%s vs. %s)\n\n",
+ b->gameNum + 1,
+ game_globals.garray[b->gameNum].white_name,
+ game_globals.garray[b->gameNum].black_name);
+ } else
+ bstring[0] = '\0';
+ if (bh && !IsMachineStyle(style))
+ append_holding_display(bstring, b, orientation==BLACK);
+ if (styleFuncs[style] (b, ml))
+ return NULL;
+ if (bh) {
+ if (IsMachineStyle(style))
+ append_holding_machine(bstring, b->gameNum, 0, 0);
+ else
+ append_holding_display(bstring, b, orientation==WHITE);
+ }
+ return bstring;
+}
+
+char *move_and_time(struct move_t *m)
+{
+ static char tmp[20];
+ sprintf(tmp, "%-7s (%s)", m->algString, tenth_str(m->tookTime, 0));
+ return tmp;
+}
+
+/* The following take the game state and whole move list */
+
+static int genstyle(struct game_state_t *b, struct move_t *ml, const char *wp[], const char *bp[],
+ const char *wsqr, const char *bsqr,
+ const char *top, const char *mid, const char *start, const char *end,
+ const char *label,const char *blabel)
+{
+ int f, r, count;
+ char tmp[80];
+ int first, last, inc;
+ int ws, bs;
+
+ board_calc_strength(b, &ws, &bs);
+ if (orient == WHITE) {
+ first = 7;
+ last = 0;
+ inc = -1;
+ } else {
+ first = 0;
+ last = 7;
+ inc = 1;
+ }
+ strcat(bstring, top);
+ for (f = first, count = 7; f != last + inc; f += inc, count--) {
+ sprintf(tmp, " %d %s", f + 1, start);
+ strcat(bstring, tmp);
+ for (r = last; r != first - inc; r = r - inc) {
+ if (square_color(r, f) == WHITE)
+ strcat(bstring, wsqr);
+ else
+ strcat(bstring, bsqr);
+ if (piecetype(b->board[r][f]) == NOPIECE) {
+ if (square_color(r, f) == WHITE)
+ strcat(bstring, bp[0]);
+ else
+ strcat(bstring, wp[0]);
+ } else {
+ if (colorval(b->board[r][f]) == WHITE)
+ strcat(bstring, wp[piecetype(b->board[r][f])]);
+ else
+ strcat(bstring, bp[piecetype(b->board[r][f])]);
+ }
+ }
+ sprintf(tmp, "%s", end);
+ strcat(bstring, tmp);
+ switch (count) {
+ case 7:
+ sprintf(tmp, " Move # : %d (%s)", b->moveNum, CString(b->onMove));
+ strcat(bstring, tmp);
+ break;
+ case 6:
+/* if ((b->moveNum > 1) || (b->onMove == BLACK)) { */
+/* The change from the above line to the one below is a kludge by hersco. */
+ if (game_globals.garray[b->gameNum].numHalfMoves > 0) {
+/* loon: think this fixes the crashing ascii board on takeback bug */
+ sprintf(tmp, " %s Moves : '%s'", CString(CToggle(b->onMove)),
+ move_and_time(&ml[game_globals.garray[b->gameNum].numHalfMoves - 1]));
+ strcat(bstring, tmp);
+ }
+ break;
+ case 5:
+ break;
+ case 4:
+ sprintf(tmp, " Black Clock : %s", tenth_str(((bTime > 0) ? bTime : 0), 1));
+ strcat(bstring, tmp);
+ break;
+ case 3:
+ sprintf(tmp, " White Clock : %s", tenth_str(((wTime > 0) ? wTime : 0), 1));
+ strcat(bstring, tmp);
+ break;
+ case 2:
+ sprintf(tmp, " Black Strength : %d", bs);
+ strcat(bstring, tmp);
+ break;
+ case 1:
+ sprintf(tmp, " White Strength : %d", ws);
+ strcat(bstring, tmp);
+ break;
+ case 0:
+ break;
+ }
+ strcat(bstring, "\n");
+ if (count != 0)
+ strcat(bstring, mid);
+ else
+ strcat(bstring, top);
+ }
+ if (orient == WHITE)
+ strcat(bstring, label);
+ else
+ strcat(bstring, blabel);
+ return 0;
+}
+
+/* Experimental ANSI board for colour representation */
+static int style13(struct game_state_t *b, struct move_t *ml)
+{
+ static const char *wp[] = {" ", "\033[37m\033[1m P ", "\033[37m\033[1m N ", "\033[37m\033[1m B ", "\033[37m\033[1m R ", "\033[37m\033[1m Q ", "\033[37m\033[1m K "};
+ static const char *bp[] = {" ", "\033[21m\033[37m P ", "\033[21m\033[37m N ", "\033[21m\033[37m B ", "\033[21m\033[37m R ", "\033[21m\033[37m Q ", "\033[21m\033[37m K "};
+ static const char *wsqr = "\033[40m";
+ static const char *bsqr = "\033[45m";
+ static const char *top = "\t+------------------------+\n";
+ static const char *mid = "";
+ static const char *start = "|";
+ static const char *end = "\033[0m|";
+ static const char *label = "\t a b c d e f g h\n";
+ static const char *blabel = "\t h g f e d c b a\n";
+
+ return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
+}
+
+/* Standard ICS */
+static int style1(struct game_state_t *b, struct move_t *ml)
+{
+ static const char *wp[] = {" |", " P |", " N |", " B |", " R |", " Q |", " K |"};
+ static const char *bp[] = {" |", " *P|", " *N|", " *B|", " *R|", " *Q|", " *K|"};
+ static char *wsqr = "";
+ static char *bsqr = "";
+ static char *top = "\t---------------------------------\n";
+ static char *mid = "\t|---+---+---+---+---+---+---+---|\n";
+ static char *start = "|";
+ static char *end = "";
+ static char *label = "\t a b c d e f g h\n";
+ static char *blabel = "\t h g f e d c b a\n";
+
+ return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
+}
+
+/* USA-Today Sports Center-style board */
+static int style2(struct game_state_t *b, struct move_t *ml)
+{
+ static const char *wp[] = {"+ ", "P ", "N ", "B ", "R ", "Q ", "K "};
+ static const char *bp[] = {"- ", "p' ", "n' ", "b' ", "r' ", "q' ", "k' "};
+ static char *wsqr = "";
+ static char *bsqr = "";
+ static char *top = "";
+ static char *mid = "";
+ static char *start = "";
+ static char *end = "";
+ static char *label = "\ta b c d e f g h\n";
+ static char *blabel = "\th g f e d c b a\n";
+
+ return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
+}
+
+/* Experimental vt-100 ANSI board for dark backgrounds */
+static int style3(struct game_state_t *b, struct move_t *ml)
+{
+ static const char *wp[] = {" ", " P ", " N ", " B ", " R ", " Q ", " K "};
+ static const char *bp[] = {" ", " *P", " *N", " *B", " *R", " *Q", " *K"};
+ static char *wsqr = "\033[0m";
+ static char *bsqr = "\033[7m";
+ static char *top = "\t+------------------------+\n";
+ static char *mid = "";
+ static char *start = "|";
+ static char *end = "\033[0m|";
+ static char *label = "\t a b c d e f g h\n";
+ static char *blabel = "\t h g f e d c b a\n";
+
+ return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
+}
+
+/* Experimental vt-100 ANSI board for light backgrounds */
+static int style4(struct game_state_t *b, struct move_t *ml)
+{
+ static const char *wp[] = {" ", " P ", " N ", " B ", " R ", " Q ", " K "};
+ static const char *bp[] = {" ", " *P", " *N", " *B", " *R", " *Q", " *K"};
+ static char *wsqr = "\033[7m";
+ static char *bsqr = "\033[0m";
+ static char *top = "\t+------------------------+\n";
+ static char *mid = "";
+ static char *start = "|";
+ static char *end = "\033[0m|";
+ static char *label = "\t a b c d e f g h\n";
+ static char *blabel = "\t h g f e d c b a\n";
+
+ return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
+}
+
+/* Style suggested by ajpierce@med.unc.edu */
+static int style5(struct game_state_t *b, struct move_t *ml)
+{
+ static const char *wp[] = {" ", " o ", " :N:", " <B>", " |R|", " {Q}", " =K="};
+ static const char *bp[] = {" ", " p ", " :n:", " <b>", " |r|", " {q}", " =k="};
+ static char *wsqr = "";
+ static char *bsqr = "";
+ static char *top = " . . . . . . . . .\n";
+ static char *mid = " . . . . . . . . .\n";
+ static char *start = "";
+ static char *end = "";
+ static char *label = "\t a b c d e f g h\n";
+ static char *blabel = "\t h g f e d c b a\n";
+
+ return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
+}
+
+/* Email Board suggested by Thomas Fought (tlf@rsch.oclc.org) */
+static int style6(struct game_state_t *b, struct move_t *ml)
+{
+ static const char *wp[] = {" |", " wp |", " WN |", " WB |", " WR |", " WQ |", " WK |"};
+ static const char *bp[] = {" |", " bp |", " BN |", " BB |", " BR |", " BQ |", " BK |"};
+ static char *wsqr = "";
+ static char *bsqr = "";
+ static char *top = "\t-----------------------------------------\n";
+ static char *mid = "\t-----------------------------------------\n";
+ static char *start = "|";
+ static char *end = "";
+ static char *label = "\t A B C D E F G H\n";
+ static char *blabel = "\t H G F E D C B A\n";
+
+ return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
+}
+
+/* Miniature board */
+static int style7(struct game_state_t *b, struct move_t *ml)
+{
+ static const char *wp[] = {" ", " P", " N", " B", " R", " Q", " K"};
+ static const char *bp[] = {" -", " p", " n", " b", " r", " q", " k"};
+ static char *wsqr = "";
+ static char *bsqr = "";
+ static char *top = "\t:::::::::::::::::::::\n";
+ static char *mid = "";
+ static char *start = "..";
+ static char *end = " ..";
+ static char *label = "\t a b c d e f g h\n";
+ static char *blabel = "\t h g f e d c b a\n";
+
+ return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
+}
+
+/* ICS interface maker board-- raw data dump */
+static int style8(struct game_state_t *b, struct move_t *ml)
+{
+ char tmp[80];
+ int f, r;
+ int ws, bs;
+
+ board_calc_strength(b, &ws, &bs);
+ sprintf(tmp, "#@#%03d%-16s%s%-16s%s", b->gameNum + 1,
+ game_globals.garray[b->gameNum].white_name,
+ (orient == WHITE) ? "*" : ":",
+ game_globals.garray[b->gameNum].black_name,
+ (orient == WHITE) ? ":" : "*");
+ strcat(bstring, tmp);
+ for (r = 0; r < 8; r++) {
+ for (f = 0; f < 8; f++) {
+ if (b->board[f][r] == NOPIECE) {
+ strcat(bstring, " ");
+ } else {
+ if (colorval(b->board[f][r]) == WHITE)
+ strcat(bstring, wpstring[piecetype(b->board[f][r])]);
+ else
+ strcat(bstring, bpstring[piecetype(b->board[f][r])]);
+ }
+ }
+ }
+ sprintf(tmp, "%03d%s%02d%02d%05d%05d%-7s(%s)@#@\n",
+ game_globals.garray[b->gameNum].numHalfMoves / 2 + 1,
+ (b->onMove == WHITE) ? "W" : "B",
+ ws,
+ bs,
+ (wTime + 5) / 10,
+ (bTime + 5) / 10,
+ game_globals.garray[b->gameNum].numHalfMoves ?
+ ml[game_globals.garray[b->gameNum].numHalfMoves - 1].algString :
+ "none",
+ game_globals.garray[b->gameNum].numHalfMoves ?
+ tenth_str(ml[game_globals.garray[b->gameNum].numHalfMoves - 1].tookTime, 0) :
+ "0:00");
+ strcat(bstring, tmp);
+ return 0;
+}
+
+/* last 2 moves only (previous non-verbose mode) */
+static int style9(struct game_state_t *b, struct move_t *ml)
+{
+ int i, count;
+ char tmp[80];
+ int startmove;
+
+ sprintf(tmp, "\nMove %-23s%s\n",
+ game_globals.garray[b->gameNum].white_name,
+ game_globals.garray[b->gameNum].black_name);
+ strcat(bstring, tmp);
+ sprintf(tmp, "---- -------------- --------------\n");
+ strcat(bstring, tmp);
+ startmove = ((game_globals.garray[b->gameNum].numHalfMoves - 3) / 2) * 2;
+ if (startmove < 0)
+ startmove = 0;
+ for (i = startmove, count = 0;
+ i < game_globals.garray[b->gameNum].numHalfMoves && count < 4;
+ i++, count++) {
+ if (!(i & 0x01)) {
+ sprintf(tmp, " %2d ", i / 2 + 1);
+ strcat(bstring, tmp);
+ }
+ sprintf(tmp, "%-23s", move_and_time(&ml[i]));
+ strcat(bstring, tmp);
+ if (i & 0x01)
+ strcat(bstring, "\n");
+ }
+ if (i & 0x01)
+ strcat(bstring, "\n");
+ return 0;
+}
+
+/* Sleator's 'new and improved' raw dump format... */
+static int style10(struct game_state_t *b, struct move_t *ml)
+{
+ int f, r;
+ char tmp[80];
+ int ws, bs;
+
+ board_calc_strength(b, &ws, &bs);
+ sprintf(tmp, "<10>\n");
+ strcat(bstring, tmp);
+ for (r = 7; r >= 0; r--) {
+ strcat(bstring, "|");
+ for (f = 0; f < 8; f++) {
+ if (b->board[f][r] == NOPIECE) {
+ strcat(bstring, " ");
+ } else {
+ if (colorval(b->board[f][r]) == WHITE)
+ strcat(bstring, wpstring[piecetype(b->board[f][r])]);
+ else
+ strcat(bstring, bpstring[piecetype(b->board[f][r])]);
+ }
+ }
+ strcat(bstring, "|\n");
+ }
+ strcat(bstring, (b->onMove == WHITE) ? "W " : "B ");
+ if (game_globals.garray[b->gameNum].numHalfMoves) {
+ sprintf(tmp, "%d ",
+ ml[game_globals.garray[b->gameNum].numHalfMoves - 1].doublePawn);
+ } else {
+ sprintf(tmp, "-1 ");
+ }
+ strcat(bstring, tmp);
+ sprintf(tmp, "%d %d %d %d %d\n",
+ !(b->wkmoved || b->wkrmoved),
+ !(b->wkmoved || b->wqrmoved),
+ !(b->bkmoved || b->bkrmoved),
+ !(b->bkmoved || b->bqrmoved),
+ (game_globals.garray[b->gameNum].numHalfMoves - ((b->lastIrreversable == -1) ? 0 :
+ b->lastIrreversable)));
+ strcat(bstring, tmp);
+ sprintf(tmp, "%d %s %s %d %d %d %d %d %d %d %d %s (%s) %s %d\n",
+ b->gameNum,
+ game_globals.garray[b->gameNum].white_name,
+ game_globals.garray[b->gameNum].black_name,
+ myTurn,
+ game_globals.garray[b->gameNum].wInitTime / 600,
+ game_globals.garray[b->gameNum].wIncrement / 10,
+ ws,
+ bs,
+ (wTime + 5) / 10,
+ (bTime + 5) / 10,
+ game_globals.garray[b->gameNum].numHalfMoves / 2 + 1,
+ game_globals.garray[b->gameNum].numHalfMoves ?
+ ml[game_globals.garray[b->gameNum].numHalfMoves - 1].moveString :
+ "none",
+ game_globals.garray[b->gameNum].numHalfMoves ?
+ tenth_str(ml[game_globals.garray[b->gameNum].numHalfMoves - 1].tookTime, 0) :
+ "0:00",
+ game_globals.garray[b->gameNum].numHalfMoves ?
+ ml[game_globals.garray[b->gameNum].numHalfMoves - 1].algString :
+ "none",
+ (orient == WHITE) ? 0 : 1);
+ strcat(bstring, tmp);
+ sprintf(tmp, ">10<\n");
+ strcat(bstring, tmp);
+ return 0;
+}
+
+/* Same as 8, but with verbose moves ("P/e3-e4", instead of "e4") */
+static int style11(struct game_state_t *b, struct move_t *ml)
+{
+ char tmp[80];
+ int f, r;
+ int ws, bs;
+
+ board_calc_strength(b, &ws, &bs);
+ sprintf(tmp, "#@#%03d%-16s%s%-16s%s", b->gameNum,
+ game_globals.garray[b->gameNum].white_name,
+ (orient == WHITE) ? "*" : ":",
+ game_globals.garray[b->gameNum].black_name,
+ (orient == WHITE) ? ":" : "*");
+ strcat(bstring, tmp);
+ for (r = 0; r < 8; r++) {
+ for (f = 0; f < 8; f++) {
+ if (b->board[f][r] == NOPIECE) {
+ strcat(bstring, " ");
+ } else {
+ if (colorval(b->board[f][r]) == WHITE)
+ strcat(bstring, wpstring[piecetype(b->board[f][r])]);
+ else
+ strcat(bstring, bpstring[piecetype(b->board[f][r])]);
+ }
+ }
+ }
+ sprintf(tmp, "%03d%s%02d%02d%05d%05d%-7s(%s)@#@\n",
+ game_globals.garray[b->gameNum].numHalfMoves / 2 + 1,
+ (b->onMove == WHITE) ? "W" : "B",
+ ws,
+ bs,
+ (wTime + 5) / 10,
+ (bTime + 5) / 10,
+ game_globals.garray[b->gameNum].numHalfMoves ?
+ ml[game_globals.garray[b->gameNum].numHalfMoves - 1].moveString :
+ "none",
+ game_globals.garray[b->gameNum].numHalfMoves ?
+ tenth_str(ml[game_globals.garray[b->gameNum].numHalfMoves - 1].tookTime, 0) :
+ "0:00");
+ strcat(bstring, tmp);
+ return 0;
+}
+
+/* Similar to style 10. See the "style12" help file for information */
+static int style12(struct game_state_t *b, struct move_t *ml)
+{
+ int f, r;
+ char tmp[80];
+ int ws, bs;
+
+ board_calc_strength(b, &ws, &bs);
+ sprintf(bstring, "<12> ");
+ for (r = 7; r >= 0; r--) {
+ for (f = 0; f < 8; f++) {
+ if (b->board[f][r] == NOPIECE) {
+ strcat(bstring, "-");
+ } else {
+ if (colorval(b->board[f][r]) == WHITE)
+ strcat(bstring, wpstring[piecetype(b->board[f][r])]);
+ else
+ strcat(bstring, bpstring[piecetype(b->board[f][r])]);
+ }
+ }
+ strcat(bstring, " ");
+ }
+ strcat(bstring, (b->onMove == WHITE) ? "W " : "B ");
+ if (game_globals.garray[b->gameNum].numHalfMoves) {
+ sprintf(tmp, "%d ",
+ ml[game_globals.garray[b->gameNum].numHalfMoves - 1].doublePawn);
+ } else {
+ sprintf(tmp, "-1 ");
+ }
+ strcat(bstring, tmp);
+ sprintf(tmp, "%d %d %d %d %d ",
+ !(b->wkmoved || b->wkrmoved),
+ !(b->wkmoved || b->wqrmoved),
+ !(b->bkmoved || b->bkrmoved),
+ !(b->bkmoved || b->bqrmoved),
+ (game_globals.garray[b->gameNum].numHalfMoves - ((b->lastIrreversable == -1) ? 0 : b->lastIrreversable)));
+ strcat(bstring, tmp);
+ sprintf(tmp, "%d %s %s %d %d %d %d %d %d %d %d %s (%s) %s %d %d\n",
+ b->gameNum + 1,
+ game_globals.garray[b->gameNum].white_name,
+ game_globals.garray[b->gameNum].black_name,
+ myTurn,
+ game_globals.garray[b->gameNum].wInitTime / 600,
+ game_globals.garray[b->gameNum].wIncrement / 10,
+ ws,
+ bs,
+ (wTime / 10),
+ (bTime / 10),
+ game_globals.garray[b->gameNum].numHalfMoves / 2 + 1,
+ game_globals.garray[b->gameNum].numHalfMoves ?
+ ml[game_globals.garray[b->gameNum].numHalfMoves - 1].moveString :
+ "none",
+ game_globals.garray[b->gameNum].numHalfMoves ?
+ tenth_str(ml[game_globals.garray[b->gameNum].numHalfMoves - 1].tookTime, 0) :
+ "0:00",
+ game_globals.garray[b->gameNum].numHalfMoves ?
+ ml[game_globals.garray[b->gameNum].numHalfMoves - 1].algString :
+ "none", (orient == WHITE) ? 0 : 1,
+ b->moveNum > 1 ? 1 : 0); /* ticking */
+
+ strcat(bstring, tmp);
+ return 0;
+}
+
+static int board_read_file(char *category, char *gname, struct game_state_t *gs)
+{
+ FILE *fp;
+ int c;
+ int onNewLine = 1;
+ int onColor = -1;
+ int onPiece = -1;
+ int onFile = -1;
+ int onRank = -1;
+
+ fp = fopen_p("%s/%s/%s", "r", BOARD_DIR, category, gname);
+ if (!fp)
+ return 1;
+
+ board_clear(gs);
+ while (!feof(fp)) {
+ c = fgetc(fp);
+ if (onNewLine) {
+ if (c == 'W') {
+ onColor = WHITE;
+ if (gs->onMove < 0)
+ gs->onMove = WHITE;
+ } else if (c == 'B') {
+ onColor = BLACK;
+ if (gs->onMove < 0)
+ gs->onMove = BLACK;
+ } else if (c == '#') {
+ while (!feof(fp) && c != '\n')
+ c = fgetc(fp); /* Comment line */
+ continue;
+ } else { /* Skip any line we don't understand */
+ while (!feof(fp) && c != '\n')
+ c = fgetc(fp);
+ continue;
+ }
+ onNewLine = 0;
+ } else {
+ switch (c) {
+ case 'P':
+ onPiece = PAWN;
+ break;
+ case 'R':
+ onPiece = ROOK;
+ break;
+ case 'N':
+ onPiece = KNIGHT;
+ break;
+ case 'B':
+ onPiece = BISHOP;
+ break;
+ case 'Q':
+ onPiece = QUEEN;
+ break;
+ case 'K':
+ onPiece = KING;
+ break;
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ case 'g':
+ case 'h':
+ onFile = c - 'a';
+ onRank = -1;
+ break;
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ onRank = c - '1';
+ if (onFile >= 0 && onColor >= 0 && onPiece >= 0)
+ gs->board[onFile][onRank] = onPiece | onColor;
+ break;
+ case '#':
+ while (!feof(fp) && c != '\n')
+ c = fgetc(fp); /* Comment line */
+ case '\n':
+ onNewLine = 1;
+ onColor = -1;
+ onPiece = -1;
+ onFile = -1;
+ onRank = -1;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ fclose(fp);
+ return 0;
+}
+
+#define WHITE_SQUARE 1
+#define BLACK_SQUARE 0
+#define ANY_SQUARE -1
+#define SquareColor(f, r) ((f ^ r) & 1)
+
+static void place_piece(board_t b, int piece, int squareColor)
+{
+ int r, f;
+ int placed = 0;
+
+ if (iscolor(piece, BLACK))
+ r = 7;
+ else
+ r = 0;
+
+ while (!placed) {
+ if (squareColor == ANY_SQUARE) {
+ f = random() % 8;
+ } else {
+ f = (random() % 4) * 2;
+ if (SquareColor(f, r) != squareColor)
+ f++;
+ }
+ if ((b)[f][r] == NOPIECE) {
+ (b)[f][r] = piece;
+ placed = 1;
+ }
+ }
+}
+
+static void wild_update(int style)
+{
+ int f, r, i;
+ board_t b;
+
+ for (f = 0; f < 8; f++)
+ for (r = 0; r < 8; r++)
+ b[f][r] = NOPIECE;
+ for (f = 0; f < 8; f++) {
+ b[f][1] = W_PAWN;
+ b[f][6] = B_PAWN;
+ }
+ switch (style) {
+ case 1:
+ if (random() & 0x01) {
+ b[4][0] = W_KING;
+ b[3][0] = W_QUEEN;
+ } else {
+ b[3][0] = W_KING;
+ b[4][0] = W_QUEEN;
+ }
+ if (random() & 0x01) {
+ b[4][7] = B_KING;
+ b[3][7] = B_QUEEN;
+ } else {
+ b[3][7] = B_KING;
+ b[4][7] = B_QUEEN;
+ }
+ b[0][0] = b[7][0] = W_ROOK;
+ b[0][7] = b[7][7] = B_ROOK;
+ /* Must do bishops before knights to be sure opposite colored squares are
+ available. */
+ place_piece(b, W_BISHOP, WHITE_SQUARE);
+ place_piece(b, W_BISHOP, BLACK_SQUARE);
+ place_piece(b, W_KNIGHT, ANY_SQUARE);
+ place_piece(b, W_KNIGHT, ANY_SQUARE);
+ place_piece(b, B_BISHOP, WHITE_SQUARE);
+ place_piece(b, B_BISHOP, BLACK_SQUARE);
+ place_piece(b, B_KNIGHT, ANY_SQUARE);
+ place_piece(b, B_KNIGHT, ANY_SQUARE);
+ break;
+ case 2:
+ place_piece(b, W_KING, ANY_SQUARE);
+ place_piece(b, W_QUEEN, ANY_SQUARE);
+ place_piece(b, W_ROOK, ANY_SQUARE);
+ place_piece(b, W_ROOK, ANY_SQUARE);
+ place_piece(b, W_BISHOP, ANY_SQUARE);
+ place_piece(b, W_BISHOP, ANY_SQUARE);
+ place_piece(b, W_KNIGHT, ANY_SQUARE);
+ place_piece(b, W_KNIGHT, ANY_SQUARE);
+ /* Black mirrors White */
+ for (i = 0; i < 8; i++) {
+ b[i][7] = b[i][0] | BLACK;
+ }
+ break;
+ case 3:
+ /* Generate White king on random square plus random set of pieces */
+ place_piece(b, W_KING, ANY_SQUARE);
+ for (i = 0; i < 8; i++) {
+ if (b[i][0] != W_KING) {
+ b[i][0] = (random() % 4) + 2;
+ }
+ }
+ /* Black mirrors White */
+ for (i = 0; i < 8; i++) {
+ b[i][7] = b[i][0] | BLACK;
+ }
+ break;
+ case 4:
+ /* Generate White king on random square plus random set of pieces */
+ place_piece(b, W_KING, ANY_SQUARE);
+ for (i = 0; i < 8; i++) {
+ if (b[i][0] != W_KING) {
+ b[i][0] = (random() % 4) + 2;
+ }
+ }
+ /* Black has same set of pieces, but randomly permuted, except that Black
+ must have the same number of bishops on white squares as White has on
+ black squares, and vice versa. So we must place Black's bishops first
+ to be sure there are enough squares left of the correct color. */
+ for (i = 0; i < 8; i++) {
+ if (b[i][0] == W_BISHOP) {
+ place_piece(b, B_BISHOP, !SquareColor(i, 0));
+ }
+ }
+ for (i = 0; i < 8; i++) {
+ if (b[i][0] != W_BISHOP) {
+ place_piece(b, b[i][0] | BLACK, ANY_SQUARE);
+ }
+ }
+ break;
+ default:
+ return;
+ break;
+ }
+ {
+ FILE *fp;
+ int onPiece;
+
+ fp = fopen_p("%s/wild/%d", "w", BOARD_DIR, style);
+ if (!fp) {
+ d_printf( "CHESSD: Can't write wild style %d\n", style);
+ return;
+ }
+ fprintf(fp, "W:");
+ onPiece = -1;
+ for (r = 1; r >= 0; r--) {
+ for (f = 0; f < 8; f++) {
+ if (onPiece < 0 || b[f][r] != onPiece) {
+ onPiece = b[f][r];
+ fprintf(fp, " %s", wpstring[piecetype(b[f][r])]);
+ }
+ fprintf(fp, " %c%c", f + 'a', r + '1');
+ }
+ }
+ fprintf(fp, "\nB:");
+ onPiece = -1;
+ for (r = 6; r < 8; r++) {
+ for (f = 0; f < 8; f++) {
+ if (onPiece < 0 || b[f][r] != onPiece) {
+ onPiece = b[f][r];
+ fprintf(fp, " %s", wpstring[piecetype(b[f][r])]);
+ }
+ fprintf(fp, " %c%c", f + 'a', r + '1');
+ }
+ }
+ fprintf(fp, "\n");
+ fclose(fp);
+ }
+}
+
+void wild_init(void)
+{
+ wild_update(1);
+ wild_update(2);
+ wild_update(3);
+ wild_update(4);
+}
+
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+
+#ifndef _BOARD_H
+#define _BOARD_H
+
+#define WHITE 0x00
+#define BLACK 0x80
+#define CString( c ) ( ((c) == WHITE) ? "White" : "Black" )
+#define CToggle( c ) ( ((c) == BLACK) ? WHITE : BLACK )
+
+/* These will go into an array */
+
+#define NOPIECE 0x00
+#define PAWN 0x01
+#define KNIGHT 0x02
+#define BISHOP 0x03
+#define ROOK 0x04
+#define QUEEN 0x05
+#define KING 0x06
+
+#define MAX_BOARD_STRING_LEGTH 1280 /* Abitrarily 80 * 16 */
+#define MAX_STYLES 13
+
+#define W_PAWN (PAWN | WHITE)
+#define W_KNIGHT (KNIGHT | WHITE)
+#define W_BISHOP (BISHOP | WHITE)
+#define W_ROOK (ROOK | WHITE)
+#define W_QUEEN (QUEEN | WHITE)
+#define W_KING (KING | WHITE)
+
+#define B_PAWN (PAWN | BLACK)
+#define B_KNIGHT (KNIGHT | BLACK)
+#define B_BISHOP (BISHOP | BLACK)
+#define B_ROOK (ROOK | BLACK)
+#define B_QUEEN (QUEEN | BLACK)
+#define B_KING (KING | BLACK)
+
+#define isblack(p) ((p) & BLACK)
+#define iswhite(p) (!isblack(p))
+#define iscolor(p,color) (((p) & BLACK) == (color))
+#define piecetype(p) ((p) & 0x7f)
+#define colorval(p) ((p) & 0x80)
+#define square_color(r,f) ((((r)+(f)) & 0x01) ? BLACK : WHITE)
+
+extern int pieceValues[7];
+
+/* Treated as [file][rank] */
+typedef int board_t[8][8];
+
+GENSTRUCT struct game_state_t {
+ int board[8][8];
+ /* for bughouse */
+ int holding[2][5];
+ /* For castling */
+ unsigned char wkmoved, wqrmoved, wkrmoved;
+ unsigned char bkmoved, bqrmoved, bkrmoved;
+ /* for ep */
+ int ep_possible[2][8];
+ /* For draws */
+ int lastIrreversable;
+ int onMove;
+ int moveNum;
+ /* Game num not saved, must be restored when read */
+ int gameNum;
+};
+
+#define ALG_DROP -2
+
+/* bughouse: if a drop move, then fromFile is ALG_DROP and fromRank is piece */
+
+GENSTRUCT struct move_t {
+ int color;
+ int fromFile, fromRank;
+ int toFile, toRank;
+ int pieceCaptured;
+ int piecePromotionTo;
+ int enPassant; /* 0 = no, 1=higher -1= lower */
+ int doublePawn; /* Only used for board display */
+ char moveString[8]; _NULLTERM
+ char algString[8]; _NULLTERM
+ unsigned char FENpos[74]; _NULLTERM
+ unsigned atTime;
+ unsigned tookTime;
+
+ /* these are used when examining a game */
+ int wTime;
+ int bTime;
+};
+
+#define MoveToHalfMove( gs ) ((((gs)->moveNum - 1) * 2) + (((gs)->onMove == WHITE) ? 0 : 1))
+
+extern const char *wpstring[];
+extern const char *bpstring[];
+
+/* the FEN for the default initial position */
+#define INITIAL_FEN "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w"
+
+#endif
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+#include "includes.h"
+#include "command_list.h"
+
+static const char *usage_dir[NUM_LANGS] = {USAGE_DIR, USAGE_SPANISH,
+ USAGE_FRENCH, USAGE_DANISH};
+
+static int lastCommandFound = -1;
+
+static char *guest_name(void);
+static int check_user(char *user);
+
+/* Copies command into comm, and returns pointer to parameters in
+ * parameters
+ */
+static int parse_command(char *com_string,
+ char **comm,
+ char **parameters)
+{
+ *comm = com_string;
+ *parameters = eatword(com_string);
+ if (**parameters != '\0') {
+ **parameters = '\0';
+ (*parameters)++;
+ *parameters = eatwhite(*parameters);
+ }
+ if (strlen(*comm) >= MAX_COM_LENGTH) {
+ return COM_BADCOMMAND;
+ }
+ return COM_OK;
+}
+
+/* numalias is the maximum number to search through */
+int alias_lookup(char *tmp, struct alias_type *alias_list, int numalias)
+{
+ int i;
+
+ for (i = 0; i < numalias && alias_list[i].comm_name; i++) {
+ if (!strcasecmp(tmp, alias_list[i].comm_name))
+ return i;
+ }
+ return -1; /* not found */
+}
+
+/* Puts alias substitution into alias_string */
+static void alias_substitute(struct alias_type *alias_list, int num_alias,
+ char *com_str, char outalias[])
+{
+ char *name, *atpos;
+ int i;
+ int at_offset=0;
+
+ /* handle punctuation commands like '+' */
+ if (ispunct(*com_str)) {
+ int n;
+ for (n=0;ispunct(com_str[n]);n++) ;
+ name = strndup(com_str, n);
+ } else {
+ name = strndup(com_str, strcspn(com_str, " \t"));
+ }
+ com_str += strlen(name);
+
+ while (isspace(*com_str)) com_str++;
+
+ i = alias_lookup(name, alias_list, num_alias);
+
+ if (i >= 0) {
+ free(name);
+ name = strdup(alias_list[i].alias);
+ }
+
+ /* now substitute '@' values in name */
+ while ((atpos = strchr(name+at_offset, '@'))) {
+ char *name2 = NULL;
+ asprintf(&name2, "%*.*s%s%s",
+ atpos-name, atpos-name, name,
+ com_str,
+ atpos+1);
+ if (!name2) break;
+
+ /* try to prevent loops */
+ at_offset = (atpos - name) + strlen(com_str);
+
+ free(name);
+ name = name2;
+ }
+
+ /* there is an implicit @ after each alias */
+ if (at_offset == 0 && *com_str) {
+ sprintf(outalias, "%s %s", name, com_str);
+ } else {
+ strcpy(outalias, name);
+ }
+
+ free(name);
+}
+
+/* Returns pointer to command that matches */
+static int match_command(char *comm, int p)
+{
+ int i = 0;
+ int gotIt = -1;
+ int len = strlen(comm);
+
+ while (command_list[i].comm_name) {
+ if (strncmp(command_list[i].comm_name, comm, len) == 0 &&
+ check_admin(p, command_list[i].adminLevel)) {
+ if (gotIt >= 0)
+ return -COM_AMBIGUOUS;
+ gotIt = i;
+ }
+ i++;
+ }
+
+ if (gotIt == -1) {
+ return -COM_FAILED;
+ }
+
+ if (in_list(p, L_REMOVEDCOM, command_list[gotIt].comm_name)) {
+ pprintf(p, "Due to a bug - this command has been temporarily removed.\n");
+ return -COM_FAILED;
+ }
+ lastCommandFound = gotIt;
+ return gotIt;
+}
+
+/* Gets the parameters for this command */
+static int get_parameters(int command, char *parameters, param_list params)
+{
+ int i, parlen;
+ int paramLower;
+ char c;
+ static char punc[2];
+
+ punc[1] = '\0'; /* Holds punc parameters */
+ for (i = 0; i < MAXNUMPARAMS; i++)
+ (params)[i].type = TYPE_NULL; /* Set all parameters to NULL */
+ parlen = strlen(command_list[command].param_string);
+ for (i = 0; i < parlen; i++) {
+ c = command_list[command].param_string[i];
+ if (isupper(c)) {
+ paramLower = 0;
+ c = tolower(c);
+ } else {
+ paramLower = 1;
+ }
+ switch (c) {
+ case 'w':
+ case 'o': /* word or optional word */
+ parameters = eatwhite(parameters);
+ if (!*parameters)
+ return (c == 'o' ? COM_OK : COM_BADPARAMETERS);
+ (params)[i].val.word = parameters;
+ (params)[i].type = TYPE_WORD;
+ if (ispunct(*parameters)) {
+ punc[0] = *parameters;
+ (params)[i].val.word = punc;
+ parameters++;
+ if (*parameters && isspace(*parameters))
+ parameters++;
+ } else {
+ parameters = eatword(parameters);
+ if (*parameters != '\0') {
+ *parameters = '\0';
+ parameters++;
+ }
+ }
+ if (paramLower)
+ stolower((params)[i].val.word);
+ break;
+
+ case 'd':
+ case 'p': /* optional or required integer */
+ parameters = eatwhite(parameters);
+ if (!*parameters)
+ return (c == 'p' ? COM_OK : COM_BADPARAMETERS);
+ if (sscanf(parameters, "%d", &(params)[i].val.integer) != 1)
+ return COM_BADPARAMETERS;
+ (params)[i].type = TYPE_INT;
+ parameters = eatword(parameters);
+ if (*parameters != '\0') {
+ *parameters = '\0';
+ parameters++;
+ }
+ break;
+
+ case 'i':
+ case 'n': /* optional or required word or integer */
+ parameters = eatwhite(parameters);
+ if (!*parameters)
+ return (c == 'n' ? COM_OK : COM_BADPARAMETERS);
+ if (sscanf(parameters, "%d", &(params)[i].val.integer) != 1) {
+ (params)[i].val.word = parameters;
+ (params)[i].type = TYPE_WORD;
+ } else {
+ (params)[i].type = TYPE_INT;
+ }
+ if (ispunct(*parameters)) {
+ punc[0] = *parameters;
+ (params)[i].val.word = punc;
+ (params)[i].type = TYPE_WORD;
+ parameters++;
+ if (*parameters && isspace(*parameters))
+ parameters++;
+ } else {
+ parameters = eatword(parameters);
+ if (*parameters != '\0') {
+ *parameters = '\0';
+ parameters++;
+ }
+ }
+ if ((params)[i].type == TYPE_WORD)
+ if (paramLower)
+ stolower((params)[i].val.word);
+ break;
+
+ case 's':
+ case 't': /* optional or required string to end */
+ if (!*parameters)
+ return (c == 't' ? COM_OK : COM_BADPARAMETERS);
+ (params)[i].val.string = parameters;
+ (params)[i].type = TYPE_STRING;
+ while (*parameters)
+ parameters = nextword(parameters);
+ if (paramLower)
+ stolower((params)[i].val.string);
+ break;
+ }
+ }
+ if (*parameters)
+ return COM_BADPARAMETERS;
+ else
+ return COM_OK;
+}
+
+static void printusage(int p, char *command_str)
+{
+ struct player *pp = &player_globals.parray[p];
+ int i, parlen, UseLang = pp->language;
+ int command;
+ char c;
+
+ char *filenames[1000]; /* enough for all usage names */
+
+ if ((command = match_command(command_str, p)) < 0) {
+ pprintf(p, " UNKNOWN COMMAND\n");
+ return;
+ }
+
+/*Usage added by DAV 11/19/95 */
+ /* First lets check if we have a text usage file for it */
+
+ i = search_directory(usage_dir[UseLang], command_str, filenames, 1000);
+ if (i == 0) { /* nope none in current Lang */
+ if (UseLang != LANG_DEFAULT) {
+ i += search_directory(usage_dir[LANG_DEFAULT], command_str, filenames, 1000);
+ if (i > 0) {
+ pprintf(p, "No usage available in %s; using %s instead.\n",
+ Language(UseLang), Language(LANG_DEFAULT));
+ UseLang = LANG_DEFAULT;
+ }
+ }
+ }
+
+ if (i != 0) {
+ if ((i == 1) || (!strcmp(*filenames, command_str))) { /* found it? then send */
+ if (psend_file(p, usage_dir[UseLang], *filenames)) {
+ /* we should never reach this unless the file was just deleted */
+ pprintf(p, "Usage file %s could not be found! ", *filenames);
+ pprintf(p, "Please inform an admin of this. Thank you.\n");
+ /* no need to print 'system' usage - should never happen */
+ }
+ pprintf(p, "\nSee '%s %s' for a complete description.\n",
+ ((command_list[lastCommandFound].adminLevel > ADMIN_USER) ? "ahelp" :
+"help"),
+ command_list[lastCommandFound].comm_name);
+ return;
+ }
+ }
+
+ /* print the default 'system' usage files (which aren't much help!) */
+
+ pprintf(p, "Usage: %s", command_list[lastCommandFound].comm_name);
+
+ parlen = strlen(command_list[command].param_string);
+ for (i = 0; i < parlen; i++) {
+ c = command_list[command].param_string[i];
+ if (isupper(c))
+ c = tolower(c);
+ switch (c) {
+ case 'w': /* word */
+ pprintf(p, " word");
+ break;
+ case 'o': /* optional word */
+ pprintf(p, " [word]");
+ break;
+ case 'd': /* integer */
+ pprintf(p, " integer");
+ break;
+ case 'p': /* optional integer */
+ pprintf(p, " [integer]");
+ break;
+ case 'i': /* word or integer */
+ pprintf(p, " {word, integer}");
+ break;
+ case 'n': /* optional word or integer */
+ pprintf(p, " [{word, integer}]");
+ break;
+ case 's': /* string to end */
+ pprintf(p, " string");
+ break;
+ case 't': /* optional string to end */
+ pprintf(p, " [string]");
+ break;
+ }
+ }
+ pprintf(p, "\nSee '%s %s' for a complete description.\n",
+ ((command_list[lastCommandFound].adminLevel > ADMIN_USER) ? "ahelp" :
+"help"),
+ command_list[lastCommandFound].comm_name);
+}
+
+static int one_command(int p, char *command, char **cmd)
+{
+ struct player *pp = &player_globals.parray[p];
+ int which_command, retval;
+ char *comm=NULL, *parameters=NULL;
+ param_list params;
+
+ if ((retval = parse_command(command, &comm, ¶meters)))
+ return retval;
+ if (pp->game >= 0) {
+ if ((game_globals.garray[pp->game].status == GAME_SETUP) && (is_drop(comm)))
+ return COM_ISMOVE;
+ }
+ if (is_move(comm)) {
+ if (pp->game == -1) {
+ pprintf(p, "You are not playing or examining a game.\n");
+ return COM_OK;
+ }
+
+ if (game_globals.garray[pp->game].status == GAME_SETUP)
+ return COM_ISMOVE_INSETUP;
+ else
+ return COM_ISMOVE;
+ }
+ stolower(comm); /* All commands are case-insensitive */
+ *cmd = comm;
+ if ((which_command = match_command(comm, p)) < 0)
+ return -which_command;
+ if (!check_admin(p, command_list[which_command].adminLevel)) {
+ return COM_RIGHTS;
+ }
+ if ((retval = get_parameters(which_command, parameters, params)))
+ return retval;
+
+ if (command_list[which_command].adminLevel >= ADMIN_ADMIN) {
+ admin_log(pp, command, params);
+ }
+
+ return command_list[which_command].comm_func(p, params);
+}
+
+static int process_command(int p, char *com_string, char **cmd)
+{
+ struct player *pp = &player_globals.parray[p];
+ char *tok;
+ char *ptr = NULL;
+ char astring1[MAX_STRING_LENGTH * 4];
+ char astring2[MAX_STRING_LENGTH * 4];
+
+#ifdef DEBUG
+ if (strcasecmp(pp->name, pp->login)) {
+ d_printf( "CHESSD: PROBLEM Name=%s, Login=%s\n",
+ pp->name, pp->login);
+ }
+#endif
+ if (!com_string)
+ return COM_FAILED;
+#ifdef DEBUG
+ d_printf( "%s, %s, %d: >%s<\n",
+ pp->name, pp->login, pp->socket, com_string);
+#endif
+
+ /* don't expand the alias command */
+ if (strncmp(com_string, "alias ", 6) == 0) {
+ return one_command(p, com_string, cmd);
+ }
+
+ /* don't expand the alias command */
+ if (com_string[0] == '$') {
+ return one_command(p, eatwhite(com_string+1), cmd);
+ }
+
+ alias_substitute(pp->alias_list, pp->numAlias,
+ com_string, astring1);
+ alias_substitute(g_alias_list, 999,
+ astring1, astring2);
+
+#ifdef DEBUG
+ if (strcmp(com_string, astring2) != 0) {
+ d_printf( "%s -alias-: >%s< >%s<\n",
+ pp->name, com_string, astring2);
+ }
+#endif
+
+ for (tok=strtok_r(astring2, ";", &ptr); tok; tok=strtok_r(NULL, ";", &ptr)) {
+ char alias_string1[MAX_STRING_LENGTH * 4];
+ char alias_string2[MAX_STRING_LENGTH * 4];
+ int retval;
+ while (isspace(*tok)) tok++;
+
+ alias_substitute(pp->alias_list, pp->numAlias,
+ tok, alias_string1);
+ alias_substitute(g_alias_list, 999,
+ alias_string1, alias_string2);
+
+#ifdef DEBUG
+ if (strcmp(tok, alias_string2) != 0) {
+ d_printf( "%s -alias2-: >%s<\n",
+ pp->name, alias_string2);
+ }
+#endif
+
+ retval = one_command(p, alias_string2, cmd);
+
+ /* stop on first error */
+ if (retval != COM_OK) return retval;
+ }
+
+ return COM_OK;
+}
+
+static int process_login(int p, char *loginname)
+{
+ struct player *pp = &player_globals.parray[p];
+ char loginnameii[80];
+ int is_guest = 0;
+
+ loginname = eatwhite(loginname);
+
+ if (!*loginname) {
+ goto new_login;
+ }
+
+ /* if 'guest' was specified then pick a random guest name */
+ if (strcasecmp(loginname, config_get_tmp("GUEST_LOGIN")) == 0) {
+ loginname = guest_name();
+ is_guest = 1;
+ pprintf(p,"\nCreated temporary login '%s'\n", loginname);
+ }
+
+ strlcpy(loginnameii, loginname, sizeof(loginnameii));
+
+ if (!alphastring(loginnameii)) {
+ pprintf(p, "\nSorry, names can only consist of lower and upper case letters. Try again.\n");
+ goto new_login;
+ }
+ if (strlen(loginnameii) < 3) {
+ pprintf(p, "\nA name should be at least three characters long! Try again.\n");
+ goto new_login;
+ }
+
+ if (strlen(loginnameii) > (MAX_LOGIN_NAME - 1)) {
+ pprintf(p, "\nSorry, names may be at most %d characters long. Try again.\n",
+ MAX_LOGIN_NAME - 1);
+ goto new_login;
+ }
+
+ if (in_list(p, L_BAN, loginnameii)) {
+ pprintf(p, "\nPlayer \"%s\" is banned.\n", loginnameii);
+ return COM_LOGOUT;
+ }
+
+ if (!in_list(p, L_ADMIN, loginnameii) &&
+ player_count(0) >= config_get_int("MAX_PLAYER", DEFAULT_MAX_PLAYER)) {
+ psend_raw_file(p, MESS_DIR, MESS_FULL);
+ return COM_LOGOUT;
+ }
+
+ if (player_read(p, loginnameii) != 0) {
+ if (!is_guest &&
+ config_get_int("GUEST_PREFIX_ONLY", DEFAULT_GUEST_PREFIX_ONLY)) {
+ goto new_login;
+ }
+ /* they are not registered */
+ strcpy(pp->name, loginnameii);
+ if (in_list(p, L_FILTER, dotQuad(pp->thisHost))) {
+ pprintf(p, "\nDue to abusive behavior, nobody from your site may login.\n");
+ pprintf(p, "If you wish to use this server please email %s\n",
+ config_get_tmp("REGISTRATION_ADDRESS"));
+ pprintf(p, "Include details of a nick-name to be called here, e-mail address and your real name.\n");
+ pprintf(p, "We will send a password to you. Thanks.\n");
+ return COM_LOGOUT;
+ }
+
+ if (player_count(0) >= config_get_int("MAX_PLAYER", DEFAULT_MAX_PLAYER) - 100) {
+ psend_raw_file(p, MESS_DIR, MESS_FULL_UNREG);
+ return COM_LOGOUT;
+ }
+
+ pprintf_noformat(p, "\n\"%s\" is not a registered name. You may play unrated games as a guest.\n(After logging in, do \"help register\" for more info on how to register.)\n\nPress return to enter the FICS as \"%s\":",
+ loginnameii, loginnameii);
+ pp->status = PLAYER_PASSWORD;
+ turn_echo_off(pp->socket);
+ return COM_OK;
+ }
+
+ pprintf_noformat(p, "\n\"%s\" is a registered name. If it is yours, type the password.\nIf not, just hit return to try another name.\n\npassword: ",
+ pp->name);
+ pp->status = PLAYER_PASSWORD;
+ turn_echo_off(pp->socket);
+ if (strcasecmp(loginnameii, pp->name)) {
+ pprintf(p, "\nYou've got a bad name field in your playerfile -- please report this to an admin!\n");
+ return COM_LOGOUT;
+ }
+
+ if (CheckPFlag(p, PFLAG_REG)
+ && (pp->fullName == NULL)) {
+ pprintf(p, "\nYou've got a bad playerfile -- please report this to an admin!\n");
+ pprintf(p, "Your FullName is missing!");
+ pprintf(p, "Please log on as an unreg until an admin can correct this.\n");
+ return COM_LOGOUT;
+ }
+ if (CheckPFlag(p, PFLAG_REG)
+ && (pp->emailAddress == NULL)) {
+ pprintf(p, "\nYou've got a bad playerfile -- please report this to an admin!\n");
+ pprintf(p, "Your Email address is missing\n");
+ pprintf(p, "Please log on as an unreg until an admin can correct this.\n");
+ return COM_LOGOUT;
+ }
+
+
+ return COM_OK;
+
+new_login:
+ /* give them a new prompt */
+ psend_raw_file(p, MESS_DIR, MESS_LOGIN);
+ pprintf(p, "login: ");
+ return COM_OK;
+}
+
+static void boot_out(int p, int p1)
+{
+ struct player *pp = &player_globals.parray[p];
+ int fd;
+ pprintf(p, "\n **** %s is already logged in - kicking them out. ****\n", pp->name);
+ pprintf(p1, "**** %s has arrived - you can't both be logged in. ****\n", pp->name);
+ fd = player_globals.parray[p1].socket;
+ process_disconnection(fd);
+ net_close_connection(fd);
+}
+
+static int process_password(int p, char *password)
+{
+ struct player *pp = &player_globals.parray[p];
+ static int Current_ad;
+ int p1;
+ char salt[3];
+ int fd;
+ struct in_addr fromHost;
+ int messnum;
+ char fname[10];
+ int dummy; /* (to hold a return value) */
+
+ turn_echo_on(pp->socket);
+
+ if (pp->passwd && CheckPFlag(p, PFLAG_REG)) {
+ salt[0] = pp->passwd[3];
+ salt[1] = pp->passwd[4];
+ salt[2] = '\0';
+ if (strcmp(chessd_crypt(password,salt), pp->passwd)) {
+ fd = pp->socket;
+ fromHost = pp->thisHost;
+ if (*password) {
+ pprintf(p, "\n\n**** Invalid password! ****\n\n");
+ d_printf("FICS (process_password): Bad password for %s [%s] [%s] [%s]\n",
+ pp->login,
+ password,
+ salt,
+ pp->passwd);
+ }
+ player_clear(p);
+ pp->logon_time = pp->last_command_time = time(0);
+ pp->status = PLAYER_LOGIN;
+ pp->socket = fd;
+ if (fd >= net_globals.no_file)
+ d_printf("FICS (process_password): Out of range fd!\n");
+
+ pp->thisHost = fromHost;
+
+ psend_raw_file(p, MESS_DIR, MESS_LOGIN);
+ pprintf(p, "login: ");
+ return COM_OK;
+ }
+ }
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (player_globals.parray[p1].name != NULL) {
+ if ((!strcasecmp(pp->name, player_globals.parray[p1].name)) && (p != p1)) {
+ if (!CheckPFlag(p, PFLAG_REG)) {
+ pprintf(p, "\n*** Sorry %s is already logged in ***\n", pp->name);
+ return COM_LOGOUT;
+ }
+ boot_out(p, p1);
+ }
+ }
+ }
+
+ if (player_ishead(p)) {
+ pprintf(p,"\n ** LOGGED IN AS HEAD ADMIN **\n");
+ pp->adminLevel = ADMIN_GOD;
+ }
+
+ news_login(p);
+
+ if (pp->adminLevel > 0) {
+ psend_raw_file(p, MESS_DIR, MESS_ADMOTD);
+ } else {
+ psend_raw_file(p, MESS_DIR, MESS_MOTD);
+ }
+ if (MAX_ADVERTS >=0) {
+ pprintf (p, "\n");
+ sprintf (fname,"%d",Current_ad);
+ Current_ad = (Current_ad + 1) % MAX_ADVERTS;
+ psend_raw_file(p, ADVERT_DIR, fname);
+ }
+ if (!pp->passwd && CheckPFlag(p, PFLAG_REG))
+ pprintf(p, "\n*** You have no password. Please set one with the password command.");
+ if (!CheckPFlag(p, PFLAG_REG))
+ psend_raw_file(p, MESS_DIR, MESS_UNREGISTERED);
+ pp->status = PLAYER_PROMPT;
+ player_write_login(p);
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (p1 == p)
+ continue;
+ if (player_globals.parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (!CheckPFlag(p1, PFLAG_PIN))
+ continue;
+ if (player_globals.parray[p1].adminLevel > 0) {
+ pprintf_prompt(p1, "\n[%s (%s: %s) has connected.]\n", pp->name,
+ (CheckPFlag(p, PFLAG_REG) ? "R" : "U"),
+ dotQuad(pp->thisHost));
+ } else {
+ pprintf_prompt(p1, "\n[%s has connected.]\n", pp->name);
+ }
+ }
+ pp->num_comments = player_num_comments(p);
+ messnum = player_num_messages(p);
+
+ if (messnum) {
+ if (messnum == 1)
+ pprintf(p, "\nYou have 1 message.\nUse \"messages\" to display it, or \"clearmessages\" to remove it.\n");
+ else
+ pprintf(p, "\nYou have %d messages.\nUse \"messages\" to display them, or \"clearmessages\" to remove them.\n", messnum);
+ }
+
+ player_notify_present(p);
+ player_notify(p, "arrived", "arrival");
+ showstored(p);
+
+ if (CheckPFlag(p, PFLAG_REG) && (pp->lastHost.s_addr != 0) &&
+ (pp->lastHost.s_addr != pp->thisHost.s_addr)) {
+ pprintf(p, "\nPlayer %s: Last login: %s ", pp->name,
+ dotQuad(pp->lastHost));
+ pprintf(p, "This login: %s", dotQuad(pp->thisHost));
+ }
+ pp->lastHost = pp->thisHost;
+ if (CheckPFlag(p, PFLAG_REG) && !pp->timeOfReg)
+ pp->timeOfReg = time(0);
+ pp->logon_time = pp->last_command_time = time(0);
+ dummy = check_and_print_shutdown(p);
+ pprintf_prompt(p, "\n");
+ if (CheckPFlag(p, PFLAG_REG))
+ announce_avail(p);
+ return 0;
+}
+
+static int process_prompt(int p, char *command)
+{
+ struct player *pp = &player_globals.parray[p];
+ int retval;
+ char *cmd = "";
+
+ command = eattailwhite(eatwhite(command));
+ if (!*command) {
+ send_prompt(p);
+ return COM_OK;
+ }
+ retval = process_command(p, command, &cmd);
+ switch (retval) {
+ case COM_OK:
+ retval = COM_OK;
+ send_prompt(p);
+ break;
+ case COM_OK_NOPROMPT:
+ retval = COM_OK;
+ break;
+ case COM_ISMOVE:
+ retval = COM_OK;
+
+ if (pp->game >= 0 && game_globals.garray[pp->game].status == GAME_ACTIVE
+ && pp->side == game_globals.garray[pp->game].game_state.onMove
+ && game_globals.garray[pp->game].flag_pending != FLAG_NONE) {
+ ExecuteFlagCmd(p, net_globals.con[pp->socket]);
+ }
+
+ process_move(p, command);
+ send_prompt(p);
+
+ break;
+ case COM_ISMOVE_INSETUP:
+ pprintf(p, "You are still setting up the position.\n");
+ pprintf_prompt(p, "Type: 'setup done' when you are finished editing.\n");
+ retval = COM_OK;
+ break;
+ case COM_RIGHTS:
+ pprintf_prompt(p, "%s: Insufficient rights.\n", cmd);
+ retval = COM_OK;
+ break;
+ case COM_AMBIGUOUS:
+/* pprintf(p, "%s: Ambiguous command.\n", cmd); */
+ {
+ int len = strlen(cmd);
+ int i = 0;
+ pprintf(p, "Ambiguous command. Matches:");
+ while (command_list[i].comm_name) {
+ if (strncmp(command_list[i].comm_name, cmd, len) == 0 &&
+ check_admin(p, command_list[i].adminLevel)) {
+ pprintf(p, " %s", command_list[i].comm_name);
+ }
+ i++;
+ }
+ }
+ pprintf_prompt(p, "\n");
+ retval = COM_OK;
+ break;
+ case COM_BADPARAMETERS:
+ printusage(p, command_list[lastCommandFound].comm_name);
+ send_prompt(p);
+ retval = COM_OK;
+ break;
+ case COM_FAILED:
+ case COM_BADCOMMAND:
+ pprintf_prompt(p, "%s: Command not found.\n", cmd);
+ d_printf("Command not found [%s]\n", cmd);
+ retval = COM_OK;
+ break;
+ case COM_LOGOUT:
+ retval = COM_LOGOUT;
+ break;
+ }
+ return retval;
+}
+
+/* Return 1 to disconnect */
+int process_input(int fd, char *com_string)
+{
+ int p = player_find(fd);
+ int retval = 0;
+ struct player *pp;
+
+ if (p < 0) {
+ d_printf( "CHESSD: Input from a player not in array!\n");
+ return -1;
+ }
+
+ pp = &player_globals.parray[p];
+
+ command_globals.commanding_player = p;
+ pp->last_command_time = time(0);
+
+ switch (pp->status) {
+ case PLAYER_EMPTY:
+ d_printf( "CHESSD: Command from an empty player!\n");
+ break;
+ case PLAYER_NEW:
+ d_printf( "CHESSD: Command from a new player!\n");
+ break;
+ case PLAYER_INQUEUE:
+ /* Ignore input from player in queue */
+ break;
+ case PLAYER_LOGIN:
+ retval = process_login(p, com_string);
+ if (retval == COM_LOGOUT && com_string != NULL)
+ d_printf("%s tried to log in and failed.\n", com_string);
+ break;
+ case PLAYER_PASSWORD:
+ retval = process_password(p, com_string);
+ break;
+ case PLAYER_PROMPT:
+ FREE(pp->busy);
+ retval = process_prompt(p, com_string);
+ break;
+ }
+
+ command_globals.commanding_player = -1;
+ return retval;
+}
+
+int process_new_connection(int fd, struct in_addr fromHost)
+{
+ struct player *pp;
+ int p = player_new();
+
+ pp = &player_globals.parray[p];
+
+ pp->status = PLAYER_LOGIN;
+ if (fd >= net_globals.no_file)
+ d_printf("FICS (process_new_connection): Out of range fd!\n");
+
+ pp->socket = fd;
+ pp->thisHost = fromHost;
+ pp->logon_time = time(0);
+ psend_raw_file(p, MESS_DIR, MESS_WELCOME);
+ pprintf(p, "Head admin : %s", config_get_tmp("HEAD_ADMIN"));
+ pprintf(p, " Complaints to : %s\n", config_get_tmp("HEAD_ADMIN_EMAIL"));
+ pprintf(p, "Server location: %s", config_get_tmp("SERVER_LOCATION"));
+ pprintf(p, " Server version : %s\n", VERS_NUM);
+ pprintf(p, "Server name : %s\n", config_get_tmp("SERVER_HOSTNAME"));
+ psend_raw_file(p, MESS_DIR, MESS_LOGIN);
+ pprintf(p, "login: ");
+
+ return 0;
+}
+
+int process_disconnection(int fd)
+{
+ int p = player_find(fd);
+ int p1;
+ char command[1024];
+ struct player *pp;
+
+ if (p < 0) {
+ d_printf( "CHESSD: Disconnect from a player not in array!\n");
+ return -1;
+ }
+
+ pp = &player_globals.parray[p];
+
+ if (CheckPFlag(p, PFLAG_REG) && CheckPFlag(p, PFLAG_OPEN) &&
+ pp->game < 0)
+ announce_notavail(p);
+ if ((pp->game >=0) && ((game_globals.garray[pp->game].status == GAME_EXAMINE) || (game_globals.garray[pp->game].status == GAME_SETUP))) {
+ pcommand(p, "unexamine");
+ }
+ if ((pp->game >=0) && (in_list(p, L_ABUSER, pp->name)
+ || (game_globals.garray[pp->game].link >= 0)))
+
+ pcommand(p, "resign");
+
+ if (pp->ftell != -1)
+ pcommand (p,"tell 0 I am logging out now - conversation forwarding stopped.");
+
+ withdraw_seeks(p);
+
+ if (pp->status == PLAYER_PROMPT) {
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (p1 == p)
+ continue;
+ if (player_globals.parray[p1].status != PLAYER_PROMPT)
+ continue;
+
+ if (player_globals.parray[p1].ftell == p) {
+ player_globals.parray[p1].ftell = -1;
+ sprintf (command,"tell 0 *%s* has logged out - conversation forwarding stopped.",pp->name);
+ pcommand (p1,command);
+ pprintf_prompt (p1,"%s, whose tells you were forwarding has logged out.\n",
+ pp->name);
+ }
+
+ if (!CheckPFlag(p1, PFLAG_PIN))
+ continue;
+ pprintf_prompt(p1, "\n[%s has disconnected.]\n", pp->name);
+ }
+ player_notify(p, "departed", "departure");
+ player_notify_departure(p);
+ player_write_logout(p);
+ if (CheckPFlag(p, PFLAG_REG)) {
+ pp->totalTime += time(0) - pp->logon_time;
+ player_save(p);
+ } else { /* delete unreg history file */
+ char fname[MAX_FILENAME_SIZE];
+ sprintf(fname, "%s/player_data/%c/%s.games", STATS_DIR, pp->login[0], pp->login);
+ unlink(fname);
+ }
+ }
+ player_remove(p);
+ return 0;
+}
+
+/* Called every few seconds */
+int process_heartbeat(int *fd)
+{
+ struct tm *nowtm;
+ int p;
+ time_t now = time(0);
+ unsigned idle_timeout = config_get_int("IDLE_TIMEOUT", DEFAULT_IDLE_TIMEOUT);
+ unsigned login_timeout = config_get_int("LOGIN_TIMEOUT", DEFAULT_LOGIN_TIMEOUT);
+
+ /* Check for timed out connections */
+ for (p = 0; p < player_globals.p_num; p++) {
+ struct player *pp = &player_globals.parray[p];
+
+ if ((pp->status == PLAYER_LOGIN ||
+ pp->status == PLAYER_PASSWORD) &&
+ player_idle(p) > login_timeout) {
+ pprintf(p, "\n**** LOGIN TIMEOUT ****\n");
+ *fd = pp->socket;
+ return COM_LOGOUT;
+ }
+ if (pp->status == PLAYER_PROMPT &&
+ player_idle(p) > idle_timeout &&
+ !check_admin(p, ADMIN_ADMIN) &&
+ !in_list(p, L_TD, pp->name)) {
+ pprintf(p, "\n**** Auto-logout - you were idle more than %u minutes. ****\n",
+ idle_timeout/60);
+ *fd = pp->socket;
+ return COM_LOGOUT;
+ }
+ }
+ nowtm=localtime((time_t *)&now);
+ if (nowtm->tm_min==0) {
+ gics_globals.userstat.users[nowtm->tm_hour*2]=player_count(1);
+ save_userstat();
+ }
+ if (nowtm->tm_min==30) {
+ gics_globals.userstat.users[nowtm->tm_hour*2+1]=player_count(1);
+ save_userstat();
+ }
+ if (command_globals.player_high > gics_globals.userstat.usermax) {
+ gics_globals.userstat.usermax=command_globals.player_high;
+ gics_globals.userstat.usermaxtime=now;
+ save_userstat();
+ }
+ if (command_globals.game_high > gics_globals.userstat.gamemax) {
+ gics_globals.userstat.gamemax=command_globals.game_high;
+ gics_globals.userstat.gamemaxtime=now;
+ save_userstat();
+ }
+
+ ShutHeartBeat();
+ return COM_OK;
+}
+
+/* helper function for sorting command list */
+static int command_compare(struct command_type *c1, struct command_type *c2)
+{
+ return strcasecmp(c1->comm_name, c2->comm_name);
+}
+
+void commands_init(void)
+{
+ FILE *fp, *afp;
+ int i = 0;
+ int count=0, acount=0;
+
+ /* sort the command list */
+ qsort(command_list,
+ (sizeof(command_list)/sizeof(command_list[0])) - 1,
+ sizeof(command_list[0]),
+ (COMPAR_FN_T)command_compare);
+
+ command_globals.commanding_player = -1;
+
+ fp = fopen_s(HELP_DIR "/commands", "w");
+ if (!fp) {
+ d_printf( "CHESSD: Could not write commands help file.\n");
+ return;
+ }
+ afp = fopen_s(ADHELP_DIR "/commands", "w");
+ if (!afp) {
+ d_printf( "CHESSD: Could not write admin commands help file.\n");
+ fclose(fp);
+ return;
+ }
+
+ while (command_list[i].comm_name) {
+ if (command_list[i].adminLevel >= ADMIN_ADMIN) {
+ fprintf(afp, "%-19s", command_list[i].comm_name);
+ acount++;
+ if (acount % 4 == 0) {
+ fprintf(afp,"\n");
+ }
+ } else {
+ fprintf(fp, "%-19s", command_list[i].comm_name);
+ count++;
+ if (count % 4 == 0) {
+ fprintf(fp,"\n");
+ }
+ }
+ i++;
+ }
+
+ fprintf(afp,"\n");
+ fprintf(fp,"\n");
+
+ fclose(fp);
+ fclose(afp);
+
+ d_printf("CHESSD: Loaded %d commands (admin=%d normal=%d)\n", i, acount, count);
+}
+
+/* Need to save rated games */
+void TerminateCleanup(void)
+{
+ int p1;
+ int g;
+
+ save_userstat();
+
+ for (g = 0; g < game_globals.g_num; g++) {
+ if (game_globals.garray[g].status != GAME_ACTIVE)
+ continue;
+ if (game_globals.garray[g].rated) {
+ game_ended(g, WHITE, END_ADJOURN);
+ }
+ }
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (player_globals.parray[p1].status == PLAYER_EMPTY)
+ continue;
+ pprintf(p1, "\n **** Server shutting down immediately. ****\n\n");
+ if (player_globals.parray[p1].status != PLAYER_PROMPT) {
+ close(player_globals.parray[p1].socket);
+ } else {
+ pprintf(p1, "Logging you out.\n");
+ psend_raw_file(p1, MESS_DIR, MESS_LOGOUT);
+ player_write_logout(p1);
+ if (CheckPFlag(p1, PFLAG_REG))
+ player_globals.parray[p1].totalTime += time(0) - player_globals.parray[p1].logon_time;
+ player_save(p1);
+ }
+ }
+ destruct_pending();
+}
+
+static char *guest_name(void)
+{
+ static char name[20];
+ int found;
+
+#define RANDLET ((char)('A' + (random() % 26)))
+ srandom(time(0));
+
+ found = 0;
+ while(!found) {
+ snprintf(name,sizeof(name), "Guest%c%c%c%c", RANDLET, RANDLET, RANDLET, RANDLET);
+ found = check_user(name);
+ }
+#undef RANDLET
+ return name;
+}
+
+static int check_user(char *user)
+{
+ int i;
+
+ for (i = 0; i < player_globals.p_num; i++) {
+ if (player_globals.parray[i].name != NULL) {
+ if (!strcasecmp(user, player_globals.parray[i].name))
+ return 0;
+ }
+ }
+ return 1;
+}
+
+
+/* return the global alias list */
+const struct alias_type *alias_list_global(void)
+{
+ return g_alias_list;
+}
+
+/* return a personal alias list */
+const struct alias_type *alias_list_personal(int p, int *n)
+{
+ struct player *pp = &player_globals.parray[p];
+
+ *n = pp->numAlias;
+ return pp->alias_list;
+}
+
+/*
+ report on any missing help pages
+*/
+int com_acheckhelp(int p, param_list param)
+{
+ int i;
+ int count;
+
+ for (count=i=0; command_list[i].comm_name; i++) {
+ char *fname;
+ asprintf(&fname, "%s/%s",
+ command_list[i].adminLevel?ADHELP_DIR:HELP_DIR,
+ command_list[i].comm_name);
+ if (!file_exists(fname)) {
+ pprintf(p, "Help for command '%s' is missing%s\n",
+ command_list[i].comm_name,
+ command_list[i].adminLevel?" (admin)":"");
+ count++;
+ }
+ free(fname);
+ }
+
+ pprintf(p, "%d commands are missing help files\n", count);
+
+ for (count=i=0; command_list[i].comm_name; i++) {
+ char *fname;
+ asprintf(&fname, "%s/%s", USAGE_DIR, command_list[i].comm_name);
+ if (!file_exists(fname)) {
+ pprintf(p, "Usage for command '%s' is missing%s\n",
+ command_list[i].comm_name,
+ command_list[i].adminLevel?" (admin)":"");
+ count++;
+ }
+ free(fname);
+ }
+
+ pprintf(p, "%d commands are missing usage files\n", count);
+
+ return COM_OK;
+}
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+#ifndef _COMMAND_H
+#define _COMMAND_H
+
+extern const char *help_dir[NUM_LANGS];
+extern const char *usage_dir[NUM_LANGS];
+
+/* Maximum length of a login name +1 */
+#define MAX_LOGIN_NAME 18
+
+/* Maximum number of parameters per command */
+#define MAXNUMPARAMS 10
+
+/* Maximum string length of a single command word */
+#define MAX_COM_LENGTH 50
+
+/* Maximum string length of the whole command line */
+#define MAX_STRING_LENGTH 1024
+
+#define COM_OK 0
+#define COM_FAILED 1
+#define COM_ISMOVE 2
+#define COM_AMBIGUOUS 3
+#define COM_BADPARAMETERS 4
+#define COM_BADCOMMAND 5
+#define COM_LOGOUT 6
+#define COM_FLUSHINPUT 7
+#define COM_RIGHTS 8
+#define COM_OK_NOPROMPT 9
+#define COM_ISMOVE_INSETUP 10
+
+#define ADMIN_USER 0
+#define ADMIN_ADMIN 10
+#define ADMIN_MASTER 20
+#define ADMIN_DEMIGOD 60
+#define ADMIN_GOD 100
+
+#define TYPE_NULL 0
+#define TYPE_WORD 1
+#define TYPE_STRING 2
+#define TYPE_INT 3
+typedef struct u_parameter {
+ int type;
+ union {
+ char *word;
+ char *string;
+ int integer;
+ } val;
+} parameter;
+
+typedef parameter param_list[MAXNUMPARAMS];
+
+typedef struct command_type {
+ char *comm_name;
+ char *param_string;
+ int (*comm_func)();
+ int adminLevel;
+} command_type;
+
+GENSTRUCT struct alias_type {
+ char *comm_name;
+ char *alias;
+};
+
+#endif /* _COMMAND_H */
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+
+#ifndef _COMMAND_LIST_H
+#define _COMMAND_LIST_H
+
+/*
+ Parameter string format
+ w - a word
+ o - an optional word
+ d - integer
+ p - optional integer
+ i - word or integer
+ n - optional word or integer
+ s - string to end
+ t - optional string to end
+
+ If the parameter option is given in lower case then the parameter is
+ converted to lower case before being passsed to the function. If it is
+ in upper case, then the parameter is passed as typed.
+ */
+
+/* Try to keep this list in alpha order */
+
+ /* Name Options Functions Security */
+static struct command_type command_list[] = {
+
+ {"abort", "", com_abort, ADMIN_USER },
+ {"accept", "n", com_accept, ADMIN_USER },
+ {"addlist", "ww", com_addlist, ADMIN_USER },
+ {"adjourn", "", com_adjourn, ADMIN_USER },
+ {"alias", "oT", com_alias, ADMIN_USER },
+ {"allobservers", "n", com_allobservers, ADMIN_USER },
+ {"assess", "noo", com_assess, ADMIN_USER },
+ {"backward", "p", com_backward, ADMIN_USER },
+ {"bell", "", com_bell, ADMIN_USER },
+ {"best", "o", com_best, ADMIN_USER },
+ {"bname", "O", com_bname, ADMIN_USER },
+ {"boards", "o", com_boards, ADMIN_USER },
+ {"bsetup", "oT", com_setup, ADMIN_USER},
+/* {"channel", "p", com_channel, ADMIN_USER }, */
+ {"clearmessages", "n", com_clearmessages, ADMIN_USER },
+ {"clrsquare", "w", com_clrsquare, ADMIN_USER },
+ {"cshout", "S", com_cshout, ADMIN_USER },
+ {"date", "", com_date, ADMIN_USER },
+ {"decline", "n", com_decline, ADMIN_USER },
+ {"draw", "", com_draw, ADMIN_USER },
+ {"eco", "n", com_eco, ADMIN_USER },
+ {"examine", "on", com_examine, ADMIN_USER },
+ {"finger", "oo", com_stats, ADMIN_USER },
+ {"flag", "", com_flag, ADMIN_USER },
+ {"flip", "", com_flip, ADMIN_USER },
+ {"fmessage", "wd", com_forwardmess, ADMIN_USER },
+ {"forward", "p", com_forward, ADMIN_USER },
+ {"games", "o", com_games, ADMIN_USER },
+ {"getgi", "w", com_getgi, ADMIN_USER },
+ {"getpi", "w", com_getpi, ADMIN_USER },
+ {"goboard", "i", com_goboard, ADMIN_USER },
+ {"handles", "w", com_handles, ADMIN_USER },
+ {"hbest", "o", com_hbest, ADMIN_USER },
+ {"help", "t", com_help, ADMIN_USER },
+ {"history", "o", com_history, ADMIN_USER },
+ {"hrank", "oo", com_hrank, ADMIN_USER },
+ {"inchannel", "n", com_inchannel, ADMIN_USER },
+ {"iset", "wS", com_iset, ADMIN_USER },
+ {"it", "T", com_it, ADMIN_USER },
+ {"jkill", "w", com_jkill, ADMIN_USER },
+ {"journal", "o", com_journal, ADMIN_USER },
+ {"jsave", "wwi", com_jsave, ADMIN_USER },
+ {"kibitz", "S", com_kibitz, ADMIN_USER },
+ {"limits", "", com_limits, ADMIN_USER },
+ {"llogons", "", com_llogons, ADMIN_USER },
+ {"logons", "o", com_logons, ADMIN_USER },
+ {"mailmoves", "n", com_mailmoves, ADMIN_USER },
+ {"mailoldmoves", "o", com_mailoldmoves, ADMIN_USER },
+ {"mailstored", "wi", com_mailstored, ADMIN_USER },
+ {"match", "wt", com_match, ADMIN_USER },
+ {"rmatch", "wwt", com_rmatch, ADMIN_USER },
+ {"messages", "nT", com_messages, ADMIN_USER },
+ {"mexamine", "w", com_mexamine, ADMIN_USER },
+ {"moretime", "d", com_moretime, ADMIN_USER },
+ {"moves", "n", com_moves, ADMIN_USER },
+ {"news", "o", com_news, ADMIN_USER },
+ {"next", "", com_more, ADMIN_USER },
+ {"observe", "n", com_observe, ADMIN_USER },
+ {"oldmoves", "o", com_oldmoves, ADMIN_USER },
+ {"open", "", com_open, ADMIN_USER },
+ {"partner", "o", com_partner, ADMIN_USER },
+ {"password", "WW", com_password, ADMIN_USER },
+ {"pause", "", com_pause, ADMIN_USER },
+ {"play", "d", com_play, ADMIN_USER },
+ {"pending", "", com_pending, ADMIN_USER },
+ {"prefresh", "", com_prefresh, ADMIN_USER },
+ {"promote", "w", com_promote, ADMIN_USER },
+ {"ptell", "S", com_ptell, ADMIN_USER },
+ {"ptime", "", com_ptime, ADMIN_USER },
+ {"qtell", "iS", com_qtell, ADMIN_USER },
+ {"quit", "", com_quit, ADMIN_USER },
+ {"rank", "oo", com_rank, ADMIN_USER },
+ {"refresh", "n", com_refresh, ADMIN_USER },
+ {"revert", "", com_revert, ADMIN_USER },
+ {"resign", "o", com_resign, ADMIN_USER },
+ {"say", "S", com_say, ADMIN_USER },
+ {"seek", "pppp", com_seek, ADMIN_USER },
+ {"unseek", "", com_unseek, ADMIN_USER },
+ {"set", "wT", com_set, ADMIN_USER },
+ {"shout", "T", com_shout, ADMIN_USER },
+ {"showlist", "o", com_showlist, ADMIN_USER },
+ {"simabort", "", com_simabort, ADMIN_USER },
+ {"simallabort", "", com_simallabort,ADMIN_USER },
+ {"simadjourn", "", com_simadjourn, ADMIN_USER },
+ {"simalladjourn", "", com_simalladjourn,ADMIN_USER },
+ {"simgames", "o", com_simgames, ADMIN_USER },
+ {"simmatch", "woo", com_simmatch, ADMIN_USER },
+ {"simnext", "", com_simnext, ADMIN_USER },
+ {"simopen", "", com_simopen, ADMIN_USER },
+ {"simpass", "", com_simpass, ADMIN_USER },
+ {"simprev", "", com_simprev, ADMIN_USER },
+ {"sought", "p", com_sought, ADMIN_USER },
+ {"smoves", "wi", com_smoves, ADMIN_USER },
+ {"sposition", "ww", com_sposition, ADMIN_USER },
+ {"statistics", "", com_statistics, ADMIN_USER },
+ {"stored", "o", com_stored, ADMIN_USER },
+ {"style", "d", com_style, ADMIN_USER },
+ {"sublist", "ww", com_sublist, ADMIN_USER },
+ {"switch", "", com_switch, ADMIN_USER },
+ {"takeback", "p", com_takeback, ADMIN_USER },
+ {"tell", "nS", com_tell, ADMIN_USER },
+ {"ltell", "wS", com_ltell, ADMIN_USER },
+ {"time", "n", com_time, ADMIN_USER },
+ {"tomove", "w", com_tomove, ADMIN_USER },
+ {"toggle", "ww", com_togglelist, ADMIN_USER },
+ {"tournset", "wd", com_tournset, ADMIN_USER },
+ {"unalias", "w", com_unalias, ADMIN_USER },
+ {"unexamine", "", com_unexamine, ADMIN_USER },
+ {"unobserve", "n", com_unobserve, ADMIN_USER },
+ {"unpause", "", com_unpause, ADMIN_USER },
+ {"uptime", "", com_uptime, ADMIN_USER },
+ {"variables", "o", com_variables, ADMIN_USER },
+ {"whenshut", "", com_whenshut, ADMIN_USER },
+ {"whisper", "S", com_whisper, ADMIN_USER },
+ {"who", "T", com_who, ADMIN_USER },
+ {"withdraw", "n", com_withdraw, ADMIN_USER },
+ {"wname", "O", com_wname, ADMIN_USER },
+ {"xtell", "wS", com_xtell, ADMIN_USER },
+ {"znotify", "", com_znotify, ADMIN_USER },
+
+#if 0
+ {"ustat", "", com_ustat, ADMIN_USER },
+#endif
+
+#if 0
+ {"reply", "S", com_reply, ADMIN_USER },
+#endif
+ {"pstat", "oo", com_pstat, ADMIN_USER },
+ {"remote", "wS", com_remote, ADMIN_USER },
+
+ {"aconfig", "OS", com_aconfig, ADMIN_GOD },
+ {"addcomment", "WS", com_addcomment, ADMIN_ADMIN },
+ {"addplayer", "WWS", com_addplayer, ADMIN_ADMIN },
+ {"adjudicate", "www", com_adjudicate, ADMIN_ADMIN },
+ {"adump", "", com_adump, ADMIN_GOD },
+ {"admin", "", com_admin, ADMIN_ADMIN },
+ {"ahelp", "t", com_ahelp, ADMIN_ADMIN },
+ {"acheckhelp", "", com_acheckhelp, ADMIN_ADMIN },
+ {"announce", "S", com_announce, ADMIN_ADMIN },
+ {"annunreg", "S", com_annunreg, ADMIN_ADMIN },
+ {"anews", "o", com_anews, ADMIN_ADMIN },
+ {"areload", "", com_areload, ADMIN_GOD },
+ {"asetv", "wS", com_asetv, ADMIN_ADMIN },
+ {"asetadmin", "wd", com_asetadmin, ADMIN_ADMIN },
+ {"asetblitz", "wdpppp",com_asetblitz, ADMIN_ADMIN },
+ {"asetbughouse", "wdpppp",com_asetbug, ADMIN_ADMIN },
+ {"asetemail", "wO", com_asetemail, ADMIN_ADMIN },
+ {"asethandle", "WW", com_asethandle, ADMIN_ADMIN },
+ {"asetlight", "wdpppp",com_asetlight, ADMIN_ADMIN },
+ {"asetpasswd", "wW", com_asetpasswd, ADMIN_ADMIN },
+ {"asetrealname", "wT", com_asetrealname, ADMIN_ADMIN },
+ {"asetstd", "wdpppp",com_asetstd, ADMIN_ADMIN },
+ {"asetwild", "wdpppp",com_asetwild, ADMIN_ADMIN },
+ {"cnewsi", "S", com_cnewsi, ADMIN_ADMIN },
+ {"cnewsf", "dT", com_cnewsf, ADMIN_ADMIN },
+ {"cnewst", "dS", com_cnewst, ADMIN_ADMIN },
+ {"cnewsp", "d", com_cnewsp, ADMIN_ADMIN },
+ {"cnewse", "dp", com_cnewse, ADMIN_ADMIN },
+ {"cnewsd", "d", com_cnewsd, ADMIN_ADMIN },
+ {"canewsi", "S", com_canewsi, ADMIN_ADMIN },
+ {"canewsf", "dT", com_canewsf, ADMIN_ADMIN },
+ {"canewst", "dS", com_canewst, ADMIN_ADMIN },
+ {"canewsp", "d", com_canewsp, ADMIN_ADMIN },
+ {"canewse", "dp", com_canewse, ADMIN_ADMIN },
+ {"canewsd", "d", com_canewsd, ADMIN_ADMIN },
+ {"ftell", "o", com_ftell, ADMIN_ADMIN },
+ {"hideinfo", "", com_hideinfo, ADMIN_ADMIN },
+ {"nuke", "w", com_nuke, ADMIN_ADMIN },
+ {"pose", "wS", com_pose, ADMIN_GOD },
+ {"quota", "p", com_quota, ADMIN_ADMIN },
+ {"raisedead", "WO", com_raisedead, ADMIN_ADMIN },
+ {"remplayer", "w", com_remplayer, ADMIN_ADMIN },
+ {"rerank", "w", com_fixrank, ADMIN_ADMIN },
+ {"showcomment", "w", com_showcomment, ADMIN_ADMIN },
+ {"shutdown", "oT", com_shutdown, ADMIN_ADMIN },
+ {"summon", "w", com_summon, ADMIN_ADMIN },
+
+ {NULL, NULL, NULL, ADMIN_USER}
+};
+
+static struct alias_type g_alias_list[] = {
+ {"comment", "addcomment"},
+ {"setup", "bsetup"},
+ {"sc", "showcomment"},
+ {"b", "backward"},
+ {"w", "who"},
+ {"t", "tell"},
+ {"m", "match"},
+ {"go", "goboard"},
+ {"goto", "goboard"},
+ {"gonum", "goboard"}, /* dumping an obsolete command */
+ {"f", "finger"},
+ {"hi", "history"},
+ {"a", "accept"},
+ {"saa", "simallabort"},
+ {"saab", "simallaabort"},
+ {"sab", "simabort"},
+ {"sadj", "simadjourn"},
+ {"saadj", "simalladjourn"},
+ {"sh", "shout"},
+ {"sn", "simnext"},
+ {"sp", "simprev"},
+ {"vars", "variables"},
+ {"g", "games"},
+ {"players", "who a"},
+ {"player", "who a"},
+ {"p", "who a"},
+ {"pl", "who a"},
+ {"o", "observe"},
+ {"r", "refresh"},
+ {"re", "refresh"}, /* So r/re doesn't resign! */
+ {"ch", "channel"},
+ {"in", "inchannel"},
+ {".", "tell ."},
+ {",", "tell ,"},
+ {"`", "tell ."},
+ {"!", "shout"},
+ {"I", "it"},
+ {"i", "it"},
+ {":", "it"},
+ {"exit", "quit"},
+ {"logout", "quit"},
+ {"bye", "quit"},
+ {"*", "kibitz"},
+ {"#", "whisper"},
+ {"ma", "match"},
+ {"more", "next"},
+ {"n", "next"},
+ {"znotl", "znotify"},
+ {"+", "addlist"},
+ {"-", "sublist"},
+ {"=", "showlist"},
+ {"mam", "xtell mamer"},
+ {"tom", "tell tomato"},
+ {"egg", "tell eggoi"},
+ {"follow", "toggle follow"},
+ {"channel", "toggle channel"},
+ {NULL, NULL}
+};
+
+#endif /* _COMMAND_LIST_H */
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+
+#ifndef _COMMON_H
+#define _COMMON_H
+
+#ifndef MAX
+#define MAX(x,y) (((x)>(y))? (x):(y))
+#endif
+#ifndef MIN
+#define MIN(x,y) (((x)>(y))? (y):(x))
+#endif
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+#define SWAP(a,b,type) {\
+ type tmp; \
+ tmp = (a);\
+ (a) = (b);\
+ (b) = tmp;\
+}
+
+#define ZERO_STRUCT(s) memset(&(s), 0, sizeof(s))
+#define ZERO_STRUCTP(s) memset(s, 0, sizeof(*(s)))
+
+
+#ifdef __GNUC__
+/** Use gcc attribute to check printf fns. a1 is the 1-based index of
+ * the parameter containing the format, and a2 the index of the first
+ * argument. **/
+#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2)))
+#else
+#define PRINTF_ATTRIBUTE(a1, a2)
+#endif
+
+
+/* declare some printf style functions so the compiler checks the args */
+FILE *fopen_p(const char *fmt, const char *mode, ...) PRINTF_ATTRIBUTE(1,3);
+int asprintf(char **strp, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
+void d_printf(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
+int pprintf(int p, char *format,...) PRINTF_ATTRIBUTE(2,3);
+int pprintf_highlight(int p, char *format,...) PRINTF_ATTRIBUTE(2,3);
+int psprintf_highlight(int p, char *s, char *format,...) PRINTF_ATTRIBUTE(3,4);
+int pprintf_prompt(int p, char *format,...) PRINTF_ATTRIBUTE(2,3);
+int pprintf_noformat(int p, char *format,...) PRINTF_ATTRIBUTE(2,3);
+int pcommand(int p, char *comstr,...) PRINTF_ATTRIBUTE(2,3);
+
+
+
+/* prototypes for replacement functions */
+#ifndef HAVE_DPRINTF
+int dprintf(int fd, const char *format, ...);
+#endif
+#ifndef HAVE_STRNLEN
+size_t strnlen(const char *s, size_t n);
+#endif
+
+#ifndef HAVE_STRLCPY
+size_t strlcpy(char *d, const char *s, size_t bufsize);
+#endif
+#ifndef HAVE_STRLCAT
+size_t strlcat(char *d, const char *s, size_t bufsize);
+#endif
+
+#if HAVE_COMPAR_FN_T
+#define COMPAR_FN_T __compar_fn_t
+#else
+typedef int (*COMPAR_FN_T)(const void *, const void *);
+#endif
+
+/* tell tdb that it can use mmap */
+#define HAVE_MMAP 1
+
+#endif /* _COMMON_H */
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+
+#include "includes.h"
+
+const int none = 0;
+const int blitz_rat = 1;
+const int std_rat = 2;
+const int wild_rat = 3;
+const int light_rat = 4;
+const int bug_rat = 5;
+
+int com_more(int p, param_list param)
+{
+ pmore_text(p);
+ return COM_OK;
+}
+
+int com_quit(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+
+ /* Examined games are killed on logout */
+ if ((pp->game >= 0) &&
+ ((game_globals.garray[pp->game].status != GAME_EXAMINE) &&
+ (game_globals.garray[pp->game].status != GAME_SETUP))) {
+ pprintf(p, "You can't quit while you are playing a game.\nType 'resign' to resign the game, or you can request an abort with 'abort'.\n");
+ return COM_OK;
+ }
+
+ psend_logoutfile(p, MESS_DIR, MESS_LOGOUT);
+ return COM_LOGOUT;
+}
+
+int com_set(int p, param_list param)
+{
+ int result;
+ int which;
+ char *val;
+
+ if (param[1].type == TYPE_NULL)
+ val = NULL;
+ else
+ val = param[1].val.string;
+ result = var_set(p, param[0].val.word, val, &which);
+ switch (result) {
+ case VAR_OK:
+ break;
+ case VAR_BADVAL:
+ pprintf(p, "Bad value given for variable %s.\n", param[0].val.word);
+ break;
+ case VAR_NOSUCH:
+ pprintf(p, "No such variable name %s.\n", param[0].val.word);
+ break;
+ case VAR_AMBIGUOUS:
+ pprintf(p, "Ambiguous variable name %s.\n", param[0].val.word);
+ break;
+ }
+ /* player_save(p); */
+ return COM_OK;
+}
+
+int FindPlayer(int p, char* name, int *p1, int *connected)
+{
+ *p1 = player_search(p, name);
+ if (*p1 == 0)
+ return 0;
+ if (*p1 < 0) { /* player had to be connected and will be
+ removed later */
+ *connected = 0;
+ *p1 = (-*p1) - 1;
+ } else {
+ *connected = 1;
+ *p1 = *p1 - 1;
+ }
+ return 1;
+}
+
+static void com_stats_andify(int *numbers, int howmany, char *dest)
+{
+ char tmp[10];
+
+ *dest = '\0';
+ while (howmany--) {
+ sprintf(tmp, "%d", numbers[howmany]);
+ strcat(dest, tmp);
+ if (howmany > 1)
+ sprintf(tmp, ", ");
+ else if (howmany == 1)
+ sprintf(tmp, " and ");
+ else
+ sprintf(tmp, ".\n");
+ strcat(dest, tmp);
+ }
+ return;
+}
+
+static void com_stats_rating(char *hdr, struct statistics * stats, char *dest, long now)
+{
+ char tmp[100];
+
+ *dest = 0;
+
+ if (stats->num == 0) return;
+
+ sprintf(dest, "%-10s%4s %5.1f %4d %4d %4d %4d", hdr,
+ ratstr(stats->rating), current_sterr(stats->sterr, now-stats->ltime),
+ stats->win, stats->los, stats->dra, stats->num);
+ if (stats->whenbest) {
+ sprintf(tmp, " %d", stats->best);
+ strcat(dest, tmp);
+ strftime(tmp, sizeof(tmp), " (%d-%b-%Y)", localtime((time_t *) & stats->whenbest));
+ strcat(dest, tmp);
+ }
+ strcat(dest, "\n");
+ return;
+}
+
+int com_stats(int p, param_list param)
+{
+ int g, i;
+ time_t t;
+ int p1, connected;
+ char line[255], tmp[255], tmp2[255];
+ int numbers[MAX_OBSERVE > MAX_SIMUL ? MAX_OBSERVE : MAX_SIMUL];
+ int onTime;
+ int showRatingsFlag, showNotesFlag;
+ int showCommentsFlag = 0;
+ long now;
+
+ showRatingsFlag = showNotesFlag = 1; /* everything on by default */
+
+ if (param[0].type == TYPE_WORD) {
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+ if (param[1].type == TYPE_WORD) { /* optional second parameter */
+ char *c = param[1].val.word;
+ showRatingsFlag = showNotesFlag = 0;
+ while (*c != '\0') {
+ if (*c == 'r') { showRatingsFlag = 1; c++; }
+ else if (*c == 'n') { showNotesFlag = 1; c++; }
+ else if ((*c == 'c') && check_admin(p, ADMIN_ADMIN)) {
+ showCommentsFlag = 1; c++; }
+ else {
+ if (!connected)
+ player_remove(p1);
+ return COM_BADPARAMETERS;
+ }
+ }
+ }
+ } else {
+ p1 = p;
+ connected = 1;
+ }
+
+ strcpy(tmp2, player_globals.parray[p1].name);
+ AddPlayerLists(p1, tmp2);
+ tmp2[17] = '\0';
+ sprintf(line, "\nStatistics for %-17s", tmp2);
+ if ((connected) && (player_globals.parray[p1].status == PLAYER_PROMPT)) {
+ sprintf(tmp, "On for: %s", hms_desc(player_ontime(p1)));
+ strcat(line, tmp);
+ sprintf(tmp, " Idle: %s\n", hms_desc(player_idle(p1)));
+ } else {
+ if ((t = player_lastdisconnect(p1)))
+ sprintf(tmp, "(Last disconnected %s):\n", strltime(&t));
+ else
+ sprintf(tmp, "(Never connected.)\n");
+ }
+ strcat(line, tmp);
+ pprintf(p, "%s", line);
+ if (((player_globals.parray[p1].simul_info) != NULL) && (player_globals.parray[p1].simul_info->numBoards)) {
+ for (i = 0, t = 0; i < player_globals.parray[p1].simul_info->numBoards; i++) {
+ if ((numbers[t] = player_globals.parray[p1].simul_info->boards[i] + 1) != 0)
+ t++;
+ }
+ pprintf(p, "%s is giving a simul: game%s ", player_globals.parray[p1].name, ((t > 1) ? "s" : ""));
+ com_stats_andify(numbers, t, tmp);
+ pprintf(p, tmp);
+ } else if (player_globals.parray[p1].game >= 0) {
+ g = player_globals.parray[p1].game;
+ if (game_globals.garray[g].status == GAME_EXAMINE) {
+ pprintf(p, "(Examining game %d: %s vs. %s)\n", g + 1,
+ game_globals.garray[g].white_name, game_globals.garray[g].black_name);
+ } else if (game_globals.garray[g].status == GAME_SETUP) {
+ pprintf(p, "(Setting up game %d: %s vs. %s)\n", g + 1,
+ game_globals.garray[g].white_name, game_globals.garray[g].black_name);
+ } else {
+ pprintf(p, "(playing game %d: %s vs. %s)\n", g + 1,
+ player_globals.parray[game_globals.garray[g].white].name, player_globals.parray[game_globals.garray[g].black].name);
+ if (game_globals.garray[g].link >= 0) {
+ pprintf(p, "(partner is playing game %d: %s vs. %s)\n", game_globals.garray[g].link + 1,
+ player_globals.parray[game_globals.garray[game_globals.garray[g].link].white].name,
+ player_globals.parray[game_globals.garray[game_globals.garray[g].link].black].name);
+ }
+ }
+ }
+ if (player_globals.parray[p1].num_observe) {
+ for (i = 0, t = 0; i < player_globals.parray[p1].num_observe; i++) {
+ g = player_globals.parray[p1].observe_list[i];
+ if ((g != -1) && (check_admin(p, ADMIN_ADMIN) || (game_globals.garray[g].private == 0)))
+ numbers[t++] = g + 1;
+ }
+ if (t) {
+ pprintf(p, "%s is observing game%s ", player_globals.parray[p1].name, ((t > 1) ? "s" : ""));
+ com_stats_andify(numbers, t, tmp);
+ pprintf(p, tmp);
+ }
+ }
+ if (player_globals.parray[p1].busy != NULL) {
+ pprintf(p, "(%s %s)\n", player_globals.parray[p1].name, player_globals.parray[p1].busy);
+ }
+ if (!CheckPFlag(p1, PFLAG_REG)) {
+ pprintf(p, "%s is NOT a registered player.\n\n", player_globals.parray[p1].name);
+ } else {
+ if (showRatingsFlag > 0) {
+ now = time(NULL);
+ pprintf(p, "\n rating RD win loss draw total best\n");
+ com_stats_rating("Blitz", &player_globals.parray[p1].b_stats, tmp, now);
+ if (*tmp) pprintf(p, tmp);
+ com_stats_rating("Standard", &player_globals.parray[p1].s_stats, tmp, now);
+ if (*tmp) pprintf(p, tmp);
+ com_stats_rating("Lightning", &player_globals.parray[p1].l_stats, tmp, now);
+ if (*tmp) pprintf(p, tmp);
+ com_stats_rating("Wild", &player_globals.parray[p1].w_stats, tmp, now);
+ if (*tmp) pprintf(p, tmp);
+ com_stats_rating("Bughouse", &player_globals.parray[p1].bug_stats, tmp, now);
+ if (*tmp) pprintf(p, tmp);
+ }
+ }
+ pprintf(p, "\n");
+ if (player_globals.parray[p1].adminLevel > 0) {
+ pprintf(p, "Admin Level: ");
+ switch (5*(player_globals.parray[p1].adminLevel/5)) {
+ case 5:
+ pprintf(p, "Authorized Helper Person\n");
+ break;
+ case 10:
+ pprintf(p, "Administrator\n");
+ break;
+ case 15:
+ pprintf(p, "Help File Librarian/Administrator\n");
+ break;
+ case 20:
+ pprintf(p, "Master Administrator\n");
+ break;
+ case 50:
+ pprintf(p, "Master Help File Librarian/Administrator\n");
+ break;
+ case 60:
+ pprintf(p, "Assistant Super User\n");
+ break;
+ case 100:
+ pprintf(p, "Super User\n");
+ break;
+ default:
+ pprintf(p, "%d\n", player_globals.parray[p1].adminLevel);
+ break;
+ }
+ }
+
+ if (check_admin(p, 1) && !CheckPFlag(p, PFLAG_HIDEINFO)) {
+ pprintf(p, "Full Name : %s\n", (player_globals.parray[p1].fullName ? player_globals.parray[p1].fullName : "(none)"));
+ pprintf(p, "Address : %s\n", (player_globals.parray[p1].emailAddress ? player_globals.parray[p1].emailAddress : "(none)"));
+ pprintf(p, "Host : %s\n",
+ dotQuad(connected ? player_globals.parray[p1].thisHost : player_globals.parray[p1].lastHost));
+ if (CheckPFlag(p1, PFLAG_REG))
+ if (player_globals.parray[p1].num_comments)
+ pprintf(p, "Comments : %d\n", player_globals.parray[p1].num_comments);
+ } else if ((p1 == p) && CheckPFlag(p1, PFLAG_REG))
+ pprintf(p, "Address : %s\n", (player_globals.parray[p1].emailAddress ? player_globals.parray[p1].emailAddress : "(none)"));
+
+ if (player_globals.parray[p1].socket != -1) {
+ pprintf(p, "\nTimeseal: %s\n", net_globals.con[player_globals.parray[p1].socket]->timeseal ? "yes" : "no");
+ }
+
+ if (connected && CheckPFlag(p1, PFLAG_REG)
+ && (p==p1 || (check_admin(p, 1) && !CheckPFlag(p, PFLAG_HIDEINFO)))) {
+ char *timeToStr = ctime((time_t *) &player_globals.parray[p1].timeOfReg);
+
+ timeToStr[strlen(timeToStr)-1]='\0';
+ pprintf(p, "\n");
+ onTime = (time(0) - player_globals.parray[p1].logon_time) + player_globals.parray[p1].totalTime;
+
+ pprintf(p, "Total time on-line: %s\n", hms_desc(onTime) );
+ pprintf(p, "%% of life on-line: %3.1f (since %s)\n",
+ (double)((onTime*100)/(double)(time(0)-player_globals.parray[p1].timeOfReg)),
+ timeToStr);
+ }
+
+ if (player_globals.parray[p1].num_plan && (showNotesFlag > 0)) {
+ pprintf(p, "\n");
+ for (i = 0; i < player_globals.parray[p1].num_plan; i++)
+ pprintf(p, "%2d: %s\n", i + 1, (player_globals.parray[p1].planLines[i] != NULL) ? player_globals.parray[p1].planLines[i] : "");
+ }
+ if (showCommentsFlag) {
+ pprintf(p, "\n");
+ pprintf(p, "Comments for %s:\n",player_globals.parray[p1].name);
+ player_show_comments(p, p1);
+ }
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+int com_password(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ char *oldpassword = param[0].val.word;
+ char *newpassword = param[1].val.word;
+ char salt[3];
+
+ if (!CheckPFlag(p, PFLAG_REG)) {
+ pprintf(p, "Setting a password is only for registered players.\n");
+ return COM_OK;
+ }
+ if (pp->passwd) {
+ salt[0] = pp->passwd[3];
+ salt[1] = pp->passwd[4];
+ salt[2] = '\0';
+ if (strcmp(chessd_crypt(oldpassword,salt), pp->passwd)) {
+ pprintf(p, "Incorrect password, password not changed!\n");
+ return COM_OK;
+ }
+ free(pp->passwd);
+ pp->passwd = NULL;
+ }
+ salt[0] = 'a' + random() % 26;
+ salt[1] = 'a' + random() % 26;
+ salt[2] = '\0';
+ pp->passwd = strdup(chessd_crypt(newpassword,salt));
+ pprintf(p, "Password changed to \"%s\".\n", newpassword);
+ return COM_OK;
+}
+
+int com_uptime(int p, param_list param)
+{
+ time_t uptime = time(0) - command_globals.startuptime;
+ int days = (uptime / (60*60*24));
+ int hours = ((uptime % (60*60*24)) / (60*60));
+ int mins = (((uptime % (60*60*24)) % (60*60)) / 60);
+ int secs = (((uptime % (60*60*24)) % (60*60)) % 60);
+
+ pprintf(p, "Server location: %s Server version : %s\n",
+ config_get_tmp("SERVER_HOSTNAME"), VERS_NUM);
+ pprintf(p, "The server has been up since %s.\n", strltime(&command_globals.startuptime));
+
+ pprintf(p,"Up for");
+
+ if(days)
+ pprintf(p," %d day%s", days, (days == 1) ? "" : "s");
+
+ if(hours)
+ pprintf(p," %d hour%s", hours, (hours == 1) ? "" : "s");
+
+ if(mins)
+ pprintf(p," %d minute%s", mins, (mins == 1) ? "" : "s");
+
+ if(secs)
+ pprintf(p," %d second%s", secs, (secs == 1) ? "" : "s");
+
+ pprintf(p,".\n");
+
+ pprintf(p, "\nPlayer limit: %d\n", config_get_int("MAX_PLAYER", DEFAULT_MAX_PLAYER));
+ pprintf(p, "\nThere are currently %d players, with a high of %d since last restart.\n", player_count(1), command_globals.player_high);
+ pprintf(p, "There are currently %d games, with a high of %d since last restart.\n", game_count(), command_globals.game_high);
+ pprintf(p, "\nCompiled on %s\n", COMP_DATE);
+ return COM_OK;
+}
+
+int com_date(int p, param_list param)
+{
+ time_t t = time(0);
+ pprintf(p, "Local time - %s\n", strltime(&t));
+ pprintf(p, "Greenwich time - %s\n", strgtime(&t));
+ return COM_OK;
+}
+
+static const char *inout_string[] = {
+ "login", "logout"
+};
+
+static int plogins(int p, char *fname)
+{
+ FILE *fp;
+ int inout, registered;
+ time_t thetime;
+ char loginName[MAX_LOGIN_NAME + 1];
+ char ipstr[20];
+
+ fp = fopen_p("%s", "r", fname);
+ if (!fp) {
+ pprintf(p, "Sorry, no login information available.\n");
+ return COM_OK;
+ }
+ while (!feof(fp)) {
+ unsigned t;
+ if (fscanf(fp, "%d %s %u %d %s\n", &inout, loginName, &t,
+ ®istered, ipstr) != 5) {
+ d_printf( "CHESSD: Error in login info format. %s\n",
+ fname);
+ fclose(fp);
+ return COM_OK;
+ }
+ thetime = (time_t)t;
+ pprintf(p, "%s: %-17s %-6s", strltime(&thetime), loginName,
+ inout_string[inout]);
+ if (check_admin(p, 1) && !CheckPFlag(p, PFLAG_HIDEINFO)) {
+ pprintf(p, " from %s\n", ipstr);
+ } else
+ pprintf(p, "\n");
+ }
+ fclose(fp);
+ return COM_OK;
+}
+
+int com_llogons(int p, param_list param)
+{
+ int result;
+ if (!CheckPFlag(p, PFLAG_REG)) {
+ pprintf(p,"Sorry, guest users may not use this command\n");
+ return COM_OK;
+ }
+ result = plogins(p, STATS_DIR "/" STATS_LOGONS);
+ return result;
+}
+
+int com_logons(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ char fname[MAX_FILENAME_SIZE];
+
+ if (param[0].type == TYPE_WORD) {
+ int p1, connected;
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+ sprintf(fname, "%s/player_data/%c/%s.%s",
+ STATS_DIR,
+ player_globals.parray[p1].login[0],
+ player_globals.parray[p1].login, STATS_LOGONS);
+ if (!connected)
+ player_remove(p1);
+ } else {
+ sprintf(fname, "%s/player_data/%c/%s.%s",
+ STATS_DIR,
+ pp->login[0],
+ pp->login,
+ STATS_LOGONS);
+ }
+ return plogins(p, fname);
+}
+
+#define WHO_OPEN 0x01
+#define WHO_CLOSED 0x02
+#define WHO_RATED 0x04
+#define WHO_UNRATED 0x08
+#define WHO_FREE 0x10
+#define WHO_PLAYING 0x20
+#define WHO_REGISTERED 0x40
+#define WHO_UNREGISTERED 0x80
+#define WHO_BUGTEAM 0x100
+
+#define WHO_ALL 0xff
+
+void AddPlayerLists (int p1, char *ptmp)
+{
+ if (check_admin(p1, ADMIN_ADMIN) && CheckPFlag(p1, PFLAG_ADMINLIGHT))
+ strcat(ptmp, "(*)");
+ if (in_list(p1, L_COMPUTER, player_globals.parray[p1].name))
+ strcat(ptmp, "(C)");
+ if (in_list(p1, L_FM, player_globals.parray[p1].name))
+ strcat(ptmp, "(FM)");
+ if (in_list(p1, L_IM, player_globals.parray[p1].name))
+ strcat(ptmp, "(IM)");
+ if (in_list(p1, L_GM, player_globals.parray[p1].name))
+ strcat(ptmp, "(GM)");
+ if (in_list(p1, L_WGM, player_globals.parray[p1].name))
+ strcat(ptmp, "(WGM)");
+ if (in_list(p1, L_TD, player_globals.parray[p1].name))
+ strcat(ptmp, "(TD)");
+ if (in_list(p1, L_TEAMS, player_globals.parray[p1].name))
+ strcat(ptmp, "(T)");
+ if (in_list(p1, L_BLIND, player_globals.parray[p1].name))
+ strcat(ptmp, "(B)");
+}
+
+static void who_terse(int p, int num, int *plist, int type)
+{
+ struct player *pp = &player_globals.parray[p];
+ char ptmp[80 + 20]; /* for highlight */
+ multicol *m = multicol_start(player_globals.parray_size);
+ int i;
+ int p1;
+ int rat = 0;
+
+ /* altered DAV 3/15/95 */
+
+ for (i = 0; i < num; i++) {
+ p1 = plist[i];
+
+ if (type == blitz_rat)
+ rat = player_globals.parray[p1].b_stats.rating;
+ else if (type == wild_rat)
+ rat = player_globals.parray[p1].w_stats.rating;
+ else if (type == std_rat)
+ rat = player_globals.parray[p1].s_stats.rating;
+ else if (type == light_rat)
+ rat = player_globals.parray[p1].l_stats.rating;
+ else if (type == bug_rat)
+ rat = player_globals.parray[p1].bug_stats.rating;
+
+ if (type == none) {
+ sprintf(ptmp, " ");
+ } else {
+ sprintf(ptmp, "%-4s", ratstrii(rat, p1));
+ if ((player_globals.parray[p1].simul_info != NULL) && (player_globals.parray[p1].simul_info->numBoards))
+ strcat(ptmp, "~");
+ else if ((player_globals.parray[p1].game >= 0) && ((game_globals.garray[player_globals.parray[p1].game].status == GAME_EXAMINE) || (game_globals.garray[player_globals.parray[p1].game].status == GAME_SETUP)))
+ strcat(ptmp, "#");
+ else if (player_globals.parray[p1].game >= 0)
+ strcat(ptmp, "^");
+ else if (!CheckPFlag(p1, PFLAG_OPEN))
+ strcat(ptmp, ":");
+ else if (player_idle(p1) > 300)
+ strcat(ptmp, ".");
+ else
+ strcat(ptmp, " ");
+ }
+
+ if (p == p1) {
+ psprintf_highlight(p, ptmp + strlen(ptmp), "%s", player_globals.parray[p1].name);
+ } else {
+ strcat(ptmp, player_globals.parray[p1].name);
+ }
+
+ AddPlayerLists(p1, ptmp);
+ multicol_store(m, ptmp);
+ }
+ multicol_pprint(m, p, pp->d_width, 2);
+ multicol_end(m);
+ pprintf(p, "\n %d players displayed (of %d). (*) indicates system administrator.\n", num, player_count(1));
+}
+
+static void who_verbose(p, num, plist)
+int p;
+int num;
+int plist[];
+{
+ int i, p1;
+ char playerLine[255], tmp[255]; /* +8 for highlight */
+ char p1WithAttrs[255];
+
+ pprintf(p,
+ " +---------------------------------------------------------------+\n"
+ );
+ pprintf(p,
+ " | User Standard Blitz On for Idle |\n"
+ );
+ pprintf(p,
+ " +---------------------------------------------------------------+\n"
+ );
+
+ for (i = 0; i < num; i++) {
+ p1 = plist[i];
+
+ strcpy(playerLine, " |");
+
+ if (player_globals.parray[p1].game >= 0)
+ sprintf(tmp, "%3d", player_globals.parray[p1].game + 1);
+ else
+ sprintf(tmp, " ");
+ strcat(playerLine, tmp);
+
+ if (!CheckPFlag(p1, PFLAG_OPEN))
+ sprintf(tmp, "X");
+ else
+ sprintf(tmp, " ");
+ strcat(playerLine, tmp);
+
+ if (CheckPFlag(p1, PFLAG_REG))
+ if (CheckPFlag(p1, PFLAG_RATED)) {
+ sprintf(tmp, " ");
+ } else {
+ sprintf(tmp, "u");
+ }
+ else
+ sprintf(tmp, "U");
+ strcat(playerLine, tmp);
+
+ /* Modified by hersco to include lists in 'who v.' */
+ strcpy (p1WithAttrs, player_globals.parray[p1].name);
+ AddPlayerLists(p1, p1WithAttrs);
+ p1WithAttrs[17] = '\0';
+
+ /* Modified by DAV 3/15/95 */
+ if (p == p1) {
+ strcpy(tmp, " ");
+ psprintf_highlight(p, tmp + strlen(tmp), "%-17s", p1WithAttrs);
+ } else {
+ sprintf(tmp, " %-17s", p1WithAttrs);
+ }
+ strcat(playerLine, tmp);
+
+ sprintf(tmp, " %4s %-4s %5s ",
+ ratstrii(player_globals.parray[p1].s_stats.rating, p1),
+ ratstrii(player_globals.parray[p1].b_stats.rating, p1),
+ hms(player_ontime(p1), 0, 0, 0));
+ strcat(playerLine, tmp);
+
+ if (player_idle(p1) >= 60) {
+ sprintf(tmp, "%5s |\n", hms(player_idle(p1), 0, 0, 0));
+ } else {
+ sprintf(tmp, " |\n");
+ }
+ strcat(playerLine, tmp);
+ pprintf(p, "%s", playerLine);
+ }
+
+ pprintf(p,
+ " | |\n"
+ );
+ pprintf(p,
+ " | %3d Players Displayed |\n",
+ num
+ );
+ pprintf(p,
+ " +---------------------------------------------------------------+\n"
+ );
+}
+
+static void who_winloss(p, num, plist)
+int p;
+int num;
+int plist[];
+{
+ int i, p1;
+ char playerLine[255], tmp[255]; /* for highlight */
+ char p1WithAttrs[255];
+
+ pprintf(p,
+ "Name Stand win loss draw Blitz win loss draw idle\n"
+ );
+ pprintf(p,
+ "---------------- ----- ------------- ----- ------------- ----\n"
+ );
+
+ for (i = 0; i < num; i++) {
+ playerLine[0] = '\0';
+ p1 = plist[i];
+
+ /* Modified by hersco to include lists in 'who n.' */
+ strcpy (p1WithAttrs, player_globals.parray[p1].name);
+ AddPlayerLists(p1, p1WithAttrs);
+ p1WithAttrs[17] = '\0';
+
+ if (p1 == p) {
+ psprintf_highlight(p, playerLine, "%-17s", p1WithAttrs);
+ } else {
+ sprintf(playerLine, "%-17s", p1WithAttrs);
+ }
+ sprintf(tmp, " %4s %4d %4d %4d ",
+ ratstrii(player_globals.parray[p1].s_stats.rating, p1),
+ (int) player_globals.parray[p1].s_stats.win,
+ (int) player_globals.parray[p1].s_stats.los,
+ (int) player_globals.parray[p1].s_stats.dra);
+ strcat(playerLine, tmp);
+
+ sprintf(tmp, "%4s %4d %4d %4d ",
+ ratstrii(player_globals.parray[p1].b_stats.rating, p1),
+ (int) player_globals.parray[p1].b_stats.win,
+ (int) player_globals.parray[p1].b_stats.los,
+ (int) player_globals.parray[p1].b_stats.dra);
+ strcat(playerLine, tmp);
+
+ if (player_idle(p1) >= 60) {
+ sprintf(tmp, "%5s\n", hms(player_idle(p1), 0, 0, 0));
+ } else {
+ sprintf(tmp, " \n");
+ }
+ strcat(playerLine, tmp);
+
+ pprintf(p, "%s", playerLine);
+ }
+ pprintf(p, " %3d Players Displayed.\n", num);
+}
+
+static int who_ok(int p, unsigned int sel_bits)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p2;
+ if (pp->status != PLAYER_PROMPT)
+ return 0;
+ if (sel_bits == WHO_ALL)
+ return 1;
+ if (sel_bits & WHO_OPEN)
+ if (!CheckPFlag(p, PFLAG_OPEN) || CheckPFlag(p, PFLAG_TOURNEY))
+ return 0;
+ if (sel_bits & WHO_CLOSED)
+ if (CheckPFlag(p, PFLAG_OPEN))
+ return 0;
+ if (sel_bits & WHO_RATED)
+ if (!CheckPFlag(p, PFLAG_RATED))
+ return 0;
+ if (sel_bits & WHO_UNRATED)
+ if (CheckPFlag(p, PFLAG_RATED))
+ return 0;
+ if (sel_bits & WHO_FREE)
+ if (pp->game >= 0)
+ return 0;
+ if (sel_bits & WHO_PLAYING)
+ if (pp->game < 0)
+ return 0;
+ if (sel_bits & WHO_REGISTERED)
+ if (!CheckPFlag(p, PFLAG_REG))
+ return 0;
+ if (sel_bits & WHO_UNREGISTERED)
+ if (CheckPFlag(p, PFLAG_REG))
+ return 0;
+ if (sel_bits & WHO_BUGTEAM) {
+ p2 = pp->partner;
+ if (p2 < 0 || player_globals.parray[p2].partner != p)
+ return 0;
+ }
+ return 1;
+}
+
+
+static int blitz_cmp(const void *pp1, const void *pp2)
+{
+ register int p1 = *(int *) pp1;
+ register int p2 = *(int *) pp2;
+ if (player_globals.parray[p1].status != PLAYER_PROMPT) {
+ if (player_globals.parray[p2].status != PLAYER_PROMPT)
+ return 0;
+ else
+ return -1;
+ }
+ if (player_globals.parray[p2].status != PLAYER_PROMPT)
+ return 1;
+ if (player_globals.parray[p1].b_stats.rating > player_globals.parray[p2].b_stats.rating)
+ return -1;
+ if (player_globals.parray[p1].b_stats.rating < player_globals.parray[p2].b_stats.rating)
+ return 1;
+ if (CheckPFlag(p1, PFLAG_REG) && !CheckPFlag(p2, PFLAG_REG))
+ return -1;
+ if (!CheckPFlag(p1, PFLAG_REG) && CheckPFlag(p2, PFLAG_REG))
+ return 1;
+ return strcmp(player_globals.parray[p1].login, player_globals.parray[p2].login);
+}
+
+static int light_cmp(const void *pp1, const void *pp2)
+{
+ register int p1 = *(int *) pp1;
+ register int p2 = *(int *) pp2;
+ if (player_globals.parray[p1].status != PLAYER_PROMPT) {
+ if (player_globals.parray[p2].status != PLAYER_PROMPT)
+ return 0;
+ else
+ return -1;
+ }
+ if (player_globals.parray[p2].status != PLAYER_PROMPT)
+ return 1;
+ if (player_globals.parray[p1].l_stats.rating > player_globals.parray[p2].l_stats.rating)
+ return -1;
+ if (player_globals.parray[p1].l_stats.rating < player_globals.parray[p2].l_stats.rating)
+ return 1;
+ if (CheckPFlag(p1, PFLAG_REG) && !CheckPFlag(p2, PFLAG_REG))
+ return -1;
+ if (!CheckPFlag(p1, PFLAG_REG) && CheckPFlag(p2, PFLAG_REG))
+ return 1;
+ return strcmp(player_globals.parray[p1].login, player_globals.parray[p2].login);
+}
+
+static int bug_cmp(const void *pp1, const void *pp2)
+{
+ register int p1 = *(int *) pp1;
+ register int p2 = *(int *) pp2;
+ if (player_globals.parray[p1].status != PLAYER_PROMPT) {
+ if (player_globals.parray[p2].status != PLAYER_PROMPT)
+ return 0;
+ else
+ return -1;
+ }
+ if (player_globals.parray[p2].status != PLAYER_PROMPT)
+ return 1;
+ if (player_globals.parray[p1].bug_stats.rating > player_globals.parray[p2].bug_stats.rating)
+ return -1;
+ if (player_globals.parray[p1].bug_stats.rating < player_globals.parray[p2].bug_stats.rating)
+ return 1;
+ if (CheckPFlag(p1, PFLAG_REG) && !CheckPFlag(p2, PFLAG_REG))
+ return -1;
+ if (!CheckPFlag(p1, PFLAG_REG) && CheckPFlag(p2, PFLAG_REG))
+ return 1;
+ return strcmp(player_globals.parray[p1].login, player_globals.parray[p2].login);
+}
+
+static int stand_cmp(const void *pp1, const void *pp2)
+{
+ register int p1 = *(int *) pp1;
+ register int p2 = *(int *) pp2;
+ if (player_globals.parray[p1].status != PLAYER_PROMPT) {
+ if (player_globals.parray[p2].status != PLAYER_PROMPT)
+ return 0;
+ else
+ return -1;
+ }
+ if (player_globals.parray[p2].status != PLAYER_PROMPT)
+ return 1;
+ if (player_globals.parray[p1].s_stats.rating > player_globals.parray[p2].s_stats.rating)
+ return -1;
+ if (player_globals.parray[p1].s_stats.rating < player_globals.parray[p2].s_stats.rating)
+ return 1;
+ if (CheckPFlag(p1, PFLAG_REG) && !CheckPFlag(p2, PFLAG_REG))
+ return -1;
+ if (!CheckPFlag(p1, PFLAG_REG) && CheckPFlag(p2, PFLAG_REG))
+ return 1;
+ return strcmp(player_globals.parray[p1].login, player_globals.parray[p2].login);
+}
+
+static int wild_cmp(const void *pp1, const void *pp2)
+{
+ register int p1 = *(int *) pp1;
+ register int p2 = *(int *) pp2;
+ if (player_globals.parray[p1].status != PLAYER_PROMPT) {
+ if (player_globals.parray[p2].status != PLAYER_PROMPT)
+ return 0;
+ else
+ return -1;
+ }
+ if (player_globals.parray[p2].status != PLAYER_PROMPT)
+ return 1;
+ if (player_globals.parray[p1].w_stats.rating > player_globals.parray[p2].w_stats.rating)
+ return -1;
+ if (player_globals.parray[p1].w_stats.rating < player_globals.parray[p2].w_stats.rating)
+ return 1;
+ if (CheckPFlag(p1, PFLAG_REG) && !CheckPFlag(p2, PFLAG_REG))
+ return -1;
+ if (!CheckPFlag(p1, PFLAG_REG) && CheckPFlag(p2, PFLAG_REG))
+ return 1;
+ return strcmp(player_globals.parray[p1].login, player_globals.parray[p2].login);
+}
+
+static int alpha_cmp(const void *pp1, const void *pp2)
+{
+ register int p1 = *(int *) pp1;
+ register int p2 = *(int *) pp2;
+ if (player_globals.parray[p1].status != PLAYER_PROMPT) {
+ if (player_globals.parray[p2].status != PLAYER_PROMPT)
+ return 0;
+ else
+ return -1;
+ }
+ if (player_globals.parray[p2].status != PLAYER_PROMPT)
+ return 1;
+ return strcmp(player_globals.parray[p1].login, player_globals.parray[p2].login);
+}
+
+static void sort_players(int *players,
+ int ((*cmp_func) (const void *, const void *)))
+{
+ int i;
+
+ for (i = 0; i < player_globals.p_num; i++) {
+ players[i] = i;
+ }
+ qsort(players, player_globals.p_num, sizeof(int), cmp_func);
+}
+
+/* This is the of the most compliclicated commands in terms of parameters */
+int com_who(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int style = 0;
+ float stop_perc = 1.0;
+ float start_perc = 0;
+ unsigned int sel_bits = WHO_ALL;
+ int *sortlist, *plist;
+ int ((*cmp_func) (const void *, const void *));
+ int startpoint;
+ int stoppoint;
+ int i, len;
+ int tmpI, tmpJ;
+ char c;
+ int p1, count, num_who;
+ int sort_type;
+ int total;
+
+ sortlist = malloc(sizeof(int) * player_globals.p_num);
+ plist = malloc(sizeof(int) * player_globals.p_num);
+
+ total = pp->d_time * 60 + pp->d_inc * 40;
+ if (total < 180) {
+ sort_type = light_rat;
+ cmp_func = light_cmp;
+ } else if (total >= 900) {
+ sort_type = std_rat;
+ cmp_func = stand_cmp;
+ } else {
+ sort_type = blitz_rat;
+ cmp_func = blitz_cmp;
+ }
+
+ if (param[0].type != TYPE_NULL) {
+ len = strlen(param[0].val.string);
+ for (i = 0; i < len; i++) {
+ c = param[0].val.string[i];
+ if (isdigit(c)) {
+ if (i == 0 || !isdigit(param[0].val.string[i - 1])) {
+ tmpI = c - '0';
+ if (tmpI == 1) {
+ start_perc = 0.0;
+ stop_perc = 0.333333;
+ } else if (tmpI == 2) {
+ start_perc = 0.333333;
+ stop_perc = 0.6666667;
+ } else if (tmpI == 3) {
+ start_perc = 0.6666667;
+ stop_perc = 1.0;
+ } else if ((i == len - 1) || (!isdigit(param[0].val.string[i + 1])))
+ goto bad_parameters;
+ } else {
+ tmpI = c - '0';
+ tmpJ = param[0].val.string[i - 1] - '0';
+ if (tmpI == 0)
+ goto bad_parameters;
+ if (tmpJ > tmpI)
+ goto bad_parameters;
+ start_perc = ((float) tmpJ - 1.0) / (float) tmpI;
+ stop_perc = ((float) tmpJ) / (float) tmpI;
+ }
+ } else {
+ switch (c) {
+ case ' ':
+ case '\n':
+ case '\t':
+ break;
+ case 'o':
+ if (sel_bits == WHO_ALL)
+ sel_bits = WHO_OPEN;
+ else
+ sel_bits |= WHO_OPEN;
+ break;
+ case 'r':
+ if (sel_bits == WHO_ALL)
+ sel_bits = WHO_RATED;
+ else
+ sel_bits |= WHO_RATED;
+ break;
+ case 'f':
+ if (sel_bits == WHO_ALL)
+ sel_bits = WHO_FREE;
+ else
+ sel_bits |= WHO_FREE;
+ break;
+ case 'a':
+ if (sel_bits == WHO_ALL)
+ sel_bits = WHO_FREE | WHO_OPEN;
+ else
+ sel_bits |= (WHO_FREE | WHO_OPEN);
+ break;
+ case 'R':
+ if (sel_bits == WHO_ALL)
+ sel_bits = WHO_REGISTERED;
+ else
+ sel_bits |= WHO_REGISTERED;
+ break;
+ case 'l': /* Sort order */
+ cmp_func = alpha_cmp;
+ sort_type = none;
+ break;
+ case 'A': /* Sort order */
+ cmp_func = alpha_cmp;
+ break;
+ case 'w': /* Sort order */
+ cmp_func = wild_cmp;
+ sort_type = wild_rat;
+ break;
+ case 's': /* Sort order */
+ cmp_func = stand_cmp;
+ sort_type = std_rat;
+ break;
+ case 'b': /* Sort order */
+ cmp_func = blitz_cmp;
+ sort_type = blitz_rat;
+ break;
+ case 'L': /* Sort order */
+ cmp_func = light_cmp;
+ sort_type = light_rat;
+ break;
+ case 't': /* format */
+ style = 0;
+ break;
+ case 'v': /* format */
+ style = 1;
+ break;
+ case 'n': /* format */
+ style = 2;
+ break;
+ case 'U':
+ if (sel_bits == WHO_ALL)
+ sel_bits = WHO_UNREGISTERED;
+ else
+ sel_bits |= WHO_UNREGISTERED;
+ break;
+ case 'B':
+ if (sel_bits == WHO_ALL)
+ sel_bits = WHO_BUGTEAM;
+ else
+ sel_bits |= WHO_BUGTEAM;
+ cmp_func = bug_cmp;
+ sort_type = bug_rat;
+ break;
+ default:
+ goto bad_parameters;
+ }
+ }
+ }
+ }
+ sort_players(sortlist, cmp_func);
+ count = 0;
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (!who_ok(sortlist[p1], sel_bits))
+ continue;
+ count++;
+ }
+ startpoint = floor((float) count * start_perc);
+ stoppoint = ceil((float) count * stop_perc) - 1;
+ num_who = 0;
+ count = 0;
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (!who_ok(sortlist[p1], sel_bits))
+ continue;
+ if ((count >= startpoint) && (count <= stoppoint)) {
+ plist[num_who++] = sortlist[p1];
+ }
+ count++;
+ }
+
+ if (num_who == 0) {
+ pprintf(p, "No logged in players match the flags in your who request.\n");
+ return COM_OK;
+ }
+
+ switch (style) {
+ case 0: /* terse */
+ who_terse(p, num_who, plist, sort_type);
+ break;
+ case 1: /* verbose */
+ who_verbose(p, num_who, plist);
+ break;
+ case 2: /* win-loss */
+ who_winloss(p, num_who, plist);
+ break;
+ default:
+ goto bad_parameters;
+ }
+
+ return COM_OK;
+
+bad_parameters:
+ return COM_BADPARAMETERS;
+}
+
+int com_open(int p, param_list param)
+{
+ int retval;
+ if ((retval = pcommand(p, "set open")) != COM_OK)
+ return retval;
+ else
+ return COM_OK_NOPROMPT;
+}
+
+int com_simopen(int p, param_list param)
+{
+ int retval;
+ if ((retval = pcommand(p, "set simopen")) != COM_OK)
+ return retval;
+ else
+ return COM_OK_NOPROMPT;
+}
+
+int com_bell(int p, param_list param)
+{
+ int retval;
+ if ((retval = pcommand(p, "set bell")) != COM_OK)
+ return retval;
+ else
+ return COM_OK_NOPROMPT;
+}
+
+int com_flip(int p, param_list param)
+{
+ int retval;
+ if ((retval = pcommand(p, "set flip")) != COM_OK)
+ return retval;
+ else
+ return COM_OK_NOPROMPT;
+}
+
+int com_style(int p, param_list param)
+{
+ int retval;
+ if ((retval = pcommand(p, "set style %d", param[0].val.integer)) != COM_OK)
+ return retval;
+ else
+ return COM_OK_NOPROMPT;
+}
+
+int com_promote(int p, param_list param)
+{
+ int retval;
+ if ((retval = pcommand(p, "set promote %s", param[0].val.word)) != COM_OK)
+ return retval;
+ else
+ return COM_OK_NOPROMPT;
+}
+
+void alias_add(int p, const char *name, const char *value)
+{
+ struct player *pp = &player_globals.parray[p];
+
+ pp->alias_list = (struct alias_type *)realloc(pp->alias_list,
+ sizeof(struct alias_type) * (pp->numAlias+1));
+ pp->alias_list[pp->numAlias].comm_name = strdup(name);
+ pp->alias_list[pp->numAlias].alias = strdup(value);
+ pp->numAlias++;
+}
+
+
+int com_alias(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int al, i;
+ const char *noalias[] = {"quit", "unalias", NULL};
+
+ if (param[0].type == TYPE_NULL) {
+ for (al = 0; al < pp->numAlias; al++) {
+ pprintf(p, "%s -> %s\n",
+ pp->alias_list[al].comm_name,
+ pp->alias_list[al].alias);
+ }
+ return COM_OK;
+ }
+
+ al = alias_lookup(param[0].val.word, pp->alias_list, pp->numAlias);
+ if (param[1].type == TYPE_NULL) {
+ if (al < 0) {
+ pprintf(p, "You have no alias named '%s'.\n", param[0].val.word);
+ } else {
+ pprintf(p, "%s -> %s\n",
+ pp->alias_list[al].comm_name,
+ pp->alias_list[al].alias);
+ }
+ return COM_OK;
+ }
+
+ if (al >= 0) {
+ FREE(pp->alias_list[al].alias);
+ pp->alias_list[al].alias = strdup(param[1].val.string);
+ pprintf(p, "Alias %s replaced.\n", param[0].val.string);
+ return COM_OK;
+ }
+
+ if (pp->numAlias >= config_get_int("MAX_ALIASES", DEFAULT_MAX_ALIASES)) {
+ pprintf(p, "You have your maximum number of aliases.\n");
+ return COM_OK;
+ }
+
+ for (i=0;noalias[i];i++) {
+ if (strcasecmp(param[0].val.string, noalias[i]) == 0) {
+ pprintf(p, "Sorry, you can't alias this command.\n");
+ return COM_OK;
+ }
+ }
+
+ alias_add(p, param[0].val.word, param[1].val.string);
+
+ pprintf(p, "Alias set.\n");
+
+ return COM_OK;
+}
+
+int com_unalias(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int al;
+ int i;
+
+ al = alias_lookup(param[0].val.word, pp->alias_list, pp->numAlias);
+ if (al < 0) {
+ pprintf(p, "You have no alias named '%s'.\n", param[0].val.word);
+ return COM_OK;
+ }
+
+ FREE(pp->alias_list[al].comm_name);
+ FREE(pp->alias_list[al].alias);
+ for (i = al; i < pp->numAlias-1; i++) {
+ pp->alias_list[i].comm_name = pp->alias_list[i+1].comm_name;
+ pp->alias_list[i].alias = pp->alias_list[i+1].alias;
+ }
+ pp->numAlias--;
+ pp->alias_list = (struct alias_type *)realloc(pp->alias_list,
+ sizeof(struct alias_type) * pp->numAlias);
+ pprintf(p,"Alias removed.\n");
+
+ return COM_OK;
+}
+
+
+int com_handles(int p, param_list param)
+{
+ char *buffer[1000];
+ char pdir[MAX_FILENAME_SIZE];
+ int count;
+
+ sprintf(pdir, "%s/%c", PLAYER_DIR, param[0].val.word[0]);
+ count = search_directory(pdir, param[0].val.word, buffer, 1000);
+ pprintf(p, "Found %d names.\n", count);
+ if (count > 0)
+ display_directory(p, buffer, count);
+ return COM_OK;
+}
+
+int com_getgi(int p, param_list param)
+{
+ int p1, g;
+ struct player *pp = &player_globals.parray[p];
+
+ if (!in_list(p, L_TD, pp->name)) {
+ pprintf(p, "Only TD programs are allowed to use this command.\n");
+ return COM_OK;
+ }
+ if (((p1 = player_find_bylogin(param[0].val.word)) < 0)
+ || (!CheckPFlag(p1, PFLAG_REG))) {
+ /* Darkside suggested not to return anything */
+ return COM_OK;
+ }
+ if (!CheckPFlag(p1, PFLAG_REG)) {
+ pprintf(p, "*getgi %s none none -1 -1 -1 -1 -1*\n", player_globals.parray[p1].name);
+ } else if (player_globals.parray[p1].game >= 0) {
+ g = player_globals.parray[p1].game;
+ if (game_globals.garray[g].status == GAME_ACTIVE) {
+ pprintf(p, "*getgi %s %s %s %d %d %d %d %d*\n",
+ player_globals.parray[p1].name,
+ game_globals.garray[g].white_name,
+ game_globals.garray[g].black_name,
+ g + 1,
+ game_globals.garray[g].wInitTime,
+ game_globals.garray[g].wIncrement,
+ game_globals.garray[g].rated,
+ game_globals.garray[g].private);
+ } else {
+ pprintf(p, "%s is not playing a game.\n", player_globals.parray[p1].name);
+ }
+ } else {
+ pprintf(p, "%s is not playing a game.\n", player_globals.parray[p1].name);
+ }
+ return COM_OK;
+}
+
+int com_getpi(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1;
+
+ if (!in_list(p, L_TD, pp->name)) {
+ pprintf(p, "Only TD programs are allowed to use this command.\n");
+ return COM_OK;
+ }
+ if (((p1 = player_find_bylogin(param[0].val.word)) < 0)
+ || (!CheckPFlag(p1, PFLAG_REG))) {
+ /* Darkside suggested not to return anything */
+ return COM_OK;
+ }
+ if (!CheckPFlag(p1, PFLAG_REG)) {
+ pprintf(p, "*getpi %s -1 -1 -1*\n", player_globals.parray[p1].name);
+ } else {
+ pprintf(p, "*getpi %s %d %d %d %d*\n", player_globals.parray[p1].name,
+ player_globals.parray[p1].w_stats.rating,
+ player_globals.parray[p1].b_stats.rating,
+ player_globals.parray[p1].s_stats.rating,
+ player_globals.parray[p1].l_stats.rating);
+ }
+ return COM_OK;
+}
+
+int com_limits(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+
+ pprintf(p, "\nCurrent hardcoded limits:\n");
+ pprintf(p, " Max number of channels and max capacity: %d\n", MAX_CHANNELS);
+ pprintf(p, " Max number of channels one can be in: %d\n", MAX_INCHANNELS);
+ pprintf(p, " Max number of people on the notify list: %d\n", MAX_NOTIFY);
+ pprintf(p, " Max number of people on the censor list: %d\n", MAX_CENSOR);
+ pprintf(p, " Max number of people in a simul game: %d\n", MAX_SIMUL);
+ pprintf(p, " Max number of messages one can receive: %d\n", MAX_MESSAGES);
+ pprintf(p, " Min number of games to be active: %d\n", PROVISIONAL);
+ if (!check_admin(p, ADMIN_ADMIN) &&
+ !titled_player(p,pp->login)) {
+ pprintf(p, " Size of journal (entries): %d\n", MAX_JOURNAL);
+ } else {
+ pprintf(p, " Size of journal (entries): 26\n");
+ }
+ pprintf(p, "\nAdmin settable limits:\n");
+ pprintf(p, " Shout quota gives two shouts per %d seconds.\n", seek_globals.quota_time);
+ return COM_OK;
+}
+
+
+int com_remote(int p, param_list param)
+{
+ int p1;
+
+ if ((p1 = player_find_part_login(param[0].val.word)) < 0) {
+ pprintf(p, "%s is not logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ if (!in_list(p1, L_REMOTE, player_globals.parray[p].login)) {
+ pprintf(p, "You are not in the remote list for %s\n",
+ player_globals.parray[p1].login);
+ return COM_OK;
+ }
+ pprintf(p, "Command issued as %s\n", player_globals.parray[p1].name);
+ pprintf(p1, "Remote command [%s] issued by %s\n",
+ param[1].val.string, player_globals.parray[p].name);
+ pcommand(p1, "%s\n", param[1].val.string);
+ return COM_OK;
+}
--- /dev/null
+/*
+ global configuration option handler for lasker chess server
+
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+#include "includes.h"
+
+/* database for holding config info */
+static TDB_CONTEXT *config_db;
+
+static int config_set(const char *name, char *value);
+
+/*
+ tdb logging function, just in case something goes wrong we log database errors to stderr
+ */
+static void tdb_log_fn(TDB_CONTEXT *t, int level, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ vfprintf(stderr, format, ap);
+ va_end(ap);
+}
+
+
+/*
+ initialise the config database with some default values. This is only called once
+ on initial installation
+ returns 0 on success
+ */
+static int config_init(void)
+{
+ config_db = tdb_open_ex(CONFIG_DB, 0, 0, O_RDWR|O_CREAT, 0600, tdb_log_fn);
+ if (!config_db) {
+ d_printf("Failed to create the config database!\n");
+ return -1;
+ }
+
+ /* a few important defaults */
+ config_set("DEFAULT_PROMPT", "fics% ");
+ config_set("GUEST_LOGIN", "guest");
+
+ /* this allows an initial admin connection */
+ return config_set("HEAD_ADMIN", "admin");
+}
+
+/* close the config database */
+void config_close(void)
+{
+ if (!config_db) return;
+ tdb_close(config_db);
+ config_db = NULL;
+}
+
+/*
+ open the config database
+ returns 0 on success
+ */
+int config_open(void)
+{
+ config_db = tdb_open_ex(CONFIG_DB, 0, 0, O_RDWR, 0600, tdb_log_fn);
+ if (!config_db && errno == ENOENT) {
+ return config_init();
+ }
+ if (!config_db) {
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ fetch a value from the config database - caller must free
+*/
+const char *config_get(const char *name)
+{
+ TDB_DATA data;
+ TDB_DATA key;
+
+ key.dptr = name;
+ key.dsize = strlen(name)+1;
+
+ data = tdb_fetch(config_db, key);
+
+ /* this trick allows config variables to show up in 'aconfig' as
+ soon as they are used */
+ if (!data.dptr && config_set(name, "NOT_CONFIGURED") == 0) {
+ data = tdb_fetch(config_db, key);
+ }
+
+ return data.dptr;
+}
+
+
+/*
+ fetch an integer value from the config database, with a default value
+*/
+int config_get_int(const char *name, int default_v)
+{
+ TDB_DATA data;
+ TDB_DATA key;
+ int v;
+
+ key.dptr = name;
+ key.dsize = strlen(name)+1;
+
+ data = tdb_fetch(config_db, key);
+
+ /* this trick allows config variables to show up in 'aconfig' as
+ soon as they are used */
+ if (!data.dptr) {
+ char *s = NULL;
+ data.dsize = asprintf(&s, "%d", default_v) + 1;
+ data.dptr = s;
+ tdb_store(config_db, key, data, TDB_REPLACE);
+ }
+
+ v = atoi(data.dptr);
+ free(data.dptr);
+
+ return v;
+}
+
+
+/*
+ set a configration variable.
+ Returns 0 on success
+*/
+static int config_set(const char *name, char *value)
+{
+ TDB_DATA data;
+ TDB_DATA key;
+ int ret;
+
+ key.dptr = name;
+ key.dsize = strlen(name)+1;
+
+ if (strcmp(value, "-") == 0) {
+ return tdb_delete(config_db, key);
+ }
+
+ data.dptr = value;
+ data.dsize = strlen(value)+1;
+
+ ret = tdb_store(config_db, key, data, TDB_REPLACE);
+ return ret;
+}
+
+/*
+ fetch a value from the config database - will be auto-freed on a future call
+ to config_get_tmp()
+*/
+const char *config_get_tmp(const char *name)
+{
+ static const char *ret[10];
+ static unsigned idx;
+ const char **p = &ret[idx];
+ idx = (idx+1) % 10;
+ if (*p) {
+ free(*p);
+ }
+ *p = config_get(name);
+ return *p;
+}
+
+
+/*
+ dump the current config
+ */
+static void config_dump(int p)
+{
+ TDB_DATA data1, data2;
+
+ /* looping using firstkey/nextkey is a pain ... */
+ for (data1 = tdb_firstkey(config_db);
+ data1.dptr;
+ data2 = data1,
+ data1 = tdb_nextkey(config_db, data2),
+ free(data2.dptr)) {
+ pprintf(p, "%s = %s\n", data1.dptr, config_get_tmp(data1.dptr));
+ }
+}
+
+/*
+ * aconfig
+ *
+ * Usage: aconfig variable value
+ *
+ * sets the config variable 'variable' to 'value'
+ */
+int com_aconfig(int p, param_list param)
+{
+ if (param[0].type == TYPE_NULL) {
+ /* if no parameters are given then dump the current config */
+ config_dump(p);
+ return COM_OK;
+ }
+
+ if (config_set(param[0].val.word, param[1].val.string) != 0) {
+ return COM_FAILED;
+ }
+
+ return COM_OK;
+}
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+/* Configure file locations in this include file. */
+
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+
+/* CONFIGURE THIS: The port on which the server binds */
+
+#define DEFAULT_PORT 5000
+
+/* Which is the default language for help files, see variable.h for the
+ current available settings */
+
+#define LANG_DEFAULT LANG_ENGLISH
+
+
+/* CONFIGURE THESE: Locations of the data, players, and games directories */
+/* These must be absolute paths because some mail daemons may be called */
+/* from outside the pwd */
+
+#define MAX_ADVERTS 24
+/* These small files are printed when users log in
+ They can be used for advertisements or to promote server features
+ MAX_ADVERTS = the number of adverts you have
+ They should be put in the DEFAULT_ADVERTS directory
+ and be labelled with the numbers 0 - MAX_ADVERTS-1 inclusive
+ Eg if MAX_ADVERTS is 3 then the files are 0,1,2
+
+ If you do not want to use the adverts feature set it to -1
+*/
+
+/* define the directory that will be the root directory of FICS */
+#define FICSROOT "./"
+
+#define CONFIG_DB FICSROOT "config.tdb"
+#define NEWS_DB FICSROOT "news.tdb"
+#define LIB_DIR FICSROOT "lib"
+#define ADVERT_DIR FICSROOT "data/adverts"
+#define MESS_DIR FICSROOT "data/messages"
+#define INDEX_DIR FICSROOT "data/index"
+#define HELP_DIR FICSROOT "data/help"
+#define HELP_SPANISH FICSROOT "data/Spanish"
+#define HELP_FRENCH FICSROOT "data/French"
+#define HELP_DANISH FICSROOT "data/Danish"
+#define INFO_DIR FICSROOT "data/info"
+#define ADHELP_DIR FICSROOT "data/admin"
+#define USCF_DIR FICSROOT "data/uscf"
+#define STATS_DIR FICSROOT "data/stats"
+#define SPOOL_DIR FICSROOT "spool/mail.XXXXXX"
+#define PLAYER_DIR FICSROOT "players"
+#define ADJOURNED_DIR FICSROOT "games/adjourned"
+#define HISTORY_DIR FICSROOT "games/history"
+#define JOURNAL_DIR FICSROOT "games/journal"
+#define BOARD_DIR FICSROOT "data/boards"
+#define LISTS_DIR FICSROOT "data/lists"
+#define BOOK_DIR FICSROOT "data/book"
+#define MESS_FULL FICSROOT "data/messages/full"
+#define MESS_FULL_UNREG FICSROOT "data/messages/full_unreg"
+#define USAGE_DIR FICSROOT "data/usage"
+#define USAGE_SPANISH FICSROOT "data/usage_spanish"
+#define USAGE_FRENCH FICSROOT "data/usage_french"
+#define USAGE_DANISH FICSROOT "data/usage_danish"
+
+/* all of these can be overridden using the 'aconfig' command */
+#define DEFAULT_MAX_PLAYER 5000
+#define DEFAULT_MAX_USER_LIST_SIZE 100
+#define DEFAULT_MAX_ALIASES 20
+#define DEFAULT_RATING 0
+#define DEFAULT_RD 350
+#define DEFAULT_TIME 2
+#define DEFAULT_INCREMENT 12
+#define DEFAULT_MAX_SOUGHT 1000
+#define DEFAULT_IDLE_TIMEOUT 3600
+#define DEFAULT_LOGIN_TIMEOUT 300
+#define DEFAULT_GUEST_PREFIX_ONLY 0
+
+#endif /* _CONFIG_H */
--- /dev/null
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=acconfig.h
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+
+
+CHESSD_CFLAGS=""
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:533: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:563: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:614: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:646: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 657 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:662: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:688: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:693: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:702: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:721: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:753: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+ rm -f conftestdata
+ ac_cv_prog_LN_S="ln -s"
+else
+ ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:804: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+echo $ac_n "checking for main in -lm""... $ac_c" 1>&6
+echo "configure:858: checking for main in -lm" >&5
+ac_lib_var=`echo m'_'main | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lm $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 866 "configure"
+#include "confdefs.h"
+
+int main() {
+main()
+; return 0; }
+EOF
+if { (eval echo configure:873: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo m | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-lm $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
+echo "configure:906: checking for $ac_hdr that defines DIR" >&5
+if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 911 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <$ac_hdr>
+int main() {
+DIR *dirp = 0;
+; return 0; }
+EOF
+if { (eval echo configure:919: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_header_dirent_$ac_safe=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_dirent_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ ac_header_dirent=$ac_hdr; break
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6
+echo "configure:944: checking for opendir in -ldir" >&5
+ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldir $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 952 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char opendir();
+
+int main() {
+opendir()
+; return 0; }
+EOF
+if { (eval echo configure:963: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -ldir"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
+echo "configure:985: checking for opendir in -lx" >&5
+ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lx $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 993 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char opendir();
+
+int main() {
+opendir()
+; return 0; }
+EOF
+if { (eval echo configure:1004: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -lx"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1027: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 1042 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1048: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 1059 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1065: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 1076 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1082: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1107: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1112 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1120: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1137 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1155 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1176 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1187: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
+echo "configure:1211: checking for sys/wait.h that is POSIX.1 compatible" >&5
+if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1216 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+#define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+int main() {
+int s;
+wait (&s);
+s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+; return 0; }
+EOF
+if { (eval echo configure:1232: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_header_sys_wait_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_sys_wait_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6
+if test $ac_cv_header_sys_wait_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_SYS_WAIT_H 1
+EOF
+
+fi
+
+for ac_hdr in fcntl.h strings.h sys/file.h sys/ioctl.h sys/md5.h sys/time.h unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1256: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1261 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1266: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:1294: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1299 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:1348: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:1369: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1374 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_size_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+ cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
+echo "configure:1402: checking whether time.h and sys/time.h may both be included" >&5
+if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1407 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+int main() {
+struct tm *tp;
+; return 0; }
+EOF
+if { (eval echo configure:1416: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_header_time=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_time=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_time" 1>&6
+if test $ac_cv_header_time = yes; then
+ cat >> confdefs.h <<\EOF
+#define TIME_WITH_SYS_TIME 1
+EOF
+
+fi
+
+echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6
+echo "configure:1437: checking whether struct tm is in sys/time.h or time.h" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1442 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <time.h>
+int main() {
+struct tm *tp; tp->tm_sec;
+; return 0; }
+EOF
+if { (eval echo configure:1450: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_struct_tm=time.h
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_struct_tm=sys/time.h
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_tm" 1>&6
+if test $ac_cv_struct_tm = sys/time.h; then
+ cat >> confdefs.h <<\EOF
+#define TM_IN_SYS_TIME 1
+EOF
+
+fi
+
+
+for ac_func in dlopen
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1474: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1479 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1502: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+if test x"$ac_cv_func_dlopen" = x"no"; then
+ echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+echo "configure:1528: checking for dlopen in -ldl" >&5
+ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1536 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo configure:1547: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -ldl";
+ cat >> confdefs.h <<\EOF
+#define HAVE_DLOPEN 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking for compar_fn_t in stdlib.h""... $ac_c" 1>&6
+echo "configure:1574: checking for compar_fn_t in stdlib.h" >&5
+if eval "test \"`echo '$''{'ccache_cv_COMPAR_FN_T'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+ cat > conftest.$ac_ext <<EOF
+#line 1580 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+int main() {
+
+void test_fn(void) { qsort(NULL, 0, 0, (__compar_fn_t)NULL); }
+
+; return 0; }
+EOF
+if { (eval echo configure:1589: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ccache_cv_COMPAR_FN_T=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ccache_cv_COMPAR_FN_T=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ccache_cv_COMPAR_FN_T" 1>&6
+if test x"$ccache_cv_COMPAR_FN_T" = x"yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_COMPAR_FN_T 1
+EOF
+
+fi
+
+if test $ac_cv_prog_gcc = yes; then
+ echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6
+echo "configure:1611: checking whether ${CC-cc} needs -traditional" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_pattern="Autoconf.*'x'"
+ cat > conftest.$ac_ext <<EOF
+#line 1617 "configure"
+#include "confdefs.h"
+#include <sgtty.h>
+Autoconf TIOCGETP
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "$ac_pattern" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_prog_gcc_traditional=yes
+else
+ rm -rf conftest*
+ ac_cv_prog_gcc_traditional=no
+fi
+rm -f conftest*
+
+
+ if test $ac_cv_prog_gcc_traditional = no; then
+ cat > conftest.$ac_ext <<EOF
+#line 1635 "configure"
+#include "confdefs.h"
+#include <termio.h>
+Autoconf TCGETA
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "$ac_pattern" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_prog_gcc_traditional=yes
+fi
+rm -f conftest*
+
+ fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6
+ if test $ac_cv_prog_gcc_traditional = yes; then
+ CC="$CC -traditional"
+ fi
+fi
+
+echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
+echo "configure:1657: checking return type of signal handlers" >&5
+if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1662 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int main() {
+int i;
+; return 0; }
+EOF
+if { (eval echo configure:1679: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_type_signal=void
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_type_signal=int
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_type_signal" 1>&6
+cat >> confdefs.h <<EOF
+#define RETSIGTYPE $ac_cv_type_signal
+EOF
+
+
+echo $ac_n "checking for strftime""... $ac_c" 1>&6
+echo "configure:1698: checking for strftime" >&5
+if eval "test \"`echo '$''{'ac_cv_func_strftime'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1703 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char strftime(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strftime();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_strftime) || defined (__stub___strftime)
+choke me
+#else
+strftime();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1726: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_strftime=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_strftime=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'strftime`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRFTIME 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+# strftime is in -lintl on SCO UNIX.
+echo $ac_n "checking for strftime in -lintl""... $ac_c" 1>&6
+echo "configure:1748: checking for strftime in -lintl" >&5
+ac_lib_var=`echo intl'_'strftime | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lintl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1756 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strftime();
+
+int main() {
+strftime()
+; return 0; }
+EOF
+if { (eval echo configure:1767: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_STRFTIME 1
+EOF
+
+LIBS="-lintl $LIBS"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking for vprintf""... $ac_c" 1>&6
+echo "configure:1794: checking for vprintf" >&5
+if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1799 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char vprintf(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char vprintf();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_vprintf) || defined (__stub___vprintf)
+choke me
+#else
+vprintf();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1822: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_vprintf=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_vprintf=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'vprintf`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_VPRINTF 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test "$ac_cv_func_vprintf" != yes; then
+echo $ac_n "checking for _doprnt""... $ac_c" 1>&6
+echo "configure:1846: checking for _doprnt" >&5
+if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1851 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char _doprnt(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char _doprnt();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub__doprnt) || defined (__stub____doprnt)
+choke me
+#else
+_doprnt();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1874: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func__doprnt=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func__doprnt=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'_doprnt`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_DOPRNT 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking for wait3 that fills in rusage""... $ac_c" 1>&6
+echo "configure:1899: checking for wait3 that fills in rusage" >&5
+if eval "test \"`echo '$''{'ac_cv_func_wait3_rusage'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_wait3_rusage=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1907 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <stdio.h>
+/* HP-UX has wait3 but does not fill in rusage at all. */
+main() {
+ struct rusage r;
+ int i;
+ /* Use a field that we can force nonzero --
+ voluntary context switches.
+ For systems like NeXT and OSF/1 that don't set it,
+ also use the system CPU time. And page faults (I/O) for Linux. */
+ r.ru_nvcsw = 0;
+ r.ru_stime.tv_sec = 0;
+ r.ru_stime.tv_usec = 0;
+ r.ru_majflt = r.ru_minflt = 0;
+ switch (fork()) {
+ case 0: /* Child. */
+ /* Unless we actually _do_ something, the kernel sometimes doesn't chalk up any system time to this process. */
+ if(fork()) { i = 123; wait(NULL); } else { i = 234; exit(0); }
+ sleep(1); /* Give up the CPU. */
+ _exit(0);
+ case -1: _exit(0); /* What can we do? */
+ default: /* Parent. */
+ wait3(&i, 0, &r);
+ sleep(2); /* Avoid "text file busy" from rm on fast HP-UX machines. */
+ exit(r.ru_nvcsw == 0 && r.ru_majflt == 0 && r.ru_minflt == 0
+ && r.ru_stime.tv_sec == 0 && r.ru_stime.tv_usec == 0);
+ }
+}
+EOF
+if { (eval echo configure:1940: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_wait3_rusage=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_wait3_rusage=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_wait3_rusage" 1>&6
+if test $ac_cv_func_wait3_rusage = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_WAIT3 1
+EOF
+
+fi
+
+for ac_func in gethostname gettimeofday select socket strcspn strdup strstr dprintf
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1965: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1970 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1993: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in strnlen strlcpy strlcat
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2020: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2025 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2048: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile autoconfig.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@CC@%$CC%g
+s%@LN_S@%$LN_S%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@CPP@%$CPP%g
+s%@CHESSD_CFLAGS@%$CHESSD_CFLAGS%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="autoconfig.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
--- /dev/null
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(acconfig.h)
+
+AC_CONFIG_HEADER(autoconfig.h)
+
+CHESSD_CFLAGS=""
+
+dnl Checks for programs.
+AC_PROG_CC
+AC_PROG_LN_S
+AC_PROG_INSTALL
+
+dnl Checks for libraries.
+dnl Replace `main' with a function in -lm:
+AC_CHECK_LIB(m, main)
+
+dnl Checks for header files.
+AC_HEADER_DIRENT
+AC_HEADER_STDC
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS(fcntl.h strings.h sys/file.h sys/ioctl.h sys/md5.h sys/time.h unistd.h)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+AC_STRUCT_TM
+
+dnl we need dlopen() for 'areload'
+AC_CHECK_FUNCS(dlopen)
+if test x"$ac_cv_func_dlopen" = x"no"; then
+ AC_CHECK_LIB(dl, dlopen, [LIBS="$LIBS -ldl";
+ AC_DEFINE(HAVE_DLOPEN)])
+fi
+
+AC_CACHE_CHECK([for compar_fn_t in stdlib.h],ccache_cv_COMPAR_FN_T, [
+ AC_TRY_COMPILE(
+[#include <stdlib.h>],
+[
+void test_fn(void) { qsort(NULL, 0, 0, (__compar_fn_t)NULL); }
+],
+ ccache_cv_COMPAR_FN_T=yes,ccache_cv_COMPAR_FN_T=no)])
+if test x"$ccache_cv_COMPAR_FN_T" = x"yes"; then
+ AC_DEFINE(HAVE_COMPAR_FN_T, 1, [ ])
+fi
+
+dnl Checks for library functions.
+AC_PROG_GCC_TRADITIONAL
+AC_TYPE_SIGNAL
+AC_FUNC_STRFTIME
+AC_FUNC_VPRINTF
+AC_FUNC_WAIT3
+AC_CHECK_FUNCS(gethostname gettimeofday select socket strcspn strdup strstr dprintf)
+AC_CHECK_FUNCS(strnlen strlcpy strlcat)
+
+AC_SUBST(CHESSD_CFLAGS)
+
+AC_OUTPUT(Makefile)
--- /dev/null
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ *
+ * $FreeBSD: src/lib/libcrypt/crypt-md5.c,v 1.5 1999/12/17 20:21:45 peter Exp $
+ *
+ */
+
+#include "includes.h"
+
+#define MD5_SIZE 16
+
+/*
+ * UNIX password
+ */
+
+char *crypt_md5(const char *pw, const char *salt)
+{
+ static char *magic = "$1$"; /*
+ * This string is magic for
+ * this algorithm. Having
+ * it this way, we can get
+ * get better later on
+ */
+ static char passwd[120], *p;
+ static const char *sp,*ep;
+ unsigned char final[MD5_SIZE];
+ int sl,pl,i;
+ MD5_CTX ctx,ctx1;
+ unsigned long l;
+
+ /* Refine the Salt first */
+ sp = salt;
+
+ /* If it starts with the magic string, then skip that */
+ if(!strncmp(sp,magic,strlen(magic)))
+ sp += strlen(magic);
+
+ /* It stops at the first '$', max 8 chars */
+ for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++)
+ continue;
+
+ /* get the length of the true salt */
+ sl = ep - sp;
+
+ MD5Init(&ctx);
+
+ /* The password first, since that is what is most unknown */
+ MD5Update(&ctx,pw,strlen(pw));
+
+ /* Then our magic string */
+ MD5Update(&ctx,magic,strlen(magic));
+
+ /* Then the raw salt */
+ MD5Update(&ctx,sp,sl);
+
+ /* Then just as many characters of the MD5(pw,salt,pw) */
+ MD5Init(&ctx1);
+ MD5Update(&ctx1,pw,strlen(pw));
+ MD5Update(&ctx1,sp,sl);
+ MD5Update(&ctx1,pw,strlen(pw));
+ MD5Final(final,&ctx1);
+ for(pl = strlen(pw); pl > 0; pl -= MD5_SIZE)
+ MD5Update(&ctx,final,pl>MD5_SIZE ? MD5_SIZE : pl);
+
+ /* Don't leave anything around in vm they could use. */
+ memset(final,0,sizeof final);
+
+ /* Then something really weird... */
+ for (i = strlen(pw); i ; i >>= 1)
+ if(i&1)
+ MD5Update(&ctx, final, 1);
+ else
+ MD5Update(&ctx, pw, 1);
+
+ /* Now make the output string */
+ strcpy(passwd,magic);
+ strncat(passwd,sp,sl);
+ strcat(passwd,"$");
+
+ MD5Final(final,&ctx);
+
+ /*
+ * and now, just to make sure things don't run too fast
+ * On a 60 Mhz Pentium this takes 34 msec, so you would
+ * need 30 seconds to build a 1000 entry dictionary...
+ */
+ for(i=0;i<1000;i++) {
+ MD5Init(&ctx1);
+ if(i & 1)
+ MD5Update(&ctx1,pw,strlen(pw));
+ else
+ MD5Update(&ctx1,final,MD5_SIZE);
+
+ if(i % 3)
+ MD5Update(&ctx1,sp,sl);
+
+ if(i % 7)
+ MD5Update(&ctx1,pw,strlen(pw));
+
+ if(i & 1)
+ MD5Update(&ctx1,final,MD5_SIZE);
+ else
+ MD5Update(&ctx1,pw,strlen(pw));
+ MD5Final(final,&ctx1);
+ }
+
+ p = passwd + strlen(passwd);
+
+ l = (final[ 0]<<16) | (final[ 6]<<8) | final[12];
+ _crypt_to64(p,l,4); p += 4;
+ l = (final[ 1]<<16) | (final[ 7]<<8) | final[13];
+ _crypt_to64(p,l,4); p += 4;
+ l = (final[ 2]<<16) | (final[ 8]<<8) | final[14];
+ _crypt_to64(p,l,4); p += 4;
+ l = (final[ 3]<<16) | (final[ 9]<<8) | final[15];
+ _crypt_to64(p,l,4); p += 4;
+ l = (final[ 4]<<16) | (final[10]<<8) | final[ 5];
+ _crypt_to64(p,l,4); p += 4;
+ l = final[11] ;
+ _crypt_to64(p,l,2); p += 2;
+ *p = '\0';
+
+ /* Don't leave anything around in vm they could use. */
+ memset(final,0,sizeof final);
+
+ return passwd;
+}
+
--- /dev/null
+/*
+ * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ *
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ * rights reserved.
+ *
+ * License to copy and use this software is granted provided that it
+ * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+ * Algorithm" in all material mentioning or referencing this software
+ * or this function.
+ *
+ * License is also granted to make and use derivative works provided
+ * that such works are identified as "derived from the RSA Data
+ * Security, Inc. MD5 Message-Digest Algorithm" in all material
+ * mentioning or referencing the derived work.
+ *
+ * RSA Data Security, Inc. makes no representations concerning either
+ * the merchantability of this software or the suitability of this
+ * software for any particular purpose. It is provided "as is"
+ * without express or implied warranty of any kind.
+ *
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ *
+ * $FreeBSD: src/lib/libmd/md5c.c,v 1.11 1999/12/29 05:04:20 peter Exp $
+ *
+ *
+ * This code is the same as the code published by RSA Inc. It has been
+ * edited for clarity and style only.
+ */
+
+#include "includes.h"
+
+static void MD5Transform __P((u_int32_t [4], const unsigned char [64]));
+
+#ifdef i386
+#define Encode memcpy
+#define Decode memcpy
+#else /* i386 */
+
+/*
+ * Encodes input (u_int32_t) into output (unsigned char). Assumes len is
+ * a multiple of 4.
+ */
+
+static void
+Encode (output, input, len)
+ unsigned char *output;
+ u_int32_t *input;
+ unsigned int len;
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4) {
+ output[j] = (unsigned char)(input[i] & 0xff);
+ output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
+ output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
+ output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
+ }
+}
+
+/*
+ * Decodes input (unsigned char) into output (u_int32_t). Assumes len is
+ * a multiple of 4.
+ */
+
+static void
+Decode (output, input, len)
+ u_int32_t *output;
+ const unsigned char *input;
+ unsigned int len;
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4)
+ output[i] = ((u_int32_t)input[j]) | (((u_int32_t)input[j+1]) << 8) |
+ (((u_int32_t)input[j+2]) << 16) | (((u_int32_t)input[j+3]) << 24);
+}
+#endif /* i386 */
+
+static unsigned char PADDING[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* F, G, H and I are basic MD5 functions. */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits. */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/*
+ * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+ * Rotation is separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s, ac) { \
+ (a) += F ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define GG(a, b, c, d, x, s, ac) { \
+ (a) += G ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define HH(a, b, c, d, x, s, ac) { \
+ (a) += H ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define II(a, b, c, d, x, s, ac) { \
+ (a) += I ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context. */
+
+void MD5Init(MD5_CTX *context)
+{
+
+ context->count[0] = context->count[1] = 0;
+
+ /* Load magic initialization constants. */
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xefcdab89;
+ context->state[2] = 0x98badcfe;
+ context->state[3] = 0x10325476;
+}
+
+/*
+ * MD5 block update operation. Continues an MD5 message-digest
+ * operation, processing another message block, and updating the
+ * context.
+ */
+
+void MD5Update(MD5_CTX *context,
+ const unsigned char *input,
+ unsigned int inputLen)
+{
+ unsigned int i, index, partLen;
+
+ /* Compute number of bytes mod 64 */
+ index = (unsigned int)((context->count[0] >> 3) & 0x3F);
+
+ /* Update number of bits */
+ if ((context->count[0] += ((u_int32_t)inputLen << 3))
+ < ((u_int32_t)inputLen << 3))
+ context->count[1]++;
+ context->count[1] += ((u_int32_t)inputLen >> 29);
+
+ partLen = 64 - index;
+
+ /* Transform as many times as possible. */
+ if (inputLen >= partLen) {
+ memcpy((void *)&context->buffer[index], (const void *)input,
+ partLen);
+ MD5Transform (context->state, context->buffer);
+
+ for (i = partLen; i + 63 < inputLen; i += 64)
+ MD5Transform (context->state, &input[i]);
+
+ index = 0;
+ }
+ else
+ i = 0;
+
+ /* Buffer remaining input */
+ memcpy ((void *)&context->buffer[index], (const void *)&input[i],
+ inputLen-i);
+}
+
+/*
+ * MD5 padding. Adds padding followed by original length.
+ */
+
+static void MD5Pad (MD5_CTX *context)
+{
+ unsigned char bits[8];
+ unsigned int index, padLen;
+
+ /* Save number of bits */
+ Encode (bits, context->count, 8);
+
+ /* Pad out to 56 mod 64. */
+ index = (unsigned int)((context->count[0] >> 3) & 0x3f);
+ padLen = (index < 56) ? (56 - index) : (120 - index);
+ MD5Update (context, PADDING, padLen);
+
+ /* Append length (before padding) */
+ MD5Update (context, bits, 8);
+}
+
+/*
+ * MD5 finalization. Ends an MD5 message-digest operation, writing the
+ * the message digest and zeroizing the context.
+ */
+
+void MD5Final(unsigned char digest[16],
+ MD5_CTX *context)
+{
+ /* Do padding. */
+ MD5Pad (context);
+
+ /* Store state in digest */
+ Encode (digest, context->state, 16);
+
+ /* Zeroize sensitive information. */
+ memset ((void *)context, 0, sizeof (*context));
+}
+
+/* MD5 basic transformation. Transforms state based on block. */
+
+static void
+MD5Transform (state, block)
+ u_int32_t state[4];
+ const unsigned char block[64];
+{
+ u_int32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+ Decode (x, block, 64);
+
+ /* Round 1 */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
+ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+ /* Round 3 */
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
+ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+ /* Round 4 */
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+
+ /* Zeroize sensitive information. */
+ memset ((void *)x, 0, sizeof (x));
+}
--- /dev/null
+/*
+ * Copyright (c) 1999
+ * University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD: src/lib/libcrypt/misc.c,v 1.1 1999/09/20 12:45:49 markm Exp $
+ *
+ */
+
+static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
+ "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+#include "includes.h"
+
+void _crypt_to64(unsigned char *s, unsigned long v, int n)
+{
+ while (--n >= 0) {
+ *s++ = itoa64[v&0x3f];
+ v >>= 6;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 1999
+ * Mark Murray. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MARK MURRAY AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL MARK MURRAY OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/lib/libcrypt/crypt.c,v 1.14 2000/01/07 06:33:54 kris Exp $
+ *
+ */
+
+#include "includes.h"
+
+char *chessd_crypt(const char *passwd, const char *salt)
+{
+ if (!strncmp(salt, "$1$", 3)) {
+ salt += 3;
+ salt = salt + strlen(salt) - strcspn(salt, "$");
+ return crypt_md5(passwd, salt);
+ }
+ return crypt_md5(passwd, salt);
+}
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+
+#include "includes.h"
+
+typedef struct {
+ char ECO[4];
+ char FENpos[74];
+} ECO_entry;
+
+typedef struct {
+ char NIC[6];
+ char FENpos[74];
+} NIC_entry;
+
+typedef struct {
+ char LONG[80];
+ char FENpos[74];
+} LONG_entry;
+
+static ECO_entry *ECO_book[1096];
+static NIC_entry *NIC_book[1096];
+static LONG_entry *LONG_book[4096];
+
+static int ECO_entries, NIC_entries, LONG_entries;
+
+/* This coverts a FEN position to a FICS board
+ it assumes FENpos contains a valid position
+ the color tag has been separated and put in color*/
+
+void FEN_to_board(char* FENpos, struct game_state_t* gs)
+{
+ int f,r;
+ char next;
+
+
+ for (r=7; r >=0; r--) {
+ f=0;
+ while (f<8) {
+ next = *(FENpos++);
+ if (isalpha(next))
+ gs->board[f++][r] = CharToPiece(next);
+ else if (next != '/') {
+ int t = (next - '0');
+ do
+ gs->board[f++][r] = NOPIECE;
+ while (--t);
+ }
+ }
+ }
+ if (*(FENpos + 1) == 'w') /* the char after the space */
+ gs->onMove = WHITE;
+ else
+ gs->onMove = BLACK;
+}
+
+/* converts a board to a FEN pos */
+
+static void board_to_FEN(char* FENpos, struct game_state_t* gs)
+{
+ int f,r,count;
+ char piece;
+
+ for (r=7; r>=0; r--) {
+ count = 0;
+ for (f=0; f<8; f++) {
+ if ((piece = PieceToChar(gs->board[f][r])) != ' ') {
+ if (count) {
+ *(FENpos++) = count + '0';
+ count = 0;
+ }
+ *(FENpos++) = piece;
+ } else {
+ if (f == 7)
+ *(FENpos++) = count + '0' + 1;
+ else
+ count++;
+ }
+ }
+ *(FENpos++) = '/';
+ }
+
+ *(--FENpos) = ' ';
+
+ if (gs->onMove == WHITE)
+ *(++FENpos) = 'w';
+ else
+ *(++FENpos) = 'b';
+ *(++FENpos) = '\0';
+}
+
+char *boardToFEN(int g)
+{
+ static char FENstring[74];
+
+ board_to_FEN (FENstring,&game_globals.garray[g].game_state);
+ return FENstring;
+}
+
+static void ECO_init()
+{
+ FILE *fp;
+ char tmp[1024];
+ char *ptmp= tmp;
+ char FENpos[73], ECO[4], onMove[2];
+ int i=0;
+
+ fp= fopen_s(BOOK_DIR "/eco999.idx", "r");
+ if (!fp) {
+ d_printf( "Could not open ECO file\n");
+ exit(1);
+ }
+ while (!feof(fp)) {
+ strcpy(ptmp, "");
+ fgets(ptmp, 1024, fp);
+ if (feof(fp)) continue;
+ sscanf(ptmp, "%[\x21-z] %s", FENpos, onMove);
+ sprintf(FENpos, "%s %s", FENpos, onMove);
+ strcpy(ptmp, "");
+ fgets(ptmp, 1024, fp);
+ if (feof(fp)) continue;
+ sscanf(ptmp, "%[0-z]", ECO);
+ ECO_book[i]= (ECO_entry *) malloc(sizeof(ECO_entry));
+ if (ECO_book[i]==NULL) {
+ d_printf( "Cound not alloc mem for ECO entry %d.\n", i);
+ exit(1);
+ }
+ strcpy(ECO_book[i]->ECO, ECO);
+ strcpy(ECO_book[i]->FENpos, FENpos);
+ ++i;
+ }
+ fclose(fp);
+ ECO_book[i]=NULL;
+ ECO_entries = i;
+
+ while (--i >= 0)
+ if (ECO_book[i] == NULL)
+ d_printf( "ERROR! ECO book position number %d is NULL.", i);
+}
+
+static void NIC_init()
+{
+ FILE *fp;
+ char tmp[1024];
+ char *ptmp= tmp;
+ char FENpos[73], NIC[6], onMove[2];
+ int i=0;
+
+ fp= fopen_p("%s/nic999.idx", "r", BOOK_DIR);
+ if (!fp) {
+ d_printf( "Could not open NIC file\n");
+ exit(1);
+ }
+ while (!feof(fp)) {
+ strcpy(ptmp, "");
+ fgets(ptmp, 1024, fp);
+ if (feof(fp)) continue;
+ sscanf(ptmp, "%[\x21-z] %s", FENpos, onMove);
+ sprintf(FENpos, "%s %s", FENpos, onMove);
+ strcpy(ptmp, "");
+ fgets(ptmp, 1024, fp);
+ if (feof(fp)) continue;
+ sscanf(ptmp, "%[.-z]", NIC);
+ NIC_book[i]= (NIC_entry *) malloc(sizeof(NIC_entry));
+ if (NIC_book[i]==NULL) {
+ d_printf( "Cound not alloc mem for NIC entry %d.\n", i);
+ exit(1);
+ }
+ strcpy(NIC_book[i]->NIC, NIC);
+ strcpy(NIC_book[i]->FENpos, FENpos);
+ ++i;
+ }
+ fclose(fp);
+ NIC_book[i]=NULL;
+ NIC_entries = i;
+}
+
+static void LONG_init()
+{
+ FILE *fp;
+ char tmp[1024];
+ char *ptmp= tmp;
+ char FENpos[74], LONG[256], onMove[2];
+ int i=0;
+
+ fp= fopen_p("%s/long999.idx", "r", BOOK_DIR);
+ if (!fp) {
+ d_printf( "Could not open LONG file\n");
+ exit(1);
+ }
+ while (!feof(fp)) {
+ strcpy(ptmp, "");
+ fgets(ptmp, 1024, fp);
+ if (feof(fp)) continue;
+ sscanf(ptmp, "%[\x21-z] %s", FENpos, onMove);
+ sprintf(FENpos, "%s %s", FENpos, onMove);
+ strcpy(ptmp, "");
+ fgets(ptmp, 1024, fp);
+ if (feof(fp)) continue;
+ sscanf(ptmp, "%[^*\n]", LONG);
+ LONG_book[i]= (LONG_entry *) malloc(sizeof(LONG_entry));
+ if (LONG_book[i]==NULL) {
+ d_printf( "Cound not alloc mem for LONG entry %d.\n", i);
+ exit(1);
+ }
+ strcpy(LONG_book[i]->LONG, LONG);
+ strcpy(LONG_book[i]->FENpos, FENpos);
+ ++i;
+ }
+ fclose(fp);
+ LONG_book[i]=NULL;
+ LONG_entries = i;
+}
+
+/* free up any memory used by books */
+void book_close(void)
+{
+ int i;
+
+ for (i=0;ECO_book[i];i++) {
+ free(ECO_book[i]);
+ ECO_book[i] = NULL;
+ }
+ for (i=0;NIC_book[i];i++) {
+ free(NIC_book[i]);
+ NIC_book[i] = NULL;
+ }
+ for (i=0;LONG_book[i];i++) {
+ free(LONG_book[i]);
+ LONG_book[i] = NULL;
+ }
+}
+
+void book_open(void)
+{
+ ECO_init();
+ NIC_init();
+ LONG_init();
+ d_printf("CHESSD: Loaded books\n");
+}
+
+char *getECO(int g)
+{
+ static char ECO[4];
+
+ int i, flag, l = 0, r = ECO_entries - 1, x;
+
+
+ if (game_globals.garray[g].type == TYPE_WILD) {
+ strcpy(ECO, "---");
+ return ECO;
+ } else if (game_globals.garray[g].moveList == NULL) {
+ strcpy(ECO, "***");
+ return ECO;
+ } else {
+ strcpy(ECO, "A00");
+ }
+
+ for (flag=0,i=game_globals.garray[g].numHalfMoves; (i>0 && !flag); i--) {
+ l = 0;
+ r = ECO_entries - 1;
+ while ((r >= l) && !flag) {
+ x = (l+r)/2;
+ if ((strcmp(game_globals.garray[g].moveList[i].FENpos, ECO_book[x]->FENpos)) < 0)
+ r = x - 1;
+ else
+ l = x + 1;
+ if (!strcmp(game_globals.garray[g].moveList[i].FENpos, ECO_book[x]->FENpos)) {
+ strcpy(ECO, ECO_book[x]->ECO);
+ flag=1;
+ }
+ }
+ }
+
+ return ECO;
+}
+
+int com_eco(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int i, flag = 0, x, l, r;
+ int g1, p1;
+
+
+ if (param[0].type == TYPE_NULL) { /* own game */
+ if (pp->game < 0) {
+ pprintf(p, "You are not playing or examining a game.\n");
+ return COM_OK;
+ }
+ g1=pp->game;
+ if (((game_globals.garray[g1].status != GAME_EXAMINE) &&
+ (game_globals.garray[g1].status != GAME_SETUP)) && !pIsPlaying(p))
+ return COM_OK;
+ } else {
+ g1 = GameNumFromParam (p, &p1, ¶m[0]);
+ if (g1 < 0) return COM_OK;
+ if ((g1 >= game_globals.g_num) || ((game_globals.garray[g1].status != GAME_ACTIVE) &&
+ (game_globals.garray[g1].status != GAME_EXAMINE) &&
+ (game_globals.garray[g1].status != GAME_SETUP))) {
+ pprintf(p, "There is no such game.\n");
+ return COM_OK;
+ }
+ }
+
+ if (game_globals.garray[g1].status == GAME_SETUP) {
+ pprintf (p,"The postion is still being set up.\n");
+ return COM_OK;
+ }
+
+ if (game_globals.garray[g1].private &&
+ (p != game_globals.garray[g1].white) && (p != game_globals.garray[g1].black) &&
+ !check_admin(p, 1)) {
+ pprintf(p, "Sorry - that game is private.\n");
+ return COM_OK;
+ } else {
+ if (game_globals.garray[g1].type == TYPE_WILD) {
+ pprintf(p, "That game is a wild game.\n");
+ return COM_OK;
+ }
+ }
+
+ pprintf(p, "Info about game %d: \"%s vs. %s\"\n\n", g1+1,
+ game_globals.garray[g1].white_name,
+ game_globals.garray[g1].black_name);
+
+ if (game_globals.garray[g1].moveList==NULL) {
+ return COM_OK;
+ }
+
+ for (flag=0,i=game_globals.garray[g1].numHalfMoves; (i>0 && !flag); i--) {
+ l = 0;
+ r = ECO_entries - 1;
+ while ((r >= l) && !flag) {
+ x = (l+r)/2;
+ if ((strcmp(game_globals.garray[g1].moveList[i].FENpos, ECO_book[x]->FENpos)) < 0)
+ r = x - 1;
+ else
+ l = x + 1;
+ if (!strcmp(game_globals.garray[g1].moveList[i].FENpos, ECO_book[x]->FENpos)) {
+ pprintf(p, " ECO[%3d]: %s\n", i, ECO_book[x]->ECO);
+ flag=1;
+ }
+ }
+ }
+
+ for (flag=0, i=game_globals.garray[g1].numHalfMoves; ((i>0) && (!flag)); i--) {
+ l = 0;
+ r = NIC_entries - 1;
+ while ((r >=l) && !flag) {
+ x = (l+r)/2;
+ if ((strcmp(game_globals.garray[g1].moveList[i].FENpos, NIC_book[x]->FENpos)) < 0)
+ r = x - 1;
+ else
+ l = x + 1;
+ if (!strcmp(game_globals.garray[g1].moveList[i].FENpos, NIC_book[x]->FENpos)) {
+ pprintf(p, " NIC[%3d]: %s\n", i, NIC_book[x]->NIC);
+ flag=1;
+ }
+ }
+ }
+
+ for (flag=0, i=game_globals.garray[g1].numHalfMoves; ((i>0) && (!flag)); i--) {
+ l = 0;
+ r = LONG_entries - 1;
+ while ((r >=l) && !flag) {
+ x = (l+r)/2;
+ if ((strcmp(game_globals.garray[g1].moveList[i].FENpos, LONG_book[x]->FENpos)) < 0)
+ r = x - 1;
+ else
+ l = x + 1;
+ if (!strcmp(game_globals.garray[g1].moveList[i].FENpos, LONG_book[x]->FENpos)) {
+ pprintf(p, " LONG[%3d]: %s\n", i, LONG_book[x]->LONG);
+ flag=1;
+ }
+ }
+ }
+
+ return COM_OK;
+}
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+#include "includes.h"
+
+static void usage(char *progname)
+{
+ d_printf( "Usage: %s [-l] [-n] UserName FullName EmailAddress\n", progname);
+ exit(1);
+}
+
+/* Parameters */
+static int local = 1;
+static char *funame = NULL, *fname = NULL, *email = NULL;
+
+unsigned chessd_reload_flag;
+
+#define PASSLEN 4
+int main(int argc, char *argv[])
+{
+ int admin, i, ch;
+ int p;
+ char password[PASSLEN + 1];
+ char salt[3];
+ char *text;
+ struct player *pp;
+
+ admin = 0;
+
+ while((ch = getopt(argc, argv, "lna:")) != -1) {
+ switch(ch) {
+ case 'l':
+ local = 1;
+ break;
+ case 'n':
+ local = 0;
+ break;
+ case 'a':
+ admin = atoi(optarg);
+ }
+ }
+
+ funame = strdup(argv[argc-3]);
+ fname = strdup(argv[argc-2]);
+ email = strdup(argv[argc-1]);
+ if (!funame || !fname || !email)
+ usage(argv[0]);
+
+ /* Add the player here */
+ if (strlen(funame) >= MAX_LOGIN_NAME) {
+ d_printf( "Player name is too long\n");
+ exit(0);
+ }
+ if (strlen(funame) < 3) {
+ d_printf( "Player name is too short\n");
+ exit(0);
+ }
+ if (!alphastring(funame)) {
+ d_printf( "Illegal characters in player name. Only A-Za-z allowed.\n");
+ exit(0);
+ }
+
+ srandom(time(0));
+ p = player_new();
+ if (!player_read(p, funame)) {
+ d_printf( "%s already exists.\n", funame);
+ exit(0);
+ }
+
+ pp = &player_globals.parray[p];
+
+ pp->name = strdup(funame);
+ pp->login = strdup(funame);
+ pp->adminLevel = admin;
+
+ stolower(pp->login);
+ pp->fullName = strdup(fname);
+ pp->emailAddress = strdup(email);
+ for (i = 0; i < PASSLEN; i++) {
+ password[i] = 'a' + random() % 26;
+ }
+ password[i] = '\0';
+ salt[0] = 'a' + random() % 26;
+ salt[1] = 'a' + random() % 26;
+ salt[2] = '\0';
+ pp->passwd = strdup(chessd_crypt(password,salt));
+ PFlagON(p, PFLAG_REG);
+/* pp->network_player = !local; */
+ PFlagON(p, PFLAG_RATED);
+ player_save(p);
+/* changed by Sparky 12/15/95 Dropped reference to 'Network' players
+ and spiffed it up */
+/*
+ printf("Added %s player >%s< >%s< >%s< >%s<\n", local ? "local" : "network",
+ funame, fname, email, password);
+ rasprintf(&text, "\nYou have been added as a %s player.\nIf this is a network account it may take a while to show up on all of the\nclients.\n\nLogin Name: %s\nFull Name: %s\nEmail Address: %s\nInitial Password: %s\n\nIf any of this information is incorrect, please contact the administrator\nto get it corrected.\nPlease write down your password, as it will be your initial passoword\non all of the servers.\n", local ? "local" : "network", funame, fname, email, password);
+*/
+
+ printf("Added %s account: >%s< >%s< >%s< >%s<\n",
+ admin?"ADMIN":"player",
+ funame, fname, email, password);
+
+ asprintf(&text, "\nYour player account has been created.\n\n"
+ "Login Name: %s\nFull Name: %s\nEmail Address: %s\nInitial Password: %s\n\n"
+ "If any of this information is incorrect, please contact the administrator\n"
+ "to get it corrected.\n\n"
+ "You may change your password with the password command on the the server.\n"
+ "\nPlease be advised that if this is an unauthorized duplicate account for\n"
+ "you, by using it you take the risk of being banned from accessing this\n"
+ "chess server.\n\n"
+ "Regards,\n\nThe FICS admins\n",
+ funame, fname, email, password);
+
+ free(text);
+
+ mail_string_to_address(email, "FICS Account Created", text);
+ return 0;
+}
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+/*
+ ficsmain.c is a minimal wrapper around chessd.so. By keeping this module to a
+ minimum size we can reload nearly all the chess server functionality on a 'areload'
+ command.
+*/
+
+
+#include "includes.h"
+
+/* handle used to talk to chessd.so */
+static void *chessd_so_handle;
+
+static void usage();
+static void main_event_loop(void);
+
+unsigned chessd_reload_flag;
+
+/*
+ load a function from chessd.so
+ this is the core of the runtime reload functionality
+*/
+static void *chessd_function(const char *name)
+{
+ void *sym;
+
+ if (!chessd_so_handle) {
+ chessd_so_handle = dlopen(LIB_DIR "/chessd.so", RTLD_LAZY);
+ if (!chessd_so_handle) {
+ fprintf(stderr, "CHESSD: Failed to load chessd.so !! (%s)\n",
+ dlerror());
+ exit(1);
+ }
+ }
+
+ sym = dlsym(chessd_so_handle, name);
+ if (!sym) {
+ fprintf(stderr, "CHESSD: Failed to find symbol %s in chessd.so !!\n",
+ name);
+ exit(1);
+ }
+
+ return sym;
+}
+
+
+static void usage()
+{
+ fprintf(stderr, "Usage: chessd -p port [-f] [-T timeseal_decoder] [-R rootdir]\n");
+ fprintf(stderr, "PORT_NUMBER is 5000 by default\n");
+ exit(1);
+}
+
+static int daemonize(void)
+{
+ pid_t pid;
+ if ((pid = fork()) == -1)
+ return -1;
+ else if (pid != 0)
+ exit(0);
+ if (setsid() == -1)
+ return -1;
+ return 0;
+}
+
+static void main_event_loop(void)
+{
+ void (*select_loop)(void ) = chessd_function("select_loop");
+
+ while (1) {
+ select_loop();
+
+ /* check the reload flag */
+ if (chessd_reload_flag) {
+ void (*reload_close)(void ) = chessd_function("reload_close");
+ void (*reload_open)(void );
+
+ chessd_reload_flag = 0;
+
+ fprintf(stderr, "CHESSD: Reloading server code!\n");
+
+ /* free up local vars */
+ reload_close();
+
+ /* close the handle to the shared lib */
+ dlclose(chessd_so_handle);
+ chessd_so_handle = NULL;
+
+ /* re-initialise local variables */
+ reload_open = chessd_function("reload_open");
+ reload_open();
+ select_loop = chessd_function("select_loop");
+ }
+ }
+}
+
+static void TerminateServer(int sig)
+{
+ void (*output_shut_mess)(void ) = chessd_function("output_shut_mess");
+ void (*TerminateCleanup)(void ) = chessd_function("TerminateCleanup");
+ void (*net_close)(void ) = chessd_function("net_close");
+
+ fprintf(stderr, "CHESSD: Received signal %d\n", sig);
+ output_shut_mess();
+ TerminateCleanup();
+ net_close();
+ exit(1);
+}
+
+static void BrokenPipe(int sig)
+{
+ signal(SIGPIPE, BrokenPipe);
+ fprintf(stderr, "CHESSD: Pipe signal\n");
+}
+
+
+/* this assumes we are setuid root to start */
+static void do_chroot(const char *dir)
+{
+ int i;
+ uid_t uid = getuid();
+ uid_t euid = geteuid();
+ struct rlimit rlp;
+
+ if (euid != 0 || setuid(0) != 0) {
+ fprintf(stderr, "Must be setuid root to use -R\n");
+ exit(1);
+ }
+ if (chroot(dir) != 0 || chdir("/") != 0) {
+ perror("chroot");
+ exit(1);
+ }
+ if (setuid(uid) != 0) {
+ perror("setuid");
+ exit(1);
+ }
+
+ /* close all extraneous file descriptors */
+ for (i=0;i<3;i++) close(i);
+ open("stdin.log", O_RDWR|O_CREAT|O_TRUNC, 0644);
+ open("stdout.log", O_WRONLY|O_CREAT|O_TRUNC, 0644);
+ open("stderr.log", O_WRONLY|O_CREAT|O_TRUNC, 0644);
+
+ /* reestabish core limits */
+ getrlimit(RLIMIT_CORE, &rlp );
+ rlp.rlim_cur = MAX(64*1024*1024, rlp.rlim_max);
+ setrlimit( RLIMIT_CORE, &rlp );
+}
+
+/*
+ give a decent backtrace on segv
+*/
+static void segv_handler(int sig)
+{
+ char cmd[100];
+ snprintf(cmd, sizeof(cmd), "/home/fics/bin/backtrace %d > /home/fics/chessd/segv_%d 2>&1",
+ (int)getpid(), (int)getpid());
+ system(cmd);
+ _exit(1);
+}
+
+int main(int argc, char *argv[])
+{
+ int i, foreground, port;
+ void (*timeseal_init)(const char * ) = chessd_function("timeseal_init");
+ int (*net_init)(int ) = chessd_function("net_init");
+ void (*initial_load)(void ) = chessd_function("initial_load");
+
+ port = DEFAULT_PORT;
+ foreground = 0;
+
+ /* enable malloc checking in libc */
+ setenv("MALLOC_CHECK_", "2", 1);
+
+ while((i = getopt(argc, argv, "p:fR:T:")) != -1) {
+ switch(i) {
+ case 'p':
+ port = atoi(optarg);
+ break;
+ case 'f':
+ foreground = 1;
+ break;
+ case 'T':
+ timeseal_init(optarg);
+ break;
+ case 'R':
+ do_chroot(optarg);
+ break;
+ default:
+ usage();
+ }
+ }
+
+ if (!foreground && daemonize()){
+ printf("Problem with Daemonization - Aborting\n");
+ exit(1);
+ }
+
+ signal(SIGTERM, TerminateServer);
+ signal(SIGSEGV, segv_handler);
+ signal(SIGBUS, segv_handler);
+ signal(SIGINT, TerminateServer);
+ signal(SIGPIPE, BrokenPipe);
+
+ if (net_init(port)) {
+ fprintf(stderr, "CHESSD: Network initialize failed on port %d.\n", port);
+ exit(1);
+ }
+ fprintf(stderr, "CHESSD: Initialized on port %d\n", port);
+
+ initial_load();
+
+ main_event_loop();
+ /* will never get here - uses TerminateServer */
+
+ return 0;
+}
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+#ifndef FICSMAIN_H
+#define FICSMAIN_H
+
+#define MESS_WELCOME "welcome"
+#define MESS_LOGIN "login"
+#define MESS_LOGOUT "logout"
+#define MESS_MOTD "motd"
+#define MESS_ADMOTD "admotd"
+#define MESS_UNREGISTERED "unregistered"
+
+#define STATS_MESSAGES "messages"
+#define STATS_LOGONS "logons"
+#define STATS_GAMES "games"
+#define STATS_JOURNAL "journal"
+
+#endif /* FICSMAIN_H */
--- /dev/null
+#!/usr/bin/perl -w
+# find a list of fns and variables in the code that could be static
+# usually called with something like this:
+# findstatic.pl `find . -name "*.o"`
+# Andrew Tridgell <tridge@samba.org>
+
+use strict;
+
+# use nm to find the symbols
+my($saved_delim) = $/;
+undef $/;
+my($syms) = `nm -o @ARGV`;
+$/ = $saved_delim;
+
+my(@lines) = split(/\n/s, $syms);
+
+my(%def);
+my(%undef);
+my(%stype);
+
+my(%typemap) = (
+ "T" => "function",
+ "C" => "uninitialised variable",
+ "D" => "initialised variable"
+ );
+
+
+# parse the symbols into defined and undefined
+for (my($i)=0; $i <= $#{@lines}; $i++) {
+ my($line) = $lines[$i];
+ if ($line =~ /(.*):[a-f0-9]* ([TCD]) (.*)/) {
+ my($fname) = $1;
+ my($symbol) = $3;
+ push(@{$def{$fname}}, $symbol);
+ $stype{$symbol} = $2;
+ }
+ if ($line =~ /(.*):\s* U (.*)/) {
+ my($fname) = $1;
+ my($symbol) = $2;
+ push(@{$undef{$fname}}, $symbol);
+ }
+}
+
+# look for defined symbols that are never referenced outside the place they
+# are defined
+foreach my $f (keys %def) {
+ print "Checking $f\n";
+ my($found_one) = 0;
+ foreach my $s (@{$def{$f}}) {
+ my($found) = 0;
+ foreach my $f2 (keys %undef) {
+ if ($f2 ne $f) {
+ foreach my $s2 (@{$undef{$f2}}) {
+ if ($s2 eq $s) {
+ $found = 1;
+ $found_one = 1;
+ }
+ }
+ }
+ }
+ if ($found == 0) {
+ my($t) = $typemap{$stype{$s}};
+ print " '$s' is unique to $f ($t)\n";
+ }
+ }
+ if ($found_one == 0) {
+ print " all symbols in '$f' are unused (main program?)\n";
+ }
+}
+
--- /dev/null
+/*
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+/*
+ handle 'follow' lists. These are a little different to FICS in that they are persistent
+ (ie. they are more similar to the personal gnotify list)
+*/
+
+#include "includes.h"
+
+/*
+ a game has started between p1 and p2
+ anyone who has either player in their personal follow list will now send an
+ effective 'observe' command if they are idle
+*/
+void follow_start(int p1,int p2)
+{
+ int p;
+ for (p = 0; p < player_globals.p_num; p++) {
+ struct player *pp = &player_globals.parray[p];
+ int in1=0, in2=0;
+
+ /* don't follow ourselves */
+ if ((p == p1) || (p == p2)) {
+ continue;
+ }
+
+ /* don't follow while playing, examining etc */
+ if (pp->status != PLAYER_PROMPT) {
+ continue;
+ }
+
+ /* see if either player is in our follow list */
+ in1 = in_list(p, L_FOLLOW, player_globals.parray[p1].login);
+ if (in1 == 0) {
+ in2 = in_list(p, L_FOLLOW, player_globals.parray[p2].login);
+ }
+
+ if (in1 == 0 && in2 == 0) {
+ continue;
+ }
+
+ /* fake up an observe command */
+ pcommand(p, "observe %s\n", player_globals.parray[in1?p1:p2].login);
+ send_prompt (p);
+ }
+}
--- /dev/null
+/*
+ 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 2 of the License, 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.
+*/
+
+/* Formula program for FICS. Written by Dave Herscovici
+ (dhersco@math.nps.navy.mil)
+ Edited by DAV to include wild,non-std and untimed
+ lightning flags
+
+*/
+
+/* Operators allowed, in order of precedence:
+ ! (not), - (unary),
+ *, /,
+ +, -,
+ <, <=, =<, >, >=, =>, (<= and =< are equivalent, as are >= and =>)
+ =, ==, !=, <>, (two ways of saying both equals and not equals)
+ &, &&, (both "and")
+ |, ||, (both "or").
+
+ Parentheses () are also allowed, as is a pound sign '#' for comments.
+ The program will divide by a fudge factor of .001 instead of 0.
+
+ Variables allowed:
+ time, inc, rating, myrating, rated, blitz, standard, lightning, registered,
+ assesswin, assessdraw, assessloss, timeseal,
+ ratingdiff = rating - myrating, private, wild, untimed, nonstandard,
+ maxtime(n) = maximum time n moves will take (in seconds),
+ mymaxtime(n) = same, but just count my time.
+ f1, f2, f3, f4, f5, f6, f7, f8, f9.
+
+ The code for translating blitz and standard variables may have to be
+ redone. F1 through f9 are user-defined formula variables. They can
+ be used to avoid having to retype your entire formula when you want
+ to change one part of it, or to compensate for the lack of a 'mood'
+ variable.
+
+ For example:
+ set f1 rated & time=5 & inc=0 # rated 5 minute games
+ set f2 rating - myrating
+ set f3 # this line is a random comment.
+ set f4 f2>400 # I want a REAL fight
+
+ Then you can type:
+ set formula f1 # rated 5 min. games only
+ set formula etime >= 10 & f2 > -100 # long games, decent competition
+ set formula f1 & !f4
+ or set formula f2 >= 0 | blitz
+ depending on your mood.
+
+ Further modifications could account for starting positions, time
+ odds games, provisional or established opponents, etc. Maybe f0
+ should be reserved for your formula upon logging in; i.e. if f0
+ is set, your formula is automatically set to f0 when you log in.
+*/
+
+#include "includes.h"
+
+static int CheckFormula(struct game *g, int clause, int *i, int op_type,
+ int *result, int eval);
+
+
+static char *GetPlayersFormula (struct player *pWho, int clause)
+{
+ if (clause==MAX_FORMULA) return (pWho->formula);
+ else return (pWho->formulaLines[clause]);
+}
+
+/* In MoveIndexPastString, *i is treated as the index into string[];
+ this function returns 1 if the character string beginning with
+ string[*i] match *text, and 0 otherwise. In the former case, *i
+ is incremented to move the index past *text.
+*/
+static int MoveIndexPastString (char *string, int *i, char *text)
+{
+ int n = strlen(text);
+ if (strncasecmp(text, string + *i, n)) return (0);
+ *i += n;
+ return (n);
+} /* end of function MoveIndexPastString. */
+
+static int GetNumberInsideParens (struct game *g, int clause, int *i, int *token,
+ int eval)
+{
+ char *string = GetPlayersFormula(&player_globals.parray[g->black], clause);
+ int ret;
+
+ while (string[*i] != '\0' && isspace(string[*i])) (*i)++;
+ if (!MoveIndexPastString(string, i, "(")) return (ERR_BADCHAR);
+
+ ret = CheckFormula(g, clause, i, OPTYPE_PAREN, token, eval);
+ if (ret != ERR_NONE)
+ return (ret);
+ if (MoveIndexPastString(string, i, ")")) return (ERR_NONE);
+ else return (ERR_PAREN);
+}
+
+static int Maxtime (struct game *g, int numMoves, int numPlayers)
+{
+ int max;
+
+ if ((g->bInitTime == g->wInitTime) && (g->bIncrement == g->wIncrement)) {
+ max = numPlayers * (60 * g->wInitTime + numMoves * g->wIncrement);
+ if ((g->type != TYPE_UNTIMED) && (g->wInitTime == 0))
+ max +=10 * numPlayers; /* 0 x start with ten secs */
+
+ } else if (numPlayers == 2) {
+ max = 60 * (g->wInitTime + g->bInitTime)
+ + numMoves * (g->wIncrement + g->bIncrement);
+ if ((g->type != TYPE_UNTIMED) && (g->wInitTime == 0))
+ max +=10; /* 0 x start with ten secs */
+ if ((g->type != TYPE_UNTIMED) && (g->bInitTime == 0))
+ max +=10; /* 0 x start with ten secs */
+
+ } else {
+ max = 60 * g->bInitTime + numMoves * g->bIncrement;
+ if ((g->type != TYPE_UNTIMED) && (g->bInitTime == 0))
+ max +=10; /* 0 x start with ten secs */
+ }
+
+ return max;
+}
+
+
+/* The black player in game *g has been challenged. S/he has a list
+ of formulas, and we're checking the one given by the index clause
+ (MAX_FORMULA denotes the actual formula; if clause is smaller,
+ we're looking at one of the user-defined formulas). We're at
+ position *i in the formula. If we find a legitimate variable there
+ and eval is 1, VarToToken puts its value in *tok; if eval is 0,
+ just move past the variable. Returns 1 or 0, depending on whether
+ a legitimate variable was found.
+*/
+static int VarToToken (struct game *g, int clause, char *string, int *i, int *tok, int eval)
+{
+ struct player *me = &player_globals.parray[g->black];
+ struct player *you = &player_globals.parray[g->white];
+ int index=0, c;
+ double dummy_sterr;
+
+ /* We list possible variables with the longest names first. */
+ if (MoveIndexPastString(string, i, "registered"))
+ *tok=BoolCheckPFlag(g->white, PFLAG_REG);
+ else if (MoveIndexPastString(string, i, "ratingdiff"))
+ *tok = GetRating(you, g->type) - GetRating(me, g->type);
+ else if (MoveIndexPastString(string, i, "assessloss"))
+ {
+ if (g->rated)
+ rating_sterr_delta(g->black, g->white, g->type,
+ time(0), RESULT_LOSS, tok, &dummy_sterr);
+ else *tok = 0;
+ }
+ else if (MoveIndexPastString(string, i, "assessdraw"))
+ {
+ if (g->rated)
+ rating_sterr_delta(g->black, g->white, g->type,
+ time(0), RESULT_DRAW, tok, &dummy_sterr);
+ else *tok = 0;
+ }
+ else if (MoveIndexPastString(string, i, "assesswin"))
+ {
+ if (g->rated)
+ rating_sterr_delta(g->black, g->white, g->type,
+ time(0), RESULT_WIN, tok, &dummy_sterr);
+ else *tok = 0;
+ }
+ else if (MoveIndexPastString(string, i, "mymaxtime"))
+ {
+ if (GetNumberInsideParens(g, clause, i, tok, eval) != ERR_NONE)
+ return (0);
+ *tok = Maxtime (g, *tok, 1);
+ }
+ else if (MoveIndexPastString(string, i, "timeseal"))
+ *tok = net_globals.con[you->socket]->timeseal;
+ else if (MoveIndexPastString(string, i, "myrating"))
+ *tok = GetRating(me, g->type);
+ else if (MoveIndexPastString(string, i, "computer"))
+ *tok = in_list(-1, L_COMPUTER, you->name);
+ else if (MoveIndexPastString(string, i, "standard"))
+ *tok = (g->type == TYPE_STAND);
+ else if (MoveIndexPastString(string, i, "private"))
+ *tok = BoolCheckPFlag(g->white, PFLAG_PRIVATE);
+ else if (MoveIndexPastString(string, i, "maxtime"))
+ {
+ if (GetNumberInsideParens(g, clause, i, tok, eval) != ERR_NONE)
+ return (0);
+ *tok = Maxtime (g, *tok, 2);
+ }
+ else if (MoveIndexPastString(string, i, "abuser"))
+ *tok = in_list(-1, L_ABUSER, you->name);
+ else if (MoveIndexPastString(string, i, "rating"))
+ *tok = GetRating(you, g->type);
+ else if (MoveIndexPastString(string, i, "rated")) *tok=g->rated;
+ else if (MoveIndexPastString(string, i, "nonstandard"))
+ *tok = (g->type == TYPE_NONSTANDARD);
+ else if (MoveIndexPastString(string, i, "lightning"))
+ *tok = (g->type == TYPE_LIGHT);
+ else if (MoveIndexPastString(string, i, "bughouse"))
+ *tok = (g->type == TYPE_BUGHOUSE);
+ else if (MoveIndexPastString(string, i, "untimed"))
+ *tok = (g->type == TYPE_UNTIMED);
+ else if (MoveIndexPastString(string, i, "blitz"))
+ *tok = (g->type == TYPE_BLITZ);
+ else if (MoveIndexPastString(string, i, "wild"))
+ *tok = (g->type == TYPE_WILD);
+ else if (MoveIndexPastString(string, i, "time")) *tok=g->wInitTime;
+ else if (MoveIndexPastString(string, i, "inc")) *tok=g->wIncrement;
+ else if (tolower(string[*i])=='f' && isdigit(string[*i+1]) &&
+ (c = (string[*i+1]-'1')) >= 0 && clause > c)
+ {
+ *i += 2;
+ return (!CheckFormula (g, c, &index, OPTYPE_NONE, tok, eval));
+ }
+ else return (0);
+ return (1);
+} /* end of function VarToToken. */
+
+/* ScanForOp checks for an operator at position *i in string[]. */
+static int ScanForOp (char *string, int *i)
+{
+ while (string[*i] != '\0' && isspace(string[*i])) (*i)++;
+
+ if (string[*i] == '\0') return (OP_NONE);
+ if (string[*i] == '#') return (OP_NONE);
+ if (string[*i] == ')') return (OP_RTPAREN);
+
+ /* Two char operators and longer first. */
+ if (MoveIndexPastString(string, i, "and")) return (OP_AND);
+ if (MoveIndexPastString(string, i, "or")) return (OP_OR);
+ if (MoveIndexPastString(string, i, "||")) return (OP_OR);
+ if (MoveIndexPastString(string, i, "&&")) return (OP_AND);
+ if (MoveIndexPastString(string, i, "==")) return (OP_EQ);
+ if (MoveIndexPastString(string, i, "!=")) return (OP_NEQ);
+ if (MoveIndexPastString(string, i, "<>")) return (OP_NEQ);
+ if (MoveIndexPastString(string, i, ">=")) return (OP_GE);
+ if (MoveIndexPastString(string, i, "=>")) return (OP_GE);
+ if (MoveIndexPastString(string, i, "<=")) return (OP_LE);
+ if (MoveIndexPastString(string, i, "=<")) return (OP_LE);
+
+ /* One char operators now. */
+ if (MoveIndexPastString(string, i, "|")) return (OP_OR);
+ if (MoveIndexPastString(string, i, "&")) return (OP_AND);
+ if (MoveIndexPastString(string, i, ">")) return (OP_GT);
+ if (MoveIndexPastString(string, i, "<")) return (OP_LT);
+ if (MoveIndexPastString(string, i, "=")) return (OP_EQ);
+ if (MoveIndexPastString(string, i, "+")) return (OP_PLUS);
+ if (MoveIndexPastString(string, i, "-")) return (OP_MINUS);
+ if (MoveIndexPastString(string, i, "*")) return (OP_MULT);
+ if (MoveIndexPastString(string, i, "/")) return (OP_DIV);
+ return (OP_BAD);
+} /* end of function ScanForOp. */
+
+/* OpType returns the precedence of the operator op. */
+static int OpType (int op)
+{
+ switch (op)
+ {
+ case OP_BAD: return (OPTYPE_BAD);
+ case OP_NONE: return (OPTYPE_NONE);
+ case OP_RTPAREN: return (OPTYPE_RPAREN);
+ case OP_OR: return (OPTYPE_OR);
+ case OP_AND: return (OPTYPE_AND);
+ case OP_EQ: case OP_NEQ: return (OPTYPE_COMPEQ);
+ case OP_GT: case OP_GE: case OP_LT: case OP_LE: return (OPTYPE_COMPGL);
+ case OP_PLUS: case OP_MINUS: return (OPTYPE_ADD);
+ case OP_MULT: case OP_DIV: return (OPTYPE_MULT);
+ case OP_NEGATE: case OP_NOT: return (OPTYPE_UNARY);
+ default: return (OPTYPE_BAD);
+ }
+} /* end of function OpType. */
+
+/* In EvalBinaryOp, *left is the left operand; and op is the
+ current operator. *g and clause specify which formula string to
+ look at (we're checking player_globals.parray[g->black].formulaLines[clause]),
+ and *i tells us where we are in the string. We look for a right
+ operand from position *i in the string, and place the expression
+ (*left op right) in *left. For example, if *left=6, op =
+ OP_MULT, and we pull off right = 4, we replace *left with
+ 6*4=24. Returns 0 if no error; otherwise indicates the error.
+*/
+static int EvalBinaryOp (int *left, int op, struct game *g, int clause, int *i)
+{
+ int right, ret;
+ if ((op==OP_OR) && (*left != 0)) /* Nothing to decide. */
+ {
+ *left = 1;
+ return (CheckFormula (g, clause, i, OpType(op), &right, 0));
+ }
+ else if ((op==OP_AND) && (*left == 0)) /* Nothing to decide. */
+ return (CheckFormula (g, clause, i, OpType(op), &right, 0));
+
+ else {
+ ret = CheckFormula (g, clause, i, OpType(op), &right, 1);
+ if (ret != ERR_NONE) return (ret);
+ }
+ switch (op)
+ {
+ default: case OP_BAD: return (ERR_BADOP);
+ case OP_NONE: case OP_RTPAREN: return (ERR_NONE);
+ case OP_OR: *left = (*left || right); return (ERR_NONE);
+ case OP_AND: *left = (*left && right); return (ERR_NONE);
+ case OP_EQ: *left = (*left == right); return (ERR_NONE);
+ case OP_NEQ: *left = (*left != right); return (ERR_NONE);
+ case OP_GT: *left = (*left > right); return (ERR_NONE);
+ case OP_GE: *left = (*left >= right); return (ERR_NONE);
+ case OP_LT: *left = (*left < right); return (ERR_NONE);
+ case OP_LE: *left = (*left <= right); return (ERR_NONE);
+ case OP_PLUS: *left += right; return (ERR_NONE);
+ case OP_MINUS: *left -= right; return (ERR_NONE);
+ case OP_MULT: *left *= right; return (ERR_NONE);
+ case OP_DIV:
+ if (right != 0)
+ {
+ *left /= right;
+ return (ERR_NONE);
+ }
+ else
+ {
+ pprintf(g->black, "Dividing by %f instead or zero in formula.\n", FUDGE_FACTOR);
+ *left /= FUDGE_FACTOR;
+ return (ERR_NONE);
+ }
+ }
+} /* end of function EvalBinaryOp. */
+
+/* If eval is 1, ScanForNumber evaluates the number at position *i
+ in the formula given by *g and clause, and place this value in
+ *token. op_type is the precedence of the operator preceding the
+ *i'th position. If we come to an operator of higher precedence,
+ we must keep going before we can leave this function. If eval
+ is 0, just move past the number we would evaluate. Returns 0 if
+ no error; otherwise return code indicates the error.
+*/
+static int ScanForNumber (struct game *g, int clause, int *i, int op_type,
+ int *token, int eval)
+{
+ char *string = GetPlayersFormula (&player_globals.parray[g->black], clause);
+ char c;
+ int ret;
+
+ while ((string[*i] != '\0') && (isspace(string[*i]))) (*i)++;
+ switch (c = string[*i])
+ {
+ case '\0': case '#':
+ if (op_type != OPTYPE_NONE) return (ERR_EOF);
+ else *token=1;
+ return (ERR_NONE);
+
+ case ')':
+ if (op_type != OPTYPE_PAREN) return (ERR_PAREN);
+ else *token=1;
+ return(ERR_NONE);
+
+ case '(': return GetNumberInsideParens(g,clause,i,token,eval);
+
+ case '-': case '!':
+ ++(*i);
+ if (c==string[*i]) return(ERR_UNARY);
+ ret = ScanForNumber(g,clause,i,OPTYPE_UNARY,token,eval);
+ if (ret != ERR_NONE)
+ return (ret);
+ if (c == '-') *token = -(*token);
+ else if (c == '!') *token = !(*token);
+ return (ERR_NONE);
+
+ default:
+ if (isdigit(string[*i]))
+ {
+ *token = 0;
+
+ do *token = 10 * (*token) + string[(*i)++] - '0';
+ while (isdigit(string[*i]));
+
+ while (string[*i] != '\0' && isspace(string[*i])) (*i)++;
+ if (MoveIndexPastString (string, i, "minutes"))
+ *token *= 60;
+ return (ERR_NONE);
+ }
+ else if (isalpha(string[*i]))
+ {
+ if (!VarToToken (g, clause, string, i, token, eval))
+ return (ERR_BADVAR);
+ return(ERR_NONE);
+ }
+ else return (ERR_NONESENSE);
+ }
+} /* end of function ScanForNumber. */
+
+/* If eval is 1, CheckFormula looks for the next token in the
+ formula given by *g, clause, and *i; usually this is the right
+ side of an expression whose operator has precedence OpType; if
+ eval is 0, just go to the end of an expression. Return 0 if no
+ error; otherwise, return error type.
+*/
+static int CheckFormula(struct game *g, int clause, int *i, int op_type,
+ int *result, int eval)
+{
+ int token, ret, nextOp, lastPos;
+ char *string = GetPlayersFormula (&player_globals.parray[g->black], clause);
+
+ if (string == NULL)
+ {
+ *result = 1;
+ return (ERR_NONE);
+ }
+ ret = ScanForNumber (g, clause, i, op_type, &token, eval);
+ if (ret != ERR_NONE)
+ return (ret);
+ lastPos = *i;
+ nextOp = ScanForOp (string, i);
+ while (OpType(nextOp) > op_type) /* higher precedence. */
+ {
+ if (nextOp==OP_RTPAREN) return (ERR_PAREN);
+ if (!eval)
+ ret = CheckFormula(g, clause, i, OpType(nextOp), &token, 0);
+ else ret = EvalBinaryOp (&token, nextOp, g, clause, i);
+ if (ret != ERR_NONE) return (ret);
+ lastPos = *i;
+ nextOp = ScanForOp (string, i);
+ }
+ if (nextOp == OP_BAD) return(ERR_BADOP);
+ *result = token;
+
+ /* move back unless we're at the end or at a right paren, in which
+ case we never went forward. */
+ if (nextOp != OP_NONE && nextOp != OP_RTPAREN) *i=lastPos;
+ return (ERR_NONE);
+} /* end of function CheckFormula. */
+
+/* which clauses are relevant for a player's formula. */
+static int ChooseClauses(struct player *who, char *formula)
+{
+ int i, which, ret=0;
+
+ if (formula == NULL)
+ return ret;
+ for (i=0; formula[i] != '\0' && formula[i] != '#'; i++) {
+ if (formula[i] != 'f' || (i > 0 && isalnum(formula[i-1]))
+ || !isdigit(formula[i+1]))
+ continue;
+ sscanf(&formula[i], "f%d", &which);
+ ret |= (1 << (which - 1));
+ }
+ /* now scan clauses found as part of the formula. */
+ for (i = MAX_FORMULA - 1; i >= 0; i--) {
+ if (ret & (1 << i)) {
+ ret |= ChooseClauses(who, who->formulaLines[i]);
+ }
+ }
+ return ret;
+} /* end of function ChooseClauses. */
+
+static void ExplainFormula (struct game *g, struct textlist **clauses)
+{
+ int i, which, dummy_index, value;
+ char txt[20];
+ struct player *challenged = &player_globals.parray[g->black];
+ struct textlist **Cur = clauses;
+
+ which = ChooseClauses(challenged, challenged->formula);
+
+ for (i = 0; i < MAX_FORMULA; i++) {
+ if ((which & (1 << i)) == 0)
+ continue;
+ dummy_index = 0;
+ CheckFormula (g, i, &dummy_index, OPTYPE_NONE, &value, 1);
+ sprintf(txt, "%d", value);
+ SaveTextListEntry (Cur, txt, i);
+ Cur = &(*Cur)->next;
+ }
+}
+
+
+/* GameMatchesFormula converts parameters to a game structure
+ and passes a pointer to this game to CheckFormula for
+ evaluation. It returns the evaluated formula.
+*/
+int GameMatchesFormula (int w, int b, int wTime, int wInc, int bTime,
+ int bInc, int rated, int gametype, struct textlist **clauseList)
+{
+ struct game g;
+ int index=0, ret;
+
+ g.white = w; g.black = b;
+ g.wInitTime = wTime; g.bInitTime = bTime;
+ g.wIncrement = wInc; g.bIncrement = bInc;
+ g.rated = rated;
+ g.type = gametype;
+
+ if (CheckFormula(&g, MAX_FORMULA, &index, OPTYPE_NONE, &ret, 1) != ERR_NONE)
+ return (0);
+ if (ret == 0) ExplainFormula (&g, clauseList);
+ return (ret);
+} /* end of function GameMatchesFormula. */
+
+/* SetValidFormula sets a clause of player p and creates a game structure
+ to check whether that new formula is legitimate. If so, return 1;
+ otherwise, reset the formula and return 0.
+*/
+int SetValidFormula (int p, int clause, char *string)
+{
+ struct game g;
+ int index=0, ret, err=ERR_NONE;
+ char *Old=NULL, **Cur;
+ struct player *me = &player_globals.parray[p];
+
+ if (clause==MAX_FORMULA)
+ Cur = &me->formula;
+ else
+ Cur = &me->formulaLines[clause];
+
+ Old = *Cur;
+
+ if (string != NULL) {
+ string = eatwhite(string);
+ *Cur = (*string != '\0' ? strdup (string) : NULL);
+ }
+ else *Cur = NULL;
+
+ if (*Cur==NULL) {
+ if (Old != NULL) free(Old);
+ return 1;
+ }
+
+ g.white = g.black = p;
+ g.wInitTime = g.bInitTime = me->d_time;
+ g.wIncrement = g.bIncrement = me->d_inc;
+ g.rated = BoolCheckFlag(me->Flags, PFLAG_RATED);
+ g.type = TYPE_BLITZ;
+ err = CheckFormula (&g, clause, &index, OPTYPE_NONE, &ret, 0);
+
+ if (err != ERR_NONE) {
+ /* Bad formula; reset it. */
+ free(*Cur);
+ *Cur = Old;
+ } else {
+ if (Old != NULL) free(Old);
+ }
+ return (err == ERR_NONE);
+}
+
+void ShowClauses (int p, int p1, textlist *clauses)
+{
+ textlist *Cur;
+
+ if (clauses != NULL)
+ pprintf(p, "\n");
+ for (Cur = clauses; Cur != NULL; Cur = Cur->next) {
+/* changed this next line to pass "" not NULL to pprintf. 2.24.96 fb
+ pprintf(p, "f%d=%s: %s\n", Cur->index + 1, Cur->text,
+ player_globals.parray[p1].formulaLines[Cur->index]);
+*/
+ pprintf(p, "f%d=%s: %s\n", Cur->index + 1, Cur->text,
+ (player_globals.parray[p1].formulaLines[Cur->index] == NULL) ? "" :
+ player_globals.parray[p1].formulaLines[Cur->index]);
+ }
+}
--- /dev/null
+/*
+ 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 2 of the License, 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.
+*/
+
+
+#ifndef FORMULA_H
+#define FORMULA_H
+
+#define OP_BAD -1
+
+#define OP_NONE 0
+#define OP_RTPAREN 1
+#define OP_OR 2
+#define OP_AND 3
+#define OP_EQ 4
+#define OP_NEQ 5
+#define OP_GT 6
+#define OP_GE 7
+#define OP_LT 8
+#define OP_LE 9
+#define OP_PLUS 10
+#define OP_MINUS 11
+#define OP_MULT 12
+#define OP_DIV 13
+#define OP_NEGATE 14
+#define OP_NOT 15
+
+#define OPTYPE_BAD 0
+#define OPTYPE_NONE 1
+#define OPTYPE_RPAREN 2
+#define OPTYPE_PAREN 3
+#define OPTYPE_OR 4
+#define OPTYPE_AND 5
+#define OPTYPE_COMPEQ 6
+#define OPTYPE_COMPGL 7
+#define OPTYPE_ADD 8
+#define OPTYPE_MULT 9
+#define OPTYPE_UNARY 10
+
+#define ERR_NONE 0
+#define ERR_EOF 1
+#define ERR_UNARY 2
+#define ERR_BADCHAR 3
+#define ERR_BADVAR 4
+#define ERR_BADOP 5
+#define ERR_NONESENSE 6
+#define ERR_DIVBYZERO 7
+#define ERR_PAREN 8
+
+#define FUDGE_FACTOR 1e-3
+
+#endif
+
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+#include "includes.h"
+
+static int check_kings(struct game_state_t *gs);
+static int get_empty_slot(void);
+static int ReadGameAttrs_common(FILE *fp, int g, int version);
+static long OldestHistGame(char *login);
+static void RemoveHistGame(char *file, int maxlines);
+static void write_g_out(int g, char *file, int maxlines, int isDraw, char *EndSymbol, char *name, time_t *now);
+static int game_zero(int g);
+
+const char *TypeStrings[NUM_GAMETYPES] = {"untimed", "blitz", "standard",
+ "nonstandard", "wild", "lightning",
+ "bughouse"};
+
+/* this method is awful! how about allocation as we need it and freeing
+ afterwards! */
+static int get_empty_slot(void)
+{
+ int i;
+
+ for (i = 0; i < game_globals.g_num; i++) {
+ if (game_globals.garray[i].status == GAME_EMPTY)
+ return i;
+ }
+ game_globals.g_num++;
+ game_globals.garray = (struct game *)realloc(game_globals.garray, sizeof(struct game) * game_globals.g_num);
+ /* yeah great, bet this causes lag! - DAV*/
+ /* I have serious doubt of the truth to the above client- bugg */
+ game_globals.garray[game_globals.g_num - 1].status = GAME_EMPTY;
+ return game_globals.g_num - 1;
+}
+
+int game_new(void)
+{
+ int new = get_empty_slot();
+ game_zero(new);
+ return new;
+}
+
+static int game_zero(int g)
+{
+ ZERO_STRUCT(game_globals.garray[g]);
+
+ game_globals.garray[g].white = -1;
+ game_globals.garray[g].black = -1;
+
+ game_globals.garray[g].status = GAME_NEW;
+ game_globals.garray[g].link = -1;
+ game_globals.garray[g].result = END_NOTENDED;
+ game_globals.garray[g].type = TYPE_UNTIMED;
+ game_globals.garray[g].game_state.gameNum = g;
+ game_globals.garray[g].wInitTime = 300; /* 5 minutes */
+ game_globals.garray[g].wIncrement = 0;
+ game_globals.garray[g].bInitTime = 300; /* 5 minutes */
+ game_globals.garray[g].bIncrement = 0;
+ game_globals.garray[g].flag_pending = FLAG_NONE;
+ strcpy(game_globals.garray[g].FENstartPos,INITIAL_FEN);
+ return 0;
+}
+
+int game_free(int g)
+{
+ FREE(game_globals.garray[g].moveList);
+ FREE(game_globals.garray[g].examMoveList);
+ game_globals.garray[g].moveList = NULL;
+ game_globals.garray[g].examMoveList = NULL;
+ game_globals.garray[g].moveListSize = 0;
+ game_globals.garray[g].examMoveListSize = 0;
+ return 0;
+}
+
+int game_remove(int g)
+{
+ /* Should remove game from players observation list */
+ game_free(g);
+ game_zero(g);
+ game_globals.garray[g].status = GAME_EMPTY;
+ return 0;
+}
+
+/* old moves not stored now - uses smoves */
+int game_finish(int g)
+{
+ player_game_ended(g); /* Alert playerdb that game ended */
+ game_remove(g);
+ return 0;
+}
+
+void MakeFENpos (int g, char *FEN)
+{
+ strcpy(FEN, boardToFEN(g));
+}
+
+static char *game_time_str(int wt, int winc, int bt, int binc)
+{
+ static char tstr[50];
+
+ if ((!wt) && (!winc)) { /* Untimed */
+ strcpy(tstr, "");
+ return tstr;
+ }
+ if ((wt == bt) && (winc == binc)) {
+ sprintf(tstr, " %d %d", wt, winc);
+ } else {
+ sprintf(tstr, " %d %d : %d %d", wt, winc, bt, binc);
+ }
+ return tstr;
+}
+
+const char *bstr[] = {"untimed", "blitz", "standard", "non-standard", "wild", "lightning", "Bughouse"};
+
+const char *rstr[] = {"unrated", "rated"};
+
+char *game_str(int rated, int wt, int winc, int bt, int binc,
+ char *cat, char *board)
+{
+ static char tstr[200];
+
+ if (cat && cat[0] && board && board[0] &&
+ (strcmp(cat, "standard") || strcmp(board, "standard"))) {
+ sprintf(tstr, "%s %s%s Loaded from %s/%s",
+ rstr[rated],
+ bstr[game_isblitz(wt / 60, winc, bt / 60, binc, cat, board)],
+ game_time_str(wt / 60, winc, bt / 60, binc),
+ cat, board);
+ } else {
+ sprintf(tstr, "%s %s%s",
+ rstr[rated],
+ bstr[game_isblitz(wt / 60, winc, bt / 60, binc, cat, board)],
+ game_time_str(wt / 60, winc, bt / 60, binc));
+ }
+ return tstr;
+}
+
+int game_isblitz(int wt, int winc, int bt, int binc,
+ char *cat, char *board)
+{
+ int total;
+
+ if(cat && cat[0]) {
+ if (!strcmp(cat, "bughouse"))
+ return TYPE_BUGHOUSE;
+ if (board && board[0]) {
+ if (!strcmp(cat, "wild"))
+ return TYPE_WILD;
+ if (strcmp(cat, "standard") || strcmp(board, "standard"))
+ return TYPE_NONSTANDARD;
+ }
+ }
+
+ if ((wt == 0) || (bt == 0))
+ /* nonsense if one is timed and one is not */
+ return TYPE_UNTIMED;
+
+ if ((wt != bt) || (winc != binc))
+ return TYPE_NONSTANDARD;
+ total = wt * 60 + winc * 40;
+ if (total < 180) /* 3 minute */
+ return TYPE_LIGHT;
+ if (total >= 900) /* 15 minutes */
+ return TYPE_STAND;
+ else
+ return TYPE_BLITZ;
+}
+
+void send_board_to(int g, int p)
+{
+ struct player *pp = &player_globals.parray[p];
+ char *b;
+ int side;
+ int relation;
+
+/* since we know g and p, figure out our relationship to this game */
+
+ side = WHITE;
+ if ((game_globals.garray[g].status == GAME_EXAMINE) || (game_globals.garray[g].status == GAME_SETUP)) {
+ if (pp->game == g) {
+ relation = 2;
+ } else {
+ relation = -2;
+ }
+ } else {
+ if (pp->game == g) {
+ side = pp->side;
+ relation = ((side == game_globals.garray[g].game_state.onMove) ? 1 : -1);
+ } else {
+ relation = 0;
+ }
+ }
+
+ if (CheckPFlag(p, PFLAG_FLIP)) { /* flip board? */
+ if (side == WHITE)
+ side = BLACK;
+ else
+ side = WHITE;
+ }
+ game_update_time(g);
+ b = board_to_string(game_globals.garray[g].white_name,
+ game_globals.garray[g].black_name,
+ game_globals.garray[g].wTime,
+ game_globals.garray[g].bTime,
+ &game_globals.garray[g].game_state,
+ (game_globals.garray[g].status == GAME_EXAMINE || game_globals.garray[g].status == GAME_SETUP) ?
+ game_globals.garray[g].examMoveList : game_globals.garray[g].moveList,
+ pp->style,
+ side, relation, p);
+ Bell(p);
+
+ if (pp->game == g && net_globals.con[pp->socket]->timeseal) {
+ pprintf_noformat(p, "\n%s\n[G]\n", b);
+ } else {
+ pprintf_noformat(p, "\n%s", b);
+ }
+
+ if (p != command_globals.commanding_player) {
+ send_prompt(p);
+ }
+}
+
+void send_boards(int g)
+{
+ int p,p1;
+ struct simul_info_t *simInfo = player_globals.parray[game_globals.garray[g].white].simul_info;
+ int which_board = -1;
+
+ /* Begin code added 3/28/96 - Figbert */
+
+ if ((game_globals.garray[g].status != GAME_SETUP) &&
+ (check_kings(&game_globals.garray[g].game_state))) {
+ d_printf( "Game has invalid amount of kings. Aborting...\n");
+ game_finish(g);
+
+ for (p = 0; p < player_globals.p_num; p++) {
+ struct player *pp = &player_globals.parray[p];
+ if (pp->status == PLAYER_EMPTY)
+ continue;
+ if (pp->game == g) {
+
+ p1 = pp->opponent;
+
+ if (p1 >= 0 && player_globals.parray[p1].game == g) {
+ pprintf (p1, "Disconnecting you from game number %d.\n", g+1);
+ player_globals.parray[p1].game = -1;
+ }
+
+ pprintf (p, "Disconnecting you from game number %d.\n", g+1);
+ pp->game = -1;
+ }
+ }
+ return;
+ }
+
+ /* End code added 3/28/96 - Figbert */
+
+ if (simInfo != NULL)
+ which_board = simInfo->boards[simInfo->onBoard];
+
+ if ((simInfo == NULL) || (which_board == g)) {
+ for (p = 0; p < player_globals.p_num; p++) {
+ struct player *pp = &player_globals.parray[p];
+ if (pp->status == PLAYER_EMPTY)
+ continue;
+ if (player_is_observe(p, g) || (pp->game == g))
+ send_board_to(g, p);
+ }
+ }
+}
+
+void game_update_time(int g)
+{
+ struct game *gg;
+ unsigned now, timesince;
+
+ if (g == -1) {
+ return;
+ }
+
+ gg = &game_globals.garray[g];
+
+ /* no update on first move */
+ if (gg->game_state.moveNum == 1)
+ return;
+ if (gg->clockStopped)
+ return;
+ if (gg->type == TYPE_UNTIMED)
+ return;
+ now = tenth_secs();
+ timesince = now - gg->lastDecTime;
+ if (gg->game_state.onMove == WHITE) {
+ gg->wTime -= timesince;
+ } else {
+ gg->bTime -= timesince;
+ }
+ gg->lastDecTime = now;
+}
+
+#if 0
+static void game_update_times(void)
+{
+ int g;
+
+ for (g = 0; g < game_globals.g_num; g++) {
+ if (game_globals.garray[g].status != GAME_ACTIVE)
+ continue;
+ if (game_globals.garray[g].clockStopped)
+ continue;
+ game_update_time(g);
+ }
+}
+#endif
+
+char *EndString(int g, int personal)
+{
+ static char endstr[200];
+ char *blackguy, *whiteguy;
+ static char blackstr[] = "Black";
+ static char whitestr[] = "White";
+
+ blackguy = (personal ? game_globals.garray[g].black_name : blackstr);
+ whiteguy = (personal ? game_globals.garray[g].white_name : whitestr);
+
+ switch (game_globals.garray[g].result) {
+ case END_CHECKMATE:
+ sprintf(endstr, "%s checkmated",
+ game_globals.garray[g].winner == WHITE ? blackguy : whiteguy);
+ break;
+ case END_RESIGN:
+ sprintf(endstr, "%s resigned",
+ game_globals.garray[g].winner == WHITE ? blackguy : whiteguy);
+ break;
+ case END_FLAG:
+ sprintf(endstr, "%s ran out of time",
+ game_globals.garray[g].winner == WHITE ? blackguy : whiteguy);
+ break;
+ case END_AGREEDDRAW:
+ sprintf(endstr, "Game drawn by mutual agreement");
+ break;
+ case END_BOTHFLAG:
+ sprintf(endstr, "Game drawn because both players ran out of time");
+ break;
+ case END_REPETITION:
+ sprintf(endstr, "Game drawn by repetition");
+ break;
+ case END_50MOVERULE:
+ sprintf(endstr, "Draw by the 50 move rule");
+ break;
+ case END_ADJOURN:
+ sprintf(endstr, "Game adjourned by mutual agreement");
+ break;
+ case END_LOSTCONNECTION:
+ sprintf(endstr, "%s lost connection, game adjourned",
+ game_globals.garray[g].winner == WHITE ? whiteguy : blackguy);
+ break;
+ case END_ABORT:
+ sprintf(endstr, "Game aborted by mutual agreement");
+ break;
+ case END_STALEMATE:
+ sprintf(endstr, "Stalemate.");
+ break;
+ case END_NOTENDED:
+ sprintf(endstr, "Still in progress");
+ break;
+ case END_COURTESY:
+ sprintf(endstr, "Game courtesyaborted by %s",
+ game_globals.garray[g].winner == WHITE ? whiteguy : blackguy);
+ break;
+ case END_COURTESYADJOURN:
+ sprintf(endstr, "Game courtesyadjourned by %s",
+ game_globals.garray[g].winner == WHITE ? whiteguy : blackguy);
+ break;
+ case END_NOMATERIAL:
+ sprintf(endstr, "Game drawn because neither player has mating material");
+ break;
+ case END_FLAGNOMATERIAL:
+ sprintf(endstr, "%s ran out of time and %s has no material to mate",
+ game_globals.garray[g].winner == WHITE ? blackguy : whiteguy,
+ game_globals.garray[g].winner == WHITE ? whiteguy : blackguy);
+ break;
+ case END_ADJDRAW:
+ sprintf(endstr, "Game drawn by adjudication");
+ break;
+ case END_ADJWIN:
+ sprintf(endstr, "%s wins by adjudication",
+ game_globals.garray[g].winner == WHITE ? whiteguy : blackguy);
+ break;
+ case END_ADJABORT:
+ sprintf(endstr, "Game aborted by adjudication");
+ break;
+ default:
+ sprintf(endstr, "???????");
+ break;
+ }
+
+ return (endstr);
+}
+
+const char *EndSym(int g)
+{
+ static const char *symbols[] = {"1-0", "0-1", "1/2-1/2", "*"};
+
+ switch (game_globals.garray[g].result) {
+ case END_CHECKMATE:
+ case END_RESIGN:
+ case END_FLAG:
+ case END_ADJWIN:
+ return ((game_globals.garray[g].winner == WHITE) ? symbols[0] : symbols[1]);
+ break;
+ case END_AGREEDDRAW:
+ case END_BOTHFLAG:
+ case END_REPETITION:
+ case END_50MOVERULE:
+ case END_STALEMATE:
+ case END_NOMATERIAL:
+ case END_FLAGNOMATERIAL:
+ case END_ADJDRAW:
+ return (symbols[2]);
+ break;
+ default:
+ break;
+ }
+
+ return (symbols[3]);
+}
+
+/* This should be enough to hold any game up to at least 8000 moves
+ * If we overwrite this, the server will crash :-).
+ */
+/* 8000? who you trying to kid? this is awful - enough for 600 halfs :) -DAV*/
+#define GAME_STRING_LEN 19000
+static char gameString[GAME_STRING_LEN];
+char *movesToString(int g, int pgn)
+{
+ char tmp[160];
+ int wr, br;
+ int i, col;
+ time_t curTime;
+ struct move_t *moves;
+
+ if (game_globals.garray[g].status == GAME_EXAMINE || game_globals.garray[g].status == GAME_SETUP)
+ moves = game_globals.garray[g].examMoveList;
+ else moves = game_globals.garray[g].moveList;
+
+ wr = game_globals.garray[g].white_rating;
+ br = game_globals.garray[g].black_rating;
+
+
+ curTime = untenths(game_globals.garray[g].timeOfStart);
+
+ if (pgn) {
+ sprintf(gameString,
+ "\n[Event \"%s %s %s game\"]\n"
+ "[Site \"%s, %s\"]\n",
+ config_get_tmp("SERVER_NAME"),
+ rstr[game_globals.garray[g].rated], bstr[game_globals.garray[g].type],
+ config_get_tmp("SERVER_NAME"),
+ config_get_tmp("SERVER_LOCATION"));
+ strftime(tmp, sizeof(tmp),
+ "[Date \"%Y.%m.%d\"]\n"
+ "[Time \"%H:%M:%S\"]\n",
+ localtime((time_t *) &curTime));
+ strcat(gameString, tmp);
+ sprintf(tmp,
+ "[Round \"-\"]\n"
+ "[White \"%s\"]\n"
+ "[Black \"%s\"]\n"
+ "[WhiteElo \"%d\"]\n"
+ "[BlackElo \"%d\"]\n",
+ game_globals.garray[g].white_name, game_globals.garray[g].black_name, wr, br);
+ strcat(gameString, tmp);
+ sprintf(tmp,
+ "[TimeControl \"%d+%d\"]\n"
+ "[Mode \"ICS\"]\n"
+ "[Result \"%s\"]\n\n",
+ game_globals.garray[g].wInitTime / 10, game_globals.garray[g].wIncrement / 10, EndSym(g));
+ strcat(gameString, tmp);
+
+ col = 0;
+ for (i = 0; i < game_globals.garray[g].numHalfMoves; i++) {
+ if (moves[i].color == WHITE) {
+ if ((col += sprintf(tmp, "%d. ", (i+1) / 2 + 1)) > 70) {
+ strcat(gameString, "\n");
+ col = 0;
+ }
+ strcat(gameString, tmp);
+ } else if (i==0) {
+ strcat (tmp, "1. ... ");
+ col += 7;
+ }
+ if ((col += sprintf(tmp, "%s ", moves[i].algString)) > 70) {
+ strcat(gameString, "\n");
+ col = 0;
+ }
+ strcat(gameString, tmp);
+ }
+ strcat(gameString, "\n");
+
+ } else {
+
+ sprintf(gameString, "\n%s ", game_globals.garray[g].white_name);
+ if (wr > 0) {
+ sprintf(tmp, "(%d) ", wr);
+ } else {
+ sprintf(tmp, "(UNR) ");
+ }
+ strcat(gameString, tmp);
+ sprintf(tmp, "vs. %s ", game_globals.garray[g].black_name);
+ strcat(gameString, tmp);
+ if (br > 0) {
+ sprintf(tmp, "(%d) ", br);
+ } else {
+ sprintf(tmp, "(UNR) ");
+ }
+ strcat(gameString, tmp);
+ strcat(gameString, "--- ");
+ strcat(gameString, strltime(&curTime));
+ if (game_globals.garray[g].rated) {
+ strcat(gameString, "\nRated ");
+ } else {
+ strcat(gameString, "\nUnrated ");
+ }
+ strcat (gameString, TypeStrings[game_globals.garray[g].type]);
+ strcat(gameString, " match, initial time: ");
+ if ((game_globals.garray[g].bInitTime != game_globals.garray[g].wInitTime) || (game_globals.garray[g].wIncrement != game_globals.garray[g].bIncrement)) { /* different starting times */
+ sprintf(tmp, "%d minutes, increment: %d seconds AND %d minutes, increment: %d seconds.\n\n", game_globals.garray[g].wInitTime / 600, game_globals.garray[g].wIncrement / 10, game_globals.garray[g].bInitTime / 600, game_globals.garray[g].bIncrement / 10);
+ } else {
+ sprintf(tmp, "%d minutes, increment: %d seconds.\n\n", game_globals.garray[g].wInitTime / 600, game_globals.garray[g].wIncrement / 10);
+ }
+ strcat(gameString, tmp);
+ sprintf(tmp, "Move %-19s%-19s\n", game_globals.garray[g].white_name, game_globals.garray[g].black_name);
+ strcat(gameString, tmp);
+ strcat(gameString, "---- ---------------- ----------------\n");
+
+ for (i = 0; i < game_globals.garray[g].numHalfMoves; i += 2) {
+ if (i==0 && (moves[i].color == BLACK)) {
+ sprintf(tmp, "%3d. %-16s %-16s\n", (i+1)/2 + 1, "...",
+ move_and_time(&moves[i]));
+ i--;
+ } else if (i + 1 < game_globals.garray[g].numHalfMoves) {
+ sprintf(tmp, "%3d. %-16s ", (i+1)/2 + 1, move_and_time(&moves[i]));
+ strcat(gameString, tmp);
+ sprintf(tmp, "%-16s\n", move_and_time(&moves[i+1]));
+ } else {
+ sprintf(tmp, "%3d. %-16s\n", (i+1)/2 + 1, move_and_time(&moves[i]));
+ }
+ strcat(gameString, tmp);
+ if (strlen(gameString) > GAME_STRING_LEN - 100) { /* Bug out if getting
+ close to filling this
+ string */
+ return gameString;
+ }
+ }
+
+ strcat(gameString, " ");
+ }
+
+ sprintf(tmp, "{%s} %s\n", EndString(g, 0), EndSym(g));
+ strcat(gameString, tmp);
+
+ return gameString;
+}
+
+void game_disconnect(int g, int p)
+{
+ game_ended(g, (game_globals.garray[g].white == p) ? WHITE : BLACK, END_LOSTCONNECTION);
+}
+
+int CharToPiece(char c)
+{
+ switch (c) {
+ case 'P':
+ return W_PAWN;
+ case 'p':
+ return B_PAWN;
+ case 'N':
+ return W_KNIGHT;
+ case 'n':
+ return B_KNIGHT;
+ case 'B':
+ return W_BISHOP;
+ case 'b':
+ return B_BISHOP;
+ case 'R':
+ return W_ROOK;
+ case 'r':
+ return B_ROOK;
+ case 'Q':
+ return W_QUEEN;
+ case 'q':
+ return B_QUEEN;
+ case 'K':
+ return W_KING;
+ case 'k':
+ return B_KING;
+ default:
+ return NOPIECE;
+ }
+}
+
+char PieceToChar(int piece)
+{
+ switch (piece) {
+ case W_PAWN:return 'P';
+ case B_PAWN:
+ return 'p';
+ case W_KNIGHT:
+ return 'N';
+ case B_KNIGHT:
+ return 'n';
+ case W_BISHOP:
+ return 'B';
+ case B_BISHOP:
+ return 'b';
+ case W_ROOK:
+ return 'R';
+ case B_ROOK:
+ return 'r';
+ case W_QUEEN:
+ return 'Q';
+ case B_QUEEN:
+ return 'q';
+ case W_KING:
+ return 'K';
+ case B_KING:
+ return 'k';
+ default:
+ return ' ';
+ }
+}
+
+/*
+ write a new style generic game file
+*/
+static void WriteGameFile_v100(FILE * fp, int g)
+{
+ struct game gg = game_globals.garray[g];
+ const char *s;
+
+ /* zero any elements we don't want to save */
+ memset(&gg, 0, offsetof(struct game, not_saved_marker));
+ gg.game_state.gameNum = 0;
+
+ /* marshall it into a string */
+ s = marshall_game(&gg);
+ if (!s) {
+ d_printf("Unable to marshall game structure!\n");
+ return;
+ }
+
+ /* and save it */
+ fprintf(fp, "v 100\n%s\n", s);
+ free(s);
+}
+
+
+/*
+ read a game file using the new generic and extensible format
+*/
+static int ReadGameAttrs_v100(FILE *fp, int g)
+{
+ char *s, *s2;
+ struct game *gg = &game_globals.garray[g];
+ struct game g1;
+
+ s = fd_load(fileno(fp), NULL);
+ if (!s) {
+ d_printf("Error reading game file!\n");
+ return -1;
+ }
+
+ /* skip first line */
+ s2 = strchr(s, '\n');
+
+ /* remember the game state for later */
+ g1 = *gg;
+
+ /* the marshaller doesn't save zero elements, but some elements don't
+ default to zero. Make sure they get the right value */
+ memset(&gg->not_saved_marker, 0,
+ sizeof(struct game) - offsetof(struct game, not_saved_marker));
+ gg->game_state.gameNum = g;
+
+ if (!s2 || unmarshall_game(gg, s2) != 0) {
+ d_printf("Error unmarshalling game data!\n");
+ free(s);
+ return -1;
+ }
+ free(s);
+
+ /* when examining we are not supposed to restore the game
+ state, so put it back here */
+ if (g1.status == GAME_EXAMINE || g1.status == GAME_SETUP) {
+ gg->game_state = g1.game_state;
+ }
+ gg->status = g1.status;
+
+ /* cope with continuing a game with timeseal that was started without it */
+ gg->wRealTime = gg->wTime * 100;
+ gg->bRealTime = gg->bTime * 100;
+
+ return 0;
+}
+
+
+static int ReadGameAttrs_common(FILE * fp, int g,int version)
+{
+ if (version == 9 || version == 100) {
+ return ReadGameAttrs_v100(fp, g);
+ }
+
+ return ReadGameAttrs_old(fp, g, version);
+}
+
+int ReadGameAttrs_exam(FILE * fp, int g)
+{
+ int version = 0;
+ char line[MAX_GLINE_SIZE];
+
+ fgets(line, MAX_GLINE_SIZE - 1, fp);
+
+ if (line[0] == 'v') {
+ sscanf(line, "%*c %d", &version);
+
+ if (version < 5)
+ return -1;
+ else
+ return ReadGameAttrs_common(fp,g,version);
+ }
+
+ else return -1;
+}
+
+int ReadGameAttrs(FILE * fp, int g)
+{
+ int version = 0;
+ char line[MAX_GLINE_SIZE];
+
+ fgets(line, MAX_GLINE_SIZE - 1, fp);
+
+ if (line[0] == 'v') {
+ sscanf(line, "%*c %d", &version);
+ }
+ return ReadGameAttrs_common(fp,g,version);
+}
+
+int game_read(int g, int wp, int bp)
+{
+ FILE *fp;
+ int piece;
+
+ game_globals.garray[g].white = wp;
+ game_globals.garray[g].black = bp;
+/* game_globals.garray[g].old_white = -1;
+ game_globals.garray[g].old_black = -1;
+*/
+ game_globals.garray[g].moveListSize = 0;
+ game_globals.garray[g].game_state.gameNum = g;
+ strcpy(game_globals.garray[g].white_name, player_globals.parray[wp].name);
+ strcpy(game_globals.garray[g].black_name, player_globals.parray[bp].name);
+ if (game_globals.garray[g].type == TYPE_BLITZ) {
+ game_globals.garray[g].white_rating = player_globals.parray[wp].b_stats.rating;
+ game_globals.garray[g].black_rating = player_globals.parray[bp].b_stats.rating;
+ } else if (game_globals.garray[g].type == TYPE_WILD) {
+ game_globals.garray[g].white_rating = player_globals.parray[wp].w_stats.rating;
+ game_globals.garray[g].black_rating = player_globals.parray[bp].w_stats.rating;
+ } else if (game_globals.garray[g].type == TYPE_LIGHT) {
+ game_globals.garray[g].white_rating = player_globals.parray[wp].l_stats.rating;
+ game_globals.garray[g].black_rating = player_globals.parray[bp].l_stats.rating;
+ } else if (game_globals.garray[g].type == TYPE_BUGHOUSE) {
+ game_globals.garray[g].white_rating = player_globals.parray[wp].bug_stats.rating;
+ game_globals.garray[g].black_rating = player_globals.parray[bp].bug_stats.rating;
+ } else {
+ game_globals.garray[g].white_rating = player_globals.parray[wp].s_stats.rating;
+ game_globals.garray[g].black_rating = player_globals.parray[bp].s_stats.rating;
+ }
+ fp = fopen_p("%s/%c/%s-%s", "r", ADJOURNED_DIR, player_globals.parray[wp].login[0],
+ player_globals.parray[wp].login, player_globals.parray[bp].login);
+ if (!fp) {
+ return -1;
+ }
+ for (piece=PAWN; piece <= QUEEN; piece++) {
+ game_globals.garray[g].game_state.holding[0][piece-PAWN]
+ = game_globals.garray[g].game_state.holding[1][piece-PAWN] = 0;
+ }
+ if (ReadGameAttrs(fp, g) < 0) {
+ fclose(fp);
+ return -1;
+ }
+ fclose(fp);
+
+ if (game_globals.garray[g].result == END_ADJOURN
+ || game_globals.garray[g].result == END_COURTESYADJOURN)
+ game_globals.garray[g].result = END_NOTENDED;
+ game_globals.garray[g].status = GAME_ACTIVE;
+ game_globals.garray[g].startTime = tenth_secs();
+ game_globals.garray[g].lastMoveTime = game_globals.garray[g].startTime;
+ game_globals.garray[g].lastDecTime = game_globals.garray[g].startTime;
+
+ /* cope with continuing a game with timeseal that was started without it */
+ game_globals.garray[g].wRealTime = game_globals.garray[g].wTime * 100;
+ game_globals.garray[g].bRealTime = game_globals.garray[g].bTime * 100;
+
+ /* Need to do notification and pending cleanup */
+ return 0;
+}
+
+int game_delete(int wp, int bp)
+{
+ char fname[MAX_FILENAME_SIZE];
+ char lname[MAX_FILENAME_SIZE];
+
+ sprintf(fname, "%s/%c/%s-%s", ADJOURNED_DIR, player_globals.parray[wp].login[0],
+ player_globals.parray[wp].login, player_globals.parray[bp].login);
+ sprintf(lname, "%s/%c/%s-%s", ADJOURNED_DIR, player_globals.parray[bp].login[0],
+ player_globals.parray[wp].login, player_globals.parray[bp].login);
+ unlink(fname);
+ unlink(lname);
+ return 0;
+}
+
+int game_save(int g)
+{
+ FILE *fp;
+ struct player *wp, *bp;
+ struct game *gg = &game_globals.garray[g];
+ char *fname;
+
+ wp = &player_globals.parray[gg->white];
+ bp = &player_globals.parray[gg->black];
+ asprintf(&fname, "%s/%c/%s-%s", ADJOURNED_DIR, wp->login[0],
+ wp->login, bp->login);
+ fp = fopen_p("%s", "w", fname);
+ if (!fp) {
+ d_printf("CHESSD: Problem opening adjourn file %s-%s for write\n",
+ wp->login, bp->login);
+ free(fname);
+ return -1;
+ }
+ WriteGameFile_v100(fp, g);
+ fclose(fp);
+ /* Create link for easier stored game finding */
+ if (bp->login[0] != wp->login[0]) {
+ char *lname;
+ asprintf(&lname, "%s/%c/%s-%s", ADJOURNED_DIR, bp->login[0],
+ wp->login, bp->login);
+ link(fname, lname);
+ free(lname);
+ }
+ free(fname);
+ return 0;
+}
+
+static long OldestHistGame(char *login)
+{
+ FILE *fp;
+ long when;
+
+ fp = fopen_p("%s/player_data/%c/%s.%s", "r", STATS_DIR,
+ login[0], login, STATS_GAMES);
+ if (fp == NULL) {
+ fp = fopen_p("%s/player_data/%c/.rem.%s.%s", "r", STATS_DIR,
+ login[0], login, STATS_GAMES);
+ }
+ if (!fp) return 0;
+
+ fscanf(fp, "%*d %*c %*d %*c %*d %*s %*s %*d %*d %*d %*d %*s %*s %ld",
+ &when);
+ fclose(fp);
+ return when;
+}
+
+static void RemoveHistGame(char *file, int maxlines)
+{
+ FILE *fp;
+ char GameFile[MAX_FILENAME_SIZE];
+ char Opponent[MAX_LOGIN_NAME];
+ char line[MAX_LINE_SIZE];
+ long When, oppWhen;
+ int count = 0;
+
+ fp = fopen_p("%s", "r", file);
+ if (fp == NULL)
+ return;
+
+ fgets(line, MAX_LINE_SIZE - 1, fp);
+ sscanf(line, "%*d %*c %*d %*c %*d %s %*s %*d %*d %*d %*d %*s %*s %ld",
+ Opponent, &When);
+ count++;
+
+ while (!feof(fp)) {
+ fgets(line, MAX_LINE_SIZE - 1, fp);
+ if (!feof(fp))
+ count++;
+ }
+ fclose(fp);
+
+ stolower(Opponent);
+ if (count > maxlines) {
+ truncate_file(file, maxlines);
+
+ oppWhen = OldestHistGame(Opponent);
+ if (oppWhen > When || oppWhen <= 0L) {
+ sprintf(GameFile, "%s/%ld/%ld", HISTORY_DIR, When % 100, When);
+ unlink(GameFile);
+ }
+ }
+}
+
+void RemHist(char *who)
+{
+ FILE *fp;
+ char Opp[MAX_LOGIN_NAME];
+ long When, oppWhen;
+
+ fp = fopen_p("%s/player_data/%c/%s.%s", "r",
+ STATS_DIR,
+ who[0], who, STATS_GAMES);
+ if (!fp) {
+ return;
+ }
+ while (!feof(fp)) {
+ fscanf(fp, "%*d %*c %*d %*c %*d %s %*s %*d %*d %*d %*d %*s %*s %ld",
+ Opp, &When);
+ stolower(Opp);
+ oppWhen = OldestHistGame(Opp);
+ if (oppWhen > When || oppWhen <= 0L) {
+ char *fName;
+ asprintf(&fName, "%s/%ld/%ld", HISTORY_DIR, When % 100, When);
+ unlink(fName);
+ free(fName);
+ }
+ }
+ fclose(fp);
+}
+
+static void write_g_out(int g, char *file, int maxlines, int isDraw,
+ char *EndSymbol, char *name, time_t *now)
+{
+ FILE *fp;
+ int wp, bp;
+ int wr, br;
+ char type[4];
+ char tmp[2048];
+ char *ptmp = tmp;
+ char cResult;
+ int count = -1;
+ char *goteco;
+
+ wp = game_globals.garray[g].white;
+ bp = game_globals.garray[g].black;
+
+ if (game_globals.garray[g].private) {
+ type[0] = 'p';
+ } else {
+ type[0] = ' ';
+ }
+ if (game_globals.garray[g].type == TYPE_BLITZ) {
+ wr = player_globals.parray[wp].b_stats.rating;
+ br = player_globals.parray[bp].b_stats.rating;
+ type[1] = 'b';
+ } else if (game_globals.garray[g].type == TYPE_WILD) {
+ wr = player_globals.parray[wp].w_stats.rating;
+ br = player_globals.parray[bp].w_stats.rating;
+ type[1] = 'w';
+ } else if (game_globals.garray[g].type == TYPE_STAND) {
+ wr = player_globals.parray[wp].s_stats.rating;
+ br = player_globals.parray[bp].s_stats.rating;
+ type[1] = 's';
+ } else if (game_globals.garray[g].type == TYPE_LIGHT) {
+ wr = player_globals.parray[wp].l_stats.rating;
+ br = player_globals.parray[bp].l_stats.rating;
+ type[1] = 'l';
+ } else if (game_globals.garray[g].type == TYPE_BUGHOUSE) {
+ wr = player_globals.parray[wp].bug_stats.rating;
+ br = player_globals.parray[bp].bug_stats.rating;
+ type[1] = 'B';
+ } else {
+ wr = 0;
+ br = 0;
+ if (game_globals.garray[g].type == TYPE_NONSTANDARD)
+ type[1] = 'n';
+ else
+ type[1] = 'u';
+ }
+ if (game_globals.garray[g].rated) {
+ type[2] = 'r';
+ } else {
+ type[2] = 'u';
+ }
+ type[3] = '\0';
+
+ fp = fopen_s(file, "r");
+ if (fp) {
+ while (!feof(fp))
+ fgets(tmp, 1024, fp);
+ sscanf(ptmp, "%d", &count);
+ fclose(fp);
+ }
+ count = (count + 1) % 100;
+
+ fp = fopen_s(file, "a");
+ if (!fp)
+ return;
+
+ goteco = getECO(g);
+
+/* Counter Result MyRating MyColor OppRating OppName [pbr 2 12 2 12] ECO End Date */
+ if (name == player_globals.parray[wp].name) {
+ if (isDraw)
+ cResult = '=';
+ else if (game_globals.garray[g].winner == WHITE)
+ cResult = '+';
+ else
+ cResult = '-';
+
+ fprintf(fp, "%d %c %d W %d %s %s %d %d %d %d %s %s %ld\n",
+ count, cResult, wr, br, player_globals.parray[bp].name, type,
+ game_globals.garray[g].wInitTime, game_globals.garray[g].wIncrement,
+ game_globals.garray[g].bInitTime, game_globals.garray[g].bIncrement,
+ goteco,
+ EndSymbol,
+ (long) *now);
+ } else {
+ if (isDraw)
+ cResult = '=';
+ else if (game_globals.garray[g].winner == BLACK)
+ cResult = '+';
+ else
+ cResult = '-';
+
+ fprintf(fp, "%d %c %d B %d %s %s %d %d %d %d %s %s %ld\n",
+ count, cResult, br, wr, player_globals.parray[wp].name, type,
+ game_globals.garray[g].wInitTime, game_globals.garray[g].wIncrement,
+ game_globals.garray[g].bInitTime, game_globals.garray[g].bIncrement,
+ goteco,
+ EndSymbol,
+ (long) *now);
+ }
+ fclose(fp);
+
+ RemoveHistGame(file, maxlines);
+}
+
+/* Test if entry is present - 1 yes 0 no */
+/* returns -1 if an error */
+
+char get_journalgame_type(int p,char* fname,char slot)
+
+{
+ struct player *pp = &player_globals.parray[p];
+ char cur_slot;
+ char type[4];
+
+ FILE* fp = fopen_s(fname,"r");
+ if (!fp) {
+ d_printf("Corrupt journal file! %s\n",fname);
+ pprintf (p, "The journal file is corrupt! See an admin.\n");
+ return 0;
+ }
+
+ while (!feof(fp)) {
+ if (fscanf(fp, "%c %*s %*d %*s %*d %s %*d %*d %*s %*s %*s\n",
+ &cur_slot,type) != 2) {
+ d_printf( "CHESSD: Error in journal info format for player %s.\n",
+ pp->name);
+ pprintf(p, "The journal file is corrupt! Error in internal format.\n");
+ return '\0';
+ }
+ if (cur_slot == slot) {
+ fclose (fp);
+ if (type[0] == 'p')
+ return type[1];
+ else
+ return type[0];
+ }
+ }
+ fclose (fp);
+ return '0';
+}
+
+
+/* Returns 1 if successful */
+
+int removejournalitem(int p, char slot,FILE* fp,char* fname, int* empty)
+
+{
+ FILE* fp_new;
+ int found = 0;
+ struct journal* j;
+
+ *empty = 1;
+ fp_new = fopen_s(fname, "w");
+ if (!fp_new) {
+ d_printf("Can't write to journal %s!\n",fname);
+ pprintf (p, "Was unable to write to the file! See an admin.\n");
+ return 0;
+ }
+ j = (struct journal*) malloc(sizeof(struct journal));
+ while (!feof(fp)) {
+ if (fscanf(fp, "%c %s %d %s %d %s %d %d %s %s %s\n",
+ &j->slot,
+ j->WhiteName,
+ &j->WhiteRating,
+ j->BlackName,
+ &j->BlackRating,
+ j->type,
+ &j->t, &j->i,
+ j->eco,
+ j->ending,
+ j->result) != 11) {
+ d_printf( "CHESSD: Error in journal info format. %s\n", fname);
+ pprintf(p, "The journal file is corrupt! Error in internal format.\n");
+ fclose(fp_new);
+ free (j);
+ return 0;
+ }
+ if (slot != j->slot) {
+ *empty = 0;
+ fprintf(fp_new, "%c %s %d %s %d %s %d %d %s %s %s\n",
+ j->slot,
+ j->WhiteName,
+ j->WhiteRating,
+ j->BlackName,
+ j->BlackRating,
+ j->type,
+ j->t, j->i,
+ j->eco,
+ j->ending,
+ j->result);
+ } else
+ found = 1;
+ }
+ fclose(fp_new);
+ free (j);
+ return found;
+}
+
+/* Find from_spot in journal list - return 0 if corrupted */
+int journal_get_info(int p, char from_spot,struct journal* j, char *fname)
+{
+ FILE *fp;
+
+ fp = fopen_s(fname, "r");
+ if (!fp) {
+ d_printf("Corrupt journal file! %s\n",fname);
+ pprintf (p, "The journal file is corrupt! See an admin.\n");
+ return 0;
+ }
+ while (!feof(fp)) {
+ if (fscanf(fp, "%c %s %d %s %d %s %d %d %s %s %s\n",
+ &j->slot,
+ j->WhiteName,
+ &j->WhiteRating,
+ j->BlackName,
+ &j->BlackRating,
+ j->type,
+ &j->t, &j->i,
+ j->eco,
+ j->ending,
+ j->result) != 11) {
+ d_printf( "CHESSD: Error in journal info format. %s\n", fname);
+ pprintf(p, "The journal file is corrupt! Error in internal format.\n");
+ fclose(fp);
+ return 0;
+ }
+ if (tolower(j->slot) == from_spot) {
+ fclose(fp);
+ return 1;
+ }
+ }
+ fclose(fp);
+ return 0;
+}
+
+void addjournalitem(int p,struct journal* j_add, char* fname)
+{
+ struct journal* j_cur;
+ int have_output=0;
+ char fname2[MAX_FILENAME_SIZE];
+ FILE *fp;
+ FILE *fp2;
+
+ strcpy (fname2,fname);
+ strcat (fname2,".w");
+ fp2 = fopen_s(fname2, "w");
+ if (!fp2) {
+ d_printf( "CHESSD: Problem opening file %s for write\n", fname);
+ pprintf (p, "Couldn't update journal! Report this to an admin.\n");
+ return;
+ }
+ fp = fopen_s(fname, "r");
+ if (!fp) { /* Empty? */
+ fprintf(fp2, "%c %s %d %s %d %s %d %d %s %s %s\n",
+ j_add->slot, j_add->WhiteName, j_add->WhiteRating,
+ j_add->BlackName, j_add->BlackRating,
+ j_add->type, j_add->t, j_add->i, j_add->eco, j_add->ending,
+ j_add->result);
+ fclose (fp2);
+ rename (fname2, fname);
+ return;
+ } else {
+ j_cur = (struct journal*) malloc(sizeof(struct journal));
+ while (!feof(fp)) {
+ if (fscanf(fp, "%c %s %d %s %d %s %d %d %s %s %s\n",
+ &j_cur->slot,
+ j_cur->WhiteName,
+ &j_cur->WhiteRating,
+ j_cur->BlackName,
+ &j_cur->BlackRating,
+ j_cur->type,
+ &j_cur->t, &j_cur->i,
+ j_cur->eco,
+ j_cur->ending,
+ j_cur->result) != 11) {
+ d_printf( "CHESSD: Error in journal info format - aborting. %s\n", fname);
+ free (j_cur);
+ fclose(fp);
+ fclose(fp2);
+ return;
+ }
+ if ((j_cur->slot >= j_add->slot) && (!have_output)) {
+
+ fprintf(fp2, "%c %s %d %s %d %s %d %d %s %s %s\n",
+ j_add->slot,
+ j_add->WhiteName,
+ j_add->WhiteRating,
+ j_add->BlackName,
+ j_add->BlackRating,
+ j_add->type,
+ j_add->t, j_add->i,
+ j_add->eco,
+ j_add->ending,
+ j_add->result);
+ have_output = 1;
+
+ }
+ if (j_cur->slot != j_add->slot) {
+
+ fprintf(fp2, "%c %s %d %s %d %s %d %d %s %s %s\n",
+ j_cur->slot,
+ j_cur->WhiteName,
+ j_cur->WhiteRating,
+ j_cur->BlackName,
+ j_cur->BlackRating,
+ j_cur->type,
+ j_cur->t, j_cur->i,
+ j_cur->eco,
+ j_cur->ending,
+ j_cur->result);
+ }
+ }
+
+ if (!have_output) { /* Haven't written yet */
+ fprintf(fp2, "%c %s %d %s %d %s %d %d %s %s %s\n",
+ j_add->slot,
+ j_add->WhiteName,
+ j_add->WhiteRating,
+ j_add->BlackName,
+ j_add->BlackRating,
+ j_add->type,
+ j_add->t, j_add->i,
+ j_add->eco,
+ j_add->ending,
+ j_add->result);
+ }
+ free (j_cur);
+ fclose(fp);
+ fclose(fp2);
+ rename(fname2, fname);
+ return;
+ }
+}
+
+int pjournal(int p, int p1, char *fname)
+{
+ FILE *fp;
+ struct journal* j;
+
+ fp = fopen_s(fname, "r");
+ if (!fp) {
+ pprintf(p, "Sorry, no journal information available.\n");
+ return COM_OK;
+ }
+
+ j = (struct journal*) malloc(sizeof(struct journal));
+ pprintf(p, "Journal for %s:\n", player_globals.parray[p1].name);
+ pprintf(p, " White Rating Black Rating Type ECO End Result\n");
+ while (!feof(fp)) {
+ if (fscanf(fp, "%c %s %d %s %d %s %d %d %s %s %s\n",
+ &j->slot,
+ j->WhiteName,
+ &j->WhiteRating,
+ j->BlackName,
+ &j->BlackRating,
+ j->type,
+ &j->t, &j->i,
+ j->eco,
+ j->ending,
+ j->result) != 11) {
+ d_printf( "CHESSD: Error in journal info format. %s\n", fname);
+ fclose(fp);
+ free(j);
+ return COM_OK;
+ }
+ j->WhiteName[13] = '\0'; /* only first 13 chars in name */
+ j->BlackName[13] = '\0';
+ pprintf(p, "%c: %-13s %4d %-13s %4d [%3s%3d%4d] %s %3s %-7s\n",
+ j->slot, j->WhiteName, j->WhiteRating,
+ j->BlackName, j->BlackRating,
+ j->type, j->t / 600, j->i / 10, j->eco, j->ending,
+ j->result);
+ }
+ free (j);
+ fclose(fp);
+ return COM_OK;
+}
+
+int pgames(int p, int p1, char *fname)
+{
+ FILE *fp;
+ time_t t;
+ int MyRating, OppRating;
+ int wt, wi, bt, bi;
+ char OppName[MAX_LOGIN_NAME + 1];
+ char type[100];
+ char eco[100];
+ char ending[100];
+ char MyColor[2];
+ int count;
+ char result[2];
+
+ fp = fopen_s(fname, "r");
+ if (!fp) {
+ pprintf(p, "Sorry, no game information available.\n");
+ return COM_OK;
+ }
+ pprintf(p, "History for %s:\n", player_globals.parray[p1].name);
+ pprintf(p, " Opponent Type ECO End Date\n");
+ while (!feof(fp)) {
+ if (fscanf(fp, "%d %s %d %s %d %s %s %d %d %d %d %s %s %ld\n",
+ &count,
+ result,
+ &MyRating,
+ MyColor,
+ &OppRating,
+ OppName,
+ type,
+ &wt, &wi,
+ &bt, &bi,
+ eco,
+ ending,
+ (long *) &t) != 14) {
+ d_printf( "CHESSD: Error in games info format. %s\n", fname);
+ fclose(fp);
+ return COM_OK;
+ }
+ OppName[13] = '\0'; /* only first 13 chars in name */
+ pprintf(p, "%2d: %s %4d %s %4d %-13s [%3s%3d%4d] %s %3s %s",
+ count, result, MyRating, MyColor,
+ OppRating, OppName,
+ type, wt / 600, wi / 10, eco, ending,
+ ctime(&t));
+ }
+ fclose(fp);
+ return COM_OK;
+}
+
+void game_write_complete(int g, int isDraw, char *EndSymbol)
+{
+ char fname[MAX_FILENAME_SIZE];
+ int wp = game_globals.garray[g].white, bp = game_globals.garray[g].black;
+ time_t now = time(NULL);
+ int Result;
+ FILE *fp = NULL;
+
+ do {
+ if (fp) {
+ fclose(fp);
+ now++;
+ }
+ sprintf(fname, "%s/%ld/%ld", HISTORY_DIR, (long) now % 100, (long) now);
+ fp = fopen_s(fname, "r");
+ } while (fp); /* terminates when the file doesn't exist */
+
+ fp = fopen_s(fname, "w");
+
+ if (fp) {
+ WriteGameFile_v100(fp, g);
+ fclose(fp);
+ } else {
+ d_printf( "Trouble writing history file %s", fname);
+ }
+
+ sprintf(fname, "%s/player_data/%c/%s.%s", STATS_DIR,
+ player_globals.parray[wp].login[0], player_globals.parray[wp].login, STATS_GAMES);
+ write_g_out(g, fname, 10, isDraw, EndSymbol, player_globals.parray[wp].name, &now);
+ sprintf(fname, "%s/player_data/%c/%s.%s", STATS_DIR,
+ player_globals.parray[bp].login[0], player_globals.parray[bp].login, STATS_GAMES);
+ write_g_out(g, fname, 10, isDraw, EndSymbol, player_globals.parray[bp].name, &now);
+
+ if (isDraw)
+ Result = -1;
+ else if (game_globals.garray[g].winner == WHITE)
+ Result = 1;
+ else
+ Result = 0;
+ sprintf(fname,"%s/player_data/%c/%s.gstats", STATS_DIR, player_globals.parray[game_globals.garray[g].white].login[0], player_globals.parray[game_globals.garray[g].white].login);
+ if ((CheckPFlag(bp, PFLAG_REG)) && (CheckPFlag(wp, PFLAG_REG)) && (game_globals.garray[g].type != TYPE_WILD))
+ game_save_playerratio(fname,player_globals.parray[game_globals.garray[g].black].name,Result,game_globals.garray[g].rated);
+ if (isDraw)
+ Result = -1;
+ else if (game_globals.garray[g].winner == BLACK)
+ Result = 1;
+ else
+ Result = 0;
+ sprintf(fname,"%s/player_data/%c/%s.gstats", STATS_DIR, player_globals.parray[game_globals.garray[g].black].login[0], player_globals.parray[game_globals.garray[g].black].login);
+ if ((CheckPFlag(bp, PFLAG_REG)) && (CheckPFlag(wp, PFLAG_REG)) && (game_globals.garray[g].type != TYPE_WILD))
+ game_save_playerratio(fname,player_globals.parray[game_globals.garray[g].white].name,Result,game_globals.garray[g].rated);
+}
+
+int game_count(void)
+{
+ int g, count = 0;
+
+ for (g = 0; g < game_globals.g_num; g++) {
+ if ((game_globals.garray[g].status == GAME_ACTIVE) || (game_globals.garray[g].status == GAME_EXAMINE)
+ || (game_globals.garray[g].status == GAME_SETUP))
+ count++;
+ }
+ if (count > command_globals.game_high)
+ command_globals.game_high = count;
+ return count;
+}
+
+static int check_kings(struct game_state_t *gs)
+{
+ /* Function written 3/28/96 by Figbert to check for 1 king each side only! */
+ int blackking = 0, whiteking = 0;
+ int f, r;
+
+
+ for (f = 0; f < 8; f++) {
+ for (r = 0; r < 8; r++) {
+ if (gs->board[f][r] == B_KING) blackking++;
+ if (gs->board[f][r] == W_KING) whiteking++;
+ }
+ }
+
+ if (blackking == 1 && whiteking == 1) return 0; /* Perfect! */
+
+ return -1;
+}
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+#ifndef _GAMEDB_H
+#define _GAMEDB_H
+
+extern const char *bstr[];
+extern const char *rstr[];
+
+#define GAMEFILE_VERSION 5
+#define MAX_GLINE_SIZE 1024
+
+#define REL_GAME 0
+#define REL_SPOS 1
+#define REL_REFRESH 2
+#define REL_EXAMINE 3
+
+GENSTRUCT enum gamestatus {GAME_EMPTY, GAME_NEW, GAME_ACTIVE, GAME_EXAMINE, GAME_SETUP};
+
+/* Do not change the order of these - DAV */
+GENSTRUCT enum gametype {TYPE_UNTIMED, TYPE_BLITZ, TYPE_STAND, TYPE_NONSTANDARD,
+ TYPE_WILD, TYPE_LIGHT, TYPE_BUGHOUSE};
+
+#define NUM_GAMETYPES 7
+
+/* OK, DAV, I'll try it another way. -- hersco */
+enum ratetype {RATE_STAND, RATE_BLITZ, RATE_WILD, RATE_LIGHT, RATE_BUGHOUSE};
+#define NUM_RATEDTYPE 5
+
+#define FLAG_CHECKING -1
+#define FLAG_NONE 0
+#define FLAG_CALLED 1
+#define FLAG_ABORT 2
+
+GENSTRUCT enum gameend {
+ END_CHECKMATE = 0,
+ END_RESIGN,
+ END_FLAG,
+ END_AGREEDDRAW,
+ END_REPETITION,
+ END_50MOVERULE,
+ END_ADJOURN,
+ END_LOSTCONNECTION,
+ END_ABORT,
+ END_STALEMATE,
+ END_NOTENDED,
+ END_COURTESY,
+ END_BOTHFLAG,
+ END_NOMATERIAL,
+ END_FLAGNOMATERIAL,
+ END_ADJDRAW,
+ END_ADJWIN,
+ END_ADJABORT,
+ END_COURTESYADJOURN
+};
+
+struct journal {
+ char slot;
+ char WhiteName[MAX_LOGIN_NAME];
+ int WhiteRating;
+ char BlackName[MAX_LOGIN_NAME];
+ int BlackRating;
+ char type[4];
+ int t;
+ int i;
+ char eco[4];
+ char ending[4];
+ char result[8];
+};
+
+
+GENSTRUCT struct game {
+ /* Not saved in game file */
+ int revertHalfMove;
+ int totalHalfMoves;
+ int white;
+ int black;
+ int link;
+ enum gamestatus status;
+ int examHalfMoves;
+ int examMoveListSize;
+ struct move_t *examMoveList; _LEN(examMoveListSize) /* extra movelist for examine */
+
+ unsigned startTime; /* The relative time the game started */
+ unsigned lastMoveTime; /* Last time a move was made */
+ unsigned lastDecTime; /* Last time a players clock was decremented */
+ int flag_pending;
+ int wTimeWhenReceivedMove;
+ int wTimeWhenMoved;
+ int bTimeWhenReceivedMove;
+ int bTimeWhenMoved;
+ int wLastRealTime;
+ int wRealTime;
+ int bLastRealTime;
+ int bRealTime;
+
+ /* this is a dummy variable used to tell which bits are saved in the structure */
+ unsigned not_saved_marker;
+
+ /* Saved in the game file */
+ enum gameend result;
+ int winner;
+ int wInitTime, wIncrement;
+ int bInitTime, bIncrement;
+ time_t timeOfStart;
+ unsigned flag_check_time;
+ int wTime;
+ int bTime;
+ int clockStopped;
+ int rated;
+ int private;
+ enum gametype type;
+ int passes; /* For simul's */
+ int numHalfMoves;
+ int moveListSize; /* Total allocated in *moveList */
+ struct move_t *moveList; _LEN(moveListSize) /* primary movelist */
+ char FENstartPos[74]; _NULLTERM /* Save the starting position. */
+ struct game_state_t game_state;
+
+ char white_name[MAX_LOGIN_NAME]; _NULLTERM /* to hold the playername even after he disconnects */
+ char black_name[MAX_LOGIN_NAME]; _NULLTERM
+ int white_rating;
+ int black_rating;
+};
+
+extern const char *TypeStrings[NUM_GAMETYPES];
+extern const char *TypeChars[NUM_GAMETYPES];
+
+#endif
+
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+#include "includes.h"
+
+#if 0
+/* One line has everything on it */
+static int WriteMoves(FILE * fp, struct move_t *m)
+{
+ unsigned long MoveInfo = (m->color == BLACK);
+ int piece, castle;
+ int useFile = 0, useRank = 0, check = 0;
+ int i;
+
+ castle = (m->moveString[0] == 'o');
+ if (castle)
+ piece = KING;
+ else
+ piece = piecetype(CharToPiece(m->moveString[0]));
+
+ MoveInfo = (MoveInfo <<= 3) | piece;
+ MoveInfo = (MoveInfo <<= 3) | m->fromFile;
+ MoveInfo = (MoveInfo <<= 3) | m->fromRank;
+ MoveInfo = (MoveInfo <<= 3) | m->toFile;
+ MoveInfo = (MoveInfo <<= 3) | m->toRank;
+ MoveInfo = (MoveInfo <<= 3) | (m->pieceCaptured & 7);
+ MoveInfo = (MoveInfo <<= 3) | (m->piecePromotionTo & 7);
+ MoveInfo = (MoveInfo <<= 1) | (m->enPassant != 0);
+
+ /* Are we using from-file or from-rank in algString? */
+ i = strlen(m->algString) - 1;
+ if (m->algString[i] == '+') {
+ check = 1;
+ i--;
+ }
+ if (piece != PAWN && !castle) {
+ i -= 2;
+ if (i < 0)
+ return -1;
+ if (m->algString[i] == 'x')
+ i--;
+ if (i < 0)
+ return -1;
+ if (isdigit(m->algString[i])) {
+ useRank = 2;
+ i--;
+ }
+ if (i < 0)
+ return -1;
+ useFile = (islower(m->algString[i]) ? 4 : 0);
+ }
+ MoveInfo = (MoveInfo << 3) | useFile | useRank | check;
+ fprintf(fp, "%lx %x %x\n", MoveInfo, m->tookTime, m->atTime);
+
+ return 0;
+}
+#endif
+
+static int ReadMove(FILE * fp, struct move_t *m)
+{
+ char line[MAX_GLINE_SIZE];
+ fgets(line, MAX_GLINE_SIZE - 1, fp);
+ if (sscanf(line, "%d %d %d %d %d %d %d %d %d \"%[^\"]\" \"%[^\"]\" %u %u\n",
+ &m->color, &m->fromFile, &m->fromRank, &m->toFile, &m->toRank,
+ &m->pieceCaptured, &m->piecePromotionTo, &m->enPassant, &m->doublePawn,
+ m->moveString, m->algString, &m->atTime, &m->tookTime) != 13)
+ return -1;
+ return 0;
+}
+
+#if 0
+static void WriteGameState(FILE * fp, struct game_state_t *gs)
+{
+ int i, j;
+
+ for (i = 0; i < 8; i++)
+ for (j = 0; j < 8; j++) {
+ fprintf(fp, "%c", PieceToChar(gs->board[i][j]));
+ }
+ fprintf(fp, "%d %d %d %d %d %d",
+ gs->wkmoved, gs->wqrmoved, gs->wkrmoved,
+ gs->bkmoved, gs->bqrmoved, gs->bkrmoved);
+ for (i = 0; i < 8; i++)
+ fprintf(fp, " %d %d", gs->ep_possible[0][i], gs->ep_possible[1][i]);
+ fprintf(fp, " %d %d %d\n", gs->lastIrreversable, gs->onMove, gs->moveNum);
+}
+#endif
+
+#if 0
+static void WriteGameFile(FILE * fp, int g)
+{
+ int i;
+ struct game *gg = &game_globals.garray[g];
+ struct player *wp = &player_globals.parray[gg->white], *bp = &player_globals.parray[gg->black];
+
+ fprintf(fp, "v %d\n", GAMEFILE_VERSION);
+ fprintf(fp, "%s %s\n", wp->name, bp->name);
+ fprintf(fp, "%d %d\n", gg->white_rating, gg->black_rating);
+ fprintf(fp, "%d %d %d %d\n", gg->wInitTime, gg->wIncrement,
+ gg->bInitTime, gg->bIncrement);
+ fprintf(fp, "%lx\n", gg->timeOfStart);
+ fprintf(fp, "%d %d\n",
+ (net_globals.con[wp->socket]->timeseal ? gg->wRealTime/100 : gg->wTime),
+ (net_globals.con[bp->socket]->timeseal ? gg->bRealTime/100 : gg->bTime));
+ fprintf(fp, "%d %d\n", gg->result, gg->winner);
+ fprintf(fp, "%d %d %d %d\n", gg->private, gg->type,
+ gg->rated, gg->clockStopped);
+ fprintf(fp, "%d\n", gg->numHalfMoves);
+ for (i = 0; i < game_globals.garray[g].numHalfMoves; i++) {
+ WriteMoves(fp, &game_globals.garray[g].moveList[i]);
+ }
+/* took out the next 3 lines to see if it helps with the crash bug we are
+ having on examine... fb 2.25.96 */
+/* The next three lines stop wild games crashing the system - they are vital.
+ I fixed the problem with examine - don't remove these again - DAV */
+ if (strcmp(gg->FENstartPos, INITIAL_FEN) != 0)
+ fprintf (fp, "%s\n",gg->FENstartPos);
+ else
+ fprintf (fp, "d w\n");
+ WriteGameState(fp, &game_globals.garray[g].game_state);
+}
+#endif
+
+
+
+static int ReadGameState(FILE * fp, struct game_state_t *gs, int version)
+{
+ int i, j;
+ char pieceChar;
+ int wkmoved, wqrmoved, wkrmoved, bkmoved, bqrmoved, bkrmoved;
+
+ if (version == 0) {
+ for (i = 0; i < 8; i++)
+ for (j = 0; j < 8; j++)
+ if (fscanf(fp, "%d ", &gs->board[i][j]) != 1)
+ return -1;
+ } else {
+ for (i = 0; i < 8; i++)
+ for (j = 0; j < 8; j++) {
+ pieceChar = getc(fp);
+ gs->board[i][j] = CharToPiece(pieceChar);
+ }
+ }
+ if (fscanf(fp, "%d %d %d %d %d %d",
+ &wkmoved, &wqrmoved, &wkrmoved,
+ &bkmoved, &bqrmoved, &bkrmoved) != 6)
+ return -1;
+ gs->wkmoved = wkmoved;
+ gs->wqrmoved = wqrmoved;
+ gs->wkrmoved = wkrmoved;
+ gs->bkmoved = bkmoved;
+ gs->bqrmoved = bqrmoved;
+ gs->bkrmoved = bkrmoved;
+ for (i = 0; i < 8; i++)
+ if (fscanf(fp, " %d %d", &gs->ep_possible[0][i], &gs->ep_possible[1][i]) != 2)
+ return -1;
+ if (fscanf(fp, " %d %d %d\n", &gs->lastIrreversable, &gs->onMove, &gs->moveNum) != 3)
+ return -1;
+ return 0;
+}
+
+
+static int got_attr_value(int g, char *attr, char *value, FILE * fp)
+{
+ int i;
+
+ if (!strcmp(attr, "w_init:")) {
+ game_globals.garray[g].wInitTime = atoi(value);
+ } else if (!strcmp(attr, "w_inc:")) {
+ game_globals.garray[g].wIncrement = atoi(value);
+ } else if (!strcmp(attr, "b_init:")) {
+ game_globals.garray[g].bInitTime = atoi(value);
+ } else if (!strcmp(attr, "b_inc:")) {
+ game_globals.garray[g].bIncrement = atoi(value);
+ } else if (!strcmp(attr, "white_name:")) {
+ strcpy(game_globals.garray[g].white_name, value);
+ } else if (!strcmp(attr, "black_name:")) {
+ strcpy(game_globals.garray[g].black_name, value);
+ } else if (!strcmp(attr, "white_rating:")) {
+ game_globals.garray[g].white_rating = atoi(value);
+ } else if (!strcmp(attr, "black_rating:")) {
+ game_globals.garray[g].black_rating = atoi(value);
+ } else if (!strcmp(attr, "result:")) {
+ game_globals.garray[g].result = atoi(value);
+ } else if (!strcmp(attr, "timestart:")) {
+ game_globals.garray[g].timeOfStart = atoi(value);
+ } else if (!strcmp(attr, "w_time:")) {
+ game_globals.garray[g].wTime = atoi(value);
+ } else if (!strcmp(attr, "b_time:")) {
+ game_globals.garray[g].bTime = atoi(value);
+ } else if (!strcmp(attr, "clockstopped:")) {
+ game_globals.garray[g].clockStopped = atoi(value);
+ } else if (!strcmp(attr, "rated:")) {
+ game_globals.garray[g].rated = atoi(value);
+ } else if (!strcmp(attr, "private:")) {
+ game_globals.garray[g].private = atoi(value);
+ } else if (!strcmp(attr, "type:")) {
+ game_globals.garray[g].type = atoi(value);
+ } else if (!strcmp(attr, "halfmoves:")) {
+ game_globals.garray[g].numHalfMoves = atoi(value);
+ if (game_globals.garray[g].numHalfMoves == 0)
+ return 0;
+ game_globals.garray[g].moveListSize = game_globals.garray[g].numHalfMoves;
+ game_globals.garray[g].moveList = (struct move_t *) malloc(sizeof(struct move_t) * game_globals.garray[g].moveListSize);
+ for (i = 0; i < game_globals.garray[g].numHalfMoves; i++) {
+ if (ReadMove(fp, &game_globals.garray[g].moveList[i])) {
+ d_printf( "CHESSD: Trouble reading moves\n");
+ return -1;
+ }
+ }
+ } else if (!strcmp(attr, "gamestate:")) { /* Value meaningless */
+ if (game_globals.garray[g].status != GAME_EXAMINE && game_globals.garray[g].status != GAME_SETUP &&
+ ReadGameState(fp, &game_globals.garray[g].game_state, 0)) {
+ d_printf( "CHESSD: Trouble reading game state\n");
+ return -1;
+ }
+ } else {
+ d_printf( "CHESSD: Error bad attribute >%s<\n", attr);
+ }
+ return 0;
+}
+
+static void ReadOneV1Move(FILE * fp, struct move_t *m)
+{
+ int i;
+ char PieceChar;
+ int useFile, useRank, check, piece;
+ unsigned long MoveInfo;
+
+ fscanf(fp, "%lx %x %x", &MoveInfo, &m->tookTime, &m->atTime);
+ check = MoveInfo & 1;
+ useRank = MoveInfo & 2;
+ useFile = MoveInfo & 4;
+ MoveInfo >>= 3;
+ m->enPassant = MoveInfo & 1; /* may have to negate later. */
+ MoveInfo >>= 1;
+ m->piecePromotionTo = MoveInfo & 7; /* may have to change color. */
+ MoveInfo >>= 3;
+ m->pieceCaptured = MoveInfo & 7; /* may have to change color. */
+ MoveInfo >>= 3;
+ m->toRank = MoveInfo & 7;
+ MoveInfo >>= 3;
+ m->toFile = MoveInfo & 7;
+ MoveInfo >>= 3;
+ m->fromRank = MoveInfo & 7;
+ MoveInfo >>= 3;
+ m->fromFile = MoveInfo & 7;
+ MoveInfo >>= 3;
+ piece = MoveInfo & 7;
+
+ m->color = (MoveInfo & 8) ? BLACK : WHITE;
+ if (m->pieceCaptured != NOPIECE) {
+ if (m->color == BLACK)
+ m->pieceCaptured |= WHITE;
+ else
+ m->pieceCaptured |= BLACK;
+ }
+ if (piece == PAWN) {
+ PieceChar = 'P';
+ if ((m->toRank == 3 && m->fromRank == 1)
+ || (m->toRank == 4 && m->fromRank == 6))
+ m->doublePawn = m->toFile;
+ else
+ m->doublePawn = -1;
+ if (m->pieceCaptured)
+ sprintf(m->algString, "%cx%c%d", 'a' + m->fromFile,
+ 'a' + m->toFile, m->toRank + 1);
+ else
+ sprintf(m->algString, "%c%d", 'a' + m->toFile, m->toRank + 1);
+ if (m->piecePromotionTo != 0) {
+ if (m->piecePromotionTo == KNIGHT)
+ strcat(m->algString, "=N");
+ else if (m->piecePromotionTo == BISHOP)
+ strcat(m->algString, "=B");
+ else if (m->piecePromotionTo == ROOK)
+ strcat(m->algString, "=R");
+ else if (m->piecePromotionTo == QUEEN)
+ strcat(m->algString, "=Q");
+ m->piecePromotionTo |= m->color;
+ }
+ if (m->enPassant)
+ m->enPassant = m->toFile - m->fromFile;
+ } else {
+ m->doublePawn = -1;
+ PieceChar = PieceToChar(piecetype(piece) | WHITE);
+ if (PieceChar == 'K' && m->fromFile == 4 && m->toFile == 6) {
+ strcpy(m->algString, "O-O");
+ strcpy(m->moveString, "o-o");
+ } else if (PieceChar == 'K' && m->fromFile == 4 && m->toFile == 2) {
+ strcpy(m->algString, "O-O-O");
+ strcpy(m->moveString, "o-o-o");
+ } else {
+ i = 0;
+ m->algString[i++] = PieceChar;
+ if (useFile)
+ m->algString[i++] = 'a' + m->fromFile;
+ if (useRank)
+ m->algString[i++] = '1' + m->fromRank;
+ if (m->pieceCaptured != 0)
+ m->algString[i++] = 'x';
+ m->algString[i++] = 'a' + m->toFile;
+ m->algString[i++] = '1' + m->toRank;
+ m->algString[i] = '\0';
+ }
+ }
+ if (m->algString[0] != 'O')
+ sprintf(m->moveString, "%c/%c%d-%c%d", PieceChar, 'a' + m->fromFile,
+ m->fromRank + 1, 'a' + m->toFile, m->toRank + 1);
+ if (check)
+ strcat(m->algString, "+");
+}
+
+static int ReadV1Moves(struct game *g, FILE * fp)
+{
+ int i;
+
+ g->moveListSize = g->numHalfMoves;
+ g->moveList = (struct move_t *) malloc(sizeof(struct move_t) * g->moveListSize);
+ for (i = 0; i < g->numHalfMoves; i++) {
+ ReadOneV1Move(fp, &g->moveList[i]);
+ }
+ return 0;
+}
+
+static int ReadV1GameFmt(struct game *g, FILE * fp, int version)
+{
+ char* FEN;
+ char tmp[MAX_STRING_LENGTH];
+ unsigned result;
+
+ fscanf(fp, "%s %s", g->white_name, g->black_name);
+ fscanf(fp, "%d %d", &g->white_rating, &g->black_rating);
+ fscanf(fp, "%d %d %d %d", &g->wInitTime, &g->wIncrement,
+ &g->bInitTime, &g->bIncrement);
+ if ((version < 3) && (!(g->bInitTime)))
+ g->bInitTime = g->wInitTime;
+ /*PRE-V3 assumed bInitTime was 0 if balanced clocks*/
+ fscanf(fp, "%lx", &g->timeOfStart);
+ fscanf(fp, "%d %d", &g->wTime, &g->bTime);
+
+/* fixing an (apparently) old bug: winner not saved */
+ if (version > 1)
+ fscanf(fp, "%d %d", &result, &g->winner);
+ else
+ fscanf(fp, "%d", &result);
+
+ g->result = (enum gameend)result;
+
+ fscanf(fp, "%d %d %d %d", &g->private, (int *) &g->type,
+ &g->rated, &g->clockStopped);
+ fscanf(fp, "%d", &g->numHalfMoves);
+ ReadV1Moves(g, fp);
+
+ if (version >= 4) {
+ getc(fp); /* Skip past a newline. */
+
+ fgets(tmp, MAX_LINE_SIZE, fp);
+ tmp [strlen(tmp)-1] = '\0'; /* kill the newline char */
+
+ if ((tmp[0] == '\0') || (!strcmp(tmp,"d w"))) {
+ /* default position */
+ strcpy (g->FENstartPos,INITIAL_FEN);
+ } else {
+ if (!strcmp(tmp,"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR"))
+ /* missing colour for default pos 1.7.1 bug */
+ strcpy(g->FENstartPos,INITIAL_FEN);
+ else {
+ strcpy (g->FENstartPos,tmp);
+ FEN = g->FENstartPos;
+ while (*(FEN) != '/') { /* check for missing fen pos (1.7.1 bug) */
+ if (*(FEN++) == '\0') {
+ d_printf("Corrupt game %s vs %s!\n",g->white_name,g->black_name);
+ return -1;
+ }
+ }
+ }
+ }
+ } else
+ getc(fp); /* Skip past a newline. */
+
+ if (g->status != GAME_EXAMINE && g->status != GAME_SETUP) {
+ if (ReadGameState(fp, &g->game_state, version)) {
+ d_printf( "CHESSD: Trouble reading game state\n");
+ return -1;
+ }
+ } else if (g->status == GAME_EXAMINE)
+ FEN_to_board(g->FENstartPos, &g->game_state);
+ return 0;
+}
+
+
+int ReadGameAttrs_old(FILE * fp, int g,int version)
+{
+ int len;
+ char *attr, *value;
+ char line[MAX_GLINE_SIZE];
+
+ if (version > 0) {
+ if ((ReadV1GameFmt(&game_globals.garray[g], fp, version)) < 0)
+ return -1;
+ }
+ /* Read the game file here */
+ else
+ do {
+ if ((len = strlen(line)) <= 1) {
+ fgets(line, MAX_GLINE_SIZE - 1, fp);
+ continue;
+ }
+ line[len - 1] = '\0';
+ attr = eatwhite(line);
+ if (attr[0] == '#')
+ continue; /* Comment */
+ value = eatword(attr);
+ if (!*value) {
+ d_printf( "CHESSD: Error reading file\n");
+ fgets(line, MAX_GLINE_SIZE - 1, fp);
+ continue;
+ }
+ *value = '\0';
+ value++;
+ value = eatwhite(value);
+ if (!*value) {
+ d_printf( "CHESSD: Error reading file\n");
+ fgets(line, MAX_GLINE_SIZE - 1, fp);
+ continue;
+ }
+ stolower(attr);
+ if (got_attr_value(g, attr, value, fp)) {
+ return -1;
+ }
+ fgets(line, MAX_GLINE_SIZE - 1, fp);
+ } while (!feof(fp));
+ if (!(game_globals.garray[g].bInitTime))
+ game_globals.garray[g].bInitTime = game_globals.garray[g].wInitTime;
+
+ return 0;
+}
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+#include "includes.h"
+
+/*Let users know that someone is available (format the message)*/
+static void getavailmess(int p, char* message)
+{
+ struct player *pp = &player_globals.parray[p];
+ char titles[100];
+
+ titles [0]='\0';
+ AddPlayerLists(p,titles);
+ sprintf (message,"%s%s Blitz (%s), Std (%s), Wild (%s), Light(%s), Bug(%s)\n"
+ " is now available for matches.",
+ pp->name, titles,
+ ratstrii(pp->b_stats.rating, p),
+ ratstrii(pp->s_stats.rating, p),
+ ratstrii(pp->w_stats.rating, p),
+ ratstrii(pp->l_stats.rating, p),
+ ratstrii(pp->bug_stats.rating, p));
+}
+
+void getnotavailmess(int p, char* message)
+{
+ struct player *pp = &player_globals.parray[p];
+ char titles[100];
+
+ titles[0]='\0';
+ AddPlayerLists(p,titles);
+ sprintf (message,"%s%s is no longer available for matches.",
+ pp->name, titles);
+}
+
+void announce_avail(int p)
+{
+ struct player *pp = &player_globals.parray[p];
+ char avail[200];
+ int p1;
+ if ((pp->game < 0) && (CheckPFlag(p, PFLAG_OPEN))) {
+ getavailmess (p,avail);
+
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (p == p1)
+ continue;
+ if (player_globals.parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (CheckPFlag(p1, PFLAG_AVAIL) && CheckPFlag(p1, PFLAG_OPEN)
+ && (player_globals.parray[p1].game < 0))
+ if (((pp->b_stats.rating <= player_globals.parray[p1].availmax) && (pp->b_stats.rating >= player_globals.parray[p1].availmin)) || (!player_globals.parray[p1].availmax))
+ pprintf_prompt (p1,"\n%s\n",avail);
+ }
+ }
+}
+
+void announce_notavail(int p)
+{
+ struct player *pp = &player_globals.parray[p];
+ char avail[200];
+ int p1;
+
+ getnotavailmess (p,avail);
+
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (p == p1)
+ continue;
+ if (player_globals.parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (CheckPFlag(p1, PFLAG_AVAIL) && CheckPFlag(p1, PFLAG_OPEN)
+ && (player_globals.parray[p1].game < 0))
+ if (((pp->b_stats.rating <= player_globals.parray[p1].availmax) && (pp->b_stats.rating >= player_globals.parray[p1].availmin)) || (!player_globals.parray[p1].availmax))
+ pprintf_prompt (p1,"\n%s\n",avail);
+ }
+}
+
+void game_ended(int g, int winner, int why)
+{
+ struct game *gg = &game_globals.garray[g];
+ char outstr[200];
+ char avail_black[200]; /* for announcing white/black avail */
+ char avail_white[200];
+ char avail_bugwhite[200];
+ char avail_bugblack[200];
+ char tmp[200];
+ int p;
+ int gl = gg->link;
+ int rate_change = 0;
+ int isDraw = 0;
+ int whiteResult;
+ char winSymbol[10];
+ char EndSymbol[10];
+ char *NameOfWinner, *NameOfLoser;
+ int beingplayed = 0; /* i.e. it wasn't loaded for adjudication */
+ int print_avail = 0;
+
+ avail_white[0] = '\0';
+ avail_black[0] = '\0';
+ avail_bugwhite[0] = '\0';
+ avail_bugblack[0] = '\0';
+
+ beingplayed = (player_globals.parray[gg->black].game == g);
+
+ sprintf(outstr, "\n{Game %d (%s vs. %s) ", g + 1,
+ player_globals.parray[gg->white].name,
+ player_globals.parray[gg->black].name);
+ gg->result = why;
+ gg->winner = winner;
+ if (winner == WHITE) {
+ whiteResult = RESULT_WIN;
+ strcpy(winSymbol, "1-0");
+ NameOfWinner = player_globals.parray[gg->white].name;
+ NameOfLoser = player_globals.parray[gg->black].name;
+ } else {
+ whiteResult = RESULT_LOSS;
+ strcpy(winSymbol, "0-1");
+ NameOfWinner = player_globals.parray[gg->black].name;
+ NameOfLoser = player_globals.parray[gg->white].name;
+ }
+ switch (why) {
+ case END_CHECKMATE:
+ sprintf(tmp, "%s checkmated} %s", NameOfLoser, winSymbol);
+ strcpy(EndSymbol, "Mat");
+ rate_change = 1;
+ break;
+ case END_RESIGN:
+ sprintf(tmp, "%s resigns} %s", NameOfLoser, winSymbol);
+ strcpy(EndSymbol, "Res");
+ rate_change = 1;
+ break;
+ case END_FLAG:
+ sprintf(tmp, "%s forfeits on time} %s", NameOfLoser, winSymbol);
+ strcpy(EndSymbol, "Fla");
+ rate_change = 1;
+ break;
+ case END_STALEMATE:
+ sprintf(tmp, "Game drawn by stalemate} 1/2-1/2");
+ isDraw = 1;
+ strcpy(EndSymbol, "Sta");
+ rate_change = 1;
+ whiteResult = RESULT_DRAW;
+ break;
+ case END_AGREEDDRAW:
+ sprintf(tmp, "Game drawn by mutual agreement} 1/2-1/2");
+ isDraw = 1;
+ strcpy(EndSymbol, "Agr");
+ rate_change = 1;
+ whiteResult = RESULT_DRAW;
+ break;
+ case END_BOTHFLAG:
+ sprintf(tmp, "Game drawn because both players ran out of time} 1/2-1/2");
+ isDraw = 1;
+ strcpy(EndSymbol, "Fla");
+ rate_change = 1;
+ whiteResult = RESULT_DRAW;
+ break;
+ case END_REPETITION:
+ sprintf(tmp, "Game drawn by repetition} 1/2-1/2");
+ isDraw = 1;
+ strcpy(EndSymbol, "Rep");
+ rate_change = 1;
+ whiteResult = RESULT_DRAW;
+ break;
+ case END_50MOVERULE:
+ sprintf(tmp, "Game drawn by the 50 move rule} 1/2-1/2");
+ isDraw = 1;
+ strcpy(EndSymbol, "50");
+ rate_change = 1;
+ whiteResult = RESULT_DRAW;
+ break;
+ case END_ADJOURN:
+ if (gl >= 0) {
+ sprintf(tmp, "Bughouse game aborted.} *");
+ whiteResult = RESULT_ABORT;
+ } else {
+ sprintf(tmp, "Game adjourned by mutual agreement} *");
+ game_save(g);
+ }
+ break;
+ case END_LOSTCONNECTION:
+ sprintf(tmp, "%s lost connection; game ", NameOfWinner);
+ if (CheckPFlag(gg->white, PFLAG_REG)
+ && CheckPFlag(gg->black, PFLAG_REG)
+ && gl < 0) {
+ sprintf(tmp, "adjourned} *");
+ game_save(g);
+ } else
+ sprintf(tmp, "aborted} *");
+ whiteResult = RESULT_ABORT;
+ break;
+ case END_ABORT:
+ sprintf(tmp, "Game aborted by mutual agreement} *");
+ whiteResult = RESULT_ABORT;
+ break;
+ case END_COURTESY:
+ sprintf(tmp, "Game courtesyaborted by %s} *", NameOfWinner);
+ whiteResult = RESULT_ABORT;
+ break;
+ case END_COURTESYADJOURN:
+ if (gl >= 0) {
+ sprintf(tmp, "Bughouse game courtesyaborted by %s.} *", NameOfWinner);
+ whiteResult = RESULT_ABORT;
+ } else {
+ sprintf(tmp, "Game courtesyadjourned by %s} *", NameOfWinner);
+ game_save(g);
+ }
+ break;
+ case END_NOMATERIAL:
+ /* Draw by insufficient material (e.g., lone K vs. lone K) */
+ sprintf(tmp, "Neither player has mating material} 1/2-1/2");
+ isDraw = 1;
+ strcpy(EndSymbol, "NM ");
+ rate_change = 1;
+ whiteResult = RESULT_DRAW;
+ break;
+ case END_FLAGNOMATERIAL:
+ sprintf(tmp, "%s ran out of time and %s has no material to mate} 1/2-1/2",
+ NameOfLoser, NameOfWinner);
+ isDraw = 1;
+ strcpy(EndSymbol, "TM ");
+ rate_change = 1;
+ whiteResult = RESULT_DRAW;
+ break;
+ case END_ADJWIN:
+ sprintf(tmp, "%s wins by adjudication} %s", NameOfWinner, winSymbol);
+ strcpy(EndSymbol, "Adj");
+ rate_change = 1;
+ break;
+ case END_ADJDRAW:
+ sprintf(tmp, "Game drawn by adjudication} 1/2-1/2");
+ isDraw = 1;
+ strcpy(EndSymbol, "Adj");
+ rate_change = 1;
+ whiteResult = RESULT_DRAW;
+ break;
+ case END_ADJABORT:
+ sprintf(tmp, "Game aborted by adjudication} *");
+ whiteResult = RESULT_ABORT;
+ break;
+ default:
+ sprintf(tmp, "Hmm, the game ended and I don't know why} *");
+ break;
+ }
+ strcat(outstr, tmp);
+
+ if (CheckPFlag(gg->white, PFLAG_TOURNEY) &&
+ CheckPFlag(gg->black, PFLAG_TOURNEY)) {
+ /* mamer wants more info */
+ sprintf(tmp," [%d %d %d %d %d]",
+ gg->wInitTime/(60*10), gg->wIncrement/10, gg->rated, gg->private, (int)gg->type);
+ strcat(outstr, tmp);
+ }
+
+ strcat(outstr, "\n");
+
+ if (gg->rated && rate_change && gg->type != TYPE_BUGHOUSE)
+ /* Adjust ratings; bughouse gets done later. */
+ rating_update(g, -1);
+
+ if (beingplayed) {
+ int printed = 0;
+ int avail_printed = 0;
+
+ pprintf_noformat(gg->white, outstr);
+ pprintf_noformat(gg->black, outstr);
+ Bell (gg->white);
+ Bell (gg->black);
+
+ gg->link = -1; /*IanO: avoids recursion */
+ if (gl >= 0 && game_globals.garray[gl].link >= 0) {
+ pprintf_noformat(game_globals.garray[gl].white, outstr);
+ pprintf_noformat(game_globals.garray[gl].black, outstr);
+ if (CheckPFlag(game_globals.garray[gl].white, PFLAG_OPEN)) {
+ getavailmess (game_globals.garray[gl].white, avail_bugwhite);
+ print_avail = 1;
+ }
+ if (CheckPFlag(game_globals.garray[gl].black, PFLAG_OPEN)) {
+ getavailmess (game_globals.garray[gl].black, avail_bugblack);
+ print_avail = 1;
+ }
+ if ((gg->rated) && (rate_change)) {
+ /* Adjust ratings */
+ rating_update(g, gl);
+ }
+ game_ended(gl, CToggle(winner), why);
+ }
+
+ if ((player_num_active_boards(gg->white) <= 1) /* not a simul or */
+ && CheckPFlag(gg->white, PFLAG_OPEN)) { /* simul is over? */
+ getavailmess (gg->white,avail_white);
+ print_avail = 1;
+ } else { /* Part of an ongoing simul! Let's shrink the array. */
+
+ }
+
+ if (CheckPFlag(gg->black, PFLAG_OPEN)) {
+ getavailmess (gg->black,avail_black);
+ print_avail = 1;
+ }
+
+ for (p = 0; p < player_globals.p_num; p++) {
+ struct player *pp = &player_globals.parray[p];
+ if ((p == gg->white) || (p == gg->black))
+ continue;
+ if (pp->status != PLAYER_PROMPT)
+ continue;
+
+ if (CheckPFlag(p, PFLAG_GIN) || player_is_observe(p, g)) {
+ pprintf_noformat(p, outstr);
+ printed = 1;
+ }
+
+ if (CheckPFlag(p, PFLAG_AVAIL) && (CheckPFlag(p, PFLAG_OPEN)) && (pp->game < 0) && (print_avail)) {
+ if (((player_globals.parray[gg->white].b_stats.rating <= pp->availmax) && (player_globals.parray[gg->white].b_stats.rating >= pp->availmin)) || (!pp->availmax)) {
+ pprintf (p,"\n%s",avail_white);
+ avail_printed = 1;
+ }
+ if (((player_globals.parray[gg->black].b_stats.rating <= pp->availmax) && (player_globals.parray[gg->black].b_stats.rating >= pp->availmin)) || (!pp->availmax)) {
+ pprintf (p,"\n%s",avail_black);
+ avail_printed = 1;
+ }
+ if (gl != -1) /* bughouse ? */ {
+ if (((player_globals.parray[game_globals.garray[gl].white].b_stats.rating <= pp->availmax) && (player_globals.parray[game_globals.garray[gl].white].b_stats.rating >= pp->availmin)) || (!pp->availmax)) {
+ pprintf (p,"\n%s",avail_bugwhite);
+ avail_printed = 1;
+ }
+ if (((player_globals.parray[game_globals.garray[gl].black].b_stats.rating <= pp->availmax) && (player_globals.parray[game_globals.garray[gl].black].b_stats.rating >= pp->availmin)) || (!pp->availmax)) {
+ pprintf (p,"\n%s",avail_bugblack);
+ avail_printed = 1;
+ }
+ }
+ if (avail_printed) {
+ avail_printed = 0;
+ printed = 1;
+ pprintf (p,"\n");
+ }
+ }
+
+ if (printed) {
+ send_prompt(p);
+ printed = 0;
+ }
+ }
+
+ if (!(gg->rated && rate_change)) {
+ pprintf(gg->white, "No ratings adjustment done.\n");
+ pprintf(gg->black, "No ratings adjustment done.\n");
+ }
+ }
+
+ if (rate_change && gl < 0)
+ game_write_complete(g, isDraw, EndSymbol);
+ /* Mail off the moves */
+ if (CheckPFlag(gg->white, PFLAG_AUTOMAIL)) {
+ pcommand(gg->white, "mailmoves");
+ }
+ if (CheckPFlag(gg->black, PFLAG_AUTOMAIL)) {
+ pcommand(gg->black, "mailmoves");
+ }
+ if (!((player_globals.parray[gg->white].simul_info != NULL) &&
+ (player_globals.parray[gg->white].simul_info->numBoards))) {
+ player_globals.parray[gg->white].num_white++;
+ PFlagOFF(gg->white, PFLAG_LASTBLACK);
+ player_globals.parray[gg->black].num_black++;
+ PFlagON(gg->black, PFLAG_LASTBLACK);
+ }
+ player_globals.parray[gg->white].last_opponent =
+ strdup(gg->black_name);
+ player_globals.parray[gg->black].last_opponent =
+ strdup(gg->white_name);
+ if (beingplayed) {
+ player_globals.parray[gg->white].game = -1;
+ player_globals.parray[gg->black].game = -1;
+ player_globals.parray[gg->white].opponent = -1;
+ player_globals.parray[gg->black].opponent = -1;
+ if (gg->white != command_globals.commanding_player)
+ send_prompt(gg->white);
+ if (gg->black != command_globals.commanding_player)
+ send_prompt(gg->black);
+ if ((player_globals.parray[gg->white].simul_info != NULL) &&
+ (player_globals.parray[gg->white].simul_info->numBoards))
+ player_simul_over(gg->white, g, whiteResult);
+ }
+ game_finish(g);
+}
+
+static int was_promoted(struct game *g, int f, int r)
+{
+#define BUGHOUSE_PAWN_REVERT 1
+#ifdef BUGHOUSE_PAWN_REVERT
+ int i;
+
+ for (i = g->numHalfMoves-2; i > 0; i -= 2) {
+ if (g->moveList[i].toFile == f && g->moveList[i].toRank == r) {
+ if (g->moveList[i].piecePromotionTo)
+ return 1;
+ if (g->moveList[i].fromFile == ALG_DROP)
+ return 0;
+ f = g->moveList[i].fromFile;
+ r = g->moveList[i].fromRank;
+ }
+ }
+#endif
+ return 0;
+}
+
+int pIsPlaying (int p)
+{
+ struct player *pp = &player_globals.parray[p];
+ int g = pp->game;
+ int p1 = pp->opponent;
+
+ if (g < 0 || game_globals.garray[g].status != GAME_ACTIVE) {
+ pprintf (p, "You are not playing a game.\n");
+ return 0;
+ }
+
+ if (game_globals.garray[g].white != p && game_globals.garray[g].black != p) {
+ /* oh oh; big bad game bug. */
+ d_printf("BUG: Player %s playing game %d according to player_globals.parray,"
+ "\n but not according to game_globals.garray.\n", pp->name, g+1);
+ pprintf (p, "Disconnecting you from game number %d.\n", g+1);
+ pp->game = -1;
+ if (p1 >= 0 && player_globals.parray[p1].game == g
+ && game_globals.garray[g].white != p1 && game_globals.garray[g].black != p1) {
+ pprintf (p1, "Disconnecting you from game number %d.\n", g+1);
+ player_globals.parray[p1].game = -1;
+ }
+ return 0;
+ }
+ return 1;
+}
+
+/* add clock increments */
+static void game_add_increment(struct player *pp, struct game *gg)
+{
+ /* no update on first move */
+ if (gg->game_state.moveNum == 1) return;
+
+ if (net_globals.con[pp->socket]->timeseal) { /* does he use timeseal? */
+ if (pp->side == WHITE) {
+ gg->wRealTime += gg->wIncrement * 100;
+ gg->wTime = gg->wRealTime / 100; /* remember to conv to
+ tenth secs */
+ } else if (pp->side == BLACK) {
+ gg->bRealTime += gg->bIncrement * 100; /* conv to ms */
+ gg->bTime = gg->bRealTime / 100; /* remember to conv to
+ tenth secs */
+ }
+ } else {
+ if (gg->game_state.onMove == BLACK) {
+ gg->bTime += gg->bIncrement;
+ }
+ if (gg->game_state.onMove == WHITE) {
+ gg->wTime += gg->wIncrement;
+ }
+ }
+}
+
+/* updates clocks for a game with timeseal */
+void timeseal_update_clocks(struct player *pp, struct game *gg)
+{
+ /* no update on first move */
+ if (gg->game_state.moveNum == 1) return;
+
+ if (pp->side == WHITE) {
+ gg->wLastRealTime = gg->wRealTime;
+ gg->wTimeWhenMoved = net_globals.con[pp->socket]->time;
+ if (((gg->wTimeWhenMoved - gg->wTimeWhenReceivedMove) < 0) ||
+ (gg->wTimeWhenReceivedMove == 0)) {
+ /* might seem weird - but could be caused by a person moving BEFORE
+ he receives the board pos (this is possible due to lag) but it's
+ safe to say he moved in 0 secs :-) */
+ gg->wTimeWhenReceivedMove = gg->wTimeWhenMoved;
+ } else {
+ gg->wRealTime -= gg->wTimeWhenMoved - gg->wTimeWhenReceivedMove;
+ }
+ } else if (pp->side == BLACK) {
+ gg->bLastRealTime = gg->bRealTime;
+ gg->bTimeWhenMoved = net_globals.con[pp->socket]->time;
+ if (((gg->bTimeWhenMoved - gg->bTimeWhenReceivedMove) < 0) ||
+ (gg->bTimeWhenReceivedMove == 0)) {
+ /* might seem weird - but could be caused by a person moving BEFORE
+ he receives the board pos (this is possible due to lag) but it's
+ safe to say he moved in 0 secs :-) */
+ gg->bTimeWhenReceivedMove = gg->bTimeWhenMoved;
+ } else {
+ gg->bRealTime -= gg->bTimeWhenMoved - gg->bTimeWhenReceivedMove;
+ }
+ }
+}
+
+
+void process_move(int p, char *command)
+{
+ struct player *pp = &player_globals.parray[p];
+ struct game *gg;
+ int g, result, len, i;
+ struct move_t move;
+ unsigned now = 0;
+
+ if (pp->game < 0) {
+ pprintf(p, "You are not playing or examining a game.\n");
+ return;
+ }
+ decline_withdraw_offers(p, -1, -PEND_SIMUL,DO_DECLINE);
+
+ g = pp->game;
+ gg = &game_globals.garray[g];
+
+ if (gg->status == GAME_SETUP) {
+ if (!attempt_drop(p,g,command)) {
+ pprintf(p, "You are still setting up the position.\n");
+ pprintf(p, "Type: 'setup done' when you are finished editing.\n");
+ } else
+ send_board_to(g, p);
+ return;
+ }
+
+ if (gg->status != GAME_EXAMINE) {
+ if (!pIsPlaying(p)) return;
+
+ if (pp->side != gg->game_state.onMove) {
+ pprintf(p, "It is not your move.\n");
+ return;
+ }
+ if (gg->clockStopped) {
+ pprintf(p, "Game clock is paused, use \"unpause\" to resume.\n");
+ return;
+ }
+ }
+ if ((len = strlen(command)) > 1) {
+ if (command[len - 2] == '=') {
+ switch (tolower(command[strlen(command) - 1])) {
+ case 'n':
+ pp->promote = KNIGHT;
+ break;
+ case 'b':
+ pp->promote = BISHOP;
+ break;
+ case 'r':
+ pp->promote = ROOK;
+ break;
+ case 'q':
+ pp->promote = QUEEN;
+ break;
+ default:
+ pprintf(p, "Don't understand that move.\n");
+ return;
+ break;
+ }
+ }
+ }
+ switch (parse_move(command, &gg->game_state, &move, pp->promote)) {
+ case MOVE_ILLEGAL:
+ pprintf(p, "Illegal move.\n");
+ return;
+ break;
+ case MOVE_AMBIGUOUS:
+ pprintf(p, "Ambiguous move.\n");
+ return;
+ break;
+ default:
+ break;
+ }
+
+ if (gg->status == GAME_EXAMINE) {
+ gg->numHalfMoves++;
+ if (gg->numHalfMoves > gg->examMoveListSize) {
+ gg->examMoveListSize += 20; /* Allocate 20 moves at a time */
+ gg->examMoveList = (struct move_t *) realloc(gg->examMoveList, sizeof(struct move_t) * gg->examMoveListSize);
+ }
+ result = execute_move(&gg->game_state, &move, 1);
+ move.atTime = now;
+ move.tookTime = 0;
+ MakeFENpos(g, move.FENpos);
+ gg->examMoveList[gg->numHalfMoves - 1] = move;
+ /* roll back time */
+ if (gg->game_state.onMove == WHITE) {
+ gg->wTime += (gg->lastDecTime - gg->lastMoveTime);
+ } else {
+ gg->bTime += (gg->lastDecTime - gg->lastMoveTime);
+ }
+ now = tenth_secs();
+ if (gg->numHalfMoves == 0)
+ gg->timeOfStart = now;
+ gg->lastMoveTime = now;
+ gg->lastDecTime = now;
+
+ } else { /* real game */
+ i = pp->opponent;
+ if ((player_globals.parray[i].simul_info != NULL) && (player_globals.parray[i].simul_info->numBoards &&
+ (player_globals.parray[i].simul_info->boards[player_globals.parray[i].simul_info->onBoard] != g))) {
+ pprintf(p, "It isn't your turn: wait until the simul giver is at your board.\n");
+ return;
+ }
+ if (net_globals.con[pp->socket]->timeseal) { /* does he use timeseal? */
+ timeseal_update_clocks(pp, &game_globals.garray[g]);
+ }
+ /* we need to reset the opp's time for receiving the board since the
+ timeseal decoder only alters the time if it's 0 Otherwise the time
+ would be changed if the player did a refresh which would screw up
+ the timings */
+ if (pp->side == WHITE) {
+ gg->bTimeWhenReceivedMove = 0;
+ } else {
+ gg->wTimeWhenReceivedMove = 0;
+ }
+
+ game_update_time(g);
+ game_add_increment(pp, gg);
+
+ /* Do the move */
+ gg->numHalfMoves++;
+ if (gg->numHalfMoves > gg->moveListSize) {
+ gg->moveListSize += 20; /* Allocate 20 moves at a time */
+ gg->moveList = (struct move_t *) realloc(gg->moveList, sizeof(struct move_t) * gg->moveListSize);
+ }
+ result = execute_move(&gg->game_state, &move, 1);
+ if (result == MOVE_OK && gg->link >= 0 && move.pieceCaptured != NOPIECE) {
+ /* transfer captured piece to partner */
+ /* check if piece reverts to a pawn */
+ if (was_promoted(&game_globals.garray[g], move.toFile, move.toRank))
+ update_holding(gg->link, colorval(move.pieceCaptured) | PAWN);
+ else
+ update_holding(gg->link, move.pieceCaptured);
+ }
+ now = tenth_secs();
+ move.atTime = now;
+ if (gg->numHalfMoves > 1) {
+ move.tookTime = move.atTime - gg->lastMoveTime;
+ } else {
+ move.tookTime = move.atTime - gg->startTime;
+ }
+ gg->lastMoveTime = now;
+ gg->lastDecTime = now;
+ move.wTime = gg->wTime;
+ move.bTime = gg->bTime;
+
+ if (net_globals.con[pp->socket]->timeseal) { /* does he use timeseal? */
+ if (pp->side == WHITE) {
+ move.tookTime = (game_globals.garray[pp->game].wTimeWhenMoved -
+ game_globals.garray[pp->game].wTimeWhenReceivedMove) / 100;
+ } else {
+ move.tookTime = (game_globals.garray[pp->game].bTimeWhenMoved -
+ game_globals.garray[pp->game].bTimeWhenReceivedMove) / 100;
+ }
+ }
+
+ if (gg->numHalfMoves <= 2) {
+ move.tookTime = 0;
+ }
+
+ MakeFENpos(g, move.FENpos);
+ gg->moveList[gg->numHalfMoves - 1] = move;
+ }
+
+ send_boards(g);
+
+ if (result == MOVE_ILLEGAL) {
+ pprintf(p, "Internal error, illegal move accepted!\n");
+ }
+ if ((result == MOVE_OK) && (gg->status == GAME_EXAMINE)) {
+ int p1;
+
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (player_globals.parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || player_globals.parray[p1].game == g) {
+ pprintf(p1, "%s moves: %s\n", pp->name, move.algString);
+ }
+ }
+ }
+ if (result == MOVE_CHECKMATE) {
+ if (gg->status == GAME_EXAMINE) {
+ int p1;
+
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (player_globals.parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || player_globals.parray[p1].game == g) {
+ pprintf(p1, "%s has been checkmated.\n",
+ (CToggle(gg->game_state.onMove) == BLACK) ? "White" : "Black");
+ }
+ }
+ } else {
+ game_ended(g, CToggle(gg->game_state.onMove), END_CHECKMATE);
+ }
+ }
+ if (result == MOVE_STALEMATE) {
+ if (gg->status == GAME_EXAMINE) {
+ int p1;
+
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (player_globals.parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || player_globals.parray[p1].game == g) {
+ pprintf(p1, "Stalemate.\n");
+ }
+ }
+ } else {
+ game_ended(g, CToggle(gg->game_state.onMove), END_STALEMATE);
+ }
+ }
+ if (result == MOVE_NOMATERIAL) {
+ if (gg->status == GAME_EXAMINE) {
+ int p1;
+
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (player_globals.parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || player_globals.parray[p1].game == g) {
+ pprintf(p1, "No mating material.\n");
+ }
+ }
+ } else {
+ game_ended(g, CToggle(gg->game_state.onMove), END_NOMATERIAL);
+ }
+ }
+}
+
+int com_resign(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int g, o, oconnected;
+
+ if (param[0].type == TYPE_NULL) {
+ g = pp->game;
+ if (!pIsPlaying(p))
+ return COM_OK;
+ else {
+ decline_withdraw_offers(p, -1, -1, DO_DECLINE);
+ game_ended(g, (game_globals.garray[g].white == p) ? BLACK : WHITE, END_RESIGN);
+ }
+ } else if (FindPlayer(p, param[0].val.word, &o, &oconnected)) {
+ g = game_new();
+ if (game_read(g, p, o) < 0) {
+ if (game_read(g, o, p) < 0) {
+ pprintf(p, "You have no stored game with %s\n", player_globals.parray[o].name);
+ if (!oconnected)
+ player_remove(o);
+ return COM_OK;
+ } else {
+ game_globals.garray[g].white = o;
+ game_globals.garray[g].black = p;
+ }
+ } else {
+ game_globals.garray[g].white = p;
+ game_globals.garray[g].black = o;
+ }
+ pprintf(p, "You resign your stored game with %s\n", player_globals.parray[o].name);
+ pcommand(p, "message %s I have resigned our stored game \"%s vs. %s.\"",
+ player_globals.parray[o].name,
+ player_globals.parray[game_globals.garray[g].white].name,
+ player_globals.parray[game_globals.garray[g].black].name);
+ game_delete(game_globals.garray[g].white, game_globals.garray[g].black);
+ game_ended(g, (game_globals.garray[g].white == p) ? BLACK : WHITE, END_RESIGN);
+ if (!oconnected)
+ player_remove(o);
+ }
+ return COM_OK;
+}
+
+static int Check50MoveRule (int p, int g)
+{
+ int num_reversible = game_globals.garray[g].numHalfMoves;
+
+ if (game_globals.garray[g].game_state.lastIrreversable >= 0) {
+ num_reversible -= game_globals.garray[g].game_state.lastIrreversable;
+ }
+ if (num_reversible > 99) {
+ game_ended(g, (game_globals.garray[g].white == p) ? BLACK : WHITE, END_50MOVERULE);
+ return 1;
+ }
+ return 0;
+}
+
+static char *GetFENpos (int g, int half_move)
+{
+ if (half_move < 0)
+ return game_globals.garray[g].FENstartPos;
+ else return game_globals.garray[g].moveList[half_move].FENpos;
+}
+
+static int CheckRepetition (int p, int g)
+{
+ struct player *pp = &player_globals.parray[p];
+ struct pending* pend;
+ int move_num;
+ int flag1 = 1, flag2 = 1;
+ char *pos1 = GetFENpos (g, game_globals.garray[g].numHalfMoves - 1);
+ char *pos2 = GetFENpos (g, game_globals.garray[g].numHalfMoves);
+ char *pos;
+
+ if (game_globals.garray[g].numHalfMoves < 8) /* can't have three repeats any quicker. */
+ return 0;
+
+ for (move_num = game_globals.garray[g].game_state.lastIrreversable;
+ move_num < game_globals.garray[g].numHalfMoves - 1; move_num++) {
+ pos = GetFENpos (g, move_num);
+ if (strlen(pos1) == strlen(pos) && !strcmp(pos1, pos))
+ flag1++;
+ if (strlen(pos2) == strlen(pos) && !strcmp(pos2, pos))
+ flag2++;
+ }
+ if (flag1 >= 3 || flag2 >= 3) {
+ if ((pend = find_pend(pp->opponent, p, PEND_DRAW)) != NULL) {
+ delete_pending(pend);
+ decline_withdraw_offers(p, -1, -1,DO_DECLINE);
+ }
+ game_ended(g, (game_globals.garray[g].white == p) ? BLACK : WHITE, END_REPETITION);
+ return 1;
+ }
+ else return 0;
+}
+
+int com_draw(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ struct pending* pend;
+ int p1, g = pp->game;
+
+ if (!pIsPlaying(p)) {
+ return COM_OK;
+ }
+ if (Check50MoveRule (p, g) || CheckRepetition(p, g)) {
+ return COM_OK;
+ }
+ p1 = pp->opponent;
+
+ if ((player_globals.parray[p1].simul_info != NULL) && (player_globals.parray[p1].simul_info->numBoards &&
+ player_globals.parray[p1].simul_info->boards[player_globals.parray[p1].simul_info->onBoard] != g)) {
+ pprintf(p, "You can only make requests when the simul player is at your board.\n");
+ return COM_OK;
+ }
+
+ if ((pend = (find_pend(pp->opponent, p, PEND_DRAW))) != NULL) {
+ delete_pending(pend);
+ decline_withdraw_offers(p, -1, -1,DO_DECLINE);
+ game_ended(g, (game_globals.garray[g].white == p) ? BLACK : WHITE, END_AGREEDDRAW);
+ } else {
+ pprintf(pp->opponent, "\n");
+ pprintf_highlight(pp->opponent, "%s", pp->name);
+ pprintf_prompt(pp->opponent, " offers you a draw.\n");
+ pprintf(p, "Draw request sent.\n");
+ add_request(p, pp->opponent, PEND_DRAW);
+ }
+ return COM_OK;
+}
+
+int com_pause(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int g, now;
+ struct pending* pend;
+
+ if (!pIsPlaying(p)) {
+ return COM_OK;
+ }
+ g = pp->game;
+ if (game_globals.garray[g].wTime == 0) {
+ pprintf(p, "You can't pause untimed games.\n");
+ return COM_OK;
+ }
+ if (game_globals.garray[g].clockStopped) {
+ pprintf(p, "Game is already paused, use \"unpause\" to resume.\n");
+ return COM_OK;
+ }
+ if ((pend = find_pend(pp->opponent, p, PEND_PAUSE)) != NULL) {
+ delete_pending(pend);
+ game_globals.garray[g].clockStopped = 1;
+ /* Roll back the time */
+ if (game_globals.garray[g].game_state.onMove == WHITE) {
+ game_globals.garray[g].wTime += (game_globals.garray[g].lastDecTime - game_globals.garray[g].lastMoveTime);
+ } else {
+ game_globals.garray[g].bTime += (game_globals.garray[g].lastDecTime - game_globals.garray[g].lastMoveTime);
+ }
+ now = tenth_secs();
+ if (game_globals.garray[g].numHalfMoves == 0)
+ game_globals.garray[g].timeOfStart = now;
+ game_globals.garray[g].lastMoveTime = now;
+ game_globals.garray[g].lastDecTime = now;
+ send_boards(g);
+ pprintf_prompt(pp->opponent, "\n%s accepted pause. Game clock paused.\n",
+ pp->name);
+ pprintf(p, "Game clock paused.\n");
+ } else {
+ pprintf(pp->opponent, "\n");
+ pprintf_highlight(pp->opponent, "%s", pp->name);
+ pprintf_prompt(pp->opponent, " requests to pause the game.\n");
+ pprintf(p, "Pause request sent.\n");
+ add_request(p, pp->opponent, PEND_PAUSE);
+ }
+ return COM_OK;
+}
+
+int com_unpause(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int g;
+ int now;
+ struct pending* pend;
+
+ if (!pIsPlaying(p)) {
+ return COM_OK;
+ }
+
+ g = pp->game;
+
+ if (!game_globals.garray[g].clockStopped) {
+ pprintf(p, "Game is not paused.\n");
+ return COM_OK;
+ }
+ if ((pend = find_pend(pp->opponent, p, PEND_UNPAUSE)) != NULL) {
+ delete_pending(pend);
+ game_globals.garray[g].clockStopped = 0;
+ now = tenth_secs();
+ if (game_globals.garray[g].numHalfMoves == 0)
+ game_globals.garray[g].timeOfStart = now;
+ game_globals.garray[g].lastMoveTime = now;
+ game_globals.garray[g].lastDecTime = now;
+ send_boards(g);
+ pprintf(p, "Game clock resumed.\n");
+ pprintf_prompt(pp->opponent, "\nGame clock resumed.\n");
+ } else {
+ pprintf(pp->opponent, "\n");
+ pprintf_highlight(pp->opponent, "%s", pp->name);
+ pprintf_prompt(pp->opponent, " requests to unpause the game.\n");
+ pprintf(p, "Unpause request sent.\n");
+ add_request(p, pp->opponent, PEND_UNPAUSE);
+ }
+ return COM_OK;
+}
+
+int com_abort(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ struct pending* pend;
+ int p1, g, myColor, yourColor, myGTime, yourGTime;
+ int courtesyOK = 1;
+
+ g = pp->game;
+ if (!pIsPlaying(p))
+ return COM_OK;
+
+ p1 = pp->opponent;
+ if (p == game_globals.garray[g].white) {
+ myColor = WHITE;
+ yourColor = BLACK;
+ myGTime = game_globals.garray[g].wTime;
+ yourGTime = game_globals.garray[g].bTime;
+ } else {
+ myColor = BLACK;
+ yourColor = WHITE;
+ myGTime = game_globals.garray[g].bTime;
+ yourGTime = game_globals.garray[g].wTime;
+ }
+ if ((player_globals.parray[p1].simul_info != NULL) &&
+ (player_globals.parray[p1].simul_info->numBoards &&
+ player_globals.parray[p1].simul_info->boards[player_globals.parray[p1].simul_info->onBoard] != g)) {
+ pprintf(p, "You can only make requests when the simul player is at your board.\n");
+ return COM_OK;
+ }
+ if ((pend = find_pend(p1, p, PEND_ABORT)) != NULL) {
+ delete_pending(pend);
+ decline_withdraw_offers(p, -1, -1,DO_DECLINE);
+ game_ended(g, yourColor, END_ABORT);
+ } else {
+ game_update_time(g);
+
+ if (net_globals.con[pp->socket]->timeseal
+ && game_globals.garray[g].game_state.onMove == myColor
+ && game_globals.garray[g].flag_pending == FLAG_ABORT) {
+ /* It's my move, opponent has asked for abort; I lagged out,
+ my timeseal prevented courtesyabort, and I am sending an abort
+ request before acknowledging (and processing) my opponent's
+ courtesyabort. OK, let's abort already :-). */
+ decline_withdraw_offers(p, -1, -1,DO_DECLINE);
+ game_ended(g, yourColor, END_ABORT);
+ }
+
+ if (net_globals.con[player_globals.parray[p1].socket]->timeseal) { /* opp uses timeseal? */
+
+ int yourRealTime = (myColor == WHITE ? game_globals.garray[g].bRealTime
+ : game_globals.garray[g].wRealTime);
+ if (myGTime > 0 && yourGTime <= 0 && yourRealTime > 0) {
+ /* Override courtesyabort; opponent still has time. Check for lag. */
+ courtesyOK = 0;
+
+ if (game_globals.garray[g].game_state.onMove != myColor
+ && game_globals.garray[g].flag_pending != FLAG_CHECKING) {
+ /* Opponent may be lagging; let's ask. */
+ game_globals.garray[g].flag_pending = FLAG_ABORT;
+ game_globals.garray[g].flag_check_time = time(0);
+ pprintf(p, "Opponent has timeseal; trying to courtesyabort.\n");
+ pprintf(p1, "\n[G]\n");
+ return COM_OK;
+ }
+ }
+ }
+
+ if (myGTime > 0 && yourGTime <= 0 && courtesyOK) {
+ /* player wants to abort + opponent is out of time = courtesyabort */
+ pprintf(p, "Since you have time, and your opponent has none, the game has been aborted.");
+ pprintf(p1, "Your opponent has aborted the game rather than calling your flag.");
+ decline_withdraw_offers(p, -1, -1, DO_DECLINE);
+ game_ended(g, myColor, END_COURTESY);
+ } else {
+ pprintf(p1, "\n");
+ pprintf_highlight(p1, "%s", pp->name);
+ pprintf(p1, " would like to abort the game; ");
+ pprintf_prompt(p1, "type \"abort\" to accept.\n");
+ pprintf(p, "Abort request sent.\n");
+ add_request(p, p1, PEND_ABORT);
+ }
+ }
+ return COM_OK;
+}
+
+static int player_has_mating_material(struct game_state_t *gs, int color)
+{
+ int i, j;
+ int piece;
+ int minor_pieces = 0;
+
+ for (i = 0; i < 8; i++)
+ for (j = 0; j < 8; j++) {
+ piece = gs->board[i][j];
+ switch (piecetype(piece)) {
+ case BISHOP:
+ case KNIGHT:
+ if (iscolor(piece, color))
+ minor_pieces++;
+ break;
+ case KING:
+ case NOPIECE:
+ break;
+ default:
+ if (iscolor(piece, color))
+ return 1;
+ }
+ }
+ return ((minor_pieces > 1) ? 1 : 0);
+}
+
+int com_flag(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ struct game *gg;
+ int g;
+ int myColor;
+
+ if (!pIsPlaying(p)) {
+ return COM_OK;
+ }
+ g = pp->game;
+
+ gg = &game_globals.garray[g];
+
+ myColor = (p == gg->white ? WHITE : BLACK);
+ if (gg->type == TYPE_UNTIMED) {
+ pprintf(p, "You can't flag an untimed game.\n");
+ return COM_OK;
+ }
+ if (gg->numHalfMoves < 2) {
+ pprintf(p, "You cannot flag before both players have moved.\nUse abort instead.\n");
+ return COM_OK;
+ }
+ game_update_time(g);
+
+ {
+ int myTime, yourTime, opp = pp->opponent, serverTime;
+
+ if (net_globals.con[pp->socket]->timeseal) { /* does caller use timeseal? */
+ myTime = (myColor==WHITE?gg->wRealTime:gg->bRealTime);
+ } else {
+ myTime = (myColor == WHITE?gg->wTime:gg->bTime);
+ }
+ serverTime = (myColor == WHITE?gg->bTime:gg->wTime);
+
+ if (net_globals.con[player_globals.parray[opp].socket]->timeseal) { /* opp uses timeseal? */
+ yourTime = (myColor == WHITE?gg->bRealTime:gg->wRealTime);
+ } else {
+ yourTime = serverTime;
+ }
+
+ /* the clocks to compare are now in myTime and yourTime */
+ if ((myTime <= 0) && (yourTime <= 0)) {
+ decline_withdraw_offers(p, -1, -1,DO_DECLINE);
+ game_ended(g, myColor, END_BOTHFLAG);
+ return COM_OK;
+ }
+
+ if (yourTime > 0) {
+ /* Opponent still has time, but if that's only because s/he
+ * may be lagging, we should ask for an acknowledgement and then
+ * try to call the flag. */
+
+ if (serverTime <= 0 && gg->game_state.onMove != myColor
+ && gg->flag_pending != FLAG_CHECKING) {
+ /* server time thinks opponent is down, but RealTIme disagrees.
+ * ask client to acknowledge it's alive. */
+ gg->flag_pending = FLAG_CALLED;
+ gg->flag_check_time = time(0);
+ pprintf(p, "Opponent has timeseal; checking if (s)he's lagging.\n");
+ pprintf (opp, "\n[G]\n");
+ return COM_OK;
+ }
+
+ /* if we're here, it means one of:
+ * 1. the server agrees opponent has time, whether lagging or not.
+ * 2. opp. has timeseal (if yourTime != serverTime), had time left
+ * after the last move (yourTime > 0), and it's still your move.
+ * 3. we're currently checking a flag call after having receiving
+ * acknowledgement from the other timeseal (and would have reset
+ * yourTime if the flag were down). */
+
+ pprintf(p, "Your opponent is not out of time!\n");
+ return COM_OK;
+ }
+ }
+
+ decline_withdraw_offers(p, -1, -1,DO_DECLINE);
+ if (player_has_mating_material(&gg->game_state, myColor))
+ game_ended(g, myColor, END_FLAG);
+ else
+ game_ended(g, myColor, END_FLAGNOMATERIAL);
+ return COM_OK;
+}
+
+int com_adjourn(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ struct pending* pend;
+ int p1, g, myColor, yourColor;
+
+ if (!pIsPlaying(p))
+ return COM_OK;
+
+ p1 = pp->opponent;
+ g = pp->game;
+ if (!CheckPFlag(p, PFLAG_REG) || !CheckPFlag(p, PFLAG_REG)) {
+ pprintf(p, "Both players must be registered to adjourn a game. Use \"abort\".\n");
+ return COM_OK;
+ }
+ if (game_globals.garray[g].link >= 0) {
+ pprintf(p, "Bughouse games cannot be adjourned.\n");
+ return COM_OK;
+ }
+ myColor = (p == game_globals.garray[g].white ? WHITE : BLACK);
+ yourColor = (myColor == WHITE ? BLACK : WHITE);
+
+ if ((pend = find_pend(p1, p, PEND_ADJOURN)) != NULL) {
+ delete_pending(pend);
+ decline_withdraw_offers(p, -1, -1,DO_DECLINE);
+ game_ended(pp->game, yourColor, END_ADJOURN);
+ } else {
+ game_update_time(g);
+ if (((myColor == WHITE) && (game_globals.garray[g].wTime > 0) && (game_globals.garray[g].bTime <= 0))
+ || ((myColor == BLACK) && (game_globals.garray[g].bTime > 0) && (game_globals.garray[g].wTime <= 0))) {
+/* player wants to adjourn + opponent is out of time = courtesyadjourn */
+ pprintf(p, "Since you have time, and your opponent has none, the game has been adjourned.");
+ pprintf(p1, "Your opponent has adjourned the game rather than calling your flag.");
+ decline_withdraw_offers(p, -1, -1,DO_DECLINE);
+ game_ended(g, myColor, END_COURTESYADJOURN);
+ } else {
+ pprintf(p1, "\n");
+ pprintf_highlight(p1, "%s", pp->name);
+ pprintf(p1, " would like to adjourn the game; ");
+ pprintf_prompt(p1, "type \"adjourn\" to accept.\n");
+ pprintf(p, "Adjourn request sent.\n");
+ add_request(p, p1, PEND_ADJOURN);
+ }
+ }
+ return COM_OK;
+}
+
+int com_takeback(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int nHalfMoves = 1, g, i, p1, pend_half_moves;
+ struct pending* from;
+
+ if (!pIsPlaying(p))
+ return COM_OK;
+
+ p1 = pp->opponent;
+ if ((player_globals.parray[p1].simul_info != NULL) &&
+ (player_globals.parray[p1].simul_info->numBoards &&
+ player_globals.parray[p1].simul_info->boards[player_globals.parray[p1].simul_info->onBoard] !=
+ pp->game)) {
+ pprintf(p, "You can only make requests when the simul player is at your board.\n");
+ return COM_OK;
+ }
+
+ g = pp->game;
+ if (game_globals.garray[g].link >= 0) {
+ pprintf(p, "Takeback not implemented for bughouse games yet.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_INT) {
+ nHalfMoves = param[0].val.integer;
+ if (nHalfMoves <= 0) {
+ pprintf (p,"You can't takeback less than 1 move.\n");
+ return COM_OK;
+ }
+ }
+ if ((from = find_pend(pp->opponent, p, PEND_TAKEBACK)) != NULL) {
+ pend_half_moves = from->wtime;
+ delete_pending(from);
+ if (pend_half_moves == nHalfMoves) {
+ /* Doing the takeback */
+ decline_withdraw_offers(p, -1, -PEND_SIMUL,DO_DECLINE);
+ for (i = 0; i < nHalfMoves; i++) {
+ if (backup_move(g, REL_GAME) != MOVE_OK) {
+ pprintf(game_globals.garray[g].white, "Can only backup %d moves\n", i);
+ pprintf(game_globals.garray[g].black, "Can only backup %d moves\n", i);
+ break;
+ }
+ }
+
+ game_globals.garray[g].wTimeWhenReceivedMove = 0;
+ game_globals.garray[g].bTimeWhenReceivedMove = 0;
+
+ send_boards(g);
+ } else {
+
+ if (!game_globals.garray[g].numHalfMoves) {
+ pprintf(p, "There are no moves in your game.\n");
+ pprintf_prompt(pp->opponent, "\n%s has declined the takeback request.\n",
+ pp->name);
+ return COM_OK;
+ }
+
+ if (game_globals.garray[g].numHalfMoves < nHalfMoves) {
+ pprintf(p, "There are only %d half moves in your game.\n", game_globals.garray[g].numHalfMoves);
+ pprintf_prompt(pp->opponent, "\n%s has declined the takeback request.\n",
+ pp->name);
+ return COM_OK;
+ }
+ pprintf(p, "You disagree on the number of half-moves to takeback.\n");
+ pprintf(p, "Alternate takeback request sent.\n");
+ pprintf_prompt(pp->opponent, "\n%s proposes a different number (%d) of half-move(s).\n", pp->name, nHalfMoves);
+ from = add_request(p, pp->opponent, PEND_TAKEBACK);
+ from->wtime = nHalfMoves;
+ }
+ } else {
+
+ if (!game_globals.garray[g].numHalfMoves) {
+ pprintf(p, "There are no moves in your game.\n");
+ return COM_OK;
+ }
+ if (game_globals.garray[g].numHalfMoves < nHalfMoves) {
+ pprintf(p, "There are only %d half moves in your game.\n", game_globals.garray[g].numHalfMoves);
+ return COM_OK;
+ }
+ pprintf(pp->opponent, "\n");
+ pprintf_highlight(pp->opponent, "%s", pp->name);
+ pprintf_prompt(pp->opponent, " would like to take back %d half move(s).\n",
+ nHalfMoves);
+ pprintf(p, "Takeback request sent.\n");
+ from = add_request(p, pp->opponent, PEND_TAKEBACK);
+ from->wtime = nHalfMoves;
+ }
+ return COM_OK;
+}
+
+
+int com_switch(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int g = pp->game, tmp, now, p1;
+ char *strTmp;
+ struct pending* pend;
+
+ if (!pIsPlaying(p))
+ return COM_OK;
+
+ p1 = pp->opponent;
+ if ((player_globals.parray[p1].simul_info != NULL) && (player_globals.parray[p1].simul_info->numBoards &&
+ player_globals.parray[p1].simul_info->boards[player_globals.parray[p1].simul_info->onBoard] != g)) {
+ pprintf(p, "You can only make requests when the simul player is at your board.\n");
+ return COM_OK;
+ }
+
+ if (game_globals.garray[g].link >= 0) {
+ pprintf(p, "Switch not implemented for bughouse games.\n");
+ return COM_OK;
+ }
+ if ((pend = find_pend(pp->opponent, p, PEND_SWITCH)) != NULL) {
+ delete_pending(pend);
+ /* Doing the switch */
+ decline_withdraw_offers(p, -1, -PEND_SIMUL,DO_DECLINE);
+
+ tmp = game_globals.garray[g].white;
+ game_globals.garray[g].white = game_globals.garray[g].black;
+ game_globals.garray[g].black = tmp;
+ pp->side = (pp->side == WHITE) ? BLACK : WHITE;
+ strTmp = strdup(game_globals.garray[g].white_name);
+ strcpy(game_globals.garray[g].white_name, game_globals.garray[g].black_name);
+ strcpy(game_globals.garray[g].black_name, strTmp);
+ free(strTmp);
+
+ player_globals.parray[pp->opponent].side =
+ (player_globals.parray[pp->opponent].side == WHITE) ? BLACK : WHITE;
+ /* Roll back the time */
+ if (game_globals.garray[g].game_state.onMove == WHITE) {
+ game_globals.garray[g].wTime += (game_globals.garray[g].lastDecTime - game_globals.garray[g].lastMoveTime);
+ } else {
+ game_globals.garray[g].bTime += (game_globals.garray[g].lastDecTime - game_globals.garray[g].lastMoveTime);
+ }
+ now = tenth_secs();
+ if (game_globals.garray[g].numHalfMoves == 0)
+ game_globals.garray[g].timeOfStart = now;
+ game_globals.garray[g].lastMoveTime = now;
+ game_globals.garray[g].lastDecTime = now;
+ send_boards(g);
+ return COM_OK;
+ }
+ if (game_globals.garray[g].rated && game_globals.garray[g].numHalfMoves > 0) {
+ pprintf(p, "You cannot switch sides once a rated game is underway.\n");
+ return COM_OK;
+ }
+ pprintf(pp->opponent, "\n");
+ pprintf_highlight(pp->opponent, "%s", pp->name);
+ pprintf_prompt(pp->opponent, " would like to switch sides.\nType \"accept\" to switch sides, or \"decline\" to refuse.\n");
+ pprintf(p, "Switch request sent.\n");
+ add_request(p, pp->opponent, PEND_SWITCH);
+ return COM_OK;
+}
+
+int com_time(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1, g;
+
+ if (param[0].type == TYPE_NULL) {
+ g = pp->game;
+ if (!pIsPlaying(p))
+ return COM_OK;
+ } else {
+ g = GameNumFromParam(p, &p1, ¶m[0]);
+ if (g < 0)
+ return COM_OK;
+ }
+ if ((g < 0) || (g >= game_globals.g_num) || (game_globals.garray[g].status != GAME_ACTIVE)) {
+ pprintf(p, "There is no such game.\n");
+ return COM_OK;
+ }
+ game_update_time(g);
+ pprintf(p, "White (%s) : %d mins, %d secs\n",
+ player_globals.parray[game_globals.garray[g].white].name,
+ game_globals.garray[g].wTime / 600,
+ (game_globals.garray[g].wTime - ((game_globals.garray[g].wTime / 600) * 600)) / 10);
+ pprintf(p, "Black (%s) : %d mins, %d secs\n",
+ player_globals.parray[game_globals.garray[g].black].name,
+ game_globals.garray[g].bTime / 600,
+ (game_globals.garray[g].bTime - ((game_globals.garray[g].bTime / 600) * 600)) / 10);
+ return COM_OK;
+}
+
+int com_ptime(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int retval, part = pp->partner;
+
+ if (part < 0) {
+ pprintf(p, "You do not have a partner.\n");
+ return COM_OK;
+ }
+ retval = pcommand (p, "time %s", player_globals.parray[part].name);
+ if (retval == COM_OK)
+ return COM_OK_NOPROMPT;
+ else
+ return retval;
+}
+
+int com_boards(int p, param_list param)
+{
+ char *category = NULL;
+ char dname[MAX_FILENAME_SIZE];
+ DIR *dirp;
+ struct dirent *dp;
+
+ if (param[0].type == TYPE_WORD)
+ category = param[0].val.word;
+ if (category) {
+ pprintf(p, "Boards Available For Category %s:\n", category);
+ sprintf(dname, "%s/%s", BOARD_DIR, category);
+ } else {
+ pprintf(p, "Categories Available:\n");
+ sprintf(dname, "%s", BOARD_DIR);
+ }
+ dirp = opendir(dname);
+ if (!dirp) {
+ pprintf(p, "No such category %s, try \"boards\".\n", category);
+ return COM_OK;
+ }
+
+/* YUK! what a mess, how about printing an ordered directory? - DAV*/
+
+ for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
+ if (!strcmp(dp->d_name, "."))
+ continue;
+ if (!strcmp(dp->d_name, ".."))
+ continue;
+ pprintf(p, "%s\n", dp->d_name);
+ }
+ closedir(dirp);
+ return COM_OK;
+}
+
+int com_simmatch(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1, g, adjourned;
+ int num;
+ char tmp[100];
+ struct pending* pend;
+ char* board = NULL;
+ char* category = NULL;
+ char fname[MAX_FILENAME_SIZE];
+
+ if (pp->game >=0) {
+ if (game_globals.garray[pp->game].status == GAME_EXAMINE) {
+ pprintf(p, "You are still examining a game.\n");
+ return COM_OK;
+ }
+ if (game_globals.garray[pp->game].status == GAME_SETUP) {
+ pprintf(p, "You are still setting up a position.\n");
+ return COM_OK;
+ }
+ }
+ p1 = player_find_part_login(param[0].val.word);
+ if (p1 < 0) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ if (p == p1) {
+ pprintf(p, "You can't simmatch yourself!\n");
+ return COM_OK;
+ }
+ if ((pend = find_pend(p1, p, PEND_SIMUL)) != NULL) {
+
+ /* Accepting Simul ! */
+
+ if ((pp->simul_info != NULL) &&
+ (pp->simul_info->numBoards >= MAX_SIMUL)) {
+ pprintf(p, "You are already playing the maximum of %d boards.\n", MAX_SIMUL);
+ pprintf(p1, "Simul request removed, boards filled.\n");
+ delete_pending(pend);
+ return COM_OK;
+ }
+ unobserveAll(p); /* stop observing when match starts */
+ unobserveAll(p1);
+
+ g = game_new();
+ adjourned = 0;
+ if (game_read(g, p, p1) >= 0) {
+ adjourned = 1;
+ delete_pending(pend);
+ }
+
+ if (!adjourned) { /* no adjourned game, so begin a new game */
+
+ if ((pend->category != NULL) && (pend->board_type != NULL)) {
+ board = strdup(pend->category);
+ category = strdup(pend->board_type);
+ }
+
+ delete_pending(pend);
+
+ if (create_new_match(g,p, p1, 0, 0, 0, 0, 0, ((board == NULL) ? "\0" : board), ((category == NULL) ? "\0" : category), 1,1) == COM_FAILED) {
+ pprintf(p, "There was a problem creating the new match.\n");
+ pprintf_prompt(p1, "There was a problem creating the new match.\n");
+ game_remove(g);
+
+ if (board != NULL) {
+ free (board);
+ free (category);
+ }
+ return COM_OK;
+ }
+
+ if (board != NULL) {
+ free (board);
+ free (category);
+ }
+
+ } else { /* resume adjourned game */
+ game_delete(p, p1);
+
+ sprintf(tmp, "{Game %d (%s vs. %s) Continuing %s %s simul.}\n", g + 1, pp->name, player_globals.parray[p1].name, rstr[game_globals.garray[g].rated], bstr[game_globals.garray[g].type]);
+ pprintf(p, tmp);
+ pprintf(p1, tmp);
+
+ game_globals.garray[g].white = p;
+ game_globals.garray[g].black = p1;
+ game_globals.garray[g].status = GAME_ACTIVE;
+ game_globals.garray[g].startTime = tenth_secs();
+ game_globals.garray[g].lastMoveTime = game_globals.garray[g].startTime;
+ game_globals.garray[g].lastDecTime = game_globals.garray[g].startTime;
+ pp->game = g;
+ pp->opponent = p1;
+ pp->side = WHITE;
+ player_globals.parray[p1].game = g;
+ player_globals.parray[p1].opponent = p;
+ player_globals.parray[p1].side = BLACK;
+ send_boards(g);
+ }
+
+ if (pp->simul_info == NULL) {
+ pp->simul_info = (struct simul_info_t *) malloc(sizeof(struct simul_info_t));
+ pp->simul_info->numBoards = 0;
+ pp->simul_info->onBoard = 0;
+ pp->simul_info->num_wins = pp->simul_info->num_draws
+ = pp->simul_info->num_losses = 0;
+ }
+ num = pp->simul_info->numBoards;
+ /* pp->simul_info->results[num] = -1; */
+ pp->simul_info->boards[num] = pp->game;
+ pp->simul_info->numBoards++;
+ if (pp->simul_info->numBoards > 1 &&
+ pp->simul_info->onBoard >= 0)
+ player_goto_board(p, pp->simul_info->onBoard);
+ else
+ pp->simul_info->onBoard = 0;
+ return COM_OK;
+ }
+ if (find_pend(-1, p, PEND_SIMUL) != NULL) {
+ pprintf(p, "You cannot be the simul giver and request to join another simul.\nThat would just be too confusing for me and you.\n");
+ return COM_OK;
+ }
+ if (pp->simul_info != NULL) {
+ if (pp->simul_info->numBoards) {
+ pprintf(p, "You cannot be the simul giver and request to join another simul.\nThat would just be too confusing for me and you.\n");
+ return COM_OK;
+ }
+ }
+ if (pp->game >=0) {
+ pprintf(p, "You are already playing a game.\n");
+ return COM_OK;
+ }
+ if (!CheckPFlag(p1, PFLAG_SIMOPEN)) {
+ pprintf_highlight(p, "%s", player_globals.parray[p1].name);
+ pprintf(p, " is not open to receiving simul requests.\n");
+ return COM_OK;
+ }
+ if ((player_globals.parray[p1].simul_info != NULL) && (player_globals.parray[p1].simul_info->numBoards >= MAX_SIMUL)) {
+ pprintf_highlight(p, "%s", player_globals.parray[p1].name);
+ pprintf(p, " is already playing the maximum of %d boards.\n", MAX_SIMUL);
+ return COM_OK;
+ }
+
+/* loon: checking for some crazy situations we can't allow :) */
+
+ if ((player_globals.parray[p1].simul_info != NULL) && (player_globals.parray[p1].game >=0) && (player_globals.parray[p1].simul_info->numBoards == 0)) {
+ pprintf_highlight(p, "%s", player_globals.parray[p1].name);
+ if (player_globals.parray[game_globals.garray[player_globals.parray[p1].game].white].simul_info->numBoards) {
+ pprintf(p, " is playing in ");
+ pprintf_highlight(p, "%s", player_globals.parray[player_globals.parray[p1].opponent].name);
+ pprintf(p, "'s simul, and can't accept.\n");
+ } else {
+ pprintf(p, " can't begin a simul while playing a non-simul game.\n");
+ }
+ return COM_OK;
+ }
+
+ g = game_new(); /* Check if an adjourned untimed game */
+ adjourned = ((game_read(g, p, p1) < 0) && (game_read(g, p1, p) < 0)) ? 0 : 1;
+ if (adjourned) {
+ if (!(game_globals.garray[g].type == TYPE_UNTIMED))
+ adjourned = 0;
+ }
+ game_remove(g);
+
+ pend = add_request(p, p1, PEND_SIMUL);
+
+ if ((param[1].type == TYPE_WORD) && (param[2].type == TYPE_WORD)) {
+
+ sprintf(fname, "%s/%s/%s", BOARD_DIR, param[1].val.word , param[2].val.word);
+ if (!file_exists(fname)) {
+ pprintf(p, "No such category/board: %s/%s\n", param[1].val.word , param[2].val.word);
+ return COM_OK;
+ }
+ pend->category = strdup(param[1].val.word);
+ pend->board_type = strdup(param[2].val.word);
+ } else {
+ pend->category = NULL;
+ pend->board_type = NULL;
+ }
+
+ pprintf(p1, "\n");
+ pprintf_highlight(p1, "%s", pp->name);
+ if (adjourned) {
+ pprintf_prompt(p1, " requests to continue an adjourned simul game.\n");
+ pprintf(p, "Request to resume simul sent. Adjourned game found.\n");
+ } else {
+ if (pend->category == NULL)
+ pprintf_prompt(p1, " requests to join a simul match with you.\n");
+ else
+ pprintf_prompt(p1, " requests to join a %s %s simul match with you.\n",
+ pend->category,pend->board_type);
+ pprintf(p, "Simul match request sent.\n");
+ }
+ return COM_OK;
+}
+
+int com_goboard(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int on, g, p1, gamenum;
+
+ if (pp->simul_info == NULL) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+
+ if (!pp->simul_info->numBoards) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+
+ if (param[0].type == TYPE_WORD) {
+
+ p1 = player_find_part_login(param[0].val.word);
+ if (p1 < 0) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ if (p == p1) {
+ pprintf(p, "You can't goboard yourself!\n");
+ return COM_OK;
+ }
+
+ gamenum = player_globals.parray[p1].game;
+ if (gamenum < 0) {
+ pprintf (p,"%s is not playing a game.\n", player_globals.parray[p1].login);
+ return COM_OK;
+ }
+
+ } else {
+ gamenum = param[0].val.integer - 1;
+ if (gamenum < 0)
+ gamenum = 0;
+ }
+
+ on = pp->simul_info->onBoard;
+ g = pp->simul_info->boards[on];
+ if (gamenum == g) {
+ pprintf(p, "You are already at that board!\n");
+ return COM_OK;
+ }
+ if (pp->simul_info->numBoards > 1) {
+ decline_withdraw_offers(p, -1, -PEND_SIMUL,DO_DECLINE);
+ if (player_goto_simulgame_bynum(p, gamenum) !=-1) {
+ if (g >= 0) {
+ pprintf(game_globals.garray[g].black, "\n");
+ pprintf_highlight(game_globals.garray[g].black, "%s", pp->name);
+ pprintf_prompt(game_globals.garray[g].black, " has moved away from your board.\n");
+ }
+ } else
+ pprintf(p, "You are not playing that game/person.\n");
+ } else
+ pprintf(p, "You are only playing one board!\n");
+ return COM_OK;
+}
+
+int com_simnext(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int on, g;
+
+ if (pp->simul_info == NULL) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+
+ if (!pp->simul_info->numBoards) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+
+ if (pp->simul_info->numBoards > 1) {
+ decline_withdraw_offers(p, -1, -PEND_SIMUL,DO_DECLINE);
+ on = pp->simul_info->onBoard;
+ g = pp->simul_info->boards[on];
+ if (g >= 0) {
+ pprintf(game_globals.garray[g].black, "\n");
+ pprintf_highlight(game_globals.garray[g].black, "%s", pp->name);
+ pprintf_prompt(game_globals.garray[g].black, " is moving away from your board.\n");
+ player_goto_next_board(p);
+ }
+ } else
+ pprintf(p, "You are only playing one board!\n");
+ return COM_OK;
+}
+
+int com_simprev(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int on, g;
+
+ if (pp->simul_info == NULL) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+
+ if (!pp->simul_info->numBoards) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+ if (pp->simul_info->numBoards > 1) {
+ decline_withdraw_offers(p, -1, -PEND_SIMUL,DO_DECLINE);
+ on = pp->simul_info->onBoard;
+ g = pp->simul_info->boards[on];
+ if (g >= 0) {
+ pprintf(game_globals.garray[g].black, "\n");
+ pprintf_highlight(game_globals.garray[g].black, "%s", pp->name);
+ pprintf_prompt(game_globals.garray[g].black, " is moving back to the previous board.\n");
+ }
+ player_goto_prev_board(p);
+ } else
+ pprintf(p, "You are only playing one board!\n");
+ return COM_OK;
+}
+
+int com_simgames(int p, param_list param)
+{
+ int p1 = p;
+
+ if (param[0].type == TYPE_WORD) {
+ if ((p1 = player_find_part_login(param[0].val.word)) < 0) {
+ pprintf(p, "No player named %s is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ }
+ if (p1 == p)
+ pprintf(p, "You are playing %d simultaneous games.\n",
+ player_num_active_boards(p1));
+ else
+ pprintf(p, "%s is playing %d simultaneous games.\n", player_globals.parray[p1].name,
+ player_num_active_boards(p1));
+ return COM_OK;
+}
+
+int com_simpass(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int g, p1, on;
+
+ if (!pIsPlaying(p))
+ return COM_OK;
+
+ g = pp->game;
+ p1 = game_globals.garray[g].white;
+
+ if (player_globals.parray[p1].simul_info == NULL) {
+ pprintf(p, "You are not participating in a simul.\n");
+ return COM_OK;
+ }
+
+ if (!player_globals.parray[p1].simul_info->numBoards) {
+ pprintf(p, "You are not participating in a simul.\n");
+ return COM_OK;
+ }
+ if (p == p1) {
+ pprintf(p, "You are the simul holder and cannot pass!\n");
+ return COM_OK;
+ }
+ if (player_num_active_boards(p1) == 1) {
+ pprintf(p, "This is the only game, so passing is futile.\n");
+ return COM_OK;
+ }
+ on = player_globals.parray[p1].simul_info->onBoard;
+ if (player_globals.parray[p1].simul_info->boards[on] != g) {
+ pprintf(p, "You cannot pass until the simul holder arrives!\n");
+ return COM_OK;
+ }
+ if (game_globals.garray[g].passes >= MAX_SIMPASS) {
+ Bell (p);
+ pprintf(p, "You have reached your maximum of %d pass(es).\n", MAX_SIMPASS);
+ pprintf(p, "Please move IMMEDIATELY!\n");
+ pprintf_highlight(p1, "%s", pp->name);
+ pprintf_prompt(p1, " tried to pass, but is out of passes.\n");
+ return COM_OK;
+ }
+ decline_withdraw_offers(p, -1, -PEND_SIMUL,DO_DECLINE);
+
+ game_globals.garray[g].passes++;
+ pprintf(p, "You have passed and have %d pass(es) left.\n",
+ (MAX_SIMPASS - game_globals.garray[g].passes));
+ pprintf_highlight(p1, "%s", pp->name);
+ pprintf_prompt(p1, " has decided to pass and has %d pass(es) left.\n",
+ (MAX_SIMPASS - game_globals.garray[g].passes));
+ player_goto_next_board(p1);
+ return COM_OK;
+}
+
+int com_simabort(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+
+ if (pp->simul_info == NULL) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+
+ if (!pp->simul_info->numBoards) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+ decline_withdraw_offers(p, -1, -PEND_SIMUL,DO_DECLINE);
+ game_ended(pp->simul_info->boards[pp->simul_info->onBoard],
+ WHITE, END_ABORT);
+ return COM_OK;
+}
+
+int com_simallabort(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int i;
+
+ if (pp->simul_info == NULL) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+
+ if (!pp->simul_info->numBoards) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+
+ decline_withdraw_offers(p, -1, -PEND_SIMUL,DO_DECLINE);
+ for (i = 0; i < pp->simul_info->numBoards; i++)
+ if (pp->simul_info->boards[i] >= 0)
+ game_ended(pp->simul_info->boards[i],
+ WHITE, END_ABORT);
+
+ return COM_OK;
+}
+
+int com_simadjourn(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+
+ if (pp->simul_info == NULL) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+
+ if (!pp->simul_info->numBoards) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+ decline_withdraw_offers(p, -1, -PEND_SIMUL,DO_DECLINE);
+ game_ended(pp->simul_info->boards[pp->simul_info->onBoard],
+ WHITE, END_ADJOURN);
+ return COM_OK;
+}
+
+int com_simalladjourn(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int i;
+
+ if (pp->simul_info == NULL) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+
+ if (!pp->simul_info->numBoards) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+ decline_withdraw_offers(p, -1, -PEND_SIMUL,DO_DECLINE);
+ for (i = 0; i < pp->simul_info->numBoards; i++)
+ if (pp->simul_info->boards[i] >= 0)
+ game_ended(pp->simul_info->boards[i],
+ WHITE, END_ADJOURN);
+
+ return COM_OK;
+}
+
+int com_moretime(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int g, increment;
+
+ if ((pp->game >=0) &&((game_globals.garray[pp->game].status == GAME_EXAMINE) ||
+ (game_globals.garray[pp->game].status == GAME_SETUP))) {
+ pprintf(p, "You cannot use moretime in an examined game.\n");
+ return COM_OK;
+ }
+ increment = param[0].val.integer;
+ if (increment <= 0) {
+ pprintf(p, "Moretime requires an integer value greater than zero.\n");
+ return COM_OK;
+ }
+ if (!pIsPlaying(p))
+ return COM_OK;
+
+ if (increment > 600) {
+ pprintf(p, "Moretime has a maximum limit of 600 seconds.\n");
+ increment = 600;
+ }
+ g = pp->game;
+ if (game_globals.garray[g].white == p) {
+ game_globals.garray[g].bTime += increment * 10;
+ game_globals.garray[g].bRealTime += increment * 10 * 100;
+ pprintf(p, "%d seconds were added to your opponents clock\n",
+ increment);
+ pprintf_prompt(pp->opponent,
+ "\nYour opponent has added %d seconds to your clock.\n",
+ increment);
+ }
+ if (game_globals.garray[g].black == p) {
+ game_globals.garray[g].wTime += increment * 10;;
+ game_globals.garray[g].wRealTime += increment * 10 * 100;
+ pprintf(p, "%d seconds were added to your opponents clock\n",
+ increment);
+ pprintf_prompt(pp->opponent,
+ "\nYour opponent has added %d seconds to your clock.\n",
+ increment);
+ }
+ return COM_OK;
+}
+
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+
+#ifndef _GAMEPROC_H
+#define _GAMEPROC_H
+
+#define MAX_SIMPASS 3
+
+#endif /* _GAMEPROC_H */
--- /dev/null
+/*
+ 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 2 of the License, 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.
+*/
+
+/*
+ * FICS-Extensions used at GICS chess.unix-ag.uni-kl.de 5000
+ * (c) 1995/1996 by Ulrich Schlechte <Ulrich.Schlechte@ipp.tu-clausthal.de>
+ * Klaus Knopper <Knopper@unix-ag.uni-kl.de>
+ *
+ *
+*/
+
+#include "includes.h"
+
+
+void init_userstat(void)
+{
+ FILE *fp;
+ int i;
+
+ if ((fp = fopen_s(STATS_DIR "/user.stats", "r")) == NULL) {
+ bzero((char *) &gics_globals.userstat, sizeof(gics_globals.userstat));
+ return;
+ }
+
+ for (i = 0; i < 48; i++) {
+ fscanf(fp, "%d\n", &gics_globals.userstat.users[i]);
+ }
+ fscanf(fp, "%d\n", &gics_globals.userstat.usermax);
+ fscanf(fp, "%d\n", (int *) &gics_globals.userstat.usermaxtime);
+ fscanf(fp, "%d\n", &gics_globals.userstat.logins);
+ fscanf(fp, "%d\n", &gics_globals.userstat.games);
+ fscanf(fp, "%d\n", &gics_globals.userstat.gamemax);
+ fscanf(fp, "%d\n", (int *) &gics_globals.userstat.gamemaxtime);
+ fclose(fp);
+}
+
+void save_userstat(void)
+{
+ FILE *fp;
+ int i;
+
+ if ((fp = fopen_s(STATS_DIR "/user.stats", "w")) == NULL)
+ return;
+ for (i = 0; i < 48; i++)
+ fprintf(fp, "%d\n", gics_globals.userstat.users[i]);
+ fprintf(fp, "%d\n%d\n%d\n",
+ gics_globals.userstat.usermax, gics_globals.userstat.usermaxtime, gics_globals.userstat.logins);
+ fprintf(fp, "%d\n%d\n%d\n",
+ gics_globals.userstat.games, gics_globals.userstat.gamemax, gics_globals.userstat.gamemaxtime);
+ fclose(fp);
+}
+
+#if 0
+int com_ping(int p, param_list param)
+{
+ int p1;
+ struct timeval timeState;
+ struct timezone tz;
+
+ if ((p1 = player_find_bylogin(param[0].val.word)) < 0) {
+ pprintf(p, "Player \"%s\" not logged on!\n", param[0].val.word);
+ return COM_OK;
+ }
+ if ((!con[player_globals.parray[p1].socket].timeseal) || (con[player_globals.parray[p1].socket].method)) {
+ pprintf(p, "%s is not using timeseal or uses an old client.\n", player_globals.parray[p1].name);
+ return COM_OK;
+ }
+ pprintf(p1, "\n[P]\n");
+ gettimeofday(&timeState, &tz);
+ con[player_globals.parray[p1].socket].pingtime = (((int) timeState.tv_sec % 10000) * 1000) + ((int) timeState.tv_usec / 1000);
+ con[player_globals.parray[p1].socket].pingplayer = p;
+ return COM_OK;
+}
+#endif
+
+void game_save_playerratio(char *file, char *Opponent, int Result, int rated)
+{
+ FILE *fp, *fp1;
+ char Name[32], file1[256];
+ int win, loss, draw, flag = 0, inc = 1;
+
+ if (!rated)
+ inc = 100000;
+
+ sprintf(file1, "%s.new", file);
+ if ((fp = fopen_s(file, "r")) != NULL) {
+ fp1 = fopen_s(file1, "w");
+ while (!feof(fp)) {
+ if (fscanf(fp, "%s %d %d %d\n", Name, &win, &draw, &loss) != 4) {
+ break;
+ }
+ if (strcasecmp(Name, Opponent) == 0) {
+ if (Result == 1)
+ win += inc;
+ if (Result == 0)
+ loss += inc;
+ if (Result == -1)
+ draw += inc;
+ flag++;
+ }
+ fprintf(fp1, "%s %d %d %d\n", Name, win, draw, loss);
+ }
+ fclose(fp);
+ if (!flag) {
+ win = loss = draw = 0;
+ if (Result == 1)
+ win += inc;
+ if (Result == 0)
+ loss += inc;
+ if (Result == -1)
+ draw += inc;
+ fprintf(fp1, "%s %d %d %d\n", Opponent, win, draw, loss);
+ }
+ fclose(fp1);
+ unlink(file);
+ if (rename(file1, file) != 0) {
+ d_printf("CHESSD: Problems rename %s to %s : %d\n", file1, file, errno);
+ return;
+ }
+ return;
+ } else {
+ fp = fopen_s(file, "w");
+ if(fp == NULL) {
+ perror("fopen");
+ d_printf("Unable to open %s - very bad, info not saved\n",file);
+ return;
+ }
+ win = loss = draw = 0;
+ if (Result == 1)
+ win += inc;
+ if (Result == 0)
+ loss += inc;
+ if (Result == -1)
+ draw += inc;
+ fprintf(fp, "%s %d %d %d\n", Opponent, win, draw, loss);
+ fclose(fp);
+ }
+}
+
+int com_pstat(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1 = p, p2, ptemp, pflag=0;
+ int p1_connected = 1, p2_connected = 1;
+ int win = 0, draw = 0, loss = 0, flag = 0;
+ FILE *fp;
+ char Name[32], fname[256];
+
+ if (param[0].type == TYPE_NULL) {
+ if (pp->game < 0) {
+ pprintf(p, "You are not playing a game.\n");
+ return COM_OK;
+ }
+ if (game_globals.garray[pp->game].status == GAME_EXAMINE) {
+ pprintf(p, "You are examining a game please specify variables.\n");
+ return COM_OK;
+ }
+ p2 = pp->opponent;
+ } else {
+ if (!FindPlayer(p, param[0].val.word, &p2, &p2_connected)) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ if (param[1].type != TYPE_NULL) {
+ if (!FindPlayer(p, param[1].val.word, &p1, &p1_connected)) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[1].val.word);
+ if (!p2_connected)
+ player_remove(p2);
+ return COM_OK;
+ }
+ ptemp = p2;
+ p2 = p1;
+ p1 = ptemp;
+ pflag = 1;
+ }
+ }
+ if (p1 == p2) {
+ pprintf(p, "You have not played against yourself ;-)\n");
+ if (!p1_connected)
+ player_remove(p1);
+ if (!p2_connected)
+ player_remove(p2);
+ return COM_OK;
+ }
+ sprintf(fname, "%s/player_data/%c/%s.gstats", STATS_DIR, player_globals.parray[p1].login[0], player_globals.parray[p1].login);
+ if ((fp = fopen_s(fname, "r")) != NULL) {
+ while (!feof(fp)) {
+ if (fscanf(fp, "%s %d %d %d\n", Name, &win, &draw, &loss) != 4) {
+ win = loss = draw = 0;
+ break;
+ }
+ if (strcasecmp(Name, player_globals.parray[p2].name) == 0) {
+ flag++;
+ break;
+ }
+ }
+ fclose(fp);
+ }
+ if (!flag)
+ win = loss = draw = 0;
+ pprintf(p, "Record for %s vs. %s:\n", player_globals.parray[p1].name, player_globals.parray[p2].name);
+ pprintf(p, " wins losses draws\n");
+ pprintf(p, " rated %4d %4d %4d\n", win % 100000, loss % 100000, draw % 100000);
+ pprintf(p, " unrated %4d %4d %4d\n", win / 100000, loss / 100000, draw / 100000);
+ /* pprintf(p, "Ratio of %s vs. %s (r/u): %d/%d wins %d/%d draws %d/%d losses\n", player_globals.parray[p1].name, player_globals.parray[p2].name,
+ * win % 100000, win / 100000, draw % 100000, draw / 100000, loss % 100000, loss / 100000);
+ */
+ if (pflag) {
+ ptemp = p1;
+ p1 = p2;
+ p2 = ptemp;
+ }
+ if (!p1_connected)
+ player_remove(p1);
+ if (!p2_connected)
+ player_remove(p2);
+ return COM_OK;
+}
+
+
+
+
+
+
+
+
+
--- /dev/null
+/*
+ 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 2 of the License, 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.
+*/
+
+/*
+ * FICS-Extensions used at GICS chess.unix-ag.uni-kl.de 5000
+ * (c) 1995/1996 by Ulrich Schlechte <Ulrich.Schlechte@ipp.tu-clausthal.de>
+ * Klaus Knopper <Knopper@unix-ag.uni-kl.de>
+ *
+ *
+*/
+
+
+#ifndef GICS_H
+#define GICS_H
+
+/* Needed for ustat-funktion */
+GENSTRUCT struct userstat_type {
+ int users[48];
+ int usermax;
+ int usermaxtime;
+ int logins;
+ int games;
+ int gamemax;
+ int gamemaxtime;
+};
+
+#endif /* GICS_H */
+
+
+
--- /dev/null
+/*
+ Copyright 2002 Andrew Tridgell <tridge@samba.org>
+
+ 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 2 of the License, 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.
+*/
+
+/*
+ all global variiables in chessd have been moved here so that they can
+ be maintained over a code reload. As long as the code reload does not change the
+ shape or meaning of any of the following globals then the reload should work
+*/
+
+
+/* the EXTERN macro is used to allow ficsmain.c to declare real variables while
+ other modules declare them as extern */
+#ifndef EXTERN
+#define EXTERN extern
+#endif
+
+/* from network.c */
+GENSTRUCT struct net_globals {
+ int sockfd; /* main listening socket */
+ int numConnections; /* number of active connections */
+ int no_file; /* number of connections allocated */
+ struct connection_t **con; _LEN(no_file)
+};
+EXTERN struct net_globals net_globals;
+
+/* from gamedb.c */
+
+GENSTRUCT struct game_globals {
+ int g_num;
+ struct game *garray; _LEN(g_num)
+};
+EXTERN struct game_globals game_globals;
+
+/* from playerdb.c */
+GENSTRUCT struct player_globals {
+ int p_num;
+ unsigned parray_size;
+ struct player *parray; _LEN(parray_size)
+};
+EXTERN struct player_globals player_globals;
+
+/* from command.c */
+GENSTRUCT struct command_globals {
+ time_t startuptime;
+ int player_high;
+ int game_high;
+ int commanding_player;
+};
+EXTERN struct command_globals command_globals;
+
+/* from gics.c */
+GENSTRUCT struct gics_globals {
+ struct userstat_type userstat;
+};
+EXTERN struct gics_globals gics_globals;
+
+/* from seekproc.c */
+GENSTRUCT struct seek_globals {
+ int quota_time;
+ struct pending *pendlist;
+ unsigned max_ads;
+ struct pending *ads; _LEN(max_ads)
+};
+EXTERN struct seek_globals seek_globals;
+
+/* from timeseal.c */
+GENSTRUCT struct timeseal_globals {
+ int decoder_conn;
+};
+EXTERN struct timeseal_globals timeseal_globals;
+
+/* a structure containing all globals, to make it easy to save
+ globals for a reload
+*/
+GENSTRUCT struct all_globals {
+ struct net_globals *net_globals;
+ struct game_globals *game_globals;
+ struct player_globals *player_globals;
+ struct command_globals *command_globals;
+ struct gics_globals *gics_globals;
+ struct seek_globals *seek_globals;
+ struct timeseal_globals *timeseal_globals;
+};
--- /dev/null
+/*
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+/*
+ support for the 'help' and 'ahelp' commands
+ */
+
+#include "includes.h"
+
+static const char *help_dir[NUM_LANGS] = {HELP_DIR, HELP_SPANISH,
+ HELP_FRENCH, HELP_DANISH};
+
+
+
+/*
+ help from a directory
+*/
+static int help_page(int p, const char *dir, const char *cmd)
+{
+ int count;
+ char *filenames[1000];
+
+ /* try for help dir exact match */
+ if (psend_file(p, dir, cmd) == 0) {
+ return COM_OK;
+ }
+
+ /* search help dir for a partial match */
+ count = search_directory(dir, cmd, filenames, 1000);
+ if (count == 1) {
+ psend_file(p, dir, filenames[0]);
+ FREE(filenames[0]);
+ return COM_OK;
+ }
+
+ if (count > 0) {
+ pprintf(p,"-- Matches: %u help topics --", count);
+ display_directory(p, filenames, count);
+ return COM_OK;
+ }
+
+ /* allow admins to use 'help' for admin pages */
+ if (dir != ADHELP_DIR && check_admin(p, ADMIN_ADMIN)) {
+ return help_page(p, ADHELP_DIR, cmd);
+ }
+
+ pprintf(p,"No help found for topic '%s'\n", cmd);
+
+ return COM_OK;
+}
+
+/*
+ public help
+ */
+int com_help(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ char *cmd;
+ int i, n;
+ const struct alias_type *list;
+
+ if (param[0].type == TYPE_STRING) {
+ cmd = param[0].val.string;
+ } else {
+ cmd = "help";
+ }
+
+ /* see if its a global alias */
+ list = alias_list_global();
+ for (i=0;list && list[i].comm_name;i++) {
+ if (strcasecmp(cmd, list[i].comm_name) == 0) {
+ pprintf(p,"'%s' is a global alias for '%s'\n",
+ cmd, list[i].alias);
+ return COM_OK;
+ }
+ }
+
+ /* or a personal alias */
+ list = alias_list_personal(p, &n);
+ for (i=0;i<n;i++) {
+ if (strcasecmp(cmd, list[i].comm_name) == 0) {
+ pprintf(p,"'%s' is a personal alias for '%s'\n",
+ cmd, list[i].alias);
+ return COM_OK;
+ }
+ }
+
+ return help_page(p, help_dir[pp->language], cmd);
+}
+
+/*
+ admin only help
+ */
+int com_ahelp(int p, param_list param)
+{
+ char *cmd;
+
+ if (param[0].type == TYPE_STRING) {
+ cmd = param[0].val.string;
+ } else {
+ cmd = "commands";
+ }
+
+ return help_page(p, ADHELP_DIR, cmd);
+}
+
--- /dev/null
+/*
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
+#include <signal.h>
+#include <time.h>
+#include <math.h>
+#include <errno.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <dlfcn.h>
+#include <stddef.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/telnet.h>
+#include <netdb.h>
+
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#include <sys/resource.h>
+#include <sys/ioctl.h>
+#include <sys/wait.h>
+#include <sys/mman.h>
+
+#include "autoconfig.h"
+#include "malloc.h"
+#include "parsers/genparser.h"
+#include "common.h"
+#include "vers.h"
+#include "variable.h"
+#include "command.h"
+#include "gics.h"
+#include "tdb/tdb.h"
+#include "ficsmain.h"
+#include "config.h"
+#include "network.h"
+#include "board.h"
+#include "gamedb.h"
+#include "lists.h"
+#include "iset.h"
+#include "playerdb.h"
+#include "ratings.h"
+#include "utils.h"
+#include "talkproc.h"
+#include "comproc.h"
+#include "pending.h"
+#include "multicol.h"
+#include "movecheck.h"
+#include "obsproc.h"
+#include "formula.h"
+#include "gameproc.h"
+#include "matchproc.h"
+#include "md5.h"
+#include "news.h"
+#include "globals.h"
+
+#include "proto.h"
--- /dev/null
+#! /bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+else
+ true
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d $dst ]; then
+ instcmd=:
+ else
+ instcmd=mkdir
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f $src -o -d $src ]
+ then
+ true
+ else
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "install: no destination specified"
+ exit 1
+ else
+ true
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d $dst ]
+ then
+ dst="$dst"/`basename $src`
+ else
+ true
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ] ;
+ then
+ $mkdirprog "${pathcomp}"
+ else
+ true
+ fi
+
+ pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd $dst &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ dstfile=`basename $dst $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ true
+ fi
+
+# Make a temp file name in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd $src $dsttmp &&
+
+ trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+ $doit $rmcmd -f $dstdir/$dstfile &&
+ $doit $mvcmd $dsttmp $dstdir/$dstfile
+
+fi &&
+
+
+exit 0
--- /dev/null
+/*
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+
+#include "includes.h"
+
+/*
+ set a boolean ivar
+*/
+static int iset_bool(int p, unsigned *v, const char *var, const char *value)
+{
+ if (strcmp(value, "1") == 0) {
+ *v = 1;
+ pprintf(p, "%s set\n", var);
+ } else if (strcmp(value, "0") == 0) {
+ *v = 0;
+ pprintf(p, "%s unset\n", var);
+ } else {
+ pprintf(p, "Bad value '%s' given for ivariable '%s'.\n", value, var);
+ }
+ return COM_OK;
+}
+
+/*
+ support the iset command
+*/
+int com_iset(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ char *var = param[0].val.word;
+ char *value = param[1].val.string;
+ struct ivariables *iv;
+
+ iv = &pp->ivariables;
+
+ if (iv->lock) {
+ pprintf(p,"Cannot alter: Interface setting locked.\n");
+ return COM_OK;
+ }
+
+ if (strcasecmp(var,"ms") == 0) {
+ return iset_bool(p, &iv->ms, var, value);
+ } else if (strcasecmp(var,"lock") == 0) {
+ return iset_bool(p, &iv->lock, var, value);
+ } else if (strcasecmp(var,"startpos") == 0) {
+ return iset_bool(p, &iv->startpos, var, value);
+ } else {
+ pprintf(p,"No such ivariable \"%s\".\n", var);
+ }
+
+ return COM_OK;
+}
--- /dev/null
+/*
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+/*
+ structures for the iset command
+*/
+
+GENSTRUCT struct ivariables {
+ unsigned startpos;
+ unsigned ms;
+ unsigned lock;
+};
+
--- /dev/null
+typedef struct journal {
+ char *WhiteName2;
+ int WhiteRating2;
+ char *BlackName2;
+ int BlackRating2;
+ char *type2;
+ char *eco2;
+ char *ending2;
+ char *result2;
+ char *fname;
+} journal;
--- /dev/null
+/*
+ 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 2 of the License, 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.
+*/
+
+/* lists.c
+ * New global lists code
+ *
+ *
+ * Added by Shaney, 29 May 1995 :)
+ *
+*/
+
+#include "includes.h"
+
+static struct List *firstGlobalList = NULL;
+
+static ListTable ListArray[] =
+{{P_HEAD, "admin"},
+ {P_GOD, "removedcom"},
+ {P_ADMIN, "filter"},
+ {P_ADMIN, "ban"},
+ {P_ADMIN, "abuser"},
+ {P_ADMIN, "muzzle"},
+ {P_ADMIN, "cmuzzle"},
+ {P_ADMIN, "c1muzzle"}, /* possible FICS trouble spots */
+ {P_ADMIN, "c24muzzle"}, /* would prefer two param addlist - DAV */
+ {P_ADMIN, "c46muzzle"}, /* is a temp solution */
+ {P_ADMIN, "c49muzzle"},
+ {P_ADMIN, "c50muzzle"},
+ {P_ADMIN, "c51muzzle"},
+ {P_PUBLIC, "fm"},
+ {P_PUBLIC, "im"},
+ {P_PUBLIC, "gm"},
+ {P_PUBLIC, "wgm"},
+ {P_PUBLIC, "blind"},
+ {P_PUBLIC, "teams"},
+ {P_PUBLIC, "computer"},
+ {P_PUBLIC, "td"},
+ {P_PERSONAL, "censor"},
+ {P_PERSONAL, "gnotify"},
+ {P_PERSONAL, "noplay"},
+ {P_PERSONAL, "notify"},
+ {P_PERSONAL, "channel"},
+ {P_PERSONAL, "follow"},
+ {P_PERSONAL, "remote"},
+ {0, NULL}};
+
+/* free up memory used by lists */
+void lists_close(void)
+{
+ struct List *l;
+
+ for (l=firstGlobalList; l; ) {
+ struct List *next = l->next;
+ int i;
+ for (i=0;i<l->numMembers;i++) {
+ FREE(l->m_member[i]);
+ }
+ FREE(l->m_member);
+ l->numMembers = 0;
+ free(l);
+ l = next;
+ }
+
+ firstGlobalList = NULL;
+}
+
+
+/* find a list. does not load from disk */
+static struct List *list_find1(int p, enum ListWhich l)
+{
+ struct player *pp = &player_globals.parray[p];
+ struct List *prev, *tempList, **starter;
+ int personal;
+
+ personal = ListArray[l].rights == P_PERSONAL;
+ starter = personal ? &(pp->lists) : &firstGlobalList;
+
+ for (prev = NULL, tempList = *starter; tempList != NULL; tempList = tempList->next) {
+ if (l == tempList->which) {
+ if (prev != NULL) {
+ prev->next = tempList->next;
+ tempList->next = *starter;
+ *starter = tempList;
+ }
+ return tempList;
+ }
+ if (tempList->which >= L_LASTLIST) {
+ /* THIS SHOULD NEVER HAPPEN! But has been in personal list: bugs! */
+ d_printf( "fics: ERROR!! in lists code\n");
+ abort();
+ }
+ prev = tempList;
+ }
+
+ return NULL;
+}
+
+/* find a list. loads from disk if not in memory. */
+static struct List *list_find(int p, enum ListWhich l)
+{
+ struct List *lst;
+ FILE *fp;
+ char listmember[100];
+ int count=0;
+
+ lst = list_find1(p, l);
+ if (lst) {
+ return lst;
+ }
+
+ /* create the base list */
+ list_add(p, l, NULL);
+
+ if (ListArray[l].rights == P_PERSONAL) {
+ list_find1(p, l);
+ }
+
+ fp = fopen_p("%s/%s", "r", LISTS_DIR, ListArray[l].name);
+ if (!fp) {
+ return NULL;
+ }
+ while (!feof(fp)) {
+ if (fgets(listmember, sizeof(listmember), fp) != NULL) {
+ if (list_add(p, l, listmember) == 0) {
+ count++;
+ }
+ }
+ }
+ fclose(fp);
+
+ /* we've added some, retry */
+ if (count) {
+ return list_find1(p, l);
+ }
+
+ return NULL;
+}
+
+
+/* add item to list */
+int list_add(int p, enum ListWhich l, const char *s)
+{
+ struct player *pp = &player_globals.parray[p];
+ struct List *gl = list_find1(p, l);
+
+ if (!gl) {
+ gl = calloc(1, sizeof(*gl));
+ gl->which = l;
+ if (ListArray[l].rights == P_PERSONAL) {
+ gl->next = pp->lists;
+ pp->lists = gl;
+ } else {
+ gl->next = firstGlobalList;
+ firstGlobalList = gl;
+ }
+ }
+
+ if (!s) return 0;
+
+ if (ListArray[l].rights == P_PERSONAL &&
+ gl->numMembers >= config_get_int("MAX_USER_LIST_SIZE", DEFAULT_MAX_USER_LIST_SIZE)) {
+ return 1;
+ }
+
+ while (isspace(*s)) s++;
+
+ gl->m_member = (char **)realloc(gl->m_member, sizeof(char *) * (gl->numMembers+1));
+ gl->m_member[gl->numMembers] = strndup(s, strcspn(s, " \t\r\n"));
+ gl->numMembers++;
+
+ return 0;
+}
+
+/* remove item from list */
+static int list_sub(int p, enum ListWhich l, char *s)
+{
+ struct List *gl = list_find(p, l);
+ int i;
+
+ if (!gl) {
+ return 1;
+ }
+ for (i = 0; i < gl->numMembers; i++) {
+ if (!strcasecmp(s, gl->m_member[i])) {
+ break;
+ }
+ }
+ if (i == gl->numMembers) {
+ return 1;
+ }
+
+ FREE(gl->m_member[i]);
+
+ for (; i < (gl->numMembers - 1); i++) {
+ gl->m_member[i] = gl->m_member[i+1];
+ }
+
+ gl->numMembers--;
+ gl->m_member = (char **)realloc(gl->m_member, sizeof(char *) * gl->numMembers);
+ return 0;
+}
+
+/* find list by name, doesn't have to be the whole name */
+struct List *list_findpartial(int p, char *which, int gonnado)
+{
+ struct player *pp = &player_globals.parray[p];
+ struct List *gl;
+ int i, foundit, slen;
+
+ slen = strlen(which);
+ for (i = 0, foundit = -1; ListArray[i].name != NULL; i++) {
+ if (!strncasecmp(ListArray[i].name, which, slen)) {
+ if (foundit == -1)
+ foundit = i;
+ else
+ return NULL; /* ambiguous */
+ }
+ }
+
+ if (foundit != -1) {
+ int rights = ListArray[foundit].rights;
+ int youlose = 0;
+
+ switch (rights) { /* check rights */
+ case P_HEAD:
+ if (gonnado && !player_ishead(p))
+ youlose = 1;
+ break;
+ case P_GOD:
+ if ((gonnado && (pp->adminLevel < ADMIN_GOD)) ||
+ (!gonnado && (pp->adminLevel < ADMIN_ADMIN)))
+ youlose = 1;
+ break;
+ case P_ADMIN:
+ if (pp->adminLevel < ADMIN_ADMIN)
+ youlose = 1;
+ break;
+ case P_PUBLIC:
+ if (gonnado && (pp->adminLevel < ADMIN_ADMIN))
+ youlose = 1;
+ break;
+ }
+ if (youlose) {
+ pprintf(p, "\"%s\" is not an appropriate list name or you have insufficient rights.\n", which);
+ return NULL;
+ }
+ gl = list_find(p, foundit);
+ } else {
+ pprintf(p, "\"%s\" does not match any list name.\n", which);
+ return NULL;
+ }
+ return gl;
+}
+
+/* see if something is in a list */
+int in_list(int p, enum ListWhich which, char *member)
+{
+ struct List *gl;
+ int i;
+ int filterList = (which == L_FILTER);
+
+ gl = list_find(p, which);
+ if ((gl == NULL) || (member == NULL))
+ return 0;
+ for (i = 0; i < gl->numMembers; i++) {
+ if (filterList) {
+ if (!strncasecmp(member, gl->m_member[i], strlen(gl->m_member[i])))
+ return 1;
+ } else {
+ if (!strcasecmp(member, gl->m_member[i]))
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* add or subtract something to/from a list */
+int list_addsub(int p, char* list, char* who, int addsub)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1, connected, loadme, personal, ch;
+ char *listname, *member, junkChar;
+ struct List *gl;
+ char *yourthe, *addrem;
+
+ gl = list_findpartial(p, list, addsub);
+ if (!gl)
+ return COM_OK;
+
+ personal = ListArray[gl->which].rights == P_PERSONAL;
+ loadme = (gl->which != L_FILTER) && (gl->which != L_REMOVEDCOM) && (gl->which != L_CHANNEL);
+ listname = ListArray[gl->which].name;
+ yourthe = personal ? "your" : "the";
+ addrem = (addsub == 1) ? "added to" : "removed from";
+
+ if (loadme) {
+ if (!FindPlayer(p, who, &p1, &connected)) {
+ if (addsub == 1)
+ return COM_OK;
+ member = who; /* allow sub removed/renamed player */
+ loadme = 0;
+ } else
+ member = player_globals.parray[p1].name;
+ } else {
+ member = who;
+ }
+
+ if (addsub == 1) { /* add to list */
+
+ if (gl->which == L_CHANNEL) {
+
+ if (sscanf (who,"%d%c",&ch, &junkChar) == 1 && ch >= 0 && ch < 255) {
+ if ((ch == 0) && (!in_list(p,L_ADMIN,pp->name))) {
+ pprintf(p, "Only admins may join channel 0.\n");
+ return COM_OK;
+ }
+ } else {
+ pprintf (p,"The channel to add must be a number between 0 and %d.\n",MAX_CHANNELS - 1);
+ return COM_OK;
+ }
+ }
+ if (in_list(p, gl->which, member)) {
+ pprintf(p, "[%s] is already on %s %s list.\n", member, yourthe, listname);
+ if (loadme && !connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ if (list_add(p, gl->which, member)) {
+ pprintf(p, "Sorry, %s %s list is full.\n", yourthe, listname);
+ if (loadme && !connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ } else if (addsub == 2) { /* subtract from list */
+ if (!in_list(p, gl->which, member)) {
+ pprintf(p, "[%s] is not in %s %s list.\n", member, yourthe, listname);
+ if (loadme && !connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ list_sub(p, gl->which, member);
+ }
+ pprintf(p, "[%s] %s %s %s list.\n", member, addrem, yourthe, listname);
+
+ if (!personal) {
+ FILE *fp;
+ char filename[MAX_FILENAME_SIZE];
+
+ switch (gl->which) {
+ case L_MUZZLE:
+ case L_CMUZZLE:
+ case L_C1MUZZLE:
+ case L_C24MUZZLE:
+ case L_C46MUZZLE:
+ case L_C49MUZZLE:
+ case L_C50MUZZLE:
+ case L_C51MUZZLE:
+ case L_ABUSER:
+ case L_BAN:
+ pprintf(p, "Please leave a comment to explain why %s was %s the %s list.\n", member, addrem, listname);
+ pcommand(p, "addcomment %s %s %s list.\n", member, addrem, listname);
+ break;
+ case L_COMPUTER:
+ if (player_globals.parray[p1].b_stats.rating > 0)
+ UpdateRank(TYPE_BLITZ, member, &player_globals.parray[p1].b_stats, member);
+ if (player_globals.parray[p1].s_stats.rating > 0)
+ UpdateRank(TYPE_STAND, member, &player_globals.parray[p1].s_stats, member);
+ if (player_globals.parray[p1].w_stats.rating > 0)
+ UpdateRank(TYPE_WILD, member, &player_globals.parray[p1].w_stats, member);
+ break;
+ case L_ADMIN:
+ if (addsub == 1) { /* adding to list */
+ player_globals.parray[p1].adminLevel = 10;
+ pprintf(p, "%s has been given an admin level of 10 - change with asetadmin.\n", member);
+ } else {
+ player_globals.parray[p1].adminLevel = 0;
+ }
+ break;
+ case L_FILTER:
+ case L_REMOVEDCOM:
+ default:
+ break;
+ }
+
+ if (loadme && connected)
+ pprintf_prompt(p1, "You have been %s the %s list by %s.\n",
+ addrem, listname, pp->name);
+
+ sprintf(filename, "%s/%s", LISTS_DIR, listname);
+ fp = fopen_s(filename, "w");
+ if (fp == NULL) {
+ d_printf( "Couldn't save %s list.\n", listname);
+ } else {
+ int i;
+ for (i = 0; i < gl->numMembers; i++)
+ fprintf(fp, "%s\n", gl->m_member[i]);
+ fclose(fp);
+ }
+ }
+ if (loadme || (gl->which == L_ADMIN)) {
+ player_save(p1);
+ }
+ if (loadme && !connected) {
+ player_remove(p1);
+ }
+ return COM_OK;
+}
+
+int com_addlist(int p, param_list param)
+{
+ return list_addsub(p, param[0].val.word, param[1].val.word, 1);
+}
+
+int com_sublist(int p,param_list param)
+{
+ return list_addsub(p, param[0].val.word, param[1].val.word, 2);
+}
+
+/* toggle being in a list */
+int com_togglelist(int p,param_list param)
+{
+ char *list = param[0].val.word;
+ char *val = param[1].val.word;
+ struct List *gl = list_findpartial(p, list, 0);
+ if (!gl) {
+ pprintf(p, "'%s' does not match any list name.\n", list);
+ return COM_FAILED;
+ }
+ if (in_list(p, gl->which, val)) {
+ return com_sublist(p, param);
+ }
+ return com_addlist(p, param);
+}
+
+int com_showlist(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ struct List *gl;
+ int i, rights;
+
+ char *rightnames[] = {"EDIT HEAD, READ ADMINS", "EDIT GODS, READ ADMINS", "READ/WRITE ADMINS", "PUBLIC", "PERSONAL"};
+
+ if (param[0].type == 0) { /* Show all lists */
+ pprintf(p, "Lists:\n\n");
+ for (i = 0; ListArray[i].name != NULL; i++) {
+ rights = ListArray[i].rights;
+ if ((rights > P_ADMIN) || (pp->adminLevel >= ADMIN_ADMIN))
+ pprintf(p, "%-20s is %s\n", ListArray[i].name, rightnames[rights]);
+ }
+ } else { /* find match in index */
+ gl = list_findpartial(p, param[0].val.word, 0);
+ if (!gl) {
+ return COM_OK;
+ }
+ rights = ListArray[gl->which].rights;
+ /* display the list */
+ {
+ multicol *m = multicol_start(gl->numMembers);
+
+ pprintf(p, "-- %s list: %d %s --", ListArray[gl->which].name,
+ gl->numMembers,
+ ((!(strcmp(ListArray[gl->which].name,"filter"))) ? "ips" : (!(strcmp(ListArray[gl->which].name,"removedcom"))) ? "commands" : (!(strcmp(ListArray[gl->which].name,"channel"))) ? "channels" : "names"));
+ for (i = 0; i < gl->numMembers; i++)
+ multicol_store_sorted(m, gl->m_member[i]);
+ multicol_pprint(m, p, pp->d_width, 2);
+ multicol_end(m);
+ }
+ }
+ return COM_OK;
+}
+
+int list_channels(int p,int p1)
+{
+ struct player *pp = &player_globals.parray[p];
+ struct List *gl;
+ int i, rights;
+
+ gl = list_findpartial(p1, "channel", 0);
+ if (!gl) {
+ return 1;
+ }
+ rights = ListArray[gl->which].rights;
+ /* display the list */
+ if (gl->numMembers == 0)
+ return 1;
+ {
+ multicol *m = multicol_start(gl->numMembers);
+
+ for (i = 0; i < gl->numMembers; i++)
+ multicol_store_sorted(m, gl->m_member[i]);
+ multicol_pprint(m, p, pp->d_width, 1);
+ multicol_end(m);
+ }
+ return 0;
+}
+
+/* free the memory used by a list */
+void list_free(struct List * gl)
+{
+ int i;
+ struct List *temp;
+
+ while (gl) {
+ for (i = 0; i < gl->numMembers; i++) {
+ FREE(gl->m_member[i]);
+ }
+ FREE(gl->m_member);
+ temp = gl->next;
+ free(gl);
+ gl = temp;
+ }
+}
+
+/* check lists for validity - pure paranoia */
+void lists_validate(int p)
+{
+ struct player *pp = &player_globals.parray[p];
+ struct List *gl;
+
+ for (gl=pp->lists; gl; gl=gl->next) {
+ if (gl->numMembers && !gl->m_member) {
+ gl->numMembers = 0;
+ }
+ }
+}
+
+
+int titled_player(int p,char* name)
+{
+ if ((in_list(p, L_FM, name)) ||
+ (in_list(p, L_IM, name)) ||
+ (in_list(p, L_GM, name)) ||
+ (in_list(p, L_WGM, name))) {
+ return 1;
+ }
+ return 0;
+}
+
--- /dev/null
+
+#ifndef _LISTS_H
+#define _LISTS_H
+
+/* yes, it's all cheesy.. there is no significance to the order, but make
+ sure it matches the order in lists.c */
+
+GENSTRUCT enum ListWhich {L_ADMIN = 0, L_REMOVEDCOM, L_FILTER, L_BAN, L_ABUSER,
+ L_MUZZLE, L_CMUZZLE, L_C1MUZZLE, L_C24MUZZLE, L_C46MUZZLE, L_C49MUZZLE,
+ L_C50MUZZLE, L_C51MUZZLE, L_FM, L_IM, L_GM, L_WGM, L_BLIND, L_TEAMS,
+ L_COMPUTER, L_TD,
+ L_CENSOR, L_GNOTIFY, L_NOPLAY, L_NOTIFY, L_CHANNEL, L_FOLLOW,
+ L_REMOTE,
+ L_LASTLIST /* this MUST be the last list, add all lists before it */
+};
+
+GENSTRUCT enum ListPerm {P_HEAD = 0, P_GOD, P_ADMIN, P_PUBLIC, P_PERSONAL};
+
+typedef struct {enum ListPerm rights; char *name;} ListTable;
+
+GENSTRUCT struct List {
+ enum ListWhich which;
+ int numMembers;
+ char **m_member; _LEN(numMembers)
+ struct List *next;
+};
+
+
+#endif /* _LISTS_H */
--- /dev/null
+/*
+ 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 2 of the License, 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.
+*/
+
+
+#include "includes.h"
+
+#define COMPUTER_FILE LISTS_DIR "/computer"
+
+static char *rnames[] = {"std", "blitz", "wild", "lightning"};
+
+typedef struct _ratings {
+ int rating;
+ int num;
+ double rd;
+ long ltime;
+} ratings;
+
+typedef struct _Entry {
+ char name[MAX_LOGIN_NAME+2];
+ ratings r[4];
+ int computer;
+} ENTRY;
+
+static ENTRY **list;
+static ENTRY **sortme;
+
+unsigned chessd_reload_flag;
+
+static void copy_stats(ratings *r, struct statistics *s)
+{
+ r->num = s->num;
+ r->rating = s->rating;
+ r->rd = s->sterr;
+ r->ltime = s->ltime;
+}
+
+/*
+ read a player file using the new generic and extensible format
+*/
+static int GetPlayerInfo(char *fileName, ENTRY *e)
+{
+ char *s, *s2;
+ struct player player;
+ unsigned version;
+
+ s = file_load(fileName, NULL);
+ if (!s) {
+ d_printf("Error reading player file '%s'\n", fileName);
+ return 0;
+ }
+
+ if (sscanf(s, "v %u", &version) != 1 ||
+ (version != 100 && version != 9)) {
+ free(s);
+ return 0;
+ }
+
+ /* skip first line */
+ s2 = strchr(s, '\n');
+
+ ZERO_STRUCT(player);
+
+ if (!s2 || unmarshall_player(&player, s2) != 0) {
+ d_printf("Error unmarshalling player data in '%s'!\n", fileName);
+ free(s);
+ return 0;
+ }
+ free(s);
+
+ strcpy(e->name, player.name);
+ copy_stats(&e->r[0], &player.s_stats);
+ copy_stats(&e->r[1], &player.b_stats);
+ copy_stats(&e->r[2], &player.w_stats);
+ copy_stats(&e->r[3], &player.l_stats);
+
+ player_free(&player);
+
+ return 1;
+}
+
+static int LoadEntries(void)
+{
+ int listsize;
+ FILE *fpPlayerList;
+ char letter1;
+ char *command;
+ char pathInput[80];
+ ENTRY e;
+ int len, n = 0;
+
+ listsize = 100;
+ list = malloc(sizeof(ENTRY *)*listsize);
+
+ for (letter1 = 'a'; letter1 <= 'z'; letter1++) {
+ printf("Loading %c's.\n", letter1);
+ sprintf(pathInput, "%s/%c", PLAYER_DIR, letter1);
+ asprintf(&command, "ls -1 %s", pathInput);
+ fpPlayerList = popen(command, "r");
+ free(command);
+
+ if (fpPlayerList == NULL)
+ continue;
+ while (1) {
+ fgets(e.name, MAX_LOGIN_NAME, fpPlayerList);
+ if (feof(fpPlayerList))
+ break;
+ len = strlen(e.name);
+ e.name[len - 1] = '\0';
+ if (e.name[0] != letter1)
+ printf("File %c/%s: wrong directory.\n", letter1, e.name);
+ else {
+ sprintf(pathInput, "%s/%c/%s", PLAYER_DIR, letter1, e.name);
+ if (GetPlayerInfo(pathInput, &e)) {
+ if ((list[n] = malloc(sizeof(ENTRY))) == NULL) {
+ d_printf( "malloc() failed!\n");
+ } else {
+ memcpy(list[n], &e, sizeof(ENTRY));
+ n++;
+ if (n == listsize) {
+ listsize += 100;
+ list = realloc(list, listsize*sizeof(ENTRY *));
+ }
+ }
+ }
+ }
+ }
+ pclose(fpPlayerList);
+ }
+ return (n);
+}
+
+static int SetComputers(int n)
+{
+ FILE *fpComp;
+ int i = 0;
+ char *line, comp[30];
+
+ asprintf(&line, "sort -f %s", COMPUTER_FILE);
+ fpComp = popen(line, "r");
+ free(line);
+
+ if (fpComp == NULL)
+ return 0;
+ while (i < n) {
+ fgets(comp, 29, fpComp);
+ if (feof(fpComp))
+ break;
+ comp[strlen(comp) - 1] = '\0';
+
+ while (i < n && strcasecmp(list[i]->name, comp) < 0)
+ i++;
+
+ if (i < n && strcasecmp(list[i]->name, comp) == 0) {
+ list[i++]->computer = 1;
+ }
+ }
+ pclose(fpComp);
+ return(1);
+}
+
+static int rtype;
+
+static int sortfunc(const void *i, const void *j)
+{
+ int n = (*(ENTRY **)j)->r[rtype].rating - (*(ENTRY **)i)->r[rtype].rating;
+ return n ? n : strcasecmp((*(ENTRY **)i)->name, (*(ENTRY **)j)->name);
+}
+
+static void makerank(void)
+{
+ int sortnum, sortmesize, i, n;
+ FILE *fp;
+ char *fName;
+ long now = time(NULL);
+
+ printf("Loading players\n");
+ n = LoadEntries();
+ printf("Found %d players.\n", n);
+ printf("Setting computers.\n");
+ SetComputers(n);
+
+ for (rtype = 0; rtype < 4; rtype++) {
+ sortnum = 0; sortmesize = 100;
+ sortme = malloc(sizeof(ENTRY *)*sortmesize);
+
+ for (i = 0; i < n; i++) {
+ if (list[i]->r[rtype].rating) {
+ sortme[sortnum++] = list[i];
+ if (sortnum == sortmesize) {
+ sortmesize += 100;
+ sortme = realloc(sortme, sortmesize*sizeof(ENTRY *));
+ }
+ }
+ }
+ printf("Sorting %d %s.\n", sortnum, rnames[rtype]);
+ qsort(sortme, sortnum, sizeof(ENTRY *), sortfunc);
+ printf("Saving to file.\n");
+ asprintf(&fName, "%s/rank.%s", STATS_DIR, rnames[rtype]);
+ fp = fopen_s(fName, "w");
+ free(fName);
+
+ for (i = 0; i < sortnum; i++)
+ fprintf(fp, "%s %d %d %d %f\n", sortme[i]->name,
+ sortme[i]->r[rtype].rating, sortme[i]->r[rtype].num,
+ sortme[i]->computer, current_sterr(sortme[i]->r[rtype].rd,
+ now - sortme[i]->r[rtype].ltime));
+ fclose(fp);
+ free(sortme);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ if (argc > 1) {
+ printf("usage: %s.\n", argv[0]);
+ exit(0);
+ } else {
+ makerank();
+ }
+ return (0);
+}
+
--- /dev/null
+/*
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+/*
+ a malloc wrapper library for the dynamically loaded part of
+ chessd. This is used both as a malloc checker library and to prevent
+ some bad interactions between the dl library and malloc
+*/
+
+
+#include "includes.h"
+#undef free
+#undef malloc
+
+#define MAGIC1 0x28021967
+#define MAGIC2 0x26011966
+
+struct malloc_list {
+ void *ptr;
+ struct malloc_list *next;
+ struct malloc_list *prev;
+};
+
+static struct malloc_list *mlist;
+static int m_total;
+
+struct malloc_header {
+ struct malloc_list *m;
+ unsigned size;
+ unsigned magic;
+};
+
+/*
+ a magic-value protected malloc wrapper,
+ which can be globally freed using a single call
+*/
+void *m_malloc(size_t size)
+{
+ void *ptr;
+ struct malloc_list *m;
+ struct malloc_header *h;
+
+ if (size == 0) return NULL;
+
+ ptr = malloc(size+sizeof(struct malloc_header));
+
+ if (!ptr) return NULL;
+
+ m = malloc(sizeof(*m));
+
+#if MALLOC_DEBUG
+ fprintf(stderr,"malloc %p %u\n", ptr, size);
+ fprintf(stderr,"malloc %p\n", m);
+#endif
+
+ if (!m) {
+ free(ptr);
+ return NULL;
+ }
+
+ m->ptr = ptr;
+ m->next = mlist;
+ m->prev = NULL;
+ if (mlist) {
+ mlist->prev = m;
+ }
+ mlist = m;
+
+ m_total++;
+
+ memset(ptr, 0, size+sizeof(struct malloc_header));
+
+ h = ptr;
+ h->size = size;
+ h->magic = MAGIC1;
+ h->m = m;
+
+ return (void *)(h+1);
+}
+
+/*
+ determine the size of a malloced region
+*/
+static size_t m_malloc_size(void *ptr)
+{
+ struct malloc_header *h;
+ if (!ptr) return 0;
+
+ h = (struct malloc_header *)ptr;
+ h--;
+
+ return h->size;
+}
+
+/*
+ check that a pointer is OK
+*/
+void m_malloc_check(void *ptr)
+{
+ struct malloc_header *h;
+
+ if (!ptr) return;
+
+ h = (struct malloc_header *)ptr;
+ h--;
+
+ if (h->magic != MAGIC1) {
+ d_printf("malloc corruption ptr=%p v1=%x size=%d\n",
+ ptr, h->magic, h->size);
+ }
+}
+
+/*
+ a paranoid free() function that checks for simple corruption
+*/
+int m_free(void *ptr)
+{
+ struct malloc_header *h;
+ struct malloc_list *m;
+
+ if (!ptr) return 0;
+
+ h = (struct malloc_header *)ptr;
+ h--;
+
+ if (h->magic != MAGIC1) {
+ d_printf("malloc corruption ptr=%p v1=%x size=%d\n",
+ ptr, h->magic, h->size);
+ return -1;
+ }
+
+ m = h->m;
+ if (!m || m->ptr != h) {
+ d_printf("malloc list corruption!\n");
+ }
+ if (m->next) {
+ m->next->prev = m->prev;
+ }
+ if (m->prev) {
+ m->prev->next = m->next;
+ }
+ if (m == mlist) {
+ mlist = m->next;
+ }
+
+ m_total--;
+
+#if MALLOC_DEBUG
+ fprintf(stderr,"free %p %u\n", h, h->size);
+ fprintf(stderr,"free %p\n", m);
+#endif
+
+ memset(ptr, 'Z', h->size); /* paranoia */
+ memset(m, 0, sizeof(*m));
+ free(m);
+ memset(h, 0, sizeof(*h));
+ free(h);
+ return 0;
+}
+
+/*
+ check all allocated memory
+*/
+void m_check_all(void)
+{
+ struct malloc_list *m;
+ for (m=mlist; m; m=m->next) {
+ m_malloc_check(m->ptr + sizeof(struct malloc_header));
+ }
+}
+
+
+/*
+ free all allocated memory
+*/
+void m_free_all(void)
+{
+ struct malloc_list *m, *next;
+ d_printf("Freeing %d chunks\n", m_total);
+ for (m=mlist; m; m=next) {
+ next = m->next;
+ m_total--;
+
+#if MALLOC_DEBUG
+ fprintf(stderr,"free %p\n", m->ptr);
+ fprintf(stderr,"free %p\n", m);
+#endif
+ free(m->ptr);
+ free(m);
+ }
+ mlist = NULL;
+}
+
+/* a calloc wrapper */
+void *m_calloc(size_t n, size_t size)
+{
+ void *ptr;
+ ptr = m_malloc(n*size);
+ if (ptr) memset(ptr, 0, n*size);
+ return ptr;
+}
+
+/* strdup wrapper */
+char *m_strdup(const char *s)
+{
+ int len = strlen(s);
+ char *ret;
+ ret = m_malloc(len+1);
+ memcpy(ret, s, len+1);
+ return ret;
+}
+
+/* strndup wrapper */
+char *m_strndup(const char *s, size_t n)
+{
+ int len = strnlen(s, n);
+ char *ret;
+ ret = m_malloc(len+1);
+ memcpy(ret, s, len);
+ ret[len] = 0;
+ return ret;
+}
+
+/* a free() call that zeros the pointer to prevent re-use */
+void m_safe_free(void **ptr, const char *file, unsigned line)
+{
+ if (!*ptr) {
+ d_printf("NULL free at %s(%u)!\n", file, line);
+ return;
+ }
+ if (m_free(*ptr) != 0) {
+ d_printf("bad free at %s(%u)!\n", file, line);
+ }
+ (*ptr) = NULL;
+}
+
+
+/* a vasprintf wrapper */
+int m_vasprintf(char **strp, const char *fmt, va_list ap)
+{
+ int n;
+
+ (*strp) = NULL;
+
+ n = vsnprintf(NULL, 0, fmt, ap);
+ if (n == 0) return 0;
+
+ (*strp) = m_malloc(n+1);
+ n = vsnprintf(*strp, n+1, fmt, ap);
+
+ return n;
+}
+
+/* a asprintf wrapper */
+int m_asprintf(char **strp, const char *fmt, ...)
+{
+ int n;
+ va_list ap;
+
+ va_start(ap, fmt);
+ n = m_vasprintf(strp, fmt, ap);
+ va_end(ap);
+
+ return n;
+}
+
+/* a realloc wrapper */
+void *m_realloc(void *ptr, size_t size)
+{
+ void *ret;
+ size_t msize;
+
+ if (!ptr) {
+ return m_malloc(size);
+ }
+
+ if (size == 0) {
+ m_safe_free(&ptr, __FILE__, __LINE__);
+ return NULL;
+ }
+
+ ret = m_malloc(size);
+
+ msize = m_malloc_size(ptr);
+ memcpy(ret, ptr, size<msize?size:msize);
+ m_safe_free(&ptr, __FILE__, __LINE__);
+ return ret;
+}
--- /dev/null
+/*
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+
+
+#undef malloc
+#undef free
+#undef calloc
+#undef strdup
+#undef strndup
+#undef vasprintf
+#undef asprintf
+#undef realloc
+
+#define malloc m_malloc
+#define calloc m_calloc
+#define strdup m_strdup
+#define strndup m_strndup
+#define vasprintf m_vasprintf
+#define asprintf m_asprintf
+#define realloc m_realloc
+
+#define free(x) m_safe_free((void **)&(x), __FILE__, __LINE__)
+#define FREE(x) ((x)?free(x),(x)=NULL:0)
--- /dev/null
+/*
+ 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 2 of the License, 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.
+*/
+
+/**
+ matchproc.c
+ Feb 9 1996 - rewritten - DAV
+
+*/
+
+#include "includes.h"
+
+const char *colorstr[] = {"", "[black] ", "[white] "};
+static const char *adjustr[] = {"", " (adjourned)"};
+
+static void prepare_match(int g,int wt,int bt,int winc,int binc,int wp, int bp,int rated)
+{
+
+ wt = wt * 60; /* To Seconds */
+ bt = bt * 60;
+ game_globals.garray[g].white = wp;
+ game_globals.garray[g].black = bp;
+ strcpy(game_globals.garray[g].white_name, player_globals.parray[wp].name);
+ strcpy(game_globals.garray[g].black_name, player_globals.parray[bp].name);
+ game_globals.garray[g].status = GAME_ACTIVE;
+ if ((game_globals.garray[g].type == TYPE_UNTIMED) || (game_globals.garray[g].type == TYPE_NONSTANDARD))
+ game_globals.garray[g].rated = 0;
+ else
+ game_globals.garray[g].rated = rated;
+ game_globals.garray[g].private = BoolCheckPFlag(wp, PFLAG_PRIVATE)
+ || BoolCheckPFlag(bp, PFLAG_PRIVATE);
+ game_globals.garray[g].white = wp;
+ if (game_globals.garray[g].type == TYPE_BLITZ) {
+ game_globals.garray[g].white_rating = player_globals.parray[wp].b_stats.rating;
+ game_globals.garray[g].black_rating = player_globals.parray[bp].b_stats.rating;
+ } else if (game_globals.garray[g].type == TYPE_WILD) {
+ game_globals.garray[g].white_rating = player_globals.parray[wp].w_stats.rating;
+ game_globals.garray[g].black_rating = player_globals.parray[bp].w_stats.rating;
+ } else if (game_globals.garray[g].type == TYPE_LIGHT) {
+ game_globals.garray[g].white_rating = player_globals.parray[wp].l_stats.rating;
+ game_globals.garray[g].black_rating = player_globals.parray[bp].l_stats.rating;
+ } else if (game_globals.garray[g].type == TYPE_BUGHOUSE) {
+ game_globals.garray[g].white_rating = player_globals.parray[wp].bug_stats.rating;
+ game_globals.garray[g].black_rating = player_globals.parray[bp].bug_stats.rating;
+ } else {
+ game_globals.garray[g].white_rating = player_globals.parray[wp].s_stats.rating;
+ game_globals.garray[g].black_rating = player_globals.parray[bp].s_stats.rating;
+ }
+
+ game_globals.garray[g].game_state.gameNum = g;
+
+ game_globals.garray[g].wTime = wt * 10;
+ game_globals.garray[g].wInitTime = wt * 10;
+ game_globals.garray[g].wIncrement = winc * 10;
+ game_globals.garray[g].bTime = bt * 10;
+
+ if (game_globals.garray[g].type != TYPE_UNTIMED) {
+ if (wt == 0)
+ game_globals.garray[g].wTime = 100;
+ if (bt == 0)
+ game_globals.garray[g].bTime = 100;
+ } /* 0 x games start with 10 seconds */
+
+ game_globals.garray[g].wRealTime = game_globals.garray[g].wTime * 100;
+ game_globals.garray[g].bRealTime = game_globals.garray[g].bTime * 100;
+ game_globals.garray[g].wTimeWhenReceivedMove = 0;
+ game_globals.garray[g].bTimeWhenReceivedMove = 0;
+
+ game_globals.garray[g].bInitTime = bt * 10;
+ game_globals.garray[g].bIncrement = binc * 10;
+
+ if (game_globals.garray[g].game_state.onMove == BLACK) { /* Start with black */
+ game_globals.garray[g].numHalfMoves = 1;
+ game_globals.garray[g].moveListSize = 1;
+ game_globals.garray[g].moveList = (struct move_t *) malloc(sizeof(struct move_t));
+ game_globals.garray[g].moveList[0].fromFile = -1;
+ game_globals.garray[g].moveList[0].fromRank = -1;
+ game_globals.garray[g].moveList[0].toFile = -1;
+ game_globals.garray[g].moveList[0].toRank = -1;
+ game_globals.garray[g].moveList[0].color = WHITE;
+ strcpy(game_globals.garray[g].moveList[0].moveString, "NONE");
+ strcpy(game_globals.garray[g].moveList[0].algString, "NONE");
+ } else {
+ game_globals.garray[g].numHalfMoves = 0;
+ game_globals.garray[g].moveListSize = 0;
+ game_globals.garray[g].moveList = NULL;
+ }
+
+ game_globals.garray[g].timeOfStart = tenth_secs();
+ game_globals.garray[g].startTime = tenth_secs();
+ game_globals.garray[g].lastMoveTime = game_globals.garray[g].startTime;
+ game_globals.garray[g].lastDecTime = game_globals.garray[g].startTime;
+ game_globals.garray[g].clockStopped = 0;
+
+}
+
+static void pick_colors(int* wp,int* bp,int white,int wt,int bt,int winc,
+ int binc)
+
+{
+ int reverse = 0;
+
+ if (white == 0) {
+ reverse = 1; /* did challenger ask for black? */
+
+ } else if (white == -1) { /* unknown */
+
+ if ((wt == bt) && (winc == binc)) { /* if diff times challenger is white */
+
+ if (CheckPFlag(*wp, PFLAG_LASTBLACK)==CheckPFlag(*bp, PFLAG_LASTBLACK)) {
+ if ((player_globals.parray[*wp].num_white - player_globals.parray[*wp].num_black) >
+ (player_globals.parray[*bp].num_white - player_globals.parray[*bp].num_black))
+ reverse = 1; /* whose played the most extra whites gets black */
+
+ } else if (!CheckPFlag(*wp, PFLAG_LASTBLACK))
+ reverse = 1;
+
+ } else
+ reverse = 1;
+ }
+ if (reverse) {
+ int tmp = *wp;
+ *wp = *bp;
+ *bp = tmp;
+ }
+}
+
+static void output_match_messages(int wp,int bp,int g, char* mess)
+{
+
+ int printed;
+ int avail_printed = 0;
+ char notavail_white[200];
+ char notavail_black[200];
+ int p;
+ char *outStr;
+
+ notavail_white[0] = '\0';
+ notavail_black[0] = '\0';
+
+ asprintf(&outStr,"\nCreating: %s (%d) %s (%d) %s %s %d %d\n",
+ player_globals.parray[wp].name,
+ game_globals.garray[g].white_rating,
+ player_globals.parray[bp].name,
+ game_globals.garray[g].black_rating,
+ rstr[game_globals.garray[g].rated],
+ bstr[game_globals.garray[g].type],
+ game_globals.garray[g].wInitTime,
+ game_globals.garray[g].wIncrement);
+ pprintf(wp, "%s", outStr);
+ pprintf(bp, "%s", outStr);
+ free(outStr);
+
+ asprintf(&outStr, "\n{Game %d (%s vs. %s) %s %s %s match.}\n",
+ g + 1, player_globals.parray[wp].name,
+ player_globals.parray[bp].name,
+ mess,
+ rstr[game_globals.garray[g].rated],
+ bstr[game_globals.garray[g].type]);
+ pprintf(wp, "%s", outStr);
+ pprintf(bp, "%s", outStr);
+
+ if (!(player_num_active_boards(wp)) && CheckPFlag(wp, PFLAG_OPEN))
+/* open may be 0 if a simul */
+ getnotavailmess(wp,notavail_white);
+ if (CheckPFlag(bp, PFLAG_OPEN))
+ getnotavailmess(bp,notavail_black);
+ for (p = 0; p < player_globals.p_num; p++) {
+ struct player *pp = &player_globals.parray[p];
+ int gnw, gnb;
+ printed = 0;
+
+ if ((p == wp) || (p == bp))
+ continue;
+ if (pp->status != PLAYER_PROMPT)
+ continue;
+ if (CheckPFlag(p, PFLAG_GIN)) {
+ pprintf(p, "%s", outStr);
+ printed = 1;
+ }
+ gnw = in_list(p, L_GNOTIFY, player_globals.parray[wp].login);
+ gnb = in_list(p, L_GNOTIFY, player_globals.parray[bp].login);
+ if (gnw || gnb) {
+ pprintf(p, "\nGame notification: ");
+
+ if (gnw)
+ pprintf_highlight(p, player_globals.parray[wp].name);
+ else
+ pprintf(p, player_globals.parray[wp].name);
+
+ pprintf(p, " (%s) vs. ",
+ ratstr(GetRating(&player_globals.parray[wp], game_globals.garray[g].type)));
+
+ if (gnb)
+ pprintf_highlight(p, player_globals.parray[bp].name);
+ else
+ pprintf(p, player_globals.parray[bp].name);
+ pprintf(p, " (%s) %s %s %d %d: Game %d\n",
+ ratstr(GetRating(&player_globals.parray[bp], game_globals.garray[g].type)),
+ rstr[game_globals.garray[g].rated], bstr[game_globals.garray[g].type],
+ game_globals.garray[g].wInitTime/600, game_globals.garray[g].wIncrement/10, g+1);
+
+ printed = 1;
+ }
+
+ if (CheckPFlag(p, PFLAG_AVAIL) && CheckPFlag(p, PFLAG_OPEN) && (pp->game < 0) &&
+ (CheckPFlag(wp, PFLAG_OPEN) || CheckPFlag(bp, PFLAG_OPEN))) {
+
+ if (((player_globals.parray[wp].b_stats.rating <= pp->availmax) &&
+ (player_globals.parray[wp].b_stats.rating >= pp->availmin)) ||
+ (!pp->availmax)) {
+ pprintf (p,"\n%s",notavail_white);
+ avail_printed = 1;
+ }
+
+ if (((player_globals.parray[bp].b_stats.rating <= pp->availmax) &&
+ (player_globals.parray[bp].b_stats.rating >= pp->availmin)) ||
+ (!pp->availmax)) {
+ pprintf (p,"\n%s",notavail_black);
+ avail_printed = 1;
+ }
+
+ if (avail_printed) {
+ printed = 1;
+ avail_printed = 0;
+ pprintf (p,"\n");
+ } /* was black or white open originally (for simuls) */
+ }
+
+ if (printed)
+ send_prompt (p);
+ }
+
+ free(outStr);
+}
+
+int create_new_match(int g, int white_player, int black_player,
+ int wt, int winc, int bt, int binc,
+ int rated, char *category, char *board,
+ int white, int simul)
+{
+
+ remove_request(white_player, black_player, -PEND_PARTNER);
+
+ pick_colors(&white_player,&black_player,white,wt,bt,winc,binc);
+
+ decline_withdraw_offers(white_player,-1, PEND_MATCH,DO_WITHDRAW | DO_DECLINE);
+ decline_withdraw_offers(black_player,-1, PEND_MATCH,DO_WITHDRAW | DO_DECLINE);
+ decline_withdraw_offers(black_player,-1, PEND_SIMUL,DO_WITHDRAW | DO_DECLINE);
+ if (simul) {
+ decline_withdraw_offers(white_player, -1, PEND_SIMUL, DO_WITHDRAW);
+ } else {
+ decline_withdraw_offers(white_player, -1, PEND_SIMUL,
+ DO_WITHDRAW | DO_DECLINE);
+ }
+ if (board_init(g,&game_globals.garray[g].game_state, category, board)) {
+ pprintf(white_player, "PROBLEM LOADING BOARD. Game Aborted.\n");
+ pprintf(black_player, "PROBLEM LOADING BOARD. Game Aborted.\n");
+ d_printf( "CHESSD: PROBLEM LOADING BOARD %s %s. Game Aborted.\n",
+ category, board);
+ game_remove(g);
+ return COM_FAILED;
+ }
+
+ if (simul)
+ game_globals.garray[g].type = TYPE_UNTIMED;
+ else
+ game_globals.garray[g].type = game_isblitz(wt, winc, bt, binc, category, board);
+
+ prepare_match(g,wt,bt,winc,binc,white_player,black_player,rated);
+
+ output_match_messages(white_player,black_player,g, "Creating");
+
+ player_globals.parray[white_player].game = g;
+ player_globals.parray[white_player].opponent = black_player;
+ player_globals.parray[white_player].side = WHITE;
+ player_globals.parray[white_player].promote = QUEEN;
+ player_globals.parray[black_player].game = g;
+ player_globals.parray[black_player].opponent = white_player;
+ player_globals.parray[black_player].side = BLACK;
+ player_globals.parray[black_player].promote = QUEEN;
+ send_boards(g);
+ gics_globals.userstat.games++;
+
+ /* obey any 'follow' lists */
+ follow_start(white_player,black_player);
+
+ return COM_OK;
+}
+
+int accept_match(struct pending *pend, int p, int p1)
+{
+ struct player *pp = &player_globals.parray[p];
+ int wt, winc, bt, binc, rated, white;
+ char category[50], board[50];
+ char tmp[100];
+ int bh = 0, partner = 0, pp1 = 0, g1, g2;
+
+ unobserveAll(p); /* stop observing when match starts */
+ unobserveAll(p1);
+
+ wt = pend->wtime;
+ winc = pend->winc;
+ bt = pend->btime;
+ binc = pend->binc;
+ rated = pend->rated;
+ strcpy (category, pend->category);
+ strcpy (board, pend->board_type);
+ white = (pend->seek_color == -1) ? -1 : 1 - pend->seek_color;
+
+ pprintf(p, "You accept the challenge of %s.\n", player_globals.parray[p1].name);
+ pprintf_prompt(p1, "\n%s accepts your challenge.\n", pp->name);
+
+ if(!pend->status)
+ delete_pending(pend);
+
+ withdraw_seeks(p);
+ withdraw_seeks(p1);
+
+ pend_join_match (p,p1);
+
+ if (game_isblitz(wt, winc, bt, binc, category, board) == TYPE_BUGHOUSE) {
+ bh = 1;
+
+ if ((partner = pp->partner) >= 0 &&
+ (pp1 = player_globals.parray[p1].partner) >= 0) {
+ unobserveAll(partner); /* stop observing when match starts */
+ unobserveAll(pp1);
+
+ pprintf(partner, "\nYour partner accepts the challenge of %s.\n", player_globals.parray[p1].name);
+ pprintf(pp1, "\n%s accepts your partner's challenge.\n", pp->name);
+
+ pend_join_match (partner,pp1);
+ } else {
+ return COM_OK;
+ }
+ }
+
+ g1 = game_new(); /* create a game structure */
+ if (g1 < 0) {
+ sprintf(tmp, "There was a problem creating the new match.\n");
+ pprintf(p, tmp);
+ pprintf_prompt(p1, tmp);
+ }
+
+ if (game_read(g1, p1, p) >= 0) {
+ int swap;
+ swap = p;
+ p = p1;
+ p1 = swap;
+ pp = &player_globals.parray[p];
+ } else if (game_read(g1, p, p1) < 0) { /* so no adjourned game */
+ if (create_new_match(g1,p, p1, wt, winc, bt, binc, rated, category, board, white,0) == COM_FAILED)
+ return COM_OK;
+
+ /* create first game */
+
+ if (bh) { /* do bughouse creation */
+
+ white = (pp->side == WHITE ? 0 : 1);
+ g2 = game_new();
+ if ((g2 < 0) || (create_new_match(g2,partner, pp1, wt, winc, bt, binc, rated, category, board,white,0) == COM_FAILED)) {
+ sprintf(tmp, "There was a problem creating the new match.\n");
+ pprintf_prompt(partner, tmp);
+ pprintf_prompt(pp1, tmp);
+ sprintf(tmp, "There was a problem creating your partner's match.\n");
+ game_remove(g1); /* abort first game */
+ return COM_OK;
+ }
+
+ game_globals.garray[g1].link = g2; /* link the games */
+ game_globals.garray[g2].link = g1;
+
+ sprintf(tmp, "\nYour partner is playing game %d (%s vs. %s).\n",
+ g2 + 1, game_globals.garray[g2].white_name, game_globals.garray[g2].black_name);
+ pprintf(p, tmp);
+ pprintf_prompt(p1, tmp);
+
+ sprintf(tmp, "\nYour partner is playing game %d (%s vs. %s).\n",
+ g1 + 1, game_globals.garray[g1].white_name, game_globals.garray[g1].black_name);
+ pprintf_prompt(partner, tmp);
+ pprintf_prompt(pp1, tmp);
+ }
+ return COM_OK;
+ }
+
+ /* resume adjourned game */
+
+ game_delete(p, p1); /* remove the game from disk */
+
+ sprintf(tmp, "{Game %d (%s vs. %s) Continuing %s %s match.}\n",
+ g1+1, pp->name, player_globals.parray[p1].name,
+ rstr[game_globals.garray[g1].rated], bstr[game_globals.garray[g1].type]);
+ pprintf(p, tmp);
+ pprintf(p1, tmp);
+ output_match_messages(p, p1, g1, "Continuing");
+
+ game_globals.garray[g1].white = p;
+ game_globals.garray[g1].black = p1;
+ game_globals.garray[g1].status = GAME_ACTIVE;
+ game_globals.garray[g1].result = END_NOTENDED;
+ game_globals.garray[g1].startTime = tenth_secs();
+ game_globals.garray[g1].lastMoveTime = game_globals.garray[g1].startTime;
+ game_globals.garray[g1].lastDecTime = game_globals.garray[g1].startTime;
+ pp->game = g1;
+ pp->opponent = p1;
+ pp->side = WHITE;
+ player_globals.parray[p1].game = g1;
+ player_globals.parray[p1].opponent = p;
+ player_globals.parray[p1].side = BLACK;
+
+ send_boards(g1);
+
+ /* obey any 'follow' lists */
+ follow_start(p,p1);
+
+ return COM_OK;
+}
+
+/* board and category are initially empty strings */
+static int parse_match_string(int p, int* wt,int* bt,int* winc,int* binc,
+ int* white,int* rated,char* category,
+ char* board, char* mstring)
+{
+ int numba;
+ int confused = 0;
+ char parsebuf[100];
+ int bughouse = 0;
+
+ while (!confused && (sscanf(mstring, " %99s", parsebuf) == 1)) {
+ mstring = eatword(eatwhite(mstring));
+
+ if ((category[0] != '\0') && (board[0] == '\0') && !bughouse)
+ strcpy(board, parsebuf);
+ else if (isdigit(*parsebuf)) {
+ if ((numba = atoi(parsebuf)) < 0) {
+ pprintf(p, "You can't specify negative time controls.\n");
+ return 0;
+ } else if (numba > 999) {
+ pprintf(p, "You can't specify time or inc above 999.\n");
+ return 0;
+ } else if (*wt == -1) {
+ *wt = numba;
+ } else if (*winc == -1) {
+ *winc = numba;
+ } else if (*bt == -1) {
+ *bt = numba;
+ } else if (*binc == -1) {
+ *binc = numba;
+ } else
+ confused = 1;
+
+ } else if ((!strcmp("rated", parsebuf)) || (!strcmp("r",parsebuf))) {
+ if (*rated == -1)
+ *rated = 1;
+ else
+ confused = 1;
+ } else if ((!strcmp("unrated", parsebuf)) || (!strcmp("u",parsebuf))) {
+ if (*rated == -1)
+ *rated = 0;
+ else
+ confused = 1;
+ } else if (!strcmp("white", parsebuf) || !strcmp ("w", parsebuf)) {
+ if (*white == -1)
+ *white = 1;
+ else
+ confused = 1;
+ } else if (!strcmp("black", parsebuf) || !strcmp ("b", parsebuf)) {
+ if (*white == -1)
+ *white = 0;
+ else
+ confused = 1;
+
+ } else if (category[0] == '\0') {
+ if ((parsebuf[0] == 'w') && (isdigit(*(parsebuf + 1)))) {
+ strcpy (category, "wild");
+ strcpy (board, parsebuf+1);
+ } else {
+ strcpy(category,parsebuf);
+ if (!strncmp("bughouse",category, strlen(category))
+ && strlen(category) >= 3) {
+ strcpy(category, "bughouse");
+ bughouse = 1;
+ }
+ }
+ } else
+ confused = 1;
+ }
+
+ if (confused) {
+ pprintf(p, "Can't interpret %s in match command.\n", parsebuf);
+ return 0;
+ }
+ return 1;
+}
+
+static void print_match_rating_info(int p,int p1,int type,int rated)
+{
+ if (rated) {
+ int win, draw, loss;
+ double newsterr;
+
+ rating_sterr_delta(p1, p, type, time(0), RESULT_WIN, &win, &newsterr);
+ rating_sterr_delta(p1, p, type, time(0), RESULT_DRAW, &draw, &newsterr);
+ rating_sterr_delta(p1, p, type, time(0), RESULT_LOSS, &loss, &newsterr);
+ pprintf(p1, "Your %s rating will change: Win: %s%d, Draw: %s%d, Loss: %s%d\n",
+ bstr[type],
+ (win >= 0) ? "+" : "", win,
+ (draw >= 0) ? "+" : "", draw,
+ (loss >= 0) ? "+" : "", loss);
+ pprintf(p1, "Your new RD will be %5.1f\n", newsterr);
+
+ rating_sterr_delta(p, p1, type, time(0), RESULT_WIN, &win, &newsterr);
+ rating_sterr_delta(p, p1, type, time(0), RESULT_DRAW, &draw, &newsterr);
+ rating_sterr_delta(p, p1, type, time(0), RESULT_LOSS, &loss, &newsterr);
+ pprintf(p, "Your %s rating will change: Win: %s%d, Draw: %s%d, Loss: %s%d\n",
+ bstr[type],
+ (win >= 0) ? "+" : "", win,
+ (draw >= 0) ? "+" : "", draw,
+ (loss >= 0) ? "+" : "", loss);
+ pprintf(p, "Your new RD will be %5.1f\n", newsterr);
+ }
+}
+
+static void check_lists_match(int p,int p1)
+{
+ struct player *pp = &player_globals.parray[p];
+ if (in_list(p, L_COMPUTER, pp->name)) {
+ pprintf(p1, "--** %s is a ", pp->name);
+ pprintf_highlight(p1, "computer");
+ pprintf(p1, " **--\n");
+ }
+ if (in_list(p, L_COMPUTER, player_globals.parray[p1].name)) {
+ pprintf(p, "--** %s is a ", player_globals.parray[p1].name);
+ pprintf_highlight(p, "computer");
+ pprintf(p, " **--\n");
+ }
+ if (in_list(p, L_ABUSER, pp->name)) {
+ pprintf(p1, "--** %s is in the ", pp->name);
+ pprintf_highlight(p1, "abuser");
+ pprintf(p1, " list **--\n");
+ }
+ if (in_list(p, L_ABUSER, player_globals.parray[p1].name)) {
+ pprintf(p, "--** %s is in the ", player_globals.parray[p1].name);
+ pprintf_highlight(p, "abuser");
+ pprintf(p, " list **--\n");
+ }
+}
+
+int com_match(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int adjourned; /* adjourned game? */
+ int g; /* more adjourned game junk */
+ int p1;
+ int bh = 0, partner = 0, pp1 = 0;
+ struct pending* pendfrom;
+ struct pending* pendto;
+ struct pending* pend;
+ int wt = -1; /* white start time */
+ int winc = -1; /* white increment */
+ int bt = -1; /* black start time */
+ int binc = -1; /* black increment */
+ int rated = -1; /* 1 = rated, 0 = unrated */
+ int white = -1; /* 1 = want white, 0 = want black */
+ char category[100], board[100];
+ textlist *clauses = NULL;
+ int type = 0;
+
+ category[0] ='\0';
+ board[0] ='\0';
+
+ if ((pp->game >= 0) && ((game_globals.garray[pp->game].status == GAME_EXAMINE)
+|| (game_globals.garray[pp->game].status == GAME_SETUP))) {
+
+ pprintf(p, "You can't challenge while you are examining a game.\n");
+ return COM_OK;
+ }
+
+ if (pp->game >= 0) {
+ pprintf(p, "You can't challenge while you are playing a game.\n");
+ return COM_OK;
+ }
+
+ stolower(param[0].val.word);
+ p1 = player_find_part_login(param[0].val.word);
+ if (p1 < 0) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+
+ if (p1 == p) { /* Allowing to match yourself to enter
+ analysis mode */
+ ExamineScratch (p, param, 0);
+ return COM_OK;
+ }
+
+ if (!CheckPFlag(p1, PFLAG_OPEN)) {
+ pprintf(p, "Player \"%s\" is not open to match requests.\n", player_globals.parray[p1].name);
+ return COM_OK;
+ }
+
+ if (player_globals.parray[p1].game >= 0) {
+ pprintf(p, "Player \"%s\" is involved in another game.\n", player_globals.parray[p1].name); return COM_OK;
+ }
+
+ if (CheckPFlag(p, PFLAG_TOURNEY) && !CheckPFlag(p1, PFLAG_TOURNEY)) {
+ pprintf(p, "You may only match players with their tournament variable set.\n");
+ return COM_OK;
+ }
+
+ if (!CheckPFlag(p, PFLAG_TOURNEY) && CheckPFlag(p1, PFLAG_TOURNEY)) {
+ pprintf(p, "%s is in a tournament, and cannot accept other challenges.\n", player_globals.parray[p1].name);
+ return COM_OK;
+ }
+
+ if (!CheckPFlag(p, PFLAG_OPEN)) {
+ PFlagON(p, PFLAG_OPEN);
+ pprintf(p, "Setting you open for matches.\n");
+ }
+
+
+/* look for an adjourned game between p and p1 */
+ g = game_new();
+ adjourned = (game_read(g, p, p1) >= 0) || (game_read(g, p1, p) >= 0);
+ if (adjourned) {
+ type = game_globals.garray[g].type;
+ wt = game_globals.garray[g].wInitTime / 600;
+ bt = game_globals.garray[g].bInitTime / 600;
+ winc = game_globals.garray[g].wIncrement / 10;
+ binc = game_globals.garray[g].bIncrement / 10;
+ rated = game_globals.garray[g].rated;
+ }
+ game_remove(g);
+
+ pendto = find_pend(p, p1, PEND_MATCH);
+
+ pendfrom = find_pend(p1, p, PEND_MATCH);
+
+ if (!adjourned) {
+ if (in_list(p1, L_NOPLAY, pp->login)) {
+ pprintf(p, "You are on %s's noplay list.\n", player_globals.parray[p1].name);
+ return COM_OK;
+ }
+ if (player_censored(p1, p)) {
+ pprintf(p, "Player \"%s\" is censoring you.\n", player_globals.parray[p1].name);
+ return COM_OK;
+ }
+ if (player_censored(p, p1)) {
+ pprintf(p, "You are censoring \"%s\".\n", player_globals.parray[p1].name);
+ return COM_OK;
+ }
+
+ if (param[1].type != TYPE_NULL) {
+ if (!parse_match_string(p, &wt,&bt,&winc,&binc,&white,&rated,category,
+ board,param[1].val.string))
+ return COM_OK; /* couldn't parse */
+ }
+
+ if (rated == -1)
+ rated = BoolCheckPFlag(p, PFLAG_RATED);
+ if (!CheckPFlag(p, PFLAG_REG) || !CheckPFlag(p1, PFLAG_REG))
+ rated = 0;
+
+ if (winc == -1)
+ winc = (wt == -1) ? pp->d_inc : 0; /* match 5 == match 5 0 */
+
+ if (wt == -1)
+ wt = pp->d_time;
+
+ if (bt == -1)
+ bt = wt;
+
+ if (binc == -1)
+ binc = winc;
+
+ if (category[0]) {
+ if (!board[0] && strcmp(category,"bughouse")) {
+ pprintf(p, "You must specify a board and a category.\n");
+ return COM_OK;
+
+ } else if (board[0]) { /* not bughouse */
+ char fname[MAX_FILENAME_SIZE];
+
+ sprintf(fname, "%s/%s/%s", BOARD_DIR, category, board);
+ if (!file_exists(fname)) {
+ pprintf(p, "No such category/board: %s/%s\n", category, board);
+ return COM_OK;
+ }
+ }
+ }
+ type = game_isblitz(wt, winc, bt, binc, category, board);
+
+ if (!strcmp(category, "bughouse")) {
+ type = TYPE_BUGHOUSE;
+ if (rated && pp->partner >= 0 && player_globals.parray[p1].partner >= 0) {
+ if (!CheckPFlag(pp->partner, PFLAG_REG)
+ || !CheckPFlag(player_globals.parray[p1].partner, PFLAG_REG))
+ rated = 0;
+ }
+ }
+ if (rated && (type == TYPE_NONSTANDARD)) {
+ pprintf(p, "Game is non-standard - reverting to unrated\n");
+ rated = 0;
+ }
+ if (rated && (type == TYPE_UNTIMED)) {
+ pprintf(p, "Game is untimed - reverting to unrated\n");
+ rated = 0;
+ }
+ if ((pendfrom == NULL) && !CheckPFlag(p1, PFLAG_ROPEN)
+ && (rated != BoolCheckPFlag(p1, PFLAG_RATED))) {
+ pprintf(p, "%s only wants to play %s games.\n", player_globals.parray[p1].name,
+ rstr[!rated]);
+ pprintf_highlight(p1, "Ignoring");
+ pprintf(p1, " %srated match request from %s.\n",
+ (rated ? "" : "un"), pp->name);
+ return COM_OK;
+ }
+
+ /* Now check formula. */
+ if (!adjourned
+ && !GameMatchesFormula(p,p1, wt,winc,bt,binc, rated, type, &clauses)) {
+ pprintf(p, "Match request does not fit formula for %s:\n",
+ player_globals.parray[p1].name);
+ pprintf(p, "%s's formula: %s\n", player_globals.parray[p1].name, player_globals.parray[p1].formula);
+ ShowClauses (p, p1, clauses);
+ ClearTextList(clauses);
+ pprintf_highlight(p1, "Ignoring");
+ pprintf_prompt(p1, " (formula): %s (%d) %s (%d) %s.\n",
+ pp->name,
+ GetRating(&player_globals.parray[p], type),
+ player_globals.parray[p1].name,
+ GetRating(&player_globals.parray[p1], type),
+ game_str(rated, wt * 60, winc, bt * 60, binc, category, board));
+ return COM_OK;
+ }
+
+ if (type == TYPE_BUGHOUSE) {
+ bh = 1;
+ partner = pp->partner;
+ pp1 = player_globals.parray[p1].partner;
+
+ if (pp < 0) {
+ pprintf(p, "You have no partner for bughouse.\n");
+ return COM_OK;
+ }
+ if (pp1 < 0) {
+ pprintf(p, "Your opponent has no partner for bughouse.\n");
+ return COM_OK;
+ }
+ if (partner == pp1) { /* should be an impossible case - DAV */
+ pprintf(p, "You and your opponent both chose the same partner!\n");
+ return COM_OK;
+ }
+ if (partner == p1 || pp1 == p) {
+ pprintf(p, "You and your opponent can't choose each other as partners!\n");
+ return COM_OK;
+ }
+ if (player_globals.parray[partner].partner != p) { /* another impossible case - DAV */
+ pprintf(p, "Your partner hasn't chosen you as his partner!\n");
+ return COM_OK;
+ }
+ if (player_globals.parray[pp1].partner != p1) { /* another impossible case - DAV */
+ pprintf(p, "Your opponent's partner hasn't chosen your opponent as his partner!\n");
+ return COM_OK;
+ }
+ if (!CheckPFlag(partner, PFLAG_OPEN) || player_globals.parray[partner].game >= 0) {
+ pprintf(p, "Your partner isn't open to play right now.\n");
+ return COM_OK;
+ }
+ if (!CheckPFlag(pp1, PFLAG_OPEN) || player_globals.parray[pp1].game >= 0) {
+ pprintf(p, "Your opponent's partner isn't open to play right now.\n");
+ return COM_OK;
+ }
+
+ /* Bypass NOPLAY lists, censored lists, ratedness, privacy, and formula for now */
+ /* Active challenger/ee will determine these. */
+ }
+ /* Ok match offer will be made */
+
+ } /* adjourned games shouldn't have to worry
+ about that junk? */
+ /* keep incase of adjourned bughouse in future*/
+
+ if (pendto != NULL) {
+ pprintf(p, "Updating offer already made to \"%s\".\n", player_globals.parray[p1].name);
+ }
+
+ if (pendfrom != NULL) {
+ if (pendto != NULL) {
+ pprintf(p, "Pending list error!.\n");
+ d_printf( "CHESSD: This shouldn't happen. You can't have a match pending from and to the same person.\n");
+ return COM_OK;
+ }
+
+ if (adjourned || ((wt == pendfrom->btime) &&
+ (winc == pendfrom->binc) &&
+ (bt == pendfrom->wtime) &&
+ (binc == pendfrom->winc) &&
+ (rated == pendfrom->rated) &&
+ ((white == -1) || (white + pendfrom->seek_color == 1)) &&
+ (!strcmp(category, pendfrom->category)) &&
+ (!strcmp(board, pendfrom->board_type)))) {
+ /* Identical match, should accept! */
+ accept_match(pendfrom,p, p1);
+ return COM_OK;
+
+ } else {
+ delete_pending(pendfrom);
+ }
+ }
+
+ if (pendto == NULL)
+ pend = add_pending(p,p1,PEND_MATCH);
+ else
+ pend = pendto;
+
+ pend->wtime = wt;
+ pend->winc = winc;
+ pend->btime = bt;
+ pend->binc = binc;
+ pend->rated = rated;
+ pend->seek_color = white;
+ pend->game_type = type;
+ pend->category = strdup(category);
+ pend->board_type = strdup (board);
+
+ if (pendfrom != NULL) {
+ pprintf(p, "Declining offer from %s and offering new match parameters.\n", player_globals.parray[p1].name);
+ pprintf(p1, "\n%s declines your match offer a match with these parameters:", pp->name);
+ }
+
+ if (pendto != NULL) {
+ pprintf(p, "Updating match request to: ");
+ pprintf(p1, "\n%s updates the match request.\n", pp->name);
+ } else {
+ pprintf(p, "Issuing: ");
+ pprintf(p1, "\n");
+ }
+
+ pprintf(p, "%s (%s) %s", pp->name,
+ ratstrii(GetRating(&player_globals.parray[p], type), p),
+ colorstr[white + 1]);
+ pprintf_highlight(p, "%s", player_globals.parray[p1].name);
+ pprintf(p, " (%s) %s%s.\n",
+ ratstrii(GetRating(&player_globals.parray[p1], type), p1),
+ game_str(rated, wt * 60, winc, bt * 60, binc, category, board),
+ adjustr[adjourned]);
+ pprintf(p1, "Challenge: ");
+ pprintf_highlight(p1, "%s", pp->name);
+ pprintf(p1, " (%s) %s",
+ ratstrii(GetRating(&player_globals.parray[p], type), p),
+ colorstr[white + 1]);
+ pprintf(p1, "%s (%s) %s%s.\n", player_globals.parray[p1].name,
+ ratstrii(GetRating(&player_globals.parray[p1], type), p1),
+ game_str(rated, wt * 60, winc, bt * 60, binc, category, board),
+ adjustr[adjourned]);
+ Bell (p1);
+
+ if (bh) {
+
+ pprintf(partner, "\nYour bughouse partner issuing %s (%s) %s",
+ pp->name, ratstrii(GetRating(&player_globals.parray[p], type), p),
+ colorstr[white + 1]);
+ pprintf_highlight(partner, "%s", player_globals.parray[p1].name);
+ pprintf(partner, " (%s) %s.\n",
+ ratstrii(GetRating(&player_globals.parray[p1], type), p1),
+ game_str(rated, wt * 60, winc, bt * 60, binc, category, board));
+ pprintf(partner, "Your game would be ");
+ pprintf_highlight(partner, "%s", player_globals.parray[pp1].name);
+ pprintf_prompt(partner, " (%s) %s%s (%s) %s.\n",
+ ratstrii(GetRating(&player_globals.parray[pp1], type), pp1),
+ colorstr[white + 1], player_globals.parray[partner].name,
+ ratstrii(GetRating(&player_globals.parray[partner], type), partner),
+ game_str(rated, wt * 60, winc, bt * 60, binc, category, board));
+ Bell (partner);
+
+ pprintf(pp1, "\nYour bughouse partner was challenged ");
+ pprintf_highlight(pp1, "%s", pp->name);
+ pprintf(pp1, " (%s) %s", ratstrii(GetRating(&player_globals.parray[p], type), p),
+ colorstr[white + 1]);
+ pprintf(pp1, "%s (%s) %s.\n", player_globals.parray[p1].name,
+ ratstrii(GetRating(&player_globals.parray[p1], type), p1),
+ game_str(rated, wt * 60, winc, bt * 60, binc, category, board));
+ pprintf(pp1, "Your game would be %s (%s) %s", player_globals.parray[pp1].name,
+ ratstrii(GetRating(&player_globals.parray[pp1], type), pp1),
+ colorstr[white + 1]);
+ pprintf_highlight(pp1, "%s", player_globals.parray[partner].name);
+ pprintf_prompt(pp1, " (%s) %s.\n",
+ ratstrii(GetRating(&player_globals.parray[partner], type), partner),
+ game_str(rated, wt * 60, winc, bt * 60, binc, category, board));
+ Bell(pp1);
+ }
+
+ check_lists_match (p,p1);
+
+ print_match_rating_info (p,p1,type,rated);
+
+ pprintf_prompt(p1, "You can \"accept\" or \"decline\", or propose different parameters.\n");
+
+ return COM_OK;
+}
+
+
+/*
+ rmatch is used by mamer to start matches in tournaments
+*/
+int com_rmatch(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1, p2;
+
+ if (!in_list(p, L_TD, pp->name)) {
+ pprintf(p, "Only TD programs are allowed to use this command.\n");
+ return COM_OK;
+ }
+
+ if ((p1 = player_find_bylogin(param[0].val.word)) < 0 ||
+ !CheckPFlag(p1, PFLAG_REG)) {
+ /* can't rmatch this user ... */
+ return COM_OK;
+ }
+
+ if ((p2 = player_find_bylogin(param[1].val.word)) < 0 ||
+ !CheckPFlag(p2, PFLAG_REG)) {
+ /* can't rmatch this user ... */
+ return COM_OK;
+ }
+
+ return pcommand(p1, "match %s %s", param[1].val.word, param[2].val.string);
+}
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+#ifndef _MATCHPROC_H
+#define _MATCHPROC_H
+
+extern const char *colorstr[];
+extern const char *adjustr[];
+
+#endif /* _MATCHPROC_H */
--- /dev/null
+/* MD5.H - header file for MD5C.C
+ * $FreeBSD: src/sys/sys/md5.h,v 1.13 1999/12/29 04:24:44 peter Exp $
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+#ifndef _SYS_MD5_H_
+#define _SYS_MD5_H_
+/* MD5 context. */
+typedef struct MD5Context {
+ u_int32_t state[4]; /* state (ABCD) */
+ u_int32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */
+ unsigned char buffer[64]; /* input buffer */
+} MD5_CTX;
+
+#endif /* _SYS_MD5_H_ */
--- /dev/null
+BEGIN {
+ inheader=0;
+ current_file="";
+ if (headername=="") {
+ headername="_PROTO_H_";
+ }
+
+ print "#ifndef",headername
+ print "#define",headername
+ print ""
+ print "/* This file is automatically generated with \"make proto\". DO NOT EDIT */"
+ print ""
+}
+
+END {
+ print ""
+ print "#endif /* ",headername," */"
+}
+
+{
+ if (FILENAME!=current_file) {
+ print ""
+ print "/* The following definitions come from",FILENAME," */"
+ print ""
+ current_file=FILENAME
+ }
+ if (inheader) {
+ if (match($0,"[)][ \t]*$")) {
+ inheader = 0;
+ printf "%s;\n",$0;
+ } else {
+ printf "%s\n",$0;
+ }
+ next;
+ }
+}
+
+/^static|^extern/ || !/^[a-zA-Z]/ || /[;]/ {
+ next;
+}
+
+#
+# We have to split up the start
+# matching as we now have so many start
+# types that it can cause some versions
+# of nawk/awk to choke and fail on
+# the full match. JRA.
+#
+
+{
+ gotstart = 0;
+ if( $0 ~ /^const|^connection_struct|^pipes_struct|^smb_np_struct|^file_fd_struct|^files_struct|^connection_struct|^uid_t|^gid_t|^unsigned|^mode_t|^DIR|^user|^int|^pid_t|^ino_t|^off_t|^double/ ) {
+ gotstart = 1;
+ }
+
+ if( $0 ~ /^vuser_key|^UNISTR2|^LOCAL_GRP|^DOMAIN_GRP|^SMB_STRUCT_DIRENT|^SEC_ACL|^SEC_DESC|^SEC_DESC_BUF|^DOM_SID|^RPC_HND_NODE|^BYTE/ ) {
+ gotstart = 1;
+ }
+
+ if( $0 ~ /^ADS_STRUCT|^ADS_STATUS|^DATA_BLOB|^ASN1_DATA|^TDB_CONTEXT|^TDB_DATA|^smb_ucs2_t|^TALLOC_CTX|^hash_element|^NT_DEVICEMODE|^enum.*\(|^NT_USER_TOKEN|^SAM_ACCOUNT/ ) {
+ gotstart = 1;
+ }
+
+ if( $0 ~ /^smb_iconv_t|^long|^char|^uint|^NTSTATUS|^WERROR|^CLI_POLICY_HND|^struct|^BOOL|^void|^time|^smb_shm_offset_t|^shm_offset_t|^FILE|^XFILE|^SMB_OFF_T|^size_t|^ssize_t|^SMB_BIG_UINT/ ) {
+ gotstart = 1;
+ }
+
+ if( $0 ~ /^SAM_ACCT_INFO_NODE|^SMB_ACL_T|^ADS_MODLIST|^PyObject/ ) {
+ gotstart = 1;
+ }
+
+ if(!gotstart) {
+ next;
+ }
+}
+
+
+/[(].*[)][ \t]*$/ {
+ printf "%s;\n",$0;
+ next;
+}
+
+/[(]/ {
+ inheader=1;
+ printf "%s\n",$0;
+ next;
+}
+
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+#include "includes.h"
+
+/* Simply tests if the input string is a move or not. */
+/* If it matches patterns below */
+/* Add to this list as you improve the move parser */
+/* MS_COMP e2e4 */
+/* MS_COMPDASH e2-e4 */
+/* MS_CASTLE o-o, o-o-o */
+/* Not done yet */
+/* MS_ALG e4, Nd5 Ncd5 */
+int is_move(const char *mstr)
+{
+ int len = strlen(mstr);
+ if ((len > 3) && (mstr[len - 2] == '='))
+ len -= 2;
+
+ /* remove the 'mates' marker */
+ if (mstr[len - 1] == '#')
+ len--;
+
+ if (len == 4) { /* Test for e2e4 */
+ if (isfile(mstr[0]) && isrank(mstr[1]) &&
+ isfile(mstr[2]) && isrank(mstr[3])) {
+ return MS_COMP;
+ }
+ }
+ if (len == 5) { /* Test for e2-e4 */
+ if (isfile(mstr[0]) && isrank(mstr[1]) &&
+ (mstr[2] == '-') &&
+ isfile(mstr[3]) && isrank(mstr[4])) {
+ return MS_COMPDASH;
+ }
+ }
+ if (len == 3) { /* Test for o-o */
+ if ((mstr[0] == 'o') && (mstr[1] == '-') && (mstr[2] == 'o')) {
+ return MS_KCASTLE;
+ }
+ if ((mstr[0] == 'O') && (mstr[1] == '-') && (mstr[2] == 'O')) {
+ return MS_KCASTLE;
+ }
+ if ((mstr[0] == '0') && (mstr[1] == '-') && (mstr[2] == '0')) {
+ return MS_KCASTLE;
+ }
+ }
+ if (len == 2) { /* Test for oo */
+ if ((mstr[0] == 'o') && (mstr[1] == 'o')) {
+ return MS_KCASTLE;
+ }
+ if ((mstr[0] == 'O') && (mstr[1] == 'O')) {
+ return MS_KCASTLE;
+ }
+ if ((mstr[0] == '0') && (mstr[1] == '0')) {
+ return MS_KCASTLE;
+ }
+ }
+ if (len == 5) { /* Test for o-o-o */
+ if ((mstr[0] == 'o') && (mstr[1] == '-') && (mstr[2] == 'o') && (mstr[3] == '-') && (mstr[4] == 'o')) {
+ return MS_QCASTLE;
+ }
+ if ((mstr[0] == 'O') && (mstr[1] == '-') && (mstr[2] == 'O') && (mstr[3] == '-') && (mstr[4] == 'O')) {
+ return MS_QCASTLE;
+ }
+ if ((mstr[0] == '0') && (mstr[1] == '-') && (mstr[2] == '0') && (mstr[3] == '-') && (mstr[4] == '0')) {
+ return MS_QCASTLE;
+ }
+ }
+ if (len == 3) { /* Test for ooo */
+ if ((mstr[0] == 'o') && (mstr[1] == 'o') && (mstr[2] == 'o')) {
+ return MS_QCASTLE;
+ }
+ if ((mstr[0] == 'O') && (mstr[1] == 'O') && (mstr[2] == 'O')) {
+ return MS_QCASTLE;
+ }
+ if ((mstr[0] == '0') && (mstr[1] == '0') && (mstr[2] == '0')) {
+ return MS_QCASTLE;
+ }
+ }
+ return alg_is_move(mstr);
+}
+
+
+int NextPieceLoop(board_t b, int *f, int *r, int color)
+{
+ for (;;) {
+ (*r) = (*r) + 1;
+ if (*r > 7) {
+ *r = 0;
+ *f = *f + 1;
+ if (*f > 7)
+ break;
+ }
+ if ((b[*f][*r] != NOPIECE) && iscolor(b[*f][*r], color))
+ return 1;
+ }
+ return 0;
+}
+
+int InitPieceLoop(board_t b, int *f, int *r, int color)
+{
+ *f = 0;
+ *r = -1;
+ return 1;
+}
+
+/* All of the routines assume that the obvious problems have been checked */
+/* See legal_move() */
+static int legal_pawn_move( struct game_state_t *gs, int ff, int fr, int tf, int tr )
+{
+ if (ff == tf) {
+ if (gs->board[tf][tr] != NOPIECE) return 0;
+ if (gs->onMove == WHITE) {
+ if (tr - fr == 1) return 1;
+ if ((fr == 1) && (tr - fr == 2) && gs->board[ff][2]==NOPIECE) return 1;
+ } else {
+ if (fr - tr == 1) return 1;
+ if ((fr == 6) && (fr - tr == 2) && gs->board[ff][5]==NOPIECE) return 1;
+ }
+ return 0;
+ }
+ if (ff != tf) { /* Capture ? */
+ if ((ff - tf != 1) && (tf - ff != 1)) return 0;
+ if ((fr - tr != 1) && (tr - fr != 1)) return 0;
+ if (gs->onMove == WHITE) {
+ if (fr > tr) return 0;
+ if ((gs->board[tf][tr] != NOPIECE) && iscolor(gs->board[tf][tr],BLACK))
+ return 1;
+ if (gs->ep_possible[0][ff] == 1) {
+ if ((tf==ff+1) && (gs->board[ff+1][fr] == B_PAWN)) return 1;
+ } else if (gs->ep_possible[0][ff] == -1) {
+ if ((tf==ff-1) && (gs->board[ff-1][fr] == B_PAWN)) return 1;
+ }
+ } else {
+ if (tr > fr) return 0;
+ if ((gs->board[tf][tr] != NOPIECE) && iscolor(gs->board[tf][tr],WHITE))
+ return 1;
+ if (gs->ep_possible[1][ff] == 1) {
+ if ((tf==ff+1) && (gs->board[ff+1][fr] == W_PAWN)) return 1;
+ } else if (gs->ep_possible[1][ff] == -1) {
+ if ((tf==ff-1) && (gs->board[ff-1][fr] == W_PAWN)) return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+static int legal_knight_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+ int dx, dy;
+
+ dx = ff - tf;
+ dy = fr - tr;
+ if (abs(dx) == 2) {
+ if (abs(dy) == 1)
+ return 1;
+ }
+ if (abs(dy) == 2) {
+ if (abs(dx) == 1)
+ return 1;
+ }
+ return 0;
+}
+
+static int legal_bishop_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+ int dx, dy, x, y;
+ int startx, starty;
+ int count;
+ int incx, incy;
+
+ if (ff > tf) {
+ dx = ff - tf;
+ incx = -1;
+ } else {
+ dx = tf - ff;
+ incx = 1;
+ }
+ startx = ff + incx;
+ if (fr > tr) {
+ dy = fr - tr;
+ incy = -1;
+ } else {
+ dy = tr - fr;
+ incy = 1;
+ }
+ starty = fr + incy;
+ if (dx != dy)
+ return 0; /* Not diagonal */
+ if (dx == 1)
+ return 1; /* One square, ok */
+ count = dx - 1;
+ for (x = startx, y = starty; count; x += incx, y += incy, count--) {
+ if (gs->board[x][y] != NOPIECE)
+ return 0;
+ }
+ return 1;
+}
+
+static int legal_rook_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+ int i;
+ int start, stop;
+
+ if (ff == tf) {
+ if (abs(fr - tr) == 1)
+ return 1;
+ if (fr < tr) {
+ start = fr + 1;
+ stop = tr - 1;
+ } else {
+ start = tr + 1;
+ stop = fr - 1;
+ }
+ for (i = start; i <= stop; i++) {
+ if (gs->board[ff][i] != NOPIECE)
+ return 0;
+ }
+ return 1;
+ } else if (fr == tr) {
+ if (abs(ff - tf) == 1)
+ return 1;
+ if (ff < tf) {
+ start = ff + 1;
+ stop = tf - 1;
+ } else {
+ start = tf + 1;
+ stop = ff - 1;
+ }
+ for (i = start; i <= stop; i++) {
+ if (gs->board[i][fr] != NOPIECE)
+ return 0;
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int legal_queen_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+ return legal_rook_move(gs, ff, fr, tf, tr) || legal_bishop_move(gs, ff, fr, tf, tr);
+}
+
+/* Ckeck, if square (kf,kr) is attacked by enemy piece.
+ * Used in castling from/through check testing.
+ */
+
+/* new one from soso: */
+static int is_square_attacked (struct game_state_t *gs, int kf, int kr)
+{
+ struct game_state_t fakeMove;
+
+ fakeMove = *gs;
+ fakeMove.board[4][kr] = NOPIECE;
+ fakeMove.board[kf][kr] = KING | fakeMove.onMove;
+ fakeMove.onMove = CToggle (fakeMove.onMove);
+ if (in_check(&fakeMove)) return 1;
+ else return 0;
+}
+
+/* old one:
+static int is_square_attacked(struct game_state_t * gs, int kf, int kr)
+{
+ int f, r;
+ gs->onMove = CToggle(gs->onMove);
+
+ for (InitPieceLoop(gs->board, &f, &r, gs->onMove);
+ NextPieceLoop(gs->board, &f, &r, gs->onMove);) {
+ if (legal_move(gs, f, r, kf, kr)) {
+ gs->onMove = CToggle(gs->onMove);
+ return 1;
+ }
+ }
+ gs->onMove = CToggle(gs->onMove);
+ return 0;
+}
+*/
+
+static int legal_king_move(struct game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+ if (gs->onMove == WHITE) {
+ /* King side castling */
+ if ((fr == 0) && (tr == 0) && (ff == 4) && (tf == 6) && !gs->wkmoved
+ && (!gs->wkrmoved) && (gs->board[5][0] == NOPIECE) &&
+ (gs->board[6][0] == NOPIECE) && (gs->board[7][0] == W_ROOK) &&
+ (!is_square_attacked(gs, 4, 0)) && (!is_square_attacked(gs, 5, 0))) {
+ return 1;
+ }
+ /* Queen side castling */
+ if ((fr == 0) && (tr == 0) && (ff == 4) && (tf == 2) && !gs->wkmoved
+ && (!gs->wqrmoved) && (gs->board[3][0] == NOPIECE) &&
+ (gs->board[2][0] == NOPIECE) && (gs->board[1][0] == NOPIECE) &&
+ (gs->board[0][0] == W_ROOK) &&
+ (!is_square_attacked(gs, 4, 0)) && (!is_square_attacked(gs, 3, 0))) {
+ return 1;
+ }
+ } else { /* Black */
+ /* King side castling */
+ if ((fr == 7) && (tr == 7) && (ff == 4) && (tf == 6) && !gs->bkmoved
+ && (!gs->bkrmoved) && (gs->board[5][7] == NOPIECE) &&
+ (gs->board[6][7] == NOPIECE) && (gs->board[7][7] == B_ROOK) &&
+ (!is_square_attacked(gs, 4, 7)) && (!is_square_attacked(gs, 5, 7))) {
+ return 1;
+ }
+ /* Queen side castling */
+ if ((fr == 7) && (tr == 7) && (ff == 4) && (tf == 2) && (!gs->bkmoved)
+ && (!gs->bqrmoved) && (gs->board[3][7] == NOPIECE) &&
+ (gs->board[2][7] == NOPIECE) && (gs->board[1][7] == NOPIECE) &&
+ (gs->board[0][7] == B_ROOK) &&
+ (!is_square_attacked(gs, 4, 7)) && (!is_square_attacked(gs, 3, 7))) {
+ return 1;
+ }
+ }
+ if (abs(ff - tf) > 1)
+ return 0;
+ if (abs(fr - tr) > 1)
+ return 0;
+ return 1;
+}
+
+static void add_pos(int tof, int tor, int *posf, int *posr, int *numpos)
+{
+ posf[*numpos] = tof;
+ posr[*numpos] = tor;
+ (*numpos)++;
+}
+
+static void possible_pawn_moves(struct game_state_t * gs,
+ int onf, int onr,
+ int *posf, int *posr, int *numpos)
+{
+ if (gs->onMove == WHITE) {
+ if (gs->board[onf][onr + 1] == NOPIECE) {
+ add_pos(onf, onr + 1, posf, posr, numpos);
+ if ((onr == 1) && (gs->board[onf][onr + 2] == NOPIECE))
+ add_pos(onf, onr + 2, posf, posr, numpos);
+ }
+ if ((onf > 0) && (gs->board[onf - 1][onr + 1] != NOPIECE) &&
+ (iscolor(gs->board[onf - 1][onr + 1], BLACK)))
+ add_pos(onf - 1, onr + 1, posf, posr, numpos);
+ if ((onf < 7) && (gs->board[onf + 1][onr + 1] != NOPIECE) &&
+ (iscolor(gs->board[onf + 1][onr + 1], BLACK)))
+ add_pos(onf + 1, onr + 1, posf, posr, numpos);
+ if (gs->ep_possible[0][onf] == -1)
+ add_pos(onf - 1, onr + 1, posf, posr, numpos);
+ if (gs->ep_possible[0][onf] == 1)
+ add_pos(onf + 1, onr + 1, posf, posr, numpos);
+ } else {
+ if (gs->board[onf][onr - 1] == NOPIECE) {
+ add_pos(onf, onr - 1, posf, posr, numpos);
+ if ((onr == 6) && (gs->board[onf][onr - 2] == NOPIECE))
+ add_pos(onf, onr - 2, posf, posr, numpos);
+ }
+ if ((onf > 0) && (gs->board[onf - 1][onr - 1] != NOPIECE) &&
+ (iscolor(gs->board[onf - 1][onr - 1], WHITE)))
+ add_pos(onf - 1, onr - 1, posf, posr, numpos);
+/* loon: changed what looks like a typo, here's the original line:
+ add_pos(onf - 1, onr + 1, posf, posr, numpos);
+*/
+ if ((onf < 7) && (gs->board[onf + 1][onr - 1] != NOPIECE) &&
+ (iscolor(gs->board[onf + 1][onr - 1], WHITE)))
+ add_pos(onf + 1, onr - 1, posf, posr, numpos);
+ if (gs->ep_possible[1][onf] == -1)
+ add_pos(onf - 1, onr - 1, posf, posr, numpos);
+ if (gs->ep_possible[1][onf] == 1)
+ add_pos(onf + 1, onr - 1, posf, posr, numpos);
+ }
+}
+
+static void possible_knight_moves(struct game_state_t * gs,
+ int onf, int onr,
+ int *posf, int *posr, int *numpos)
+{
+ static int knightJumps[8][2] = {{-1, 2}, {1, 2}, {2, -1}, {2, 1},
+ {-1, -2}, {1, -2}, {-2, 1}, {-2, -1}};
+ int f, r;
+ int j;
+
+ for (j = 0; j < 8; j++) {
+ f = knightJumps[j][0] + onf;
+ r = knightJumps[j][1] + onr;
+ if ((f < 0) || (f > 7))
+ continue;
+ if ((r < 0) || (r > 7))
+ continue;
+ if ((gs->board[f][r] == NOPIECE) ||
+ (iscolor(gs->board[f][r], CToggle(gs->onMove))))
+ add_pos(f, r, posf, posr, numpos);
+ }
+}
+
+static void possible_bishop_moves(struct game_state_t * gs,
+ int onf, int onr,
+ int *posf, int *posr, int *numpos)
+{
+ int f, r;
+
+ /* Up Left */
+ f = onf;
+ r = onr;
+ for (;;) {
+ f--;
+ r++;
+ if ((f < 0) || (f > 7))
+ break;
+ if ((r < 0) || (r > 7))
+ break;
+ if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+ break;
+ add_pos(f, r, posf, posr, numpos);
+ if (gs->board[f][r] != NOPIECE)
+ break;
+ }
+ /* Up Right */
+ f = onf;
+ r = onr;
+ for (;;) {
+ f++;
+ r++;
+ if ((f < 0) || (f > 7))
+ break;
+ if ((r < 0) || (r > 7))
+ break;
+ if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+ break;
+ add_pos(f, r, posf, posr, numpos);
+ if (gs->board[f][r] != NOPIECE)
+ break;
+ }
+ /* Down Left */
+ f = onf;
+ r = onr;
+ for (;;) {
+ f--;
+ r--;
+ if ((f < 0) || (f > 7))
+ break;
+ if ((r < 0) || (r > 7))
+ break;
+ if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+ break;
+ add_pos(f, r, posf, posr, numpos);
+ if (gs->board[f][r] != NOPIECE)
+ break;
+ }
+ /* Down Right */
+ f = onf;
+ r = onr;
+ for (;;) {
+ f++;
+ r--;
+ if ((f < 0) || (f > 7))
+ break;
+ if ((r < 0) || (r > 7))
+ break;
+ if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+ break;
+ add_pos(f, r, posf, posr, numpos);
+ if (gs->board[f][r] != NOPIECE)
+ break;
+ }
+}
+
+static void possible_rook_moves(struct game_state_t * gs,
+ int onf, int onr,
+ int *posf, int *posr, int *numpos)
+{
+ int f, r;
+
+ /* Left */
+ f = onf;
+ r = onr;
+ for (;;) {
+ f--;
+ if ((f < 0) || (f > 7))
+ break;
+ if ((r < 0) || (r > 7))
+ break;
+ if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+ break;
+ add_pos(f, r, posf, posr, numpos);
+ if (gs->board[f][r] != NOPIECE)
+ break;
+ }
+ /* Right */
+ f = onf;
+ r = onr;
+ for (;;) {
+ f++;
+ if ((f < 0) || (f > 7))
+ break;
+ if ((r < 0) || (r > 7))
+ break;
+ if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+ break;
+ add_pos(f, r, posf, posr, numpos);
+ if (gs->board[f][r] != NOPIECE)
+ break;
+ }
+ /* Up */
+ f = onf;
+ r = onr;
+ for (;;) {
+ r++;
+ if ((f < 0) || (f > 7))
+ break;
+ if ((r < 0) || (r > 7))
+ break;
+ if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+ break;
+ add_pos(f, r, posf, posr, numpos);
+ if (gs->board[f][r] != NOPIECE)
+ break;
+ }
+ /* Down */
+ f = onf;
+ r = onr;
+ for (;;) {
+ r--;
+ if ((f < 0) || (f > 7))
+ break;
+ if ((r < 0) || (r > 7))
+ break;
+ if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+ break;
+ add_pos(f, r, posf, posr, numpos);
+ if (gs->board[f][r] != NOPIECE)
+ break;
+ }
+}
+
+static void possible_queen_moves(struct game_state_t * gs,
+ int onf, int onr,
+ int *posf, int *posr, int *numpos)
+{
+ possible_rook_moves(gs, onf, onr, posf, posr, numpos);
+ possible_bishop_moves(gs, onf, onr, posf, posr, numpos);
+}
+
+static void possible_king_moves(struct game_state_t * gs,
+ int onf, int onr,
+ int *posf, int *posr, int *numpos)
+{
+ static int kingJumps[8][2] = {{-1, -1}, {0, -1}, {1, -1}, {-1, 1},
+ {0, 1}, {1, 1}, {-1, 0}, {1, 0}};
+ int f, r;
+ int j;
+
+ for (j = 0; j < 8; j++) {
+ f = kingJumps[j][0] + onf;
+ r = kingJumps[j][1] + onr;
+ if ((f < 0) || (f > 7))
+ continue;
+ if ((r < 0) || (r > 7))
+ continue;
+ if ((gs->board[f][r] == NOPIECE) ||
+ (iscolor(gs->board[f][r], CToggle(gs->onMove))))
+ add_pos(f, r, posf, posr, numpos);
+ }
+}
+
+/* Doesn't check for check */
+int legal_move(struct game_state_t * gs,
+ int fFile, int fRank,
+ int tFile, int tRank)
+{
+ int move_piece;
+ int legal;
+
+ if (fFile == ALG_DROP) {
+ move_piece = fRank;
+ if (move_piece == KING)
+ return 0;
+ if (gs->holding[gs->onMove==WHITE ? 0 : 1][move_piece-1] == 0)
+ return 0;
+ if (gs->board[tFile][tRank] != NOPIECE)
+ return 0;
+ if (move_piece == PAWN && (tRank == 0 || tRank == 7))
+ return 0;
+ return 1;
+ } else {
+ move_piece = piecetype(gs->board[fFile][fRank]);
+ }
+ if (gs->board[fFile][fRank] == NOPIECE)
+ return 0;
+ if (!iscolor(gs->board[fFile][fRank], gs->onMove)) /* Wrong color */
+ return 0;
+ if ((gs->board[tFile][tRank] != NOPIECE) &&
+ iscolor(gs->board[tFile][tRank], gs->onMove)) /* Can't capture own */
+ return 0;
+ if ((fFile == tFile) && (fRank == tRank)) /* Same square */
+ return 0;
+ switch (move_piece) {
+ case PAWN:
+ legal = legal_pawn_move(gs, fFile, fRank, tFile, tRank);
+ break;
+ case KNIGHT:
+ legal = legal_knight_move(gs, fFile, fRank, tFile, tRank);
+ break;
+ case BISHOP:
+ legal = legal_bishop_move(gs, fFile, fRank, tFile, tRank);
+ break;
+ case ROOK:
+ legal = legal_rook_move(gs, fFile, fRank, tFile, tRank);
+ break;
+ case QUEEN:
+ legal = legal_queen_move(gs, fFile, fRank, tFile, tRank);
+ break;
+ case KING:
+ legal = legal_king_move(gs, fFile, fRank, tFile, tRank);
+ break;
+ default:
+ return 0;
+ break;
+ }
+ return legal;
+}
+
+#define DROP_CHAR '@'
+
+/* This fills in the rest of the mt structure once it is determined that
+ * the move is legal. Returns MOVE_ILLEGAL if move leaves you in check */
+static int move_calculate(struct game_state_t * gs, struct move_t * mt, int promote)
+{
+ struct game_state_t fakeMove;
+
+ mt->pieceCaptured = gs->board[mt->toFile][mt->toRank];
+ mt->enPassant = 0; /* Don't know yet, let execute move take care
+ of it */
+ if (mt->fromFile == ALG_DROP) {
+ mt->piecePromotionTo = NOPIECE;
+ sprintf(mt->moveString, "%s/%c%c-%c%d",
+ wpstring[mt->fromRank],
+ DROP_CHAR, DROP_CHAR,
+ mt->toFile + 'a', mt->toRank + 1);
+ } else {
+ if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == PAWN) &&
+ ((mt->toRank == 0) || (mt->toRank == 7))) {
+ mt->piecePromotionTo = promote |
+ (colorval(gs->board[mt->fromFile][mt->fromRank]));
+ } else {
+ mt->piecePromotionTo = NOPIECE;
+ }
+ if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == PAWN) &&
+ ((mt->fromRank - mt->toRank == 2) || (mt->toRank - mt->fromRank == 2))) {
+ mt->doublePawn = mt->fromFile;
+ } else {
+ mt->doublePawn = -1;
+ }
+ if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == KING) &&
+ (mt->fromFile == 4) && (mt->toFile == 2)) {
+ sprintf(mt->moveString, "o-o-o");
+ } else if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == KING) &&
+ (mt->fromFile == 4) && (mt->toFile == 6)) {
+ sprintf(mt->moveString, "o-o");
+ } else {
+ sprintf(mt->moveString, "%s/%c%d-%c%d",
+ wpstring[piecetype(gs->board[mt->fromFile][mt->fromRank])],
+ mt->fromFile + 'a', mt->fromRank + 1,
+ mt->toFile + 'a', mt->toRank + 1);
+ }
+ }
+ /* Replace this with an algabraic de-parser */
+
+ sprintf(mt->algString, alg_unparse(gs, mt));
+ fakeMove = *gs;
+ /* Calculates enPassant also */
+ execute_move(&fakeMove, mt, 0);
+
+ /* Does making this move leave ME in check? */
+ if (in_check(&fakeMove))
+ return MOVE_ILLEGAL;
+ /* IanO: bughouse variants: drop cannot be check/checkmate */
+
+ return MOVE_OK;
+}
+
+int legal_andcheck_move(struct game_state_t * gs,
+ int fFile, int fRank,
+ int tFile, int tRank)
+{
+ struct move_t mt;
+ if (!legal_move(gs, fFile, fRank, tFile, tRank))
+ return 0;
+ mt.color = gs->onMove;
+ mt.fromFile = fFile;
+ mt.fromRank = fRank;
+ mt.toFile = tFile;
+ mt.toRank = tRank;
+ /* This should take into account a pawn promoting to another piece */
+ if (move_calculate(gs, &mt, QUEEN) == MOVE_OK)
+ return 1;
+ else
+ return 0;
+}
+
+/* in_check: checks if the side that is NOT about to move is in check
+ */
+int in_check(struct game_state_t * gs)
+{
+ int f, r;
+ int kf = -1, kr = -1;
+
+ /* Find the king */
+ if (gs->onMove == WHITE) {
+ for (f = 0; f < 8 && kf < 0; f++)
+ for (r = 0; r < 8 && kf < 0; r++)
+ if (gs->board[f][r] == B_KING) {
+ kf = f;
+ kr = r;
+ }
+ } else {
+ for (f = 0; f < 8 && kf < 0; f++)
+ for (r = 0; r < 8 && kf < 0; r++)
+ if (gs->board[f][r] == W_KING) {
+ kf = f;
+ kr = r;
+ }
+ }
+ if (kf < 0) {
+ d_printf( "CHESSD: Error game with no king!\n");
+ return 0;
+ }
+ for (InitPieceLoop(gs->board, &f, &r, gs->onMove);
+ NextPieceLoop(gs->board, &f, &r, gs->onMove);) {
+ if (legal_move(gs, f, r, kf, kr)) { /* In Check? */
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int has_legal_move(struct game_state_t * gs)
+{
+ int i;
+ int f, r;
+ int kf = 0, kr = 0;
+ int possiblef[500], possibler[500];
+ int numpossible = 0;
+
+ for (InitPieceLoop(gs->board, &f, &r, gs->onMove);
+ NextPieceLoop(gs->board, &f, &r, gs->onMove);) {
+ switch (piecetype(gs->board[f][r])) {
+ case PAWN:
+ possible_pawn_moves(gs, f, r, possiblef, possibler, &numpossible);
+ break;
+ case KNIGHT:
+ possible_knight_moves(gs, f, r, possiblef, possibler, &numpossible);
+ break;
+ case BISHOP:
+ possible_bishop_moves(gs, f, r, possiblef, possibler, &numpossible);
+ break;
+ case ROOK:
+ possible_rook_moves(gs, f, r, possiblef, possibler, &numpossible);
+ break;
+ case QUEEN:
+ possible_queen_moves(gs, f, r, possiblef, possibler, &numpossible);
+ break;
+ case KING:
+ kf = f;
+ kr = r;
+ possible_king_moves(gs, f, r, possiblef, possibler, &numpossible);
+ break;
+ }
+ if (numpossible >= 500) {
+ d_printf( "CHESSD: Possible move overrun\n");
+ }
+ for (i = 0; i < numpossible; i++)
+ if (legal_andcheck_move(gs, f, r, possiblef[i], possibler[i])) {
+ return 1;
+ }
+ }
+
+ /* IanO: if we got here, then kf and kr must be set */
+ if (gs->gameNum >=0 && game_globals.garray[gs->gameNum].link >= 0) {
+ /* bughouse: potential drops as check interpositions */
+ gs->holding[gs->onMove==WHITE ? 0 : 1][QUEEN - 1]++;
+ for (f=kf-1; f<=kf+1; f++) for (r=kr-1; r<=kr+1; r++) {
+ if (f>=0 && f<8 && r>=0 && r<8 && gs->board[f][r] == NOPIECE) {
+ /* try a drop next to the king */
+ if (legal_andcheck_move(gs, ALG_DROP, QUEEN, f, r)) {
+ gs->holding[gs->onMove==WHITE ? 0 : 1][QUEEN - 1]--;
+ return 1;
+ }
+ }
+ }
+ gs->holding[gs->onMove==WHITE ? 0 : 1][QUEEN - 1]--;
+ }
+
+ return 0;
+}
+
+/* This will end up being a very complicated function */
+int parse_move(char *mstr, struct game_state_t * gs, struct move_t * mt, int promote)
+{
+ int type = is_move(mstr);
+ int result;
+
+ mt->piecePromotionTo = NOPIECE;
+ mt->color = gs->onMove;
+ switch (type) {
+ case MS_NOTMOVE:
+ return MOVE_ILLEGAL;
+ break;
+ case MS_COMP:
+ mt->fromFile = mstr[0] - 'a';
+ mt->fromRank = mstr[1] - '1';
+ mt->toFile = mstr[2] - 'a';
+ mt->toRank = mstr[3] - '1';
+ break;
+ case MS_COMPDASH:
+ mt->fromFile = mstr[0] - 'a';
+ mt->fromRank = mstr[1] - '1';
+ mt->toFile = mstr[3] - 'a';
+ mt->toRank = mstr[4] - '1';
+ break;
+ case MS_KCASTLE:
+ mt->fromFile = 4;
+ mt->toFile = 6;
+ if (gs->onMove == WHITE) {
+ mt->fromRank = 0;
+ mt->toRank = 0;
+ } else {
+ mt->fromRank = 7;
+ mt->toRank = 7;
+ }
+ break;
+ case MS_QCASTLE:
+ mt->fromFile = 4;
+ mt->toFile = 2;
+ if (gs->onMove == WHITE) {
+ mt->fromRank = 0;
+ mt->toRank = 0;
+ } else {
+ mt->fromRank = 7;
+ mt->toRank = 7;
+ }
+ break;
+ case MS_ALG:
+ /* Fills in the mt structure */
+ if ((result = alg_parse_move(mstr, gs, mt)) != MOVE_OK)
+ return result;
+ break;
+ default:
+ return MOVE_ILLEGAL;
+ break;
+ }
+ if (!legal_move(gs, mt->fromFile, mt->fromRank, mt->toFile, mt->toRank)) {
+ return MOVE_ILLEGAL;
+ }
+
+ if (mt->piecePromotionTo != NOPIECE) {
+ promote = piecetype(mt->piecePromotionTo);
+ }
+
+ return move_calculate(gs, mt, promote);
+}
+
+/* Returns MOVE_OK, MOVE_NOMATERIAL, MOVE_CHECKMATE, or MOVE_STALEMATE */
+/* check_game_status prevents recursion */
+int execute_move(struct game_state_t * gs, struct move_t * mt, int check_game_status)
+{
+ int movedPiece;
+ int tookPiece;
+ int i, j, foobar;
+
+ if (mt->fromFile == ALG_DROP) {
+ movedPiece = mt->fromRank;
+ tookPiece = NOPIECE;
+ gs->holding[gs->onMove==WHITE ? 0 : 1][movedPiece-1]--;
+ gs->board[mt->toFile][mt->toRank] = movedPiece | gs->onMove;
+ if (gs->gameNum >= 0)
+ gs->lastIrreversable = game_globals.garray[gs->gameNum].numHalfMoves;
+ } else {
+ movedPiece = gs->board[mt->fromFile][mt->fromRank];
+ tookPiece = gs->board[mt->toFile][mt->toRank];
+ if (mt->piecePromotionTo == NOPIECE) {
+ gs->board[mt->toFile][mt->toRank] = gs->board[mt->fromFile][mt->fromRank];
+ } else {
+ gs->board[mt->toFile][mt->toRank] = mt->piecePromotionTo | gs->onMove;
+ }
+ gs->board[mt->fromFile][mt->fromRank] = NOPIECE;
+ /* Check if irreversable */
+ if ((piecetype(movedPiece) == PAWN) || (tookPiece != NOPIECE)) {
+ if (gs->gameNum >= 0)
+ gs->lastIrreversable = game_globals.garray[gs->gameNum].numHalfMoves;
+ }
+ /* Check if this move is en-passant */
+ if ((piecetype(movedPiece) == PAWN) && (mt->fromFile != mt->toFile) &&
+ (tookPiece == NOPIECE)) {
+ if (gs->onMove == WHITE) {
+ mt->pieceCaptured = B_PAWN;
+ } else {
+ mt->pieceCaptured = W_PAWN;
+ }
+ if (mt->fromFile > mt->toFile) {
+ mt->enPassant = -1;
+ } else {
+ mt->enPassant = 1;
+ }
+ gs->board[mt->toFile][mt->fromRank] = NOPIECE;
+ }
+ /* Check en-passant flags for next moves */
+ for (i = 0; i < 8; i++) {
+ gs->ep_possible[0][i] = 0;
+ gs->ep_possible[1][i] = 0;
+ }
+/* Added by Sparky 3/16/95
+
+ From soso@Viktoria.drp.fmph.uniba.sk Thu Mar 16 13:08:51 1995
+ Subject: Re: To DAV: enpassant prob. again
+ To: chess@caissa.onenet.net (ICS)
+ Date: Thu, 16 Mar 1995 20:06:20 +0100 (MET)
+
+ Yeah !
+ There was bug in other part of code:
+
+ movecheck.c , line about 800:
+
+ if (gs->onMove == WHITE) {
+ if ((mt->toFile+1 < 7 ) .... should be : (mt->toFile < 7 ) }
+*/
+
+ if ((piecetype(movedPiece) == PAWN) &&
+ ((mt->fromRank == mt->toRank + 2) || (mt->fromRank + 2 == mt->toRank))) {
+ /* Should turn on enpassent flag if possible */
+ if (gs->onMove == WHITE) {
+ if ((mt->toFile < 7) && gs->board[mt->toFile + 1][3] == B_PAWN) {
+ gs->ep_possible[1][mt->toFile + 1] = -1;
+ }
+ if ((mt->toFile - 1 >= 0) && gs->board[mt->toFile - 1][3] == B_PAWN) {
+ gs->ep_possible[1][mt->toFile - 1] = 1;
+ }
+ } else {
+ if ((mt->toFile < 7) && gs->board[mt->toFile + 1][4] == W_PAWN) {
+ gs->ep_possible[0][mt->toFile + 1] = -1;
+ }
+ if ((mt->toFile - 1 >= 0) && gs->board[mt->toFile - 1][4] == W_PAWN) {
+ gs->ep_possible[0][mt->toFile - 1] = 1;
+ }
+ }
+ }
+ if ((piecetype(movedPiece) == ROOK) && (mt->fromFile == 0)) {
+ if ((mt->fromRank == 0) && (gs->onMove == WHITE))
+ gs->wqrmoved = 1;
+ if ((mt->fromRank == 7) && (gs->onMove == BLACK))
+ gs->bqrmoved = 1;
+ }
+ if ((piecetype(movedPiece) == ROOK) && (mt->fromFile == 7)) {
+ if ((mt->fromRank == 0) && (gs->onMove == WHITE))
+ gs->wkrmoved = 1;
+ if ((mt->fromRank == 7) && (gs->onMove == BLACK))
+ gs->bkrmoved = 1;
+ }
+ if (piecetype(movedPiece) == KING) {
+ if (gs->onMove == WHITE)
+ gs->wkmoved = 1;
+ else
+ gs->bkmoved = 1;
+ }
+ if ((piecetype(movedPiece) == KING) &&
+ ((mt->fromFile == 4) && ((mt->toFile == 6)))) { /* Check for KS castling */
+ gs->board[5][mt->toRank] = gs->board[7][mt->toRank];
+ gs->board[7][mt->toRank] = NOPIECE;
+ }
+ if ((piecetype(movedPiece) == KING) &&
+ ((mt->fromFile == 4) && ((mt->toFile == 2)))) { /* Check for QS castling */
+ gs->board[3][mt->toRank] = gs->board[0][mt->toRank];
+ gs->board[0][mt->toRank] = NOPIECE;
+ }
+ }
+ if (gs->onMove == BLACK)
+ gs->moveNum++;
+
+ if (check_game_status) {
+ /* Does this move result in check? */
+ if (in_check(gs)) {
+ /* Check for checkmate */
+ gs->onMove = CToggle(gs->onMove);
+ if (!has_legal_move(gs))
+ return MOVE_CHECKMATE;
+ } else {
+ /* Check for stalemate */
+ gs->onMove = CToggle(gs->onMove);
+ if (!has_legal_move(gs))
+ return MOVE_STALEMATE;
+/* loon: check for insufficient mating material, first try */
+ foobar = 0;
+ for (i=0; i<8; i++) {
+ for (j=0; j<8; j++) {
+ switch(piecetype(gs->board[i][j])) {
+ case KNIGHT:
+ case BISHOP:
+ foobar++;
+ break;
+ case KING:
+ case NOPIECE:
+ break;
+ default:
+ foobar = 2;
+ break;
+ }
+ }
+ }
+ if (foobar < 2)
+ return MOVE_NOMATERIAL;
+ }
+ } else {
+ gs->onMove = CToggle(gs->onMove);
+ }
+ return MOVE_OK;
+}
+
+int backup_move(int g, int mode)
+{
+ struct game_state_t *gs;
+ struct move_t *m, *m1;
+ int now, i;
+
+ if (game_globals.garray[g].link >= 0) /*IanO: not implemented for bughouse yet */
+ return MOVE_ILLEGAL;
+ if (game_globals.garray[g].numHalfMoves < 1)
+ return MOVE_ILLEGAL;
+ gs = &game_globals.garray[g].game_state;
+ m = (mode==REL_GAME) ? &game_globals.garray[g].moveList[game_globals.garray[g].numHalfMoves - 1] :
+ &game_globals.garray[g].examMoveList[game_globals.garray[g].numHalfMoves - 1];
+ if (m->toFile < 0) {
+ return MOVE_ILLEGAL;
+ }
+ gs->board[m->fromFile][m->fromRank] = gs->board[m->toFile][m->toRank];
+ if (m->piecePromotionTo != NOPIECE) {
+ gs->board[m->fromFile][m->fromRank] = PAWN |
+ colorval(gs->board[m->fromFile][m->fromRank]);
+ }
+ /******************
+ When takeback a _first_ move of rook, the ??rmoved variable
+ must be cleared . To check, if the move is first, we should
+ scan moveList.
+ *******************/
+ if (piecetype(gs->board[m->fromFile][m->fromRank]) == ROOK) {
+ if (m->color == WHITE) {
+ if ((m->fromFile == 0) && (m->fromRank == 0)) {
+ for (i = 2; i < game_globals.garray[g].numHalfMoves - 1; i += 2) {
+ m1 = (mode==REL_GAME) ? &game_globals.garray[g].moveList[i] : &game_globals.garray[g].examMoveList[i];
+ if ((m1->fromFile == 0) && (m1->fromRank == 0))
+ break;
+ }
+ if (i == game_globals.garray[g].numHalfMoves - 1)
+ gs->wqrmoved = 0;
+ }
+ if ((m->fromFile == 7) && (m->fromRank == 0)) {
+ for (i = 2; i < game_globals.garray[g].numHalfMoves - 1; i += 2) {
+ m1 = (mode==REL_GAME) ? &game_globals.garray[g].moveList[i] : &game_globals.garray[g].examMoveList[i];
+ if ((m1->fromFile == 7) && (m1->fromRank == 0))
+ break;
+ }
+ if (i == game_globals.garray[g].numHalfMoves - 1)
+ gs->wkrmoved = 0;
+ }
+ } else {
+ if ((m->fromFile == 0) && (m->fromRank == 7)) {
+ for (i = 3; i < game_globals.garray[g].numHalfMoves - 1; i += 2) {
+ m1 = (mode==REL_GAME) ? &game_globals.garray[g].moveList[i] : &game_globals.garray[g].examMoveList[i];
+ if ((m1->fromFile == 0) && (m1->fromRank == 0))
+ break;
+ }
+ if (i == game_globals.garray[g].numHalfMoves - 1)
+ gs->bqrmoved = 0;
+ }
+ if ((m->fromFile == 7) && (m->fromRank == 7)) {
+ for (i = 3; i < game_globals.garray[g].numHalfMoves - 1; i += 2) {
+ m1 = (mode==REL_GAME) ? &game_globals.garray[g].moveList[i] : &game_globals.garray[g].examMoveList[i];
+ if ((m1->fromFile == 7) && (m1->fromRank == 0))
+ break;
+ }
+ if (i == game_globals.garray[g].numHalfMoves - 1)
+ gs->bkrmoved = 0;
+ }
+ }
+ }
+ if (piecetype(gs->board[m->fromFile][m->fromRank]) == KING) {
+ gs->board[m->toFile][m->toRank] = m->pieceCaptured;
+
+ if (m->toFile - m->fromFile == 2) {
+ gs->board[7][m->fromRank] = ROOK |
+ colorval(gs->board[m->fromFile][m->fromRank]);
+ gs->board[5][m->fromRank] = NOPIECE;
+
+ /********
+ If takeback a castling, the appropriates ??moved variables
+ must be cleared
+ ********/
+ if (m->color == WHITE) {
+ gs->wkmoved = 0;
+ gs->wkrmoved = 0;
+ } else {
+ gs->bkmoved = 0;
+ gs->bkrmoved = 0;
+ }
+ goto cleanupMove;
+ }
+ if (m->fromFile - m->toFile == 2) {
+ gs->board[0][m->fromRank] = ROOK |
+ colorval(gs->board[m->fromFile][m->fromRank]);
+ gs->board[3][m->fromRank] = NOPIECE;
+
+ /**********
+ If takeback a castling, the appropriate ??moved variables
+ must be cleared
+ ***********/
+ if (m->color == WHITE) {
+ gs->wkmoved = 0;
+ gs->wqrmoved = 0;
+ } else {
+ gs->bkmoved = 0;
+ gs->bqrmoved = 0;
+ }
+ goto cleanupMove;
+ }
+ /******************
+ When takeback a _first_ move of king (not the castling),
+ the ?kmoved variable must be cleared . To check, if the move is first,
+ we should scan moveList.
+ *******************/
+
+ if (m->color == WHITE) {
+
+ if ((m->fromFile == 4) && (m->fromRank == 0)) {
+ for (i = 2; i < game_globals.garray[g].numHalfMoves - 1; i += 2) {
+ m1 = (mode==REL_GAME) ? &game_globals.garray[g].moveList[i] : &game_globals.garray[g].examMoveList[i];
+ if ((m1->fromFile == 4) && (m1->fromRank == 0))
+ break;
+ }
+ if (i == game_globals.garray[g].numHalfMoves - 1)
+ gs->wkmoved = 0;
+ }
+ } else {
+ if ((m->fromFile == 4) && (m->fromRank == 7)) {
+ for (i = 3; i < game_globals.garray[g].numHalfMoves - 1; i += 2) {
+ m1 = (mode==REL_GAME) ? &game_globals.garray[g].moveList[i] : &game_globals.garray[g].examMoveList[i];
+ if ((m1->fromFile == 4) && (m1->fromRank == 7))
+ break;
+ }
+ if (i == game_globals.garray[g].numHalfMoves - 1)
+ gs->bkmoved = 0;
+ }
+ }
+ }
+ if (m->enPassant) { /* Do enPassant */
+ gs->board[m->toFile][m->fromRank] = PAWN |
+ (colorval(gs->board[m->fromFile][m->fromRank]) == WHITE ? BLACK : WHITE);
+ gs->board[m->toFile][m->toRank] = NOPIECE;
+ /* Should set the enpassant array, but I don't care right now */
+ goto cleanupMove;
+ }
+ gs->board[m->toFile][m->toRank] = m->pieceCaptured;
+cleanupMove:
+ if (game_globals.garray[g].status != GAME_EXAMINE) {
+ game_update_time(g);
+ }
+ game_globals.garray[g].numHalfMoves--;
+ if (game_globals.garray[g].status != GAME_EXAMINE) {
+ if (game_globals.garray[g].wInitTime) { /* Don't update times in untimed games */
+ now = tenth_secs();
+
+ if (m->color == WHITE) {
+ if (net_globals.con[player_globals.parray[game_globals.garray[g].white].socket]->timeseal) { /* white uses timeseal? */
+ game_globals.garray[g].wRealTime += (m->tookTime * 100);
+ game_globals.garray[g].wRealTime -= (game_globals.garray[g].wIncrement * 100);
+ game_globals.garray[g].wTime = game_globals.garray[g].wRealTime / 100;
+ if (net_globals.con[player_globals.parray[game_globals.garray[g].black].socket]->timeseal) { /* opp uses timeseal? */
+ game_globals.garray[g].bTime = game_globals.garray[g].bRealTime / 100;
+ } else { /* opp has no timeseal */
+ game_globals.garray[g].bTime += (game_globals.garray[g].lastDecTime - game_globals.garray[g].lastMoveTime);
+ }
+ } else { /* white has no timeseal */
+ game_globals.garray[g].wTime += m->tookTime;
+ game_globals.garray[g].wTime -= game_globals.garray[g].wIncrement;
+ if (net_globals.con[player_globals.parray[game_globals.garray[g].black].socket]->timeseal) { /* opp uses timeseal? */
+ game_globals.garray[g].bTime = game_globals.garray[g].bRealTime / 100;
+ } else { /* opp has no timeseal */
+ game_globals.garray[g].bTime += (game_globals.garray[g].lastDecTime - game_globals.garray[g].lastMoveTime);
+ }
+ }
+ } else {
+ if (net_globals.con[player_globals.parray[game_globals.garray[g].black].socket]->timeseal) { /* black uses timeseal? */
+ game_globals.garray[g].bRealTime += (m->tookTime * 100);
+ game_globals.garray[g].bRealTime -= (game_globals.garray[g].wIncrement * 100);
+ game_globals.garray[g].bTime = game_globals.garray[g].bRealTime / 100;
+ if (net_globals.con[player_globals.parray[game_globals.garray[g].white].socket]->timeseal) { /* opp uses timeseal? */
+ game_globals.garray[g].wTime = game_globals.garray[g].wRealTime / 100;
+ } else { /* opp has no timeseal */
+ game_globals.garray[g].wTime += (game_globals.garray[g].lastDecTime - game_globals.garray[g].lastMoveTime);
+ }
+ } else { /* black has no timeseal */
+ game_globals.garray[g].bTime += m->tookTime;
+ if (!game_globals.garray[g].bIncrement)
+ game_globals.garray[g].bTime -= game_globals.garray[g].wIncrement;
+ else
+ game_globals.garray[g].bTime -= game_globals.garray[g].bIncrement;
+ if (net_globals.con[player_globals.parray[game_globals.garray[g].white].socket]->timeseal) { /* opp uses timeseal? */
+ game_globals.garray[g].wTime = game_globals.garray[g].wRealTime / 100;
+ } else { /* opp has no timeseal */
+ game_globals.garray[g].wTime += (game_globals.garray[g].lastDecTime - game_globals.garray[g].lastMoveTime);
+ }
+ }
+ }
+
+ if (game_globals.garray[g].numHalfMoves == 0)
+ game_globals.garray[g].timeOfStart = now;
+ game_globals.garray[g].lastMoveTime = now;
+ game_globals.garray[g].lastDecTime = now;
+ }
+ }
+ if (gs->onMove == BLACK)
+ gs->onMove = WHITE;
+ else {
+ gs->onMove = BLACK;
+ gs->moveNum--;
+ }
+
+ /******* Here begins the patch : ********************************
+ Takeback of last move is done already, it's time to update enpassant
+ array. (patch from Soso, added by Sparky 3/17/95)
+ ********/
+
+ if (game_globals.garray[g].numHalfMoves > 0) {
+ m1 = (mode==REL_GAME) ? &game_globals.garray[g].moveList[game_globals.garray[g].numHalfMoves - 1] :
+ &game_globals.garray[g].examMoveList[game_globals.garray[g].numHalfMoves - 1];
+ if (piecetype(gs->board[m1->toFile][m1->toRank]) == PAWN) {
+ if ((m1->toRank - m1->fromRank) == 2) {
+ if ((m1->toFile < 7) && gs->board[m1->toFile + 1][3] == B_PAWN) {
+ gs->ep_possible[1][m1->toFile + 1] = -1;
+ }
+ if ((m1->toFile - 1 >= 0) && gs->board[m1->toFile - 1][3] == B_PAWN) {
+ gs->ep_possible[1][m1->toFile - 1] = 1;
+ }
+ }
+ if ((m1->toRank - m1->fromRank) == -2) {
+ if ((m1->toFile < 7) && gs->board[m1->toFile + 1][4] == W_PAWN) {
+ gs->ep_possible[0][m1->toFile + 1] = -1;
+ }
+ if ((m1->toFile - 1 >= 0) && gs->board[m1->toFile - 1][4] == W_PAWN) {
+ gs->ep_possible[0][m1->toFile - 1] = 1;
+ }
+ }
+ }
+ }
+ /************** and here's the end **************/
+ return MOVE_OK;
+}
+
+
+
+
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+#ifndef _MOVECHECK_H
+#define _MOVECHECK_H
+
+#define MOVE_OK 0
+#define MOVE_ILLEGAL 1
+#define MOVE_STALEMATE 2
+#define MOVE_CHECKMATE 3
+#define MOVE_AMBIGUOUS 4
+#define MOVE_NOMATERIAL 5
+
+#define MS_NOTMOVE 0
+#define MS_COMP 1
+#define MS_COMPDASH 2
+#define MS_ALG 3
+#define MS_KCASTLE 4
+#define MS_QCASTLE 5
+
+#define isrank(c) (((c) <= '8') && ((c) >= '1'))
+#define isfile(c) (((c) >= 'a') && ((c) <= 'h'))
+
+#endif /* _MOVECHECK_H */
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+
+#include "includes.h"
+
+struct multicol *multicol_start(int maxArray)
+{
+ int i;
+ multicol *m;
+
+ m = (multicol *) malloc(sizeof(multicol));
+ m->arraySize = maxArray;
+ m->num = 0;
+ m->strArray = (char **) malloc(sizeof(char *) * m->arraySize);
+ for (i = 0; i < m->arraySize; i++)
+ m->strArray[i] = NULL;
+ return m;
+}
+
+int multicol_store(multicol * m, char *str)
+{
+ if (m->num >= m->arraySize)
+ return -1;
+ if (!str)
+ return -1;
+ m->strArray[m->num] = strdup(str);
+ m->num++;
+ return 0;
+}
+
+int multicol_store_sorted(multicol * m, char *str)
+/* use this instead of multicol_store to print a list sorted */
+{
+ int i;
+ int found = 0;
+ if (m->num >= m->arraySize)
+ return -1;
+ if (!str)
+ return -1;
+ for (i = m->num; (i > 0) && (!found); i--) {
+ if (strcasecmp(str, m->strArray[i - 1]) >= 0) {
+ found = 1;
+ m->strArray[i] = strdup(str);
+ } else {
+ m->strArray[i] = m->strArray[i - 1];
+ }
+ }
+ if (!found)
+ m->strArray[0] = strdup(str);
+ m->num++;
+ return 0;
+}
+
+int multicol_pprint(multicol * m, int player, int cols, int space)
+{
+ int i;
+ int maxWidth = 0;
+ int numPerLine;
+ int numLines;
+ int on, theone, len;
+ int done;
+ int temp;
+ char *tempptr;
+
+ pprintf(player, "\n");
+ for (i = 0; i < m->num; i++) {
+ tempptr = m->strArray[i];
+ temp = strlen(tempptr); /* loon: yes, this is pathetic */
+ for (; *tempptr; tempptr++) {
+ if (*tempptr == '\033')
+ temp -= 4;
+ }
+ if (temp > maxWidth)
+ maxWidth = temp;
+ }
+ maxWidth += space;
+ numPerLine = cols / maxWidth;
+ if (!numPerLine)
+ numPerLine = 1; /* stop a division by 0 on large members */
+ numLines = m->num / numPerLine;
+ if (numLines * numPerLine < m->num)
+ numLines++;
+ on = 0;
+ done = 0;
+ while (!done) {
+ for (i = 0; i < numPerLine; i++) {
+ theone = on + numLines * i;
+ if (theone >= m->num) {
+ break;
+ }
+ tempptr = m->strArray[theone];
+ temp = strlen(tempptr); /* loon: yes, still pathetic */
+ for (; *tempptr; tempptr++) {
+ if (*tempptr == '\033')
+ temp -= 4;
+ }
+ len = maxWidth - temp;
+ if (i == numPerLine - 1)
+ len -= space;
+ pprintf(player, "%s", m->strArray[theone]);
+ while (len) {
+ pprintf(player, " ");
+ len--;
+ }
+ }
+ pprintf(player, "\n");
+ on += 1;
+ if (on >= numLines)
+ break;
+ }
+ return 0;
+}
+
+int multicol_end(multicol * m)
+{
+ int i;
+ for (i = 0; i < m->num; i++)
+ FREE(m->strArray[i]);
+ FREE(m->strArray);
+ FREE(m);
+ return 0;
+}
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+#ifndef _MULTICOL_H
+#define _MULTICOL_H
+
+typedef struct multicol
+{
+ int arraySize;
+ int num;
+ char **strArray;
+} multicol;
+
+#endif /* _MULTICOL_H */
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+#include "includes.h"
+
+extern int errno;
+
+/* Index == fd, for sparse array, quick lookups! wasted memory :( */
+static int findConnection(int fd)
+{
+ if (fd == -1 || net_globals.con[fd]->status == NETSTAT_EMPTY)
+ return -1;
+ else
+ return fd;
+}
+
+
+static void set_sndbuf(int fd, int len)
+{
+ net_globals.con[fd]->sndbufpos = len;
+ if (len < net_globals.con[fd]->sndbufsize) {
+ net_globals.con[fd]->sndbuf[len] = 0;
+ }
+}
+
+static int net_addConnection(int fd, struct in_addr fromHost)
+{
+ int noblock = 1;
+
+ /* possibly expand the connections array */
+ if (fd >= net_globals.no_file) {
+ int i;
+ net_globals.con = (struct connection_t **)realloc(net_globals.con,
+ (fd+1) * sizeof(struct connection_t *));
+ for (i=net_globals.no_file;i<fd+1;i++) {
+ net_globals.con[i] = (struct connection_t *)calloc(1,
+ sizeof(struct connection_t));
+ net_globals.con[i]->status = NETSTAT_EMPTY;
+ }
+ net_globals.no_file = fd+1;
+ }
+
+ if (findConnection(fd) >= 0) {
+ d_printf( "CHESSD: FD already in connection table!\n");
+ return -1;
+ }
+ if (ioctl(fd, FIONBIO, &noblock) == -1) {
+ d_printf( "Error setting nonblocking mode errno=%d\n", errno);
+ }
+ net_globals.con[fd]->fd = fd;
+ if (fd != 0)
+ net_globals.con[fd]->outFd = fd;
+ else
+ net_globals.con[fd]->outFd = 1;
+ net_globals.con[fd]->fromHost = fromHost;
+ net_globals.con[fd]->status = NETSTAT_CONNECTED;
+ net_globals.con[fd]->timeseal = 0;
+ net_globals.con[fd]->timeseal_init = 1;
+ net_globals.con[fd]->time = 0;
+ net_globals.con[fd]->numPending = 0;
+ net_globals.con[fd]->inBuf[0] = 0;
+ net_globals.con[fd]->processed = 0;
+ net_globals.con[fd]->outPos = 0;
+ if (net_globals.con[fd]->sndbuf == NULL) {
+#ifdef DEBUG
+ d_printf( "CHESSD: nac(%d) allocating sndbuf.\n", fd);
+#endif
+ net_globals.con[fd]->sndbufpos = 0;
+ net_globals.con[fd]->sndbufsize = MAX_STRING_LENGTH;
+ net_globals.con[fd]->sndbuf = malloc(MAX_STRING_LENGTH);
+ } else {
+#ifdef DEBUG
+ d_printf( "CHESSD: nac(%d) reusing old sndbuf size %d pos %d.\n", fd, net_globals.con[fd].sndbufsize, net_globals.con[fd].sndbufpos);
+#endif
+ }
+ net_globals.con[fd]->state = 0;
+ net_globals.numConnections++;
+
+#ifdef DEBUG
+ d_printf( "CHESSD: fd: %d connections: %d descriptors: %d \n", fd, numConnections, getdtablesize()); /* sparky 3/13/95 */
+#endif
+
+ return 0;
+}
+
+static int remConnection(int fd)
+{
+ int which, i;
+ if ((which = findConnection(fd)) < 0) {
+ d_printf( "remConnection: Couldn't find fd to close.\n");
+ return -1;
+ }
+ net_globals.numConnections--;
+ net_globals.con[fd]->status = NETSTAT_EMPTY;
+ if (net_globals.con[fd]->sndbuf == NULL) {
+ d_printf( "CHESSD: remcon(%d) SNAFU, this shouldn't happen.\n", fd);
+ } else {
+ if (net_globals.con[fd]->sndbufsize > MAX_STRING_LENGTH) {
+ net_globals.con[fd]->sndbufsize = MAX_STRING_LENGTH;
+ net_globals.con[fd]->sndbuf = realloc(net_globals.con[fd]->sndbuf, MAX_STRING_LENGTH);
+ }
+ if (net_globals.con[fd]->sndbufpos) { /* didn't send everything, bummer */
+ set_sndbuf(fd, 0);
+ }
+ }
+
+ /* see if we can shrink the con array */
+ for (i=fd;i<net_globals.no_file;i++) {
+ if (net_globals.con[i]->status != NETSTAT_EMPTY) {
+ return 0;
+ }
+ }
+
+ /* yep! shrink it */
+ for (i=fd;i<net_globals.no_file;i++) {
+ FREE(net_globals.con[i]->sndbuf);
+ FREE(net_globals.con[i]);
+ }
+ net_globals.no_file = fd;
+ net_globals.con = (struct connection_t **)realloc(net_globals.con,
+ net_globals.no_file * sizeof(struct connection_t *));
+
+ return 0;
+}
+
+static void net_flushme(int which)
+{
+ int sent;
+
+ sent = send(net_globals.con[which]->outFd, net_globals.con[which]->sndbuf, net_globals.con[which]->sndbufpos, 0);
+ if (sent == -1) {
+ if (errno != EPIPE) /* EPIPE = they've disconnected */
+ d_printf( "CHESSD: net_flushme(%d) couldn't send, errno=%d.\n", which, errno);
+ set_sndbuf(which, 0);
+ } else {
+ net_globals.con[which]->sndbufpos -= sent;
+ if (net_globals.con[which]->sndbufpos)
+ memmove(net_globals.con[which]->sndbuf, net_globals.con[which]->sndbuf + sent, net_globals.con[which]->sndbufpos);
+ }
+ if (net_globals.con[which]->sndbufsize > MAX_STRING_LENGTH && net_globals.con[which]->sndbufpos < MAX_STRING_LENGTH) {
+ /* time to shrink the buffer */
+ net_globals.con[which]->sndbuf = realloc(net_globals.con[which]->sndbuf, MAX_STRING_LENGTH);
+ net_globals.con[which]->sndbufsize = MAX_STRING_LENGTH;
+ }
+ set_sndbuf(which, net_globals.con[which]->sndbufpos);
+}
+
+static void net_flush_all_connections(void)
+{
+ int which;
+ fd_set writefds;
+ struct timeval to;
+
+ FD_ZERO(&writefds);
+ for (which = 0; which < net_globals.no_file; which++) {
+ if (net_globals.con[which]->status == NETSTAT_CONNECTED &&
+ net_globals.con[which]->sndbufpos){
+ FD_SET(net_globals.con[which]->outFd, &writefds);
+ }
+ }
+
+ to.tv_usec = 0;
+ to.tv_sec = 0;
+ select(net_globals.no_file, NULL, &writefds, NULL, &to);
+ for (which = 0; which < net_globals.no_file; which++) {
+ if (FD_ISSET(net_globals.con[which]->outFd, &writefds)) {
+ net_flushme(which);
+ }
+ }
+}
+
+static void net_flush_connection(int fd)
+{
+ int which;
+ fd_set writefds;
+ struct timeval to;
+
+ if (((which = findConnection(fd)) >= 0) && (net_globals.con[which]->sndbufpos)) {
+ FD_ZERO(&writefds);
+ FD_SET(net_globals.con[which]->outFd, &writefds);
+ to.tv_usec = 0;
+ to.tv_sec = 0;
+ select(net_globals.no_file, NULL, &writefds, NULL, &to);
+ if (FD_ISSET(net_globals.con[which]->outFd, &writefds)) {
+ net_flushme(which);
+ }
+ }
+}
+
+static int sendme(int which, char *str, int len)
+{
+ int i, count;
+ fd_set writefds;
+ struct timeval to;
+ count = len;
+
+ while ((i = ((net_globals.con[which]->sndbufsize - net_globals.con[which]->sndbufpos) < len) ? (net_globals.con[which]->sndbufsize - net_globals.con[which]->sndbufpos) : len) > 0) {
+ memmove(net_globals.con[which]->sndbuf + net_globals.con[which]->sndbufpos, str, i);
+ net_globals.con[which]->sndbufpos += i;
+ if (net_globals.con[which]->sndbufpos == net_globals.con[which]->sndbufsize) {
+
+ FD_ZERO(&writefds);
+ FD_SET(net_globals.con[which]->outFd, &writefds);
+ to.tv_usec = 0;
+ to.tv_sec = 0;
+ select(net_globals.no_file, NULL, &writefds, NULL, &to);
+ if (FD_ISSET(net_globals.con[which]->outFd, &writefds)) {
+ net_flushme(which);
+ } else {
+ /* time to grow the buffer */
+ net_globals.con[which]->sndbufsize += MAX_STRING_LENGTH;
+ net_globals.con[which]->sndbuf = realloc(net_globals.con[which]->sndbuf, net_globals.con[which]->sndbufsize);
+ }
+ }
+ str += i;
+ len -= i;
+ }
+ set_sndbuf(which, net_globals.con[which]->sndbufpos);
+ return count;
+}
+
+/*
+ * -1 for an error other than EWOULDBLOCK.
+ * Put <lf> after every <cr> and put \ at the end of overlength lines.
+ * Doesn't send anything unless the buffer fills, output waits until
+ * flushed
+*/
+/* width here is terminal width = width var + 1 at presnt) */
+int net_send_string(int fd, char *str, int format, int width)
+{
+ int which, i, j;
+
+ if ((which = findConnection(fd)) < 0) {
+ return -1;
+ }
+ while (*str) {
+ for (i = 0; str[i] >= ' '; i++);
+ if (i) {
+ if (format && (i >= (j = width - net_globals.con[which]->outPos))) { /* word wrap */
+ i = j-1;
+ while (i > 0 && str[i - 1] != ' ')
+ i--;
+/*
+ while (i > 0 && str[i - 1] == ' ')
+ i--;
+*/
+ if (i == 0)
+ i = j - 1;
+ sendme(which, str, i);
+ sendme(which, "\n\r\\ ", 6);
+ net_globals.con[which]->outPos = 4;
+ while (str[i] == ' ') /* eat the leading spaces after we wrap */
+ i++;
+ } else {
+ sendme(which, str, i);
+ net_globals.con[which]->outPos += i;
+ }
+ str += i;
+ } else { /* non-printable stuff handled here */
+ switch (*str) {
+ case '\t':
+ sendme(which, " ", 8 - (net_globals.con[which]->outPos & 7));
+ net_globals.con[which]->outPos &= ~7;
+ if (net_globals.con[which]->outPos += 8 >= width)
+ net_globals.con[which]->outPos = 0;
+ break;
+ case '\n':
+ sendme(which, "\n\r", 2);
+ net_globals.con[which]->outPos = 0;
+ break;
+ case '\033':
+ net_globals.con[which]->outPos -= 3;
+ default:
+ sendme(which, str, 1);
+ }
+ str++;
+ }
+ }
+ return 0;
+}
+
+/* if we get a complete line (something terminated by \n), copy it to com
+ and return 1.
+ if we don't get a complete line, but there is no error, return 0.
+ if some error, return -1.
+ */
+static int readline2(char *com, int who)
+{
+ unsigned char *start, *s, *d;
+ int howmany, state, fd, pending;
+
+ const unsigned char will_tm[] = {IAC, WILL, TELOPT_TM, '\0'};
+ const unsigned char will_sga[] = {IAC, WILL, TELOPT_SGA, '\0'};
+ const unsigned char ayt[] = "[Responding to AYT: Yes, I'm here.]\n";
+
+ state = net_globals.con[who]->state;
+ if ((state == 2) || (state > 4)) {
+ d_printf( "CHESSD: state screwed for net_globals.con[%d], this is a bug.\n", who);
+ state = 0;
+ }
+ s = start = net_globals.con[who]->inBuf;
+ pending = net_globals.con[who]->numPending;
+ fd = net_globals.con[who]->fd;
+
+ howmany = recv(fd, start + pending, MAX_STRING_LENGTH - 1 - pending, 0);
+ if (howmany == 0) /* error: they've disconnected */
+ return (-1);
+ else if (howmany == -1) {
+ if (errno != EWOULDBLOCK) { /* some other error */
+ return (-1);
+ } else if (net_globals.con[who]->processed) { /* nothing new and nothing old */
+ return (0);
+ } else { /* nothing new, but some unprocessed old */
+ howmany = 0;
+ }
+ }
+ if (net_globals.con[who]->processed)
+ s += pending;
+ else
+ howmany += pending;
+ d = s;
+
+ for (; howmany-- > 0; s++) {
+ switch (state) {
+ case 0: /* Haven't skipped over any control chars or
+ telnet commands */
+ if (*s == IAC) {
+ d = s;
+ state = 1;
+ } else if (*s == '\n') {
+ *s = '\0';
+ strcpy(com, start);
+ if (howmany)
+ bcopy(s + 1, start, howmany);
+ net_globals.con[who]->state = 0;
+ net_globals.con[who]->numPending = howmany;
+ net_globals.con[who]->inBuf[howmany] = 0;
+ net_globals.con[who]->processed = 0;
+ net_globals.con[who]->outPos = 0;
+ return (1);
+/*
+ Cannot strip ^? yet otherwise timeseal probs occur
+*/
+ } else if (*s == '\010') { /* ^H lets delete */
+ if (s > start)
+ d = s-1;
+ else
+ d = s;
+ state = 2;
+ } else if ((*s > (0xff - 0x20)) || (*s < 0x20)) {
+ d = s;
+ state = 2;
+ }
+ break;
+ case 1: /* got telnet IAC */
+ if (*s == IP)
+ return (-1); /* ^C = logout */
+ else if (*s == DO)
+ state = 4;
+ else if ((*s == WILL) || (*s == DONT) || (*s == WONT))
+ state = 3; /* this is cheesy, but we aren't using em */
+ else if (*s == AYT) {
+ send(fd, (char *) ayt, strlen((char *) ayt), 0);
+ state = 2;
+ } else if (*s == EL) { /* erase line */
+ d = start;
+ state = 2;
+ } else /* dunno what it is, so ignore it */
+ state = 2;
+ break;
+ case 2: /* we've skipped over something, need to
+ shuffle processed chars down */
+ if (*s == IAC)
+ state = 1;
+ else if (*s == '\n') {
+ *d = '\0';
+ strcpy(com, start);
+ if (howmany)
+ memmove(start, s + 1, howmany);
+ net_globals.con[who]->state = 0;
+ net_globals.con[who]->numPending = howmany;
+ net_globals.con[who]->inBuf[howmany] = 0;
+ net_globals.con[who]->processed = 0;
+ net_globals.con[who]->outPos = 0;
+ return (1);
+/*
+ Cannot strip ^? yet otherwise timeseal probs occur
+*/
+ } else if (*s == '\010') { /* ^H lets delete */
+ if (d > start)
+ d = d-1;
+ } else if (*s >= 0x20)
+ *(d++) = *s;
+ break;
+ case 3: /* some telnet junk we're ignoring */
+ state = 2;
+ break;
+ case 4: /* got IAC DO */
+ if (*s == TELOPT_TM)
+ send(fd, (char *) will_tm, strlen((char *) will_tm), 0);
+ else if (*s == TELOPT_SGA)
+ send(fd, (char *) will_sga, strlen((char *) will_sga), 0);
+ state = 2;
+ break;
+ }
+ }
+ if (state == 0)
+ d = s;
+ else if (state == 2)
+ state = 0;
+ net_globals.con[who]->state = state;
+ net_globals.con[who]->numPending = d - start;
+ net_globals.con[who]->inBuf[d-start] = 0;
+ net_globals.con[who]->processed = 1;
+ if (net_globals.con[who]->numPending == MAX_STRING_LENGTH - 1) { /* buffer full */
+ *d = '\0';
+ strcpy(com, start);
+ net_globals.con[who]->state = 0;
+ net_globals.con[who]->numPending = 0;
+ net_globals.con[who]->inBuf[0] = 0;
+ net_globals.con[who]->processed = 0;
+ return (1);
+ }
+ return (0);
+}
+
+int net_init(int port)
+{
+ int opt;
+ struct sockaddr_in serv_addr;
+ struct linger lingeropt;
+
+ net_globals.no_file = 0;
+ net_globals.con = NULL;
+
+ /* Open a TCP socket (an Internet stream socket). */
+ if ((net_globals.sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ d_printf( "CHESSD: can't open stream socket\n");
+ return -1;
+ }
+ /* Bind our local address so that the client can send to us */
+ memset((char *) &serv_addr, 0, sizeof(serv_addr));
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ serv_addr.sin_port = htons(port);
+
+ /** added in an attempt to allow rebinding to the port **/
+
+ opt = 1;
+ setsockopt(net_globals.sockfd, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof(opt));
+ opt = 1;
+ setsockopt(net_globals.sockfd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt, sizeof(opt));
+ lingeropt.l_onoff = 0;
+ lingeropt.l_linger = 0;
+ setsockopt(net_globals.sockfd, SOL_SOCKET, SO_LINGER, (char *) &lingeropt, sizeof(lingeropt));
+
+/*
+#ifdef DEBUG
+ opt = 1;
+ setsockopt(sockfd, SOL_SOCKET, SO_DEBUG, (char *)&opt, sizeof(opt));
+#endif
+*/
+
+ if (bind(net_globals.sockfd, (struct sockaddr *) & serv_addr, sizeof(serv_addr)) < 0) {
+ d_printf( "CHESSD: can't bind local address. errno=%d\n", errno);
+ return -1;
+ }
+ opt = 1;
+ ioctl(net_globals.sockfd, FIONBIO, &opt);
+ fcntl(net_globals.sockfd, F_SETFD, 1);
+ listen(net_globals.sockfd, 5);
+ return 0;
+}
+
+void net_close(void)
+{
+ int i;
+ for (i = 0; i < net_globals.no_file; i++) {
+ if (net_globals.con[i]->status != NETSTAT_EMPTY)
+ net_close_connection(net_globals.con[i]->fd);
+ }
+}
+
+void net_close_connection(int fd)
+{
+ if (net_globals.con[fd]->status == NETSTAT_CONNECTED)
+ net_flush_connection(fd);
+ else
+ d_printf( "Trying to close an unconnected socket?!?!\n");
+
+ if (!remConnection(fd)) {
+ if (fd > 2)
+ if (close(fd) < 0) {
+ d_printf( "Couldn't close socket %d - errno %d\n", fd, errno);
+ }
+ } else {
+ d_printf( "Failed to remove connection (Socket %d)\n", fd);
+ }
+}
+
+void turn_echo_on(int fd)
+{
+ const unsigned char wont_echo[] = {IAC, WONT, TELOPT_ECHO, '\0'};
+
+ send(fd, (char *) wont_echo, strlen((char *) wont_echo), 0);
+}
+
+void turn_echo_off(int fd)
+{
+ static unsigned char will_echo[] = {IAC, WILL, TELOPT_ECHO, '\0'};
+
+ send(fd, (char *) will_echo, strlen((char *) will_echo), 0);
+}
+
+static struct in_addr net_connected_host(int fd)
+{
+ int which;
+
+ if ((which = findConnection(fd)) < 0) {
+ static struct in_addr ip_zero;
+ d_printf( "CHESSD: FD not in connection table!\n");
+ return ip_zero;
+ }
+ return net_globals.con[which]->fromHost;
+}
+
+void select_loop(void )
+{
+ char com[MAX_STRING_LENGTH];
+ struct sockaddr_in cli_addr;
+ int cli_len = (int) sizeof(struct sockaddr_in);
+ int fd, loop, nfound, lineComplete;
+ fd_set readfds;
+ struct timeval to;
+ int current_socket;
+ int timeout = 2;
+
+#if 0
+ m_check_all();
+#endif
+
+ /* we only want to get signals here. This tries to
+ ensure a clean shutdown on 'kill' */
+ unblock_signal(SIGTERM);
+ block_signal(SIGTERM);
+
+ while ((fd = accept(net_globals.sockfd, (struct sockaddr *) & cli_addr, &cli_len)) != -1) {
+ if (net_addConnection(fd, cli_addr.sin_addr)) {
+ d_printf( "FICS is full. fd = %d.\n", fd);
+ psend_raw_file(fd, MESS_DIR, MESS_FULL);
+ close(fd);
+ } else {
+ if (fd >= net_globals.no_file)
+ d_printf("FICS (ngc2): Out of range fd!\n");
+ else {
+ fcntl(fd, F_SETFD, 1);
+ process_new_connection(fd, net_connected_host(fd));
+ }
+ }
+ }
+
+ if (errno != EWOULDBLOCK)
+ d_printf( "CHESSD: Problem with accept(). errno=%d\n", errno);
+
+ net_flush_all_connections();
+
+ if (net_globals.numConnections == 0) {
+ sleep(1); /* prevent the server spinning */
+ }
+
+ FD_ZERO(&readfds);
+ for (loop = 0; loop < net_globals.no_file; loop++)
+ if (net_globals.con[loop]->status != NETSTAT_EMPTY)
+ FD_SET(net_globals.con[loop]->fd, &readfds);
+
+ to.tv_usec = 0;
+ to.tv_sec = timeout;
+ nfound = select(net_globals.no_file, &readfds, NULL, NULL, &to);
+ for (loop = 0; loop < net_globals.no_file; loop++) {
+ if (net_globals.con[loop]->status != NETSTAT_EMPTY) {
+ fd = net_globals.con[loop]->fd;
+ more_commands:
+ lineComplete = readline2(com, fd);
+ if (lineComplete == 0) /* partial line: do nothing with it */
+ continue;
+ if (lineComplete > 0) { /* complete line: process it */
+ if (!timeseal_parse(com, net_globals.con[loop])) continue;
+ if (process_input(fd, com) != COM_LOGOUT) {
+ net_flush_connection(fd);
+ goto more_commands;
+ }
+ }
+ /* Disconnect anyone who gets here */
+ process_disconnection(fd);
+ net_close_connection(fd);
+ }
+ }
+
+ if (process_heartbeat(¤t_socket) == COM_LOGOUT) {
+ process_disconnection(current_socket);
+ net_close_connection(current_socket);
+ }
+}
+
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+#ifndef NETWORK_H
+#define NETWORK_H
+
+#define NET_NETERROR 0
+#define NET_NEW 1
+#define NET_DISCONNECT 2
+#define NET_READLINE 3
+#define NET_TIMEOUT 4
+#define NET_NOTCOMPLETE 5
+
+#define LINE_WIDTH 80
+
+#ifndef O_NONBLOCK
+#define O_NONBLOCK 00004
+#endif
+
+GENSTRUCT enum netstatus {NETSTAT_EMPTY, NETSTAT_CONNECTED, NETSTAT_IDENT};
+
+GENSTRUCT struct connection_t {
+ int fd;
+ int outFd;
+ struct in_addr fromHost;
+ enum netstatus status;
+ /* Input buffering */
+ int numPending;
+ int processed;
+ unsigned char inBuf[MAX_STRING_LENGTH+1]; _NULLTERM
+ /* Output buffering */
+ int sndbufsize; /* size of send buffer (this changes) */
+ int sndbufpos; /* position in send buffer */
+ unsigned char *sndbuf; _LEN(sndbufsize)_NULLTERM /* our send buffer, or NULL if none yet */
+ int outPos; /* column count */
+ int state; /* 'telnet state' */
+ int mypal;
+ int timeseal; /* are they using timeseal */
+ int timeseal_init; /* are they in timeseal initialisation? */
+ unsigned time; /* last time received from the client */
+};
+
+#endif /* NETWORK_H */
--- /dev/null
+/*
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+/*
+ support for the 'news' command
+ */
+
+#include "includes.h"
+
+static TDB_CONTEXT *news_db;
+
+/* close the news database */
+void news_close(void)
+{
+ if (!news_db) return;
+ tdb_close(news_db);
+ news_db = NULL;
+}
+
+/*
+ open the news database
+ returns 0 on success
+ */
+int news_open(void)
+{
+ news_db = tdb_open(NEWS_DB, 0, 0, O_RDWR|O_CREAT, 0600);
+ if (!news_db) {
+ d_printf("Unable to open news database!\n");
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ free up a news item
+*/
+static void news_free(struct news *news)
+{
+ FREE(news->poster);
+ FREE(news->title);
+ FREE(news->message);
+}
+
+/*
+ return the maximum news item number
+*/
+static int news_max(int admin)
+{
+ return tdb_get_int(news_db, admin?"ADMIN_MAXNUM":"MAXNUM", 0);
+}
+
+/*
+ save a news item
+*/
+static int news_save(int num, struct news *news, int admin)
+{
+ const char *s;
+ char *name;
+
+ /* marshall it into a string */
+ s = marshall_news(news);
+ if (!s) {
+ return -1;
+ }
+
+ asprintf(&name, "%s%u", admin?"ADMIN/":"", num);
+ if (tdb_set_string(news_db, name, s) != 0) {
+ free(name);
+ free(s);
+ return -1;
+ }
+
+ free(name);
+ free(s);
+
+ if (news_max(admin) < num) {
+ tdb_set_int(news_db, admin?"ADMIN_MAXNUM":"MAXNUM", num);
+ }
+
+ return 0;
+}
+
+
+/*
+ load a news item
+*/
+static int news_load(int num, struct news *news, int admin)
+{
+ const char *s;
+ char *name;
+ int ret;
+
+ asprintf(&name, "%s%u", admin?"ADMIN/":"", num);
+ s = tdb_get_string(news_db, name);
+ if (!s) {
+ free(name);
+ return -1;
+ }
+ free(name);
+
+ ret = unmarshall_news(news, s);
+ free(s);
+ return ret;
+}
+
+/*
+ delete a news item
+*/
+static int news_delete(int p, int num, int admin)
+{
+ char *name;
+
+ asprintf(&name, "%s%u", admin?"ADMIN/":"", num);
+ if (tdb_delete_string(news_db, name) == 0) {
+ pprintf(p,"Deleted news item %u\n", num);
+ } else {
+ pprintf(p,"Unable to delete news item %u !\n", num);
+ }
+ free(name);
+ return 0;
+}
+
+
+/*
+ summarise the news
+ */
+static int news_summary(int p, int first, int how_many, int admin)
+{
+ int i;
+ if (first < 1) {
+ first = 1;
+ }
+ for (i=first; i< first+how_many; i++) {
+ struct news news;
+ if (news_load(i, &news, admin) == 0) {
+ pprintf(p, "%4u (%s) %s\n",
+ i,
+ strday(&news.post_date),
+ news.title);
+ news_free(&news);
+ }
+ }
+
+ return COM_OK;
+}
+
+
+/*
+ lookup a news item
+ */
+static int do_news(int p, param_list param, int admin)
+{
+ int num;
+ struct news news;
+
+ if (param[0].type == TYPE_NULL) {
+ return news_summary(p, news_max(admin)-9, 10, admin);
+ }
+ if (strcasecmp(param[0].val.word, "all") == 0) {
+ return news_summary(p, 1, news_max(admin), admin);
+ }
+
+ num = atoi(param[0].val.word);
+ if (num <= 0) {
+ pprintf(p, "Bad news item number '%s'\n", param[0].val.word);
+ return COM_OK;
+ }
+
+ if (news_load(num, &news, admin) != 0) {
+ pprintf(p, "News item %u not found\n", num);
+ return COM_OK;
+ }
+
+ pprintf_more(p,"%4u (%s) %s\n\n%s\n\nPosted by %s.\n",
+ num,
+ strday(&news.post_date),
+ news.title,
+ news.message,
+ news.poster);
+
+ news_free(&news);
+
+ return COM_OK;
+}
+
+/*
+ lookup a news item
+ */
+int com_news(int p, param_list param)
+{
+ return do_news(p, param, 0);
+}
+
+
+/*
+ lookup a admin news item
+ */
+int com_anews(int p, param_list param)
+{
+ return do_news(p, param, 1);
+}
+
+
+/*
+ create a new news item
+*/
+static int cnewsi(int p, const char *title, int admin)
+{
+ struct player *pp = &player_globals.parray[p];
+ struct news news;
+ int ret, num;
+
+ ZERO_STRUCT(news);
+ news.poster = strdup(pp->name);
+ news.post_date = time(NULL);
+ news.message = strdup("");
+ news.title = strndup(title, 45);
+
+ num = news_max(admin) + 1;
+ ret = news_save(num, &news, admin);
+
+ if (ret == 0) {
+ pprintf(p,"Created news item %u\n", num);
+ } else {
+ pprintf(p,"Failed to create news item %u !\n", num);
+ }
+
+ news_free(&news);
+ return ret;
+}
+
+/*
+ add to a news item
+*/
+static int cnewsf(int p, int num, const char *message, int admin)
+{
+ struct news news;
+ char *msg;
+
+ if (news_load(num, &news, admin) != 0) {
+ pprintf(p, "News item %u not found\n", num);
+ return -1;
+ }
+
+ asprintf(&msg, "%s%s\n", news.message, message);
+ FREE(news.message);
+ news.message = msg;
+
+ if (news_save(num, &news, admin) != 0) {
+ pprintf(p, "News item %u could not be updated !\n", num);
+ news_free(&news);
+ return -1;
+ }
+
+ pprintf(p, "News item %u updated\n", num);
+
+ news_free(&news);
+ return 0;
+}
+
+/*
+ set title on a news item
+*/
+static int cnewst(int p, int num, const char *title, int admin)
+{
+ struct news news;
+
+ if (news_load(num, &news, admin) != 0) {
+ pprintf(p, "News item %u not found\n", num);
+ return -1;
+ }
+
+ FREE(news.title);
+ news.title = strndup(title, 45);
+
+ if (news_save(num, &news, admin) != 0) {
+ pprintf(p, "News item %u could not be updated !\n", num);
+ news_free(&news);
+ return -1;
+ }
+
+ pprintf(p, "News item %u updated\n", num);
+
+ news_free(&news);
+ return 0;
+}
+
+/*
+ set poster on a news item
+*/
+static int cnewsp(int p, int num, int admin)
+{
+ struct player *pp = &player_globals.parray[p];
+ struct news news;
+
+ if (news_load(num, &news, admin) != 0) {
+ pprintf(p, "News item %u not found\n", num);
+ return -1;
+ }
+
+ FREE(news.poster);
+ news.poster = strdup(pp->name);
+
+ if (news_save(num, &news, admin) != 0) {
+ pprintf(p, "News item %u could not be updated !\n", num);
+ news_free(&news);
+ return -1;
+ }
+
+ pprintf(p, "News item %u updated\n", num);
+
+ news_free(&news);
+ return 0;
+}
+
+/*
+ delete last line of an item
+*/
+static int cnewsd(int p, int num, int admin)
+{
+ struct news news;
+ char *s;
+
+ if (news_load(num, &news, admin) != 0) {
+ pprintf(p, "News item %u not found\n", num);
+ return -1;
+ }
+
+ news.message[strlen(news.message)-1] = 0;
+ s = strrchr(news.message, '\n');
+ if (s) {
+ s[1] = 0;
+ } else {
+ news.message[0] = 0;
+ }
+
+ if (news_save(num, &news, admin) != 0) {
+ pprintf(p, "News item %u could not be updated !\n", num);
+ news_free(&news);
+ return -1;
+ }
+
+ pprintf(p, "News item %u updated\n", num);
+
+ news_free(&news);
+ return 0;
+}
+
+
+/*
+ set expiry on a news item
+*/
+static int cnewse(int p, int num, int expiry, int admin)
+{
+ struct news news;
+
+ if (news_load(num, &news, admin) != 0) {
+ pprintf(p, "News item %u not found\n", num);
+ return -1;
+ }
+
+ if (expiry == -1) {
+ news_free(&news);
+ return news_delete(p, num, admin);
+ } else if (expiry == 0) {
+ news.expires = 0;
+ } else {
+ news.expires = time(NULL) + (expiry * 24*60*60);
+ }
+
+ if (news_save(num, &news, admin) != 0) {
+ pprintf(p, "News item %u could not be updated !\n", num);
+ news_free(&news);
+ return -1;
+ }
+
+ pprintf(p, "News item %u updated\n", num);
+
+ news_free(&news);
+ return 0;
+}
+
+/*
+ create a normal news item
+*/
+int com_cnewsi(int p, param_list param)
+{
+ cnewsi(p, param[0].val.string, 0);
+ return COM_OK;
+}
+
+/*
+ add to a normal news item
+*/
+int com_cnewsf(int p, param_list param)
+{
+ cnewsf(p, param[0].val.integer,
+ param[1].type != TYPE_NULL?param[1].val.string:"",
+ 0);
+ return COM_OK;
+}
+
+/*
+ set title on a normal news item
+*/
+int com_cnewst(int p, param_list param)
+{
+ cnewst(p, param[0].val.integer, param[1].val.string, 0);
+ return COM_OK;
+}
+
+/*
+ set poster on a normal news item
+*/
+int com_cnewsp(int p, param_list param)
+{
+ cnewsp(p, param[0].val.integer, 0);
+ return COM_OK;
+}
+
+/*
+ set expiry on a normal news item
+*/
+int com_cnewse(int p, param_list param)
+{
+ cnewse(p,
+ param[0].val.integer,
+ param[1].type != TYPE_NULL?param[1].val.integer:-1,
+ 0);
+ return COM_OK;
+}
+
+/*
+ delete last line on a normal news item
+*/
+int com_cnewsd(int p, param_list param)
+{
+ cnewsd(p, param[0].val.integer, 0);
+ return COM_OK;
+}
+
+/*
+ create a admin news item
+*/
+int com_canewsi(int p, param_list param)
+{
+ cnewsi(p, param[0].val.string, 1);
+ return COM_OK;
+}
+
+/*
+ add to a admin news item
+*/
+int com_canewsf(int p, param_list param)
+{
+ cnewsf(p, param[0].val.integer,
+ param[1].type != TYPE_NULL?param[1].val.string:"",
+ 1);
+ return COM_OK;
+}
+
+/*
+ set title on a admin news item
+*/
+int com_canewst(int p, param_list param)
+{
+ cnewst(p, param[0].val.integer, param[1].val.string, 1);
+ return COM_OK;
+}
+
+/*
+ set poster on a admin news item
+*/
+int com_canewsp(int p, param_list param)
+{
+ cnewsp(p, param[0].val.integer, 1);
+ return COM_OK;
+}
+
+/*
+ set expiry on a admin news item
+*/
+int com_canewse(int p, param_list param)
+{
+ cnewse(p, param[0].val.integer,
+ param[1].type != TYPE_NULL?param[1].val.integer:-1,
+ 1);
+ return COM_OK;
+}
+
+/*
+ delete last line on a admin news item
+*/
+int com_canewsd(int p, param_list param)
+{
+ cnewsd(p, param[0].val.integer, 1);
+ return COM_OK;
+}
+
+
+/*
+ tell user about new news
+*/
+void news_login(int p)
+{
+ struct player *pp = &player_globals.parray[p];
+ int max;
+
+ max = news_max(0);
+ if (max > pp->latest_news) {
+ pprintf(p,"\nThere are %u new news items since your last login\n",
+ max - pp->latest_news);
+ pp->latest_news = max;
+ }
+
+ if (!check_admin(p, ADMIN_ADMIN)) return;
+
+ max = news_max(1);
+ if (max > pp->admin_latest_news) {
+ pprintf(p,"\nThere are %u new admin news items since your last login\n",
+ max - pp->admin_latest_news);
+ pp->admin_latest_news = max;
+ }
+}
--- /dev/null
+/*
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+/*
+ support structures for the 'news' command
+ */
+
+GENSTRUCT struct news {
+ char *poster;
+ time_t post_date;
+ time_t expires;
+ char *title;
+ char *message;
+};
--- /dev/null
+#!/bin/sh -
+#
+# Copyright (c) 1984, 1986, 1990, 1993
+# The Regents of the University of California. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. Neither the name of the University nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# @(#)newvers.sh 8.1 (Berkeley) 4/20/94
+# $FreeBSD: src/sys/conf/newvers.sh,v 1.45 2000/03/13 09:13:01 jkh Exp $
+#
+
+TYPE="chessd"
+REVISION="2.2.x"
+BRANCH="DEVEL"
+RELEASE="${REVISION}-${BRANCH}"
+SNAPDATE=""
+if [ "X${SNAPDATE}" != "X" ]; then
+ RELEASE="${RELEASE}-${SNAPDATE}"
+fi
+VERSION="${TYPE} ${RELEASE}"
+RELDATE="\"`date`\""
+YEAR=`date "+%Y"`
+
+COPYRIGHT="/*
+ * Copyright (c) $YEAR Dan Papasian. All rights reserved.
+ *
+ * This file is automatically generated by newvers.sh. DO NOT EDIT!
+ *
+ * Redistribution of any kind is permitted.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR \`\`AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+"
+
+LC_TIME=C; export LC_TIME
+
+cat << EOF > vers.c
+$COPYRIGHT
+char VERS_NUM[] = "${RELEASE}";
+char COMP_DATE[] = ${RELDATE};
+EOF
+
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+#include "includes.h"
+
+int GameNumFromParam(int p, int *p1, parameter *param)
+{
+ if (param->type == TYPE_WORD) {
+ *p1 = player_find_part_login(param->val.word);
+ if (*p1 < 0) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param->val.word);
+ return -1;
+ }
+ if (player_globals.parray[*p1].game < 0)
+ pprintf(p, "%s is not playing a game.\n", player_globals.parray[*p1].name);
+ return player_globals.parray[*p1].game;
+ } else { /* Must be an integer */
+ *p1 = -1;
+ if (param->val.integer <= 0)
+ pprintf(p, "%d is not a valid game number.\n", param->val.integer);
+ return param->val.integer - 1;
+ }
+}
+
+static int gamesortfunc(const void *i, const void *j)
+{
+/* examine mode games moved to top of "games" output */
+ return (GetRating(&player_globals.parray[game_globals.garray[*(int *) i].white], game_globals.garray[*(int *) i].type) +
+ GetRating(&player_globals.parray[game_globals.garray[*(int *) i].black], game_globals.garray[*(int *) i].type) -
+ (((game_globals.garray[*(int *) i].status == GAME_EXAMINE) || (game_globals.garray[*(int *) i].status == GAME_SETUP)) ? 10000 : 0) -
+ GetRating(&player_globals.parray[game_globals.garray[*(int *) j].white], game_globals.garray[*(int *) j].type) -
+ GetRating(&player_globals.parray[game_globals.garray[*(int *) j].black], game_globals.garray[*(int *) j].type) +
+ (((game_globals.garray[*(int *) j].status == GAME_EXAMINE) || (game_globals.garray[*(int *) j].status == GAME_SETUP)) ? 10000 : 0));
+}
+
+
+int com_games(int p, param_list param)
+{
+ int i, j;
+ int wp, bp;
+ int ws, bs;
+ int selected = 0;
+ int count = 0;
+ int totalcount;
+ char *s = NULL;
+ int slen = 0;
+ int *sortedgames; /* for qsort */
+
+ totalcount = game_count();
+ if (totalcount == 0) {
+ pprintf(p, "There are no games in progress.\n");
+ } else {
+ sortedgames = malloc(totalcount * sizeof(int)); /* for qsort */
+
+ if (param[0].type == TYPE_WORD) {
+ s = param[0].val.word;
+ slen = strlen(s);
+ selected = atoi(s);
+ if (selected < 0)
+ selected = 0;
+ }
+ for (i = 0; i < game_globals.g_num; i++) {
+ if ((game_globals.garray[i].status != GAME_ACTIVE) && (game_globals.garray[i].status != GAME_EXAMINE) && (game_globals.garray[i].status != GAME_SETUP))
+ continue;
+ if ((selected) && (selected != i + 1))
+ continue; /* not selected game number */
+ wp = game_globals.garray[i].white;
+ bp = game_globals.garray[i].black;
+ if ((!selected) && s && strncasecmp(s, game_globals.garray[i].white_name, slen) &&
+ strncasecmp(s, game_globals.garray[i].black_name, slen))
+ continue; /* player names did not match */
+ sortedgames[count++] = i;
+ }
+ if (!count)
+ pprintf(p, "No matching games were found (of %d in progress).\n", totalcount);
+ else {
+ qsort(sortedgames, count, sizeof(int), gamesortfunc);
+ pprintf(p, "\n");
+ for (j = 0; j < count; j++) {
+ i = sortedgames[j];
+ wp = game_globals.garray[i].white;
+ bp = game_globals.garray[i].black;
+ board_calc_strength(&game_globals.garray[i].game_state, &ws, &bs);
+ if ((game_globals.garray[i].status != GAME_EXAMINE) && (game_globals.garray[i].status != GAME_SETUP)) {
+ pprintf_noformat(p, "%3d %4s %-11.11s %4s %-10.10s [%c%c%c%3d %3d] ",
+ i + 1,
+ ratstrii(GetRating(&player_globals.parray[wp],game_globals.garray[i].type), wp),
+ player_globals.parray[wp].name,
+ ratstrii(GetRating(&player_globals.parray[bp],game_globals.garray[i].type), bp),
+ player_globals.parray[bp].name,
+ (game_globals.garray[i].private) ? 'p' : ' ',
+ *bstr[game_globals.garray[i].type],
+ *rstr[game_globals.garray[i].rated],
+ game_globals.garray[i].wInitTime / 600,
+ game_globals.garray[i].wIncrement / 10);
+ game_update_time(i);
+ pprintf_noformat(p, "%6s -",
+ tenth_str((game_globals.garray[i].wTime > 0 ? game_globals.garray[i].wTime : 0), 0));
+ pprintf_noformat(p, "%6s (%2d-%2d) %c: %2d\n",
+ tenth_str((game_globals.garray[i].bTime > 0 ? game_globals.garray[i].bTime : 0), 0),
+ ws, bs,
+ (game_globals.garray[i].game_state.onMove == WHITE) ? 'W' : 'B',
+ game_globals.garray[i].game_state.moveNum);
+ } else {
+ pprintf_noformat(p, "%3d (%s %4d %-11.11s %4d %-10.10s) [%c%c%c%3d %3d] ",
+ i + 1,
+ (game_globals.garray[i].status == GAME_EXAMINE) ? "Exam." : "Setup",
+ game_globals.garray[i].white_rating,
+ game_globals.garray[i].white_name,
+ game_globals.garray[i].black_rating,
+ game_globals.garray[i].black_name,
+ (game_globals.garray[i].private) ? 'p' : ' ',
+ *bstr[game_globals.garray[i].type],
+ *rstr[game_globals.garray[i].rated],
+ game_globals.garray[i].wInitTime / 600,
+ game_globals.garray[i].wIncrement / 10);
+ pprintf_noformat(p, "%c: %2d\n",
+ (game_globals.garray[i].game_state.onMove == WHITE) ? 'W' : 'B',
+ game_globals.garray[i].game_state.moveNum);
+ }
+ }
+ if (count < totalcount)
+ pprintf(p, "\n %d game%s displayed (of %d in progress).\n", count,
+ (count == 1) ? "" : "s", totalcount);
+ else
+ pprintf(p, "\n %d game%s displayed.\n", totalcount, (totalcount == 1) ? "" : "s");
+ }
+ free(sortedgames);
+ }
+ return COM_OK;
+}
+
+static int do_observe(int p, int obgame)
+{
+ struct player *pp = &player_globals.parray[p];
+ if ((game_globals.garray[obgame].private) && (pp->adminLevel < ADMIN_ADMIN)) {
+ pprintf(p, "Sorry, game %d is a private game.\n", obgame + 1);
+ return COM_OK;
+ }
+ if ((game_globals.garray[obgame].white == p) || (game_globals.garray[obgame].black == p)) {
+ if ((game_globals.garray[obgame].status != GAME_EXAMINE) || (game_globals.garray[obgame].status != GAME_SETUP)) {
+ pprintf(p, "You cannot observe a game that you are playing.\n");
+ return COM_OK;
+ }
+ }
+ if (player_is_observe(p, obgame)) {
+ pprintf(p, "Removing game %d from observation list.\n", obgame + 1);
+ player_remove_observe(p, obgame);
+ } else {
+ if (!player_add_observe(p, obgame)) {
+ pprintf(p, "You are now observing game %d.\n", obgame + 1);
+ send_board_to(obgame, p);
+ } else {
+ pprintf(p, "You are already observing the maximum number of games.\n");
+ }
+ }
+ return COM_OK;
+}
+
+void unobserveAll(int p)
+{
+ struct player *pp = &player_globals.parray[p];
+ int i;
+
+ for (i = 0; i < pp->num_observe; i++) {
+ pprintf(p, "Removing game %d from observation list.\n",
+ pp->observe_list[i] + 1);
+ }
+ pp->num_observe = 0;
+ return;
+}
+
+int com_unobserve(int p, param_list param)
+{
+ int gNum, p1;
+
+ if (param[0].type == TYPE_NULL) {
+ unobserveAll(p);
+ return COM_OK;
+ }
+ gNum = GameNumFromParam(p, &p1, ¶m[0]);
+ if (gNum < 0)
+ return COM_OK;
+ if (!player_is_observe(p, gNum)) {
+ pprintf(p, "You are not observing game %d.\n", gNum);
+ } else {
+ player_remove_observe(p, gNum);
+ pprintf(p, "Removing game %d from observation list.\n", gNum + 1);
+ }
+ return COM_OK;
+}
+
+int com_observe(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int i;
+ int p1, obgame;
+
+ if (param[0].type == TYPE_NULL)
+ return COM_BADPARAMETERS;
+ if ((pp->game >=0) &&(game_globals.garray[pp->game].status == GAME_EXAMINE)) {
+ pprintf(p, "You are still examining a game.\n");
+ return COM_OK;
+ }
+ if ((pp->game >=0) &&(game_globals.garray[pp->game].status == GAME_SETUP)) {
+ pprintf(p, "You are still setting up a position.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_NULL) {
+ unobserveAll(p);
+ return COM_OK;
+ }
+ obgame = GameNumFromParam(p, &p1, ¶m[0]);
+ if (obgame < 0)
+ return COM_OK;
+
+ if ((obgame >= game_globals.g_num) || ((game_globals.garray[obgame].status != GAME_ACTIVE) &&
+ (game_globals.garray[obgame].status != GAME_EXAMINE) &&
+ (game_globals.garray[obgame].status != GAME_SETUP))) {
+ pprintf(p, "There is no such game.\n");
+ return COM_OK;
+ }
+ if ((p1 >= 0) && (player_globals.parray[p1].simul_info != NULL) && (player_globals.parray[p1].simul_info->numBoards)) {
+ for (i = 0; i < player_globals.parray[p1].simul_info->numBoards; i++)
+ if (player_globals.parray[p1].simul_info->boards[i] >= 0)
+ do_observe(p, player_globals.parray[p1].simul_info->boards[i]);
+ } else
+ do_observe(p, obgame);
+ return COM_OK;
+}
+
+int com_allobservers(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int obgame;
+ int p1;
+ int start, end;
+ int g;
+ int first;
+
+ if (param[0].type == TYPE_NULL) {
+ obgame = -1;
+ } else {
+ obgame = GameNumFromParam(p, &p1, ¶m[0]);
+ if (obgame < 0)
+ return COM_OK;
+ }
+ if (obgame == -1) {
+ start = 0;
+ end = game_globals.g_num;
+ } else if ((obgame >= game_globals.g_num) || ((obgame < game_globals.g_num)
+ && ((game_globals.garray[obgame].status != GAME_ACTIVE)
+ && (game_globals.garray[obgame].status != GAME_EXAMINE)
+ && (game_globals.garray[obgame].status != GAME_SETUP)))) {
+ pprintf(p, "There is no such game.\n");
+ return COM_OK;
+ } else {
+ start = obgame;
+ end = obgame + 1;
+ }
+
+ /* list games being played */
+
+ for (g = start; g < end; g++) {
+ if ((game_globals.garray[g].status == GAME_ACTIVE) &&
+ ((pp->adminLevel > 0) || (game_globals.garray[g].private == 0))) {
+ for (first = 1, p1 = 0; p1 < player_globals.p_num; p1++) {
+ if ((player_globals.parray[p1].status != PLAYER_EMPTY) && (player_is_observe(p1, g))) {
+ if (first) {
+ pprintf(p, "Observing %2d [%s vs. %s]:",
+ g + 1,
+ player_globals.parray[game_globals.garray[g].white].name,
+ player_globals.parray[game_globals.garray[g].black].name);
+ first = 0;
+ }
+ pprintf(p, " %s%s", (player_globals.parray[p1].game >=0) ? "#" : "", player_globals.parray[p1].name);
+ }
+ }
+ if (!first)
+ pprintf(p, "\n");
+ }
+ }
+
+ /* list games being examined last */
+
+ for (g = start; g < end; g++) {
+ if (((game_globals.garray[g].status == GAME_EXAMINE) || (game_globals.garray[g].status == GAME_SETUP)) &&
+ ((pp->adminLevel > 0) || (game_globals.garray[g].private == 0))) {
+ for (first = 1, p1 = 0; p1 < player_globals.p_num; p1++) {
+ if ((player_globals.parray[p1].status != PLAYER_EMPTY) && (player_is_observe(p1, g) ||
+ (player_globals.parray[p1].game == g))) {
+ if (first) {
+ if (strcmp(game_globals.garray[g].white_name, game_globals.garray[g].black_name)) {
+ pprintf(p, "Examining %2d [%s vs %s]:", g + 1,
+ game_globals.garray[g].white_name, game_globals.garray[g].black_name);
+ } else {
+ pprintf(p, "Examining %2d (scratch):", g + 1);
+ }
+ first = 0;
+ }
+ pprintf(p, " %s%s", (player_globals.parray[p1].game == g) ? "#" : "", player_globals.parray[p1].name);
+ }
+ }
+ if (!first)
+ pprintf(p, "\n");
+ }
+ }
+ return COM_OK;
+}
+
+int com_unexamine(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int g, p1, flag = 0;
+
+ if ((pp->game <0) || ((game_globals.garray[pp->game].status != GAME_EXAMINE) && (game_globals.garray[pp->game].status != GAME_SETUP))) {
+ pprintf(p, "You are not examining any games.\n");
+ return COM_OK;
+ }
+ g = pp->game;
+ pp->game = -1;
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (player_globals.parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if ((player_globals.parray[p1].game == g) &&(p != p1)) {
+ /* ok - there are other examiners to take over the game */
+ flag = 1;
+ }
+ if ((player_is_observe(p1, g)) || (player_globals.parray[p1].game == g)) {
+ pprintf(p1, "%s stopped examining game %d.\n", pp->name, g + 1);
+ }
+ }
+ if (!flag) {
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (player_globals.parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g)) {
+ pprintf(p1, "There are no examiners.\n");
+ pcommand(p1, "unobserve %d", g + 1);
+ }
+ }
+ game_remove(g);
+ }
+ pprintf(p, "You are no longer examining game %d.\n", g + 1);
+ announce_avail(p);
+ return COM_OK;
+}
+
+int com_mexamine(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int g, p1, p2;
+
+ if ((pp->game <0) ||
+ ((game_globals.garray[pp->game].status != GAME_EXAMINE) &&
+ (game_globals.garray[pp->game].status != GAME_SETUP))) {
+ pprintf(p, "You are not examining any games.\n");
+ return COM_OK;
+ }
+ p1 = player_find_part_login(param[0].val.word);
+ if (p1 < 0) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ g = pp->game;
+ if (!player_is_observe(p1, g)) {
+ pprintf(p, "%s must observe the game you are analysing.\n", player_globals.parray[p1].name);
+ return COM_OK;
+ } else {
+ if (player_globals.parray[p1].game >=0) {
+ pprintf(p, "%s is already analysing the game.\n", player_globals.parray[p1].name);
+ return COM_OK;
+ }
+ /* if we get here - let's make him examiner of the game */
+ unobserveAll(p1); /* fix for Xboard */
+ decline_withdraw_offers(p1, -1, PEND_MATCH,DO_DECLINE | DO_WITHDRAW);
+ decline_withdraw_offers(p1, -1, PEND_SIMUL,DO_WITHDRAW);
+
+ player_globals.parray[p1].game = g; /* yep - it really is that easy :-) */
+ pprintf(p1, "You are now examiner of game %d.\n", g + 1);
+ send_board_to(g, p1); /* pos not changed - but fixes Xboard */
+ for (p2 = 0; p2 < player_globals.p_num; p2++) {
+ if (player_globals.parray[p2].status != PLAYER_PROMPT)
+ continue;
+ if (p2 == p1)
+ continue;
+ if ((player_is_observe(p2, g)) || (player_globals.parray[p2].game == g)) {
+ pprintf_prompt(p2, "%s is now examiner of game %d.\n", player_globals.parray[p1].name, g + 1);
+ }
+ }
+ }
+ if (CheckPFlag(p2, PFLAG_OPEN)) /* was open */
+ announce_notavail(p2);
+ return COM_OK;
+}
+
+int com_moves(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int g;
+ int p1;
+
+ if (param[0].type == TYPE_NULL) {
+ if (pp->game >=0) {
+ g = pp->game;
+ } else if (pp->num_observe) {
+ for (g = 0; g < pp->num_observe; g++) {
+ pprintf(p, "%s\n", movesToString(pp->observe_list[g], 0));
+ }
+ return COM_OK;
+ } else {
+ pprintf(p, "You are neither playing, observing nor examining a game.\n");
+ return COM_OK;
+ }
+ } else {
+ g = GameNumFromParam(p, &p1, ¶m[0]);
+ if (g < 0)
+ return COM_OK;
+ }
+ if ((g < 0) || (g >= game_globals.g_num) || ((game_globals.garray[g].status != GAME_ACTIVE) &&
+ (game_globals.garray[g].status != GAME_EXAMINE) &&
+ (game_globals.garray[g].status != GAME_SETUP))) {
+ pprintf(p, "There is no such game.\n");
+ return COM_OK;
+ }
+ if ((game_globals.garray[g].white != p) && (game_globals.garray[g].black != p) && (game_globals.garray[g].private) && (pp->adminLevel < ADMIN_ADMIN)) {
+ pprintf(p, "Sorry, that is a private game.\n");
+ return COM_OK;
+ }
+ pprintf(p, "%s\n", movesToString(g, 0)); /* pgn may break interfaces? */
+ return COM_OK;
+}
+
+int com_mailmoves(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int g;
+ int p1;
+ char subj[81];
+
+ if (!CheckPFlag(p, PFLAG_REG)) {
+ pprintf (p,"Unregistered players cannot use mailmoves.\n");
+ return COM_OK;
+ }
+
+ if (param[0].type == TYPE_NULL) {
+ if (pp->game >=0) {
+ g = pp->game;
+ } else {
+ pprintf(p, "You are neither playing, observing nor examining a game.\n");
+ return COM_OK;
+ }
+ } else {
+ g = GameNumFromParam(p, &p1, ¶m[0]);
+ if (g < 0)
+ return COM_OK;
+ }
+ if ((g < 0) || (g >= game_globals.g_num) || ((game_globals.garray[g].status != GAME_ACTIVE) && (game_globals.garray[g].status != GAME_EXAMINE))) {
+ pprintf(p, "There is no such game.\n");
+ return COM_OK;
+ }
+ if ((game_globals.garray[g].white != p) && (game_globals.garray[g].black != p) && (game_globals.garray[g].private) && (pp->adminLevel < ADMIN_ADMIN)) {
+ pprintf(p, "Sorry, that is a private game.\n");
+ return COM_OK;
+ }
+ sprintf(subj, "FICS game report %s vs %s", game_globals.garray[g].white_name, game_globals.garray[g].black_name);
+ if (mail_string_to_user(p, subj,
+ movesToString(g, CheckPFlag(p, PFLAG_PGN)))) {
+ pprintf(p, "Moves NOT mailed, perhaps your address is incorrect.\n");
+ } else {
+ pprintf(p, "Moves mailed.\n");
+ }
+ return COM_OK;
+}
+
+static int old_mail_moves(int p,int mail, param_list param)
+{
+ int p1, connected;
+ int count;
+ FILE *fp;
+ char fname[MAX_FILENAME_SIZE];
+ char tmp[2048];
+ char *ptmp = tmp;
+
+ if (mail && !CheckPFlag(p, PFLAG_REG)) {
+ pprintf (p,"Unregistered players cannot use mailoldmoves.\n");
+ return COM_OK;
+ }
+
+ if (param[0].type == TYPE_WORD) {
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+ } else {
+ p1 = p;
+ connected = 1;
+ }
+
+ sprintf(fname, "%s/player_data/%c/%s.%s", STATS_DIR,
+ player_globals.parray[p1].login[0], player_globals.parray[p1].login, STATS_GAMES);
+ fp = fopen_s(fname, "r"); /* old moves now looks in history to save mem - DAV */
+
+ if (!fp) {
+ pprintf (p,"There is no old game for %s.\n", player_globals.parray[p1].name);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+
+ while (!feof(fp))
+ fgets(tmp, 1024, fp);
+ sscanf(ptmp, "%d", &count);
+ fclose(fp); /* find the last game played in history */
+
+ pprintf (p,"Last game for %s was history game %d.\n",player_globals.parray[p1].name,count);
+
+ if (mail)
+ pcommand (p,"mailstored %s %d",player_globals.parray[p1].name,count);
+ else
+ pcommand (p,"smoves %s %d",player_globals.parray[p1].name,count);
+
+ if (!connected)
+ player_remove(p1);
+
+ return COM_OK;
+}
+
+int com_oldmoves(int p, param_list param)
+{
+ return old_mail_moves(p , 0, param);
+}
+
+int com_mailoldmoves(int p, param_list param)
+{
+ return old_mail_moves(p , 1, param);
+}
+
+void ExamineScratch(int p, param_list param,int setup)
+{
+ struct player *pp = &player_globals.parray[p];
+ char category[100], board[100], parsebuf[100];
+ char *val;
+ int confused = 0;
+ int g;
+
+ category[0] = '\0';
+ board[0] = '\0';
+
+ if ((param[0].val.string != pp->name) &&
+ (param[1].type == TYPE_WORD)) {
+ strcpy(category, param[0].val.string);
+ strcpy(board, param[1].val.string);
+ } else if (param[1].type != TYPE_NULL) {
+
+ val = param[1].val.string;
+
+ while (!confused && (sscanf(val, " %99s", parsebuf) == 1)) {
+ val = eatword(eatwhite(val));
+ if ((category[0] != '\0') && (board[0] == '\0'))
+ strcpy(board, parsebuf);
+ else if (isdigit(*parsebuf)) {
+ pprintf(p, "You can't specify time controls.\n");
+ return;
+ } else if (category[0] == '\0')
+ strcpy(category, parsebuf);
+ else
+ confused = 1;
+ }
+ if (confused) {
+ pprintf(p, "Can't interpret %s in match command.\n", parsebuf);
+ return;
+ }
+ }
+
+
+ if (category[0] && !board[0]) {
+ pprintf(p, "You must specify a board and a category.\n");
+ return;
+ }
+
+ g = game_new();
+
+ unobserveAll(p);
+
+ decline_withdraw_offers(p, -1, PEND_MATCH,DO_DECLINE | DO_WITHDRAW);
+ decline_withdraw_offers(p, -1, PEND_SIMUL,DO_WITHDRAW);
+
+ game_globals.garray[g].wInitTime = game_globals.garray[g].wIncrement = 0;
+ game_globals.garray[g].bInitTime = game_globals.garray[g].bIncrement = 0;
+ game_globals.garray[g].timeOfStart = tenth_secs();
+ game_globals.garray[g].wTime = game_globals.garray[g].bTime = 0;
+ game_globals.garray[g].rated = 0;
+ game_globals.garray[g].clockStopped = 0;
+ game_globals.garray[g].type = TYPE_UNTIMED;
+ game_globals.garray[g].white = game_globals.garray[g].black = p;
+ game_globals.garray[g].startTime = tenth_secs();
+ game_globals.garray[g].lastMoveTime = game_globals.garray[g].startTime;
+ game_globals.garray[g].lastDecTime = game_globals.garray[g].startTime;
+ game_globals.garray[g].totalHalfMoves = 0;
+
+ pp->side = WHITE; /* oh well... */
+ pp->game = g;
+
+
+ if (!setup)
+ pprintf(p, "Starting a game in examine (scratch) mode.\n");
+ else
+ pprintf(p, "Starting a game in examine (setup) mode.\n");
+
+ if (category[0]) {
+ pprintf(p, "Loading from catagory: %s, board: %s.\n", category, board);
+ }
+
+ if (setup) {
+ board_clear(&game_globals.garray[g].game_state);
+ game_globals.garray[g].status = GAME_SETUP;
+ } else {
+ game_globals.garray[g].status = GAME_EXAMINE;
+ if (board_init(g,&game_globals.garray[g].game_state, category, board)) {
+ pprintf(p, "PROBLEM LOADING BOARD. Examine Aborted.\n");
+ d_printf( "CHESSD: PROBLEM LOADING BOARD. Examine Aborted.\n");
+ pp->game = -1;
+ game_remove(g);
+ return;
+ }
+ }
+
+ game_globals.garray[g].game_state.gameNum = g;
+ strcpy(game_globals.garray[g].white_name, pp->name);
+ strcpy(game_globals.garray[g].black_name, pp->name);
+ game_globals.garray[g].white_rating = game_globals.garray[g].black_rating = pp->s_stats.rating;
+
+ send_boards(g);
+ if (CheckPFlag(p, PFLAG_OPEN)) /*was open */
+ announce_notavail(p);
+}
+
+static int ExamineStored(FILE * fp, int p, char type)
+{
+ struct player *pp = &player_globals.parray[p];
+ int g;
+ char category[100], board[100];
+ struct game *gg;
+
+ unobserveAll(p);
+
+ decline_withdraw_offers(p, -1, PEND_MATCH,DO_DECLINE | DO_WITHDRAW);
+ decline_withdraw_offers(p, -1, PEND_SIMUL,DO_WITHDRAW);
+
+ g = game_new();
+ gg = &game_globals.garray[g];
+ category[0] = '\0';
+ board[0] = '\0';
+ if (board_init(g,&gg->game_state, category, board)) {
+ pprintf(p, "PROBLEM LOADING BOARD. Examine Aborted.\n");
+ d_printf( "CHESSD: PROBLEM LOADING BOARD %s %s. Examine Aborted.\n",
+ category, board);
+ game_remove(g);
+ return -1;
+ }
+
+ gg->status = GAME_EXAMINE;
+
+ if (type == 'w' || type == 'n') {
+ if (ReadGameAttrs_exam(fp, g) < 0) {
+ pprintf(p, "Either this is an old wild/nonstandard game or the gamefile is corrupt.\n");
+ game_remove(g);
+ return -1;
+ }
+ } else if (ReadGameAttrs(fp, g) < 0) {
+ pprintf(p, "Gamefile is corrupt; please notify an admin.\n");
+ game_remove(g);
+ return -1;
+ }
+
+ gg->totalHalfMoves = gg->numHalfMoves;
+ gg->numHalfMoves = 0;
+ gg->revertHalfMove = 0;
+ gg->white = p;
+ gg->black = p;
+ gg->game_state.gameNum = g;
+
+ gg->startTime = tenth_secs();
+ gg->lastMoveTime = gg->startTime;
+ gg->lastDecTime = gg->startTime;
+
+ pp->side = WHITE; /* oh well... */
+ pp->game = g;
+
+ send_boards(g);
+ if (CheckPFlag(p, PFLAG_OPEN)) /* was open */
+ announce_notavail(p);
+
+ return g;
+}
+
+static void ExamineAdjourned(int p, int p1, int p2)
+{
+ FILE *fp;
+ char *p1Login, *p2Login;
+ int g;
+
+ p1Login = player_globals.parray[p1].login;
+ p2Login = player_globals.parray[p2].login;
+
+ fp = fopen_p("%s/%c/%s-%s", "r", ADJOURNED_DIR, *p1Login, p1Login, p2Login);
+ if (!fp) fp = fopen_p("%s/%c/%s-%s", "r", ADJOURNED_DIR, *p2Login, p1Login, p2Login);
+ if (!fp) fp = fopen_p("%s/%c/%s-%s", "r", ADJOURNED_DIR, *p2Login, p2Login, p1Login);
+ if (!fp) fp = fopen_p("%s/%c/%s-%s", "r", ADJOURNED_DIR, *p1Login, p2Login, p1Login);
+ if (!fp) {
+ pprintf(p, "No stored game between \"%s\" and \"%s\".\n",
+ player_globals.parray[p1].name, player_globals.parray[p2].name);
+ return;
+ }
+ /* Assume old wild games are of type blitz - adjudicators should be
+ careful */
+ g = ExamineStored(fp, p,'b');
+ fclose(fp);
+
+ if (g >= 0) {
+ if (game_globals.garray[g].white_name[0] == '\0')
+ strcpy(game_globals.garray[g].white_name, p1Login);
+ if (game_globals.garray[g].black_name[0] == '\0')
+ strcpy(game_globals.garray[g].black_name, p2Login);
+ }
+}
+
+/* type is now returned because prior to V1.7.1 loading a wild game for
+ examining was impossible since the initial position was not saved.
+ Only types blitz,standard,lightning and untimed may be loaded for
+ examining if the gamefile version is less than 4 */
+
+static char *FindHistory(int p, int p1, int game,char* type)
+{
+ FILE *fpHist;
+ static char fileName[MAX_FILENAME_SIZE];
+ int index;
+ long when;
+ char typestr[4];
+
+ sprintf(fileName, "%s/player_data/%c/%s.%s", STATS_DIR,
+ player_globals.parray[p1].login[0], player_globals.parray[p1].login, STATS_GAMES);
+ fpHist = fopen_s(fileName, "r");
+ if (fpHist == NULL) {
+ pprintf(p, "No games in history for %s.\n", player_globals.parray[p1].name);
+ return(NULL);
+ }
+ do {
+ fscanf(fpHist, "%d %*c %*d %*c %*d %*s %s %*d %*d %*d %*d %*s %*s %ld",
+ &index, typestr, &when);
+ } while (!feof(fpHist) && index != game);
+
+ if (feof(fpHist)) {
+ pprintf(p, "There is no history game %d for %s.\n", game, player_globals.parray[p1].name);
+ fclose(fpHist);
+ return(NULL);
+ }
+ fclose(fpHist);
+
+ if (typestr[0] != 'p')
+ *type = typestr[0];
+ else
+ *type = typestr[1];
+
+ sprintf(fileName, "%s/%ld/%ld", HISTORY_DIR, when % 100, when);
+ return(fileName);
+}
+
+/* I want to know how game ended/ECO code */
+
+static char *FindHistory2(int p, int p1,int game, char* Eco,char* End)
+{
+ FILE *fpHist;
+ static char fileName[MAX_FILENAME_SIZE];
+ int index;
+ long when;
+
+ sprintf(fileName, "%s/player_data/%c/%s.%s", STATS_DIR,
+ player_globals.parray[p1].login[0], player_globals.parray[p1].login, STATS_GAMES);
+ fpHist = fopen_s(fileName, "r");
+ if (fpHist == NULL) {
+ pprintf(p, "No games in history for %s.\n", player_globals.parray[p1].name);
+ return(NULL);
+ }
+ do {
+ fscanf(fpHist, "%d %*c %*d %*c %*d %*s %*s %*d %*d %*d %*d %s %s %ld",
+ &index, Eco, End, &when);
+ } while (!feof(fpHist) && index != game);
+
+ if (feof(fpHist)) {
+ pprintf(p, "There is no history game %d for %s.\n", game, player_globals.parray[p1].name);
+ fclose(fpHist);
+ return(NULL);
+ }
+ fclose(fpHist);
+
+ sprintf(fileName, "%s/%ld/%ld", HISTORY_DIR, when % 100, when);
+ return(fileName);
+}
+
+int com_wname(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+
+ int g = pp->game;
+
+ if ((g < 0) ||
+ ((g >= 0) &&
+ !((game_globals.garray[g].status != GAME_EXAMINE) || (game_globals.garray[g].status != GAME_SETUP)))) {
+ pprintf (p, "You are not examining or setting up a game.\n");
+ return COM_OK;
+ }
+
+ if (param[0].type == TYPE_NULL)
+ strcpy (game_globals.garray[g].white_name,pp->name);
+ else {
+
+ if (strlen (param[0].val.word) > MAX_LOGIN_NAME - 1) {
+ pprintf (p,"The maximum length of a name is %d characters.\n",MAX_LOGIN_NAME - 1);
+ return COM_OK;
+ } else
+ strcpy (game_globals.garray[g].white_name,param[0].val.word);
+ }
+
+ send_boards(g);
+ return COM_OK;
+}
+
+int com_bname(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+
+ int g = pp->game;
+
+ if ((g < 0) ||
+ ((g >= 0) &&
+ !((game_globals.garray[g].status != GAME_EXAMINE) || (game_globals.garray[g].status != GAME_SETUP)))) {
+ pprintf (p, "You are not examining or setting up a game.\n");
+ return COM_OK;
+ }
+
+ if (param[0].type == TYPE_NULL)
+ strcpy (game_globals.garray[g].black_name,pp->name);
+ else {
+
+ if (strlen (param[0].val.word) > MAX_LOGIN_NAME - 1) {
+ pprintf (p,"The maximum length of a name is %d characters.\n",MAX_LOGIN_NAME - 1);
+ return COM_OK;
+ } else
+ strcpy (game_globals.garray[g].black_name,param[0].val.word);
+ }
+
+ send_boards(g);
+ return COM_OK;
+}
+
+static void ExamineHistory(int p, int p1, int game)
+{
+ char *fileName;
+ char type;
+
+ fileName = FindHistory(p, p1, game,&type);
+ if (fileName) {
+ FILE *fpGame = fopen_p("%s", "r", fileName);
+ if (fpGame == NULL) {
+ pprintf(p, "History game %d not available for %s.\n",
+ game, player_globals.parray[p1].name);
+ } else {
+ ExamineStored(fpGame, p,type);
+ fclose(fpGame);
+ }
+ }
+}
+
+static void ExamineJournal(int p,int p1,char slot)
+{
+ struct player *pp = &player_globals.parray[p];
+ char* name_from = player_globals.parray[p1].login;
+ char type;
+ FILE *fpGame;
+
+ if (CheckPFlag(p1, PFLAG_JPRIVATE) && (p != p1)
+ && (pp->adminLevel < ADMIN_ADMIN)) {
+ pprintf (p,"Sorry, this journal is private.\n");
+ return;
+ }
+
+ if ((slot - 'a' + 1) > MAX_JOURNAL &&
+ !check_admin(p1, ADMIN_ADMIN) &&
+ !titled_player(p,player_globals.parray[p1].login)) {
+ pprintf(p,"%s's maximum journal entry is %c\n",
+ player_globals.parray[p1].name,
+ toupper((char)(MAX_JOURNAL + 'A' - 1)));
+ return;
+ }
+
+ fpGame = fopen_p("%s/%c/%s.%c", "r", JOURNAL_DIR, name_from[0],name_from,slot);
+ if (fpGame == NULL) {
+ pprintf(p, "Journal entry %c is not available for %s.\n", toupper (slot),
+ player_globals.parray[p1].name);
+ } else {
+ char *fname;
+ asprintf(&fname, "%s/player_data/%c/%s.journal",
+ STATS_DIR, name_from[0],name_from);
+ slot = toupper(slot);
+
+ if ((type = get_journalgame_type (p,fname,slot)) == '\0') {
+ pprintf(p, "Journal entry %c is not available for %s or is corrupt.\n",
+ slot, player_globals.parray[p1].name);
+ } else {
+ ExamineStored(fpGame, p,type);
+ }
+
+ free(fname);
+ fclose (fpGame);
+ }
+}
+
+int com_examine(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1, p2 = p, p1conn, p2conn = 1;
+ char* wincstring;
+ char fname[MAX_FILENAME_SIZE];
+
+ if (pp->game >=0) {
+ if ((game_globals.garray[pp->game].status == GAME_EXAMINE) ||
+ (game_globals.garray[pp->game].status == GAME_SETUP))
+ pprintf(p, "You are already examining a game.\n");
+ else
+ pprintf(p, "You are playing a game.\n");
+ } else if (param[0].type == TYPE_NULL) {
+ ExamineScratch(p, param, 0);
+ } else if (param[0].type != TYPE_NULL) {
+ if ((param[1].type == TYPE_NULL) && (!strcmp(param[0].val.word,"setup"))) {
+ ExamineScratch(p, param, 1);
+ return COM_OK;
+ } else if (param[1].type == TYPE_WORD) {
+ sprintf(fname, "%s/%s/%s", BOARD_DIR, param[0].val.word, param[1].val.word);
+ if (file_exists(fname)) {
+ ExamineScratch(p, param, 0);
+ return COM_OK;
+ }
+ }
+ if (!FindPlayer(p, param[0].val.word, &p1, &p1conn))
+ return COM_OK;
+
+ if (param[1].type == TYPE_INT)
+ ExamineHistory(p, p1, param[1].val.integer);
+ else {
+ if (param[1].type == TYPE_WORD) {
+
+ /* Lets check the journal */
+ wincstring = param[1].val.word;
+ if ((strlen(wincstring) == 1) && (isalpha(wincstring[0]))) {
+ ExamineJournal(p,p1,wincstring[0]);
+ if (!p1conn)
+ player_remove(p1);
+ return COM_OK;
+ } else {
+ if (!FindPlayer(p, param[1].val.word, &p2, &p2conn)) {
+ if (!p1conn)
+ player_remove(p1);
+ return COM_OK;
+ }
+ }
+ }
+ ExamineAdjourned(p, p1, p2);
+ if (!p2conn)
+ player_remove(p2);
+ }
+ if (!p1conn)
+ player_remove(p1);
+ }
+ return COM_OK;
+}
+
+int com_stored(int p, param_list param)
+{
+ int count = 0;
+ DIR *dirp;
+ struct dirent *dp;
+
+ int p1, connected;
+ char dname[MAX_FILENAME_SIZE];
+
+ if (param[0].type == TYPE_WORD) {
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+ } else {
+ p1 = p;
+ connected = 1;
+ }
+
+ sprintf(dname, "%s/%c", ADJOURNED_DIR, player_globals.parray[p1].login[0]);
+ dirp = opendir(dname);
+ if (!dirp) {
+ pprintf(p, "Player %s has no games stored.\n", player_globals.parray[p1].name);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ pprintf(p, "Stored games for %s:\n", player_globals.parray[p1].name);
+ for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
+ if (file_has_pname(dp->d_name, player_globals.parray[p1].login)) {
+ pprintf(p, " %s vs. %s\n", file_wplayer(dp->d_name), file_bplayer(dp->d_name));
+ count++;
+ }
+ }
+
+ closedir(dirp);
+ pprintf (p,"%d stored game%sfound.\n",count,(count == 1 ? " " : "s "));
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+static void stored_mail_moves(int p, int mail, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int wp, wconnected, bp, bconnected, gotit = 0;
+ int g = -1;
+ char type; /* dummy */
+ char* wincstring = NULL;
+ char* name_from = NULL;
+ char* fileName = NULL;
+ char fileName2[MAX_FILENAME_SIZE];
+ FILE* fpGame;
+
+ if (mail && !CheckPFlag(p, PFLAG_REG)) {
+ pprintf (p,"Unregistered players cannot use mailstored.\n");
+ return;
+ }
+
+ if (!FindPlayer(p, param[0].val.word, &wp, &wconnected))
+ return;
+
+ if (param[1].type == TYPE_INT) { /* look for a game from history */
+ fileName = FindHistory(p, wp, param[1].val.integer,&type);
+ if (fileName != NULL) {
+ fpGame = fopen_s(fileName, "r");
+ if (fpGame == NULL) {
+ pprintf(p, "History game %d not available for %s.\n", param[1].val.integer, player_globals.parray[wp].name);
+ } else {
+ g = game_new();
+ if (ReadGameAttrs(fpGame, g) < 0)
+ pprintf(p, "Gamefile is corrupt; please notify an admin.\n");
+ else
+ gotit = 1;
+ fclose(fpGame);
+ }
+ }
+ } else { /* Let's test for journal */
+ name_from = param[0].val.word;
+ wincstring = param[1].val.word;
+ if ((strlen(wincstring) == 1) && (isalpha(wincstring[0]))) {
+ if (CheckPFlag(wp, PFLAG_JPRIVATE)
+ && (pp->adminLevel < ADMIN_ADMIN) && (p != wp)) {
+ pprintf (p,"Sorry, the journal from which you are trying to fetch is private.\n");
+ } else {
+ if (((wincstring[0] - 'a' + 1) > MAX_JOURNAL) && (player_globals.parray[wp].adminLevel < ADMIN_ADMIN) && (!titled_player(p,player_globals.parray[wp].login))) {
+ pprintf (p,"%s's maximum journal entry is %c\n",player_globals.parray[wp].name,toupper((char)(MAX_JOURNAL + 'A' - 1)));
+ } else {
+ sprintf(fileName2, "%s/%c/%s.%c", JOURNAL_DIR, name_from[0],name_from,wincstring[0]);
+ fpGame = fopen_s(fileName2, "r");
+ if (fpGame == NULL) {
+ pprintf(p, "Journal entry %c is not available for %s.\n", toupper(wincstring[0]),
+ player_globals.parray[wp].name);
+ } else {
+ g = game_new();
+ if (ReadGameAttrs(fpGame, g) < 0)
+ pprintf(p, "Journal entry is corrupt; please notify an admin.\n");
+ else
+ gotit = 1;
+ fclose(fpGame);
+ }
+ }
+ }
+ } else {
+
+ /* look for a stored game between the players */
+
+ if (FindPlayer(p, param[1].val.word, &bp, &bconnected)) {
+ g = game_new();
+ if (game_read(g, wp, bp) >= 0) { /* look for a game white-black, */
+ gotit = 1;
+ } else if (game_read(g, bp, wp) >= 0) { /* or black-white */
+ gotit = 1;
+ } else {
+ pprintf(p, "There is no stored game %s vs. %s\n", player_globals.parray[wp].name, player_globals.parray[bp].name);
+ }
+ if (!bconnected)
+ player_remove(bp);
+ }
+ }
+ }
+ if (gotit) {
+ if (strcasecmp(pp->name, game_globals.garray[g].white_name) && strcasecmp(player_globals.parray[p]
+.name, game_globals.garray[g].black_name) && game_globals.garray[g].private && (pp->adminLevel < ADMIN_ADMIN)) {
+ pprintf(p, "Sorry, that is a private game.\n");
+ } else {
+ if (mail == 1) { /*Do mailstored */
+ char subj[81];
+ if (param[1].type == TYPE_INT)
+ sprintf(subj, "FICS history game: %s %d", player_globals.parray[wp].name, param[1].val.integer);
+ else
+ if ((strlen(wincstring) == 1) && (isalpha(wincstring[0]))) {
+ sprintf(subj, "FICS journal game %s vs %s", game_globals.garray[g].white_name, game_globals.garray[g].black_name);
+ } else {
+ sprintf(subj, "FICS adjourned game %s vs %s", game_globals.garray[g].white_name, game_globals.garray[g].black_name);
+ }
+ if (mail_string_to_user(p, subj,
+ movesToString(g, CheckPFlag(p, PFLAG_PGN))))
+ pprintf(p, "Moves NOT mailed, perhaps your address is incorrect.\n");
+ else
+ pprintf(p, "Moves mailed.\n");
+ } else {
+ pprintf(p, "%s\n", movesToString(g, 0));
+ } /* Do smoves */
+ }
+ }
+ if (!wconnected)
+ player_remove(wp);
+ if (g != -1)
+ game_remove(g);
+}
+
+/* Tidied up a bit but still messy */
+
+int com_mailstored(int p, param_list param)
+{
+ stored_mail_moves(p, 1, param);
+ return COM_OK;
+}
+
+int com_smoves(int p, param_list param)
+{
+ stored_mail_moves(p, 0, param);
+ return COM_OK;
+}
+
+int com_sposition(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int wp, wconnected, bp, bconnected, confused = 0;
+ int g;
+
+ if (!FindPlayer(p, param[0].val.word, &wp, &wconnected))
+ return (COM_OK);
+ if (!FindPlayer(p, param[1].val.word, &bp, &bconnected)) {
+ if (!wconnected)
+ player_remove(wp);
+ return (COM_OK);
+ }
+
+ g = game_new();
+ if (game_read(g, wp, bp) < 0) { /* if no game white-black, */
+ if (game_read(g, bp, wp) < 0) { /* look for black-white */
+ confused = 1;
+ pprintf(p, "There is no stored game %s vs. %s\n", player_globals.parray[wp].name, player_globals.parray[bp].name);
+ } else {
+ int tmp;
+ tmp = wp;
+ wp = bp;
+ bp = tmp;
+ tmp = wconnected;
+ wconnected = bconnected;
+ bconnected = tmp;
+ }
+ }
+ if (!confused) {
+ if ((wp != p) && (bp != p) && (game_globals.garray[g].private) && (pp->adminLevel < ADMIN_ADMIN)) {
+ pprintf(p, "Sorry, that is a private game.\n");
+ } else {
+ game_globals.garray[g].white = wp;
+ game_globals.garray[g].black = bp;
+ game_globals.garray[g].startTime = tenth_secs();
+ game_globals.garray[g].lastMoveTime = game_globals.garray[g].startTime;
+ game_globals.garray[g].lastDecTime = game_globals.garray[g].startTime;
+ pprintf(p, "Position of stored game %s vs. %s\n", player_globals.parray[wp].name, player_globals.parray[bp].name);
+ send_board_to(g, p);
+ }
+ }
+ game_remove(g);
+ if (!wconnected)
+ player_remove(wp);
+ if (!bconnected)
+ player_remove(bp);
+ return COM_OK;
+}
+
+int com_forward(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int nHalfMoves = 1;
+ int g, i;
+ int p1;
+ unsigned now;
+
+ if (!((pp->game >=0) && ((game_globals.garray[pp->game].status == GAME_EXAMINE) || (game_globals.garray[pp->game].status == GAME_SETUP)))) {
+ pprintf(p, "You are not examining any games.\n");
+ return COM_OK;
+ }
+ if (game_globals.garray[pp->game].status == GAME_SETUP) {
+ pprintf (p,"You can't move forward yet, the position is still being set up.\n");
+ return COM_OK;
+ }
+ g = pp->game;
+ if (!strcmp(game_globals.garray[g].white_name, game_globals.garray[g].black_name)) {
+ pprintf(p, "You cannot go forward; no moves are stored.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_INT) {
+ nHalfMoves = param[0].val.integer;
+ }
+ if (game_globals.garray[g].numHalfMoves > game_globals.garray[g].revertHalfMove) {
+ pprintf(p, "Game %u: No more moves.\n", g);
+ return COM_OK;
+ }
+ if (game_globals.garray[g].numHalfMoves < game_globals.garray[g].totalHalfMoves) {
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (player_globals.parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || player_globals.parray[p1].game == g) {
+ pprintf(p1, "Game %u: %s goes forward %d move%s.\n",
+ g,
+ pp->name, nHalfMoves, (nHalfMoves == 1) ? "" : "s");
+ }
+ }
+ }
+ for (i = 0; i < nHalfMoves; i++) {
+ if (game_globals.garray[g].numHalfMoves < game_globals.garray[g].totalHalfMoves) {
+ execute_move(&game_globals.garray[g].game_state, &game_globals.garray[g].moveList[game_globals.garray[g].numHalfMoves], 1);
+ if (game_globals.garray[g].numHalfMoves + 1 > game_globals.garray[g].examMoveListSize) {
+ game_globals.garray[g].examMoveListSize += 20; /* Allocate 20 moves at a
+ time */
+ game_globals.garray[g].examMoveList = (struct move_t *) realloc(game_globals.garray[g].examMoveList, sizeof(struct move_t) * game_globals.garray[g].examMoveListSize);
+ }
+ game_globals.garray[g].examMoveList[game_globals.garray[g].numHalfMoves] = game_globals.garray[g].moveList[game_globals.garray[g].numHalfMoves];
+ game_globals.garray[g].revertHalfMove++;
+ game_globals.garray[g].numHalfMoves++;
+ } else {
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (player_globals.parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || player_globals.parray[p1].game == g) {
+ pprintf(p1, "Game %u: End of game.\n", g);
+ }
+ }
+ break;
+ }
+ }
+ /* roll back time */
+ if (game_globals.garray[g].game_state.onMove == WHITE) {
+ game_globals.garray[g].wTime += (game_globals.garray[g].lastDecTime - game_globals.garray[g].lastMoveTime);
+ } else {
+ game_globals.garray[g].bTime += (game_globals.garray[g].lastDecTime - game_globals.garray[g].lastMoveTime);
+ }
+ now = tenth_secs();
+ if (game_globals.garray[g].numHalfMoves == 0)
+ game_globals.garray[g].timeOfStart = now;
+ game_globals.garray[g].lastMoveTime = now;
+ game_globals.garray[g].lastDecTime = now;
+ send_boards(g);
+
+ if (game_globals.garray[g].revertHalfMove == game_globals.garray[g].totalHalfMoves) {
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (player_globals.parray[p1].status != PLAYER_PROMPT) continue;
+ if (player_is_observe(p1, g) || player_globals.parray[p1].game == g) {
+ pprintf(p1, "Game %u: %s %s\n", g, EndString(g,0), EndSym(g));
+ }
+ }
+ }
+
+ return COM_OK;
+}
+
+int com_backward(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int nHalfMoves = 1;
+ int g, i;
+ int p1;
+ unsigned now;
+
+ if (!((pp->game >=0) && ((game_globals.garray[pp->game].status == GAME_EXAMINE) || (game_globals.garray[pp->game].status == GAME_SETUP)))) {
+ pprintf(p, "You are not examining any games.\n");
+ return COM_OK;
+ }
+ if (game_globals.garray[pp->game].status == GAME_SETUP) {
+ pprintf (p,"You can't move backward yet, the postion is still being set up.\n");
+ return COM_OK;
+ }
+
+ g = pp->game;
+ if (param[0].type == TYPE_INT) {
+ nHalfMoves = param[0].val.integer;
+ }
+ if (game_globals.garray[g].numHalfMoves != 0) {
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (player_globals.parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || player_globals.parray[p1].game == g) {
+ pprintf(p1, "Game %u: %s backs up %d move%s.\n",
+ g,
+ pp->name, nHalfMoves, (nHalfMoves == 1) ? "" : "s");
+ }
+ }
+ }
+ for (i = 0; i < nHalfMoves; i++) {
+ if (backup_move(g, REL_EXAMINE) != MOVE_OK) {
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (player_globals.parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || player_globals.parray[p1].game == g) {
+ pprintf(p1, "Game %u: Beginning of game.\n", g);
+ }
+ }
+
+ break;
+ }
+ }
+ if (game_globals.garray[g].numHalfMoves < game_globals.garray[g].revertHalfMove) {
+ game_globals.garray[g].revertHalfMove = game_globals.garray[g].numHalfMoves;
+ }
+ /* roll back time */
+ if (game_globals.garray[g].game_state.onMove == WHITE) {
+ game_globals.garray[g].wTime += (game_globals.garray[g].lastDecTime - game_globals.garray[g].lastMoveTime);
+ } else {
+ game_globals.garray[g].bTime += (game_globals.garray[g].lastDecTime - game_globals.garray[g].lastMoveTime);
+ }
+ now = tenth_secs();
+ if (game_globals.garray[g].numHalfMoves == 0)
+ game_globals.garray[g].timeOfStart = now;
+ game_globals.garray[g].lastMoveTime = now;
+ game_globals.garray[g].lastDecTime = now;
+ send_boards(g);
+ return COM_OK;
+}
+
+int com_revert(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int nHalfMoves = 1;
+ int g, i;
+ int p1;
+ unsigned now;
+
+ if (!((pp->game >=0) && ((game_globals.garray[pp->game].status == GAME_EXAMINE)|| (game_globals.garray[pp->game].status == GAME_SETUP)))) {
+ pprintf(p, "You are not examining any games.\n");
+ return COM_OK;
+ }
+ if (game_globals.garray[pp->game].status == GAME_SETUP) {
+ pprintf (p,"You can't move revert yet, the position is still being set up.\n");
+ return COM_OK;
+ }
+ g = pp->game;
+ nHalfMoves = game_globals.garray[g].numHalfMoves - game_globals.garray[g].revertHalfMove;
+ if (nHalfMoves == 0) {
+ pprintf(p, "Game %u: Already at mainline.\n", g);
+ return COM_OK;
+ }
+ if (nHalfMoves < 0) { /* eek - should NEVER happen! */
+ d_printf( "OUCH! in com_revert: nHalfMoves < 0\n");
+ return COM_OK;
+ }
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (player_globals.parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || player_globals.parray[p1].game == g) {
+ pprintf(p1, "Game %u: %s reverts to mainline.\n",
+ g, pp->name);
+ }
+ }
+ for (i = 0; i < nHalfMoves; i++) {
+ backup_move(g, REL_EXAMINE);/* should never return error */
+ }
+ /* roll back time */
+ if (game_globals.garray[g].game_state.onMove == WHITE) {
+ game_globals.garray[g].wTime += (game_globals.garray[g].lastDecTime - game_globals.garray[g].lastMoveTime);
+ } else {
+ game_globals.garray[g].bTime += (game_globals.garray[g].lastDecTime - game_globals.garray[g].lastMoveTime);
+ }
+ now = tenth_secs();
+ if (game_globals.garray[g].numHalfMoves == 0)
+ game_globals.garray[g].timeOfStart = now;
+ game_globals.garray[g].lastMoveTime = now;
+ game_globals.garray[g].lastDecTime = now;
+ send_boards(g);
+ return COM_OK;
+}
+
+int com_history(int p, param_list param)
+{
+ int p1, connected;
+ char fname[MAX_FILENAME_SIZE];
+
+ if (param[0].type == TYPE_WORD) {
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+ } else {
+ p1 = p;
+ connected = 1;
+ }
+
+ sprintf(fname, "%s/player_data/%c/%s.%s", STATS_DIR, player_globals.parray[p1].login[0],
+ player_globals.parray[p1].login, STATS_GAMES);
+ pgames(p, p1, fname);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+int com_journal(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1, connected;
+ char fname[MAX_FILENAME_SIZE];
+
+ if (param[0].type == TYPE_WORD) {
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+ } else {
+ p1 = p;
+ connected = 1;
+ }
+
+ if (!CheckPFlag(p1, PFLAG_REG)) {
+ pprintf (p,"Only registered players may keep a journal.\n");
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ if (CheckPFlag(p1, PFLAG_JPRIVATE) && (p != p1)
+ && (pp->adminLevel < ADMIN_ADMIN)) {
+ pprintf (p,"Sorry, this journal is private.\n");
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ sprintf(fname, "%s/player_data/%c/%s.%s", STATS_DIR, player_globals.parray[p1].login[0],
+ player_globals.parray[p1].login, STATS_JOURNAL);
+ pjournal(p, p1, fname);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+/* Remove a journal item */
+
+int com_jkill(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ FILE* Journal;
+ char* kill = param[0].val.word;
+ char fname[MAX_FILENAME_SIZE];
+ char fname_new[MAX_FILENAME_SIZE];
+ int empty;
+
+ if (!CheckPFlag(p, PFLAG_REG)) {
+ pprintf (p,"Only registered players may keep a journal.\n");
+ return COM_OK;
+ }
+
+ if ((strlen(kill) != 1) || (!(isalpha(kill[0])))) {
+ pprintf (p,"Journal entries are referenced by single letters.\n");
+ return COM_OK;
+ }
+
+ if (((kill[0] - 'a' + 1) > MAX_JOURNAL) && (pp->adminLevel < ADMIN_ADMIN)
+ && (!titled_player(p,pp->login))) {
+ pprintf (p,"Your maximum journal entry is %c\n",toupper ((char)(MAX_JOURNAL
++ 'A' - 1)));
+ return COM_OK;
+ }
+
+ sprintf(fname, "%s/player_data/%c/%s.journal",
+ STATS_DIR, pp->login[0],pp->login);
+ sprintf (fname_new,"%s.w",fname);
+
+ Journal = fopen_s(fname, "r");
+ if (Journal == NULL) {
+ pprintf(p, "You don't have a journal.\n");
+ return COM_OK;
+ }
+
+ kill[0] = toupper(kill[0]);
+
+ if (removejournalitem(p, kill[0], Journal,fname_new,&empty)) {
+ fclose (Journal);
+ rename (fname_new,fname);
+ if (empty)
+ unlink (fname);
+ sprintf(fname, "%s/%c/%s.%c",
+ JOURNAL_DIR, pp->login[0],pp->login,tolower(kill[0]));
+ unlink(fname);
+ pprintf (p,"Journal entry %c deleted.\n",kill[0]);
+ } else {
+ pprintf (p,"You have no journal entry %c.\n",kill[0]);
+ fclose (Journal);
+ unlink (fname_new);
+ }
+ return COM_OK;
+}
+
+static void jsave_journalentry(int p,char save_spot,int p1,char from_spot,char* to_file)
+{
+ struct player *pp = &player_globals.parray[p];
+ FILE *Game;
+ char fname[MAX_FILENAME_SIZE], fname2[MAX_FILENAME_SIZE];
+ char* name_from = player_globals.parray[p1].login;
+ char* name_to = pp->login;
+ struct journal* j;
+
+ sprintf(fname, "%s/%c/%s.%c", JOURNAL_DIR, name_from[0],name_from,from_spot);
+ Game = fopen_s(fname, "r");
+ if (Game == NULL) {
+ pprintf(p, "Journal entry %c not available for %s.\n", toupper(from_spot), player_globals.parray[p1].name);
+ return;
+ }
+ fclose (Game);
+
+ sprintf(fname2, "%s/%c/%s.%c", JOURNAL_DIR, name_to[0],name_to,save_spot);
+
+ if (file_copy(fname, fname2) != 0) {
+ pprintf (p,"Copy in jsave_journalentry failed!\n");
+ pprintf (p,"Please report this to an admin.\n");
+ d_printf("CHESSD: Copy failed in jsave_journalentry\n");
+ return;
+ }
+
+ sprintf(fname, "%s/player_data/%c/%s.%s", STATS_DIR, name_from[0],
+ name_from, STATS_JOURNAL);
+
+ j = (struct journal*) malloc (sizeof(struct journal));
+ if (!journal_get_info(p,tolower(from_spot),j,fname)) {
+ free (j);
+ return;
+ }
+
+ j->slot = toupper(save_spot);
+ addjournalitem(p, j, to_file);
+
+ pprintf(p,"Journal entry %s %c saved in slot %c in journal.\n",player_globals.parray[p1].name, toupper(from_spot), toupper(save_spot));
+ free (j);
+}
+
+static void jsave_history(int p,char save_spot,int p1,int from,char* to_file)
+{
+ struct player *pp = &player_globals.parray[p];
+ char Eco[100];
+ char End[100];
+ char jfname[MAX_FILENAME_SIZE];
+ char* HistoryFname = FindHistory2(p, p1, from, Eco, End);
+ /* End symbol Mat Res, etc is the only thing we can't find out */
+ char command[MAX_FILENAME_SIZE*2+3];
+ char* name_to = pp->login;
+ FILE *Game;
+ int g;
+ struct journal* j;
+
+ if (HistoryFname == NULL) {
+ return;
+ }
+ Game = fopen_s(HistoryFname, "r");
+ if (Game == NULL) {
+ pprintf(p, "History game %d not available for %s.\n",
+ from, player_globals.parray[p1].name);
+ return;
+ }
+
+ sprintf(jfname, "%s/%c/%s.%c", JOURNAL_DIR, name_to[0],name_to,save_spot);
+ unlink(jfname); /* necessary if cp is hard aliased to cp -i */
+ sprintf(command, "cp %s %s",HistoryFname,jfname);
+ if (file_copy(HistoryFname, jfname) != 0) {
+ pprintf (p,"Copy in jsave_history failed!\n");
+ pprintf (p,"Please report this to an admin.\n");
+ d_printf("CHESSD: Copy failed in jsave_journalentry\n");
+ return;
+ }
+ g = game_new(); /* Open a dummy game */
+
+ if (ReadGameAttrs(Game, g) < 0) {
+ pprintf (p,"Gamefile is corrupt. Please tell an admin.\n");
+ game_remove(g);
+ fclose (Game);
+ return;
+ }
+ fclose (Game);
+
+ j = (struct journal*) malloc (sizeof(struct journal));
+
+ if (game_globals.garray[g].private) {
+ j->type[0] = 'p';
+ } else {
+ j->type[0] = ' ';
+ }
+ if (game_globals.garray[g].type == TYPE_BLITZ) {
+ j->type[1] = 'b';
+ } else if (game_globals.garray[g].type == TYPE_WILD) {
+ j->type[1] = 'w';
+ } else if (game_globals.garray[g].type == TYPE_STAND) {
+ j->type[1] = 's';
+ } else if (game_globals.garray[g].type == TYPE_LIGHT) {
+ j->type[1] = 'l';
+ } else if (game_globals.garray[g].type == TYPE_BUGHOUSE) {
+ j->type[1] = 'B';
+ } else {
+ if (game_globals.garray[g].type == TYPE_NONSTANDARD)
+ j->type[1] = 'n';
+ else
+ j->type[1] = 'u';
+ }
+ if (game_globals.garray[g].rated) {
+ j->type[2] = 'r';
+ } else {
+ j->type[2] = 'u';
+ }
+ j->type[3] = '\0';
+
+ j->slot = toupper(save_spot);
+ strcpy (j->WhiteName, game_globals.garray[g].white_name);
+ j->WhiteRating = game_globals.garray[g].white_rating;
+ strcpy (j->BlackName, game_globals.garray[g].black_name);
+ j->BlackRating = game_globals.garray[g].black_rating;
+ j->t = game_globals.garray[g].wInitTime;
+ j->i = game_globals.garray[g].wIncrement;
+ strcpy (j->eco, Eco);
+ strcpy (j->ending, End);
+ strcpy (j->result, EndSym(g));
+
+ addjournalitem(p, j, to_file);
+ game_remove(g);
+ pprintf(p,"Game %s %d saved in slot %c in journal.\n",
+ player_globals.parray[p1].name, from, toupper(save_spot));
+ free(j);
+}
+
+int com_jsave(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1, p1conn;
+ char* to = param[0].val.word;
+ char* from;
+ char fname[MAX_FILENAME_SIZE];
+
+ if (!CheckPFlag(p, PFLAG_REG)) {
+ pprintf (p,"Only registered players may keep a journal.\n");
+ return COM_OK;
+ }
+
+ if ((strlen(to) != 1) || (!(isalpha(to[0])))) {
+ pprintf (p,"Journal entries are referenced by single letters.\n");
+ return COM_OK;
+ }
+
+ if (((to[0] - 'a' + 1) > MAX_JOURNAL) && (pp->adminLevel < ADMIN_ADMIN) && (!titled_player(p,pp->login))) {
+ pprintf (p,"Your maximum journal entry is %c\n",toupper ((char)(MAX_JOURNAL + 'A' - 1)));
+ return COM_OK;
+ }
+
+ if (!FindPlayer(p, param[1].val.word, &p1, &p1conn))
+ return COM_OK;
+
+ if (param[2].type == TYPE_INT) {
+
+ /* grab from a history */
+ sprintf (fname,"%s/player_data/%c/%s.%s",STATS_DIR,pp->login[0],pp->login, STATS_JOURNAL);
+ jsave_history(p, to[0], p1, param[2].val.integer,fname);
+
+ } else {
+
+ from = param[2].val.word;
+
+ if ((strlen(from) != 1) || (!(isalpha(from[0])))) {
+ pprintf (p,"Journal entries are referenced by single letters.\n");
+ if (!p1conn)
+ player_remove(p1);
+ return COM_OK;
+ }
+
+ if (CheckPFlag(p1, PFLAG_JPRIVATE)
+ && (pp->adminLevel < ADMIN_ADMIN) && (p != p1)) {
+ pprintf (p,"Sorry, the journal from which you are trying to fetch is private.\n");
+
+ if (!p1conn)
+ player_remove(p1);
+ return COM_OK;
+ }
+
+ if (((to[0] - 'a' + 1) > MAX_JOURNAL) && (player_globals.parray[p1].adminLevel < ADMIN_ADMIN) && (!titled_player(p,player_globals.parray[p1].login))) {
+ pprintf (p,"%s's maximum journal entry is %c\n",player_globals.parray[p1].name,toupper((char)(MAX_JOURNAL + 'A' - 1)));
+ if (!p1conn)
+ player_remove(p1);
+ return COM_OK;
+ }
+ if (( p == p1) && (to[0] == from [0])) {
+ pprintf (p,"Source and destination entries are the same.\n");
+ return COM_OK;
+ }
+
+ /* grab from a journal */
+
+ sprintf(fname, "%s/player_data/%c/%s.%s", STATS_DIR, pp->login[0],
+ pp->login, STATS_JOURNAL);
+ jsave_journalentry(p,to[0],p1, from[0], fname);
+
+ }
+ if (!p1conn)
+ player_remove(p1);
+ return COM_OK;
+}
+
+int com_refresh(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int g, p1;
+
+ if (param[0].type == TYPE_NULL) {
+ if (pp->game >= 0) {
+ send_board_to(pp->game, p);
+ } else { /* Do observing in here */
+ if (pp->num_observe) {
+ for (g = 0; g < pp->num_observe; g++) {
+ send_board_to(pp->observe_list[g], p);
+ }
+ } else {
+ pprintf(p, "You are neither playing, observing nor examining a game.\n");
+ return COM_OK;
+ }
+ }
+ } else {
+ g = GameNumFromParam (p, &p1, ¶m[0]);
+ if (g < 0)
+ return COM_OK;
+ if ((g >= game_globals.g_num) || ((game_globals.garray[g].status != GAME_ACTIVE)
+ && ((game_globals.garray[g].status != GAME_EXAMINE)
+ || (game_globals.garray[g].status != GAME_SETUP)))) {
+ pprintf(p, "No such game.\n");
+ } else {
+
+ int link = game_globals.garray[g].link;
+
+ if ((game_globals.garray[g].private && pp->adminLevel==ADMIN_USER) &&
+ (game_globals.garray[g].white != p) && (game_globals.garray[g].white != p1)) {
+ if (link != -1) {
+ if ((game_globals.garray[link].white != p) && (game_globals.garray[link].black != p)) {
+ pprintf (p, "Sorry, game %d is a private game.\n", g+1);
+ return COM_OK;
+ }
+ }
+ }
+
+ if (game_globals.garray[g].private)
+ pprintf(p, "Refreshing static game %d\n", g+1);
+ send_board_to(g, p);
+ }
+ }
+ return COM_OK;
+}
+
+int com_prefresh(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int retval, part = pp->partner;
+
+ if (part < 0) {
+ pprintf(p, "You do not have a partner.\n");
+ return COM_OK;
+ }
+ retval = pcommand (p, "refresh %s", player_globals.parray[part].name);
+ if (retval == COM_OK)
+ return COM_OK_NOPROMPT;
+ else
+ return retval;
+}
--- /dev/null
+/* Revision history:
+ name email yy/mm/dd Change
+ Dave Herscovici 95/11/26 Created
+*/
+
+#ifndef _OBSPROC_H
+#define _OBSPROC_H
+
+#define MAX_JOURNAL 12
+
+#endif /* _OBSPROC_H */
--- /dev/null
+parse_info.h
--- /dev/null
+/.cvsignore/1.1/Tue Jun 18 14:03:29 2002//
+/README/1.1/Mon Jun 24 04:45:36 2002//
+/genparser.c/1.16/Sat Jun 29 00:06:16 2002//
+/genparser.h/1.7/Sat Jun 29 00:06:16 2002//
+/parser.c/1.13/Sat Jun 29 00:06:16 2002//
+/genstruct.pl/1.14/Thu Jul 22 07:04:41 2004//
+D
--- /dev/null
+lasker/src/parsers
--- /dev/null
+genstruct is a system for marshalling/unmarshalling C structures. It
+has a number of unusual features:
+
+- can handle a very wide range of C constructs
+- produces a human-readable marshalled format
+- can handle significant changes in the structures between marshalling
+ and unmarshalling
+- works directly from C header files
+
+To see how to use it please take a look at test.c and test.h. I'm
+afraid that the only documentation at the moment is these examples.
+
+Limitations
+-----------
+
+genstruct cannot handle some types of C structures. In particular it
+cannot handle structures where a single pointer is used more than once
+(for example in doubly linked lists). Once I add reference counting
+this should be fixed.
+
+A second problem is that genstruct works on the C headers before they
+have been through the C pre-processor. This means that #ifdefs within
+structures will screw things up badly.
+
+Finally, genstruct only handles structure definitions if they are
+formatted in a certain way. For example this will work:
+
+GENSTRUCT struct foo {
+ char *s;
+ int x;
+};
+
+but this won't:
+
+GENSTRUCT typedef struct {
+ char *s;
+ int x;
+} foo;
+
+This may be fixed in a future release.
+
+
+ --
+ Andrew Tridgell
+ genstruct@tridgell.net
--- /dev/null
+/*
+ Copyright (C) Andrew Tridgell <genstruct@tridgell.net> 2002
+
+ 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 2 of the License, 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.
+*/
+
+/*
+ automatic marshalling/unmarshalling system for C structures
+*/
+
+#if STANDALONE
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <ctype.h>
+#include <stddef.h>
+#include <stdarg.h>
+#include <errno.h>
+#include "genparser.h"
+#else
+#include "includes.h"
+#endif
+
+/* see if a range of memory is all zero. Used to prevent dumping of zero elements */
+static int all_zero(const char *ptr, unsigned size)
+{
+ int i;
+ if (!ptr) return 1;
+ for (i=0;i<size;i++) {
+ if (ptr[i]) return 0;
+ }
+ return 1;
+}
+
+/* encode a buffer of bytes into a escaped string */
+static char *encode_bytes(const char *ptr, unsigned len)
+{
+ const char *hexdig = "0123456789abcdef";
+ char *ret, *p;
+ unsigned i;
+ ret = malloc(len*3 + 1); /* worst case size */
+ if (!ret) return NULL;
+ for (p=ret,i=0;i<len;i++) {
+ if (isalnum(ptr[i]) || isspace(ptr[i]) ||
+ (ispunct(ptr[i]) && !strchr("\\{}", ptr[i]))) {
+ *p++ = ptr[i];
+ } else {
+ unsigned char c = *(unsigned char *)(ptr+i);
+ if (c == 0 && all_zero(ptr+i, len-i)) break;
+ p[0] = '\\';
+ p[1] = hexdig[c>>4];
+ p[2] = hexdig[c&0xF];
+ p += 3;
+ }
+ }
+
+ *p = 0;
+
+ return ret;
+}
+
+/* decode an escaped string from encode_bytes() into a buffer */
+static char *decode_bytes(const char *s, unsigned *len)
+{
+ char *ret, *p;
+ unsigned i;
+ ret = calloc(1, strlen(s)+1); /* worst case length */
+
+ if (*s == '{') s++;
+
+ for (p=ret,i=0;s[i];i++) {
+ if (s[i] == '}') {
+ break;
+ } else if (s[i] == '\\') {
+ unsigned v;
+ if (sscanf(&s[i+1], "%02x", &v) != 1 || v > 255) {
+ free(ret);
+ return NULL;
+ }
+ *(unsigned char *)p = v;
+ p++;
+ i += 2;
+ } else {
+ *p++ = s[i];
+ }
+ }
+ *p = 0;
+
+ (*len) = (unsigned)(p - ret);
+
+ return ret;
+}
+
+/* the add*() functions deal with adding things to a struct
+ parse_string */
+
+/* allocate more space if needed */
+static int addgen_alloc(struct parse_string *p, int n)
+{
+ if (p->length + n <= p->allocated) return 0;
+ p->allocated = p->length + n + 200;
+ p->s = realloc(p->s, p->allocated);
+ if (!p->s) {
+ errno = ENOMEM;
+ return -1;
+ }
+ return 0;
+}
+
+/* add a character to the buffer */
+static int addchar(struct parse_string *p, char c)
+{
+ if (addgen_alloc(p, 2) != 0) {
+ return -1;
+ }
+ p->s[p->length++] = c;
+ p->s[p->length] = 0;
+ return 0;
+}
+
+/* add a string to the buffer */
+static int addstr(struct parse_string *p, const char *s)
+{
+ int len = strlen(s);
+ if (addgen_alloc(p, len+1) != 0) {
+ return -1;
+ }
+ memcpy(p->s + p->length, s, len+1);
+ p->length += len;
+ return 0;
+}
+
+/* add a string to the buffer with a tab prefix */
+static int addtabbed(struct parse_string *p, const char *s, unsigned indent)
+{
+ int len = strlen(s);
+ if (addgen_alloc(p, indent+len+1) != 0) {
+ return -1;
+ }
+ while (indent--) {
+ p->s[p->length++] = '\t';
+ }
+ memcpy(p->s + p->length, s, len+1);
+ p->length += len;
+ return 0;
+}
+
+/* note! this can only be used for results up to 60 chars wide! */
+static int addshort(struct parse_string *p, const char *fmt, ...)
+{
+ char buf[60];
+ int n;
+ va_list ap;
+ va_start(ap, fmt);
+ n = vsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+ if (addgen_alloc(p, n + 1) != 0) {
+ return -1;
+ }
+ if (n != 0) {
+ memcpy(p->s + p->length, buf, n);
+ }
+ p->length += n;
+ p->s[p->length] = 0;
+ return 0;
+}
+
+/*
+ this is here to make it easier for people to write dump functions
+ for their own types
+ */
+int gen_addgen(struct parse_string *p, const char *fmt, ...)
+{
+ char *buf = NULL;
+ int n;
+ va_list ap;
+ va_start(ap, fmt);
+ n = vasprintf(&buf, fmt, ap);
+ va_end(ap);
+ if (addgen_alloc(p, n + 1) != 0) {
+ if (buf) free(buf);
+ return -1;
+ }
+ if (n != 0) {
+ memcpy(p->s + p->length, buf, n);
+ }
+ p->length += n;
+ p->s[p->length] = 0;
+ if (buf) free(buf);
+ return 0;
+}
+
+/* dump a enumerated type */
+int gen_dump_enum(const struct enum_struct *einfo,
+ struct parse_string *p,
+ const char *ptr,
+ unsigned indent)
+{
+ unsigned v = *(unsigned *)ptr;
+ int i;
+ for (i=0;einfo[i].name;i++) {
+ if (v == einfo[i].value) {
+ addstr(p, einfo[i].name);
+ return 0;
+ }
+ }
+ /* hmm, maybe we should just fail? */
+ return gen_dump_unsigned(p, ptr, indent);
+}
+
+/* dump a single non-array element, hanlding struct and enum */
+static int gen_dump_one(struct parse_string *p,
+ const struct parse_struct *pinfo,
+ const char *ptr,
+ unsigned indent)
+{
+ if (pinfo->dump_fn == gen_dump_char && pinfo->ptr_count == 1) {
+ char *s = encode_bytes(ptr, strlen(ptr));
+ if (addchar(p,'{') ||
+ addstr(p, s) ||
+ addstr(p, "}")) {
+ free(s);
+ return -1;
+ }
+ return 0;
+ }
+
+ return pinfo->dump_fn(p, ptr, indent);
+}
+
+/* handle dumping of an array of arbitrary type */
+static int gen_dump_array(struct parse_string *p,
+ const struct parse_struct *pinfo,
+ const char *ptr,
+ int array_len,
+ int indent)
+{
+ int i, count=0;
+
+ /* special handling of fixed length strings */
+ if (array_len != 0 &&
+ pinfo->ptr_count == 0 &&
+ pinfo->dump_fn == gen_dump_char) {
+ char *s = encode_bytes(ptr, array_len);
+ if (!s) return -1;
+ if (addtabbed(p, pinfo->name, indent) ||
+ addstr(p, " = {") ||
+ addstr(p, s) ||
+ addstr(p, "}\n")) {
+ free(s);
+ return -1;
+ }
+ free(s);
+ return 0;
+ }
+
+ for (i=0;i<array_len;i++) {
+ const char *p2 = ptr;
+ unsigned size = pinfo->size;
+
+ /* generic pointer dereference */
+ if (pinfo->ptr_count) {
+ p2 = *(const char **)ptr;
+ size = sizeof(void *);
+ }
+
+ if ((count || pinfo->ptr_count) &&
+ !(pinfo->flags & FLAG_ALWAYS) &&
+ all_zero(ptr, size)) {
+ ptr += size;
+ continue;
+ }
+ if (count == 0) {
+ if (addtabbed(p, pinfo->name, indent) ||
+ addshort(p, " = %u:", i)) {
+ return -1;
+ }
+ } else {
+ if (addshort(p, ", %u:", i) != 0) {
+ return -1;
+ }
+ }
+ if (gen_dump_one(p, pinfo, p2, indent) != 0) {
+ return -1;
+ }
+ ptr += size;
+ count++;
+ }
+ if (count) {
+ return addstr(p, "\n");
+ }
+ return 0;
+}
+
+/* find a variable by name in a loaded structure and return its value
+ as an integer. Used to support dynamic arrays */
+static int find_var(const struct parse_struct *pinfo,
+ const char *data,
+ const char *var)
+{
+ int i;
+ const char *ptr;
+
+ /* this allows for constant lengths */
+ if (isdigit(*var)) {
+ return atoi(var);
+ }
+
+ for (i=0;pinfo[i].name;i++) {
+ if (strcmp(pinfo[i].name, var) == 0) break;
+ }
+ if (!pinfo[i].name) return -1;
+
+ ptr = data + pinfo[i].offset;
+
+ switch (pinfo[i].size) {
+ case sizeof(int):
+ return *(int *)ptr;
+ case sizeof(char):
+ return *(char *)ptr;
+ }
+
+ return -1;
+}
+
+
+int gen_dump_struct(const struct parse_struct *pinfo,
+ struct parse_string *p,
+ const char *ptr,
+ unsigned indent)
+{
+ char *s = gen_dump(pinfo, ptr, indent+1);
+ if (!s) return -1;
+ if (addstr(p, "{\n") ||
+ addstr(p,s) ||
+ addtabbed(p,"}", indent)) {
+ free(s);
+ return -1;
+ }
+ free(s);
+ return 0;
+}
+
+static int gen_dump_string(struct parse_string *p,
+ const struct parse_struct *pinfo,
+ const char *data,
+ unsigned indent)
+{
+ const char *ptr = *(char **)data;
+ char *s = encode_bytes(ptr, strlen(ptr));
+ if (addtabbed(p, pinfo->name, indent) ||
+ addstr(p, " = ") ||
+ addchar(p,'{') ||
+ addstr(p, s) ||
+ addstr(p, "}\n")) {
+ free(s);
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ find the length of a nullterm array
+*/
+static int len_nullterm(const char *ptr, int size, int array_len)
+{
+ int len;
+
+ if (size == 1) {
+ len = strnlen(ptr, array_len);
+ } else {
+ for (len=0;len<array_len;len++) {
+ if (all_zero(ptr+len*size, size)) break;
+ }
+ }
+
+ if (len == 0) len = 1;
+
+ return len;
+}
+
+
+/* the generic dump routine. Scans the parse information for this structure
+ and processes it recursively */
+char *gen_dump(const struct parse_struct *pinfo,
+ const char *data,
+ unsigned indent)
+{
+ struct parse_string p;
+ int i;
+
+ p.length = 0;
+ p.allocated = 0;
+ p.s = NULL;
+
+ if (addstr(&p, "") != 0) {
+ return NULL;
+ }
+
+ for (i=0;pinfo[i].name;i++) {
+ const char *ptr = data + pinfo[i].offset;
+ unsigned size = pinfo[i].size;
+
+ if (pinfo[i].ptr_count) {
+ size = sizeof(void *);
+ }
+
+ /* special handling for array types */
+ if (pinfo[i].array_len) {
+ unsigned len = pinfo[i].array_len;
+ if (pinfo[i].flags & FLAG_NULLTERM) {
+ len = len_nullterm(ptr, size, len);
+ }
+ if (gen_dump_array(&p, &pinfo[i], ptr,
+ len, indent)) {
+ goto failed;
+ }
+ continue;
+ }
+
+ /* and dynamically sized arrays */
+ if (pinfo[i].dynamic_len) {
+ int len = find_var(pinfo, data, pinfo[i].dynamic_len);
+ struct parse_struct p2 = pinfo[i];
+ if (len < 0) {
+ goto failed;
+ }
+ if (len > 0) {
+ if (pinfo[i].flags & FLAG_NULLTERM) {
+ len = len_nullterm(*(char **)ptr,
+ pinfo[i].size, len);
+ }
+ p2.ptr_count--;
+ p2.dynamic_len = NULL;
+ if (gen_dump_array(&p, &p2, *(char **)ptr,
+ len, indent) != 0) {
+ goto failed;
+ }
+ }
+ continue;
+ }
+
+ /* don't dump zero elements */
+ if (!(pinfo[i].flags & FLAG_ALWAYS) && all_zero(ptr, size)) continue;
+
+ /* assume char* is a null terminated string */
+ if (pinfo[i].size == 1 && pinfo[i].ptr_count == 1 &&
+ pinfo[i].dump_fn == gen_dump_char) {
+ if (gen_dump_string(&p, &pinfo[i], ptr, indent) != 0) {
+ goto failed;
+ }
+ continue;
+ }
+
+ /* generic pointer dereference */
+ if (pinfo[i].ptr_count) {
+ ptr = *(const char **)ptr;
+ }
+
+ if (addtabbed(&p, pinfo[i].name, indent) ||
+ addstr(&p, " = ") ||
+ gen_dump_one(&p, &pinfo[i], ptr, indent) ||
+ addstr(&p, "\n")) {
+ goto failed;
+ }
+ }
+ return p.s;
+
+failed:
+ free(p.s);
+ return NULL;
+}
+
+/* search for a character in a string, skipping over sections within
+ matching braces */
+static char *match_braces(char *s, char c)
+{
+ int depth = 0;
+ while (*s) {
+ switch (*s) {
+ case '}':
+ depth--;
+ break;
+ case '{':
+ depth++;
+ break;
+ }
+ if (depth == 0 && *s == c) {
+ return s;
+ }
+ s++;
+ }
+ return s;
+}
+
+/* parse routine for enumerated types */
+int gen_parse_enum(const struct enum_struct *einfo,
+ char *ptr,
+ const char *str)
+{
+ unsigned v;
+ int i;
+
+ if (isdigit(*str)) {
+ if (sscanf(str, "%u", &v) != 1) {
+ errno = EINVAL;
+ return -1;
+ }
+ *(unsigned *)ptr = v;
+ return 0;
+ }
+
+ for (i=0;einfo[i].name;i++) {
+ if (strcmp(einfo[i].name, str) == 0) {
+ *(unsigned *)ptr = einfo[i].value;
+ return 0;
+ }
+ }
+
+ /* unknown enum value?? */
+ return -1;
+}
+
+
+/* parse all base types */
+static int gen_parse_base(const struct parse_struct *pinfo,
+ char *ptr,
+ const char *str)
+{
+ if (pinfo->parse_fn == gen_parse_char && pinfo->ptr_count==1) {
+ unsigned len;
+ char *s = decode_bytes(str, &len);
+ if (!s) return -1;
+ *(char **)ptr = s;
+ return 0;
+ }
+
+ if (pinfo->ptr_count) {
+ struct parse_struct p2 = *pinfo;
+ *(void **)ptr = calloc(1, pinfo->ptr_count>1?sizeof(void *):pinfo->size);
+ if (! *(void **)ptr) {
+ return -1;
+ }
+ ptr = *(char **)ptr;
+ p2.ptr_count--;
+ return gen_parse_base(&p2, ptr, str);
+ }
+
+ return pinfo->parse_fn(ptr, str);
+}
+
+/* parse a generic array */
+static int gen_parse_array(const struct parse_struct *pinfo,
+ char *ptr,
+ const char *str,
+ int array_len)
+{
+ char *p, *p2;
+ unsigned size = pinfo->size;
+
+ /* special handling of fixed length strings */
+ if (array_len != 0 &&
+ pinfo->ptr_count == 0 &&
+ pinfo->dump_fn == gen_dump_char) {
+ unsigned len = 0;
+ char *s = decode_bytes(str, &len);
+ if (!s) return -1;
+ memset(ptr, 0, array_len);
+ memcpy(ptr, s, len);
+ free(s);
+ return 0;
+ }
+
+ if (pinfo->ptr_count) {
+ size = sizeof(void *);
+ }
+
+ while (*str) {
+ unsigned idx;
+ int done;
+
+ idx = atoi(str);
+ p = strchr(str,':');
+ if (!p) break;
+ p++;
+ p2 = match_braces(p, ',');
+ done = (*p2 != ',');
+ *p2 = 0;
+
+ if (*p == '{') {
+ p++;
+ p[strlen(p)-1] = 0;
+ }
+
+ if (gen_parse_base(pinfo, ptr + idx*size, p) != 0) {
+ return -1;
+ }
+
+ if (done) break;
+ str = p2+1;
+ }
+
+ return 0;
+}
+
+/* parse one element, hanlding dynamic and static arrays */
+static int gen_parse_one(const struct parse_struct *pinfo,
+ const char *name,
+ char *data,
+ const char *str)
+{
+ int i;
+ for (i=0;pinfo[i].name;i++) {
+ if (strcmp(pinfo[i].name, name) == 0) {
+ break;
+ }
+ }
+ if (pinfo[i].name == NULL) {
+ return 0;
+ }
+
+ if (pinfo[i].array_len) {
+ return gen_parse_array(&pinfo[i], data+pinfo[i].offset,
+ str, pinfo[i].array_len);
+ }
+
+ if (pinfo[i].dynamic_len) {
+ int len = find_var(pinfo, data, pinfo[i].dynamic_len);
+ if (len < 0) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (len > 0) {
+ unsigned size;
+ struct parse_struct p2 = pinfo[i];
+ char *ptr;
+ size = pinfo[i].ptr_count>1?sizeof(void*):pinfo[i].size;
+ ptr = calloc(len, size);
+ if (!ptr) {
+ errno = ENOMEM;
+ return -1;
+ }
+ *((char **)(data + pinfo[i].offset)) = ptr;
+ p2.ptr_count--;
+ p2.dynamic_len = NULL;
+ return gen_parse_array(&p2, ptr, str, len);
+ }
+ return 0;
+ }
+
+ return gen_parse_base(&pinfo[i], data + pinfo[i].offset, str);
+}
+
+int gen_parse_struct(const struct parse_struct *pinfo, char *ptr, const char *str)
+{
+ return gen_parse(pinfo, ptr, str);
+}
+
+/* the main parse routine */
+int gen_parse(const struct parse_struct *pinfo, char *data, const char *s)
+{
+ char *str, *s0;
+
+ s0 = strdup(s);
+ str = s0;
+
+ while (*str) {
+ char *p;
+ char *name;
+ char *value;
+
+ /* skip leading whitespace */
+ while (isspace(*str)) str++;
+
+ p = strchr(str, '=');
+ if (!p) break;
+ value = p+1;
+ while (p > str && isspace(*(p-1))) {
+ p--;
+ }
+
+ *p = 0;
+ name = str;
+
+ while (isspace(*value)) value++;
+
+ if (*value == '{') {
+ str = match_braces(value, '}');
+ value++;
+ } else {
+ str = match_braces(value, '\n');
+ }
+
+ *str++ = 0;
+
+ if (gen_parse_one(pinfo, name, data, value) != 0) {
+ free(s0);
+ return -1;
+ }
+ }
+
+ free(s0);
+ return 0;
+}
+
+
+
+/* for convenience supply some standard dumpers and parsers here */
+
+int gen_parse_char(char *ptr, const char *str)
+{
+ *(unsigned char *)ptr = atoi(str);
+ return 0;
+}
+
+int gen_parse_int(char *ptr, const char *str)
+{
+ *(int *)ptr = atoi(str);
+ return 0;
+}
+
+int gen_parse_unsigned(char *ptr, const char *str)
+{
+ *(unsigned *)ptr = strtoul(str, NULL, 10);
+ return 0;
+}
+
+int gen_parse_time_t(char *ptr, const char *str)
+{
+ *(time_t *)ptr = strtoul(str, NULL, 10);
+ return 0;
+}
+
+int gen_parse_double(char *ptr, const char *str)
+{
+ *(double *)ptr = atof(str);
+ return 0;
+}
+
+int gen_parse_float(char *ptr, const char *str)
+{
+ *(float *)ptr = atof(str);
+ return 0;
+}
+
+int gen_dump_char(struct parse_string *p, const char *ptr, unsigned indent)
+{
+ return addshort(p, "%u", *(unsigned char *)(ptr));
+}
+
+int gen_dump_int(struct parse_string *p, const char *ptr, unsigned indent)
+{
+ return addshort(p, "%d", *(int *)(ptr));
+}
+
+int gen_dump_unsigned(struct parse_string *p, const char *ptr, unsigned indent)
+{
+ return addshort(p, "%u", *(unsigned *)(ptr));
+}
+
+int gen_dump_time_t(struct parse_string *p, const char *ptr, unsigned indent)
+{
+ return addshort(p, "%u", *(time_t *)(ptr));
+}
+
+int gen_dump_double(struct parse_string *p, const char *ptr, unsigned indent)
+{
+ return addshort(p, "%lg", *(double *)(ptr));
+}
+
+int gen_dump_float(struct parse_string *p, const char *ptr, unsigned indent)
+{
+ return addshort(p, "%g", *(float *)(ptr));
+}
--- /dev/null
+/*
+ Copyright (C) Andrew Tridgell <genstruct@tridgell.net> 2002
+
+ 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 2 of the License, 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.
+*/
+
+/* these macros are needed for genstruct auto-parsers */
+#ifndef GENSTRUCT
+#define GENSTRUCT
+#define _LEN(x)
+#define _NULLTERM
+#endif
+
+/*
+ automatic marshalling/unmarshalling system for C structures
+*/
+
+enum parse_type {T_INT, T_UNSIGNED, T_CHAR,
+ T_FLOAT, T_DOUBLE, T_ENUM, T_STRUCT,
+ T_TIME_T, T_LONG, T_ULONG};
+
+/* flag to mark a fixed size array as actually being null terminated */
+#define FLAG_NULLTERM 1
+#define FLAG_ALWAYS 2
+
+struct enum_struct {
+ const char *name;
+ unsigned value;
+};
+
+/* intermediate dumps are stored in one of these */
+struct parse_string {
+ unsigned allocated;
+ unsigned length;
+ char *s;
+};
+
+typedef int (*gen_dump_fn)(struct parse_string *, const char *ptr, unsigned indent);
+typedef int (*gen_parse_fn)(char *ptr, const char *str);
+
+/* genstruct.pl generates arrays of these */
+struct parse_struct {
+ const char *name;
+ unsigned ptr_count;
+ unsigned size;
+ unsigned offset;
+ unsigned array_len;
+ const char *dynamic_len;
+ unsigned flags;
+ gen_dump_fn dump_fn;
+ gen_parse_fn parse_fn;
+};
+
+char *gen_dump(const struct parse_struct *pinfo,
+ const char *data,
+ unsigned indent);
+int gen_parse(const struct parse_struct *pinfo, char *data, const char *str0);
+
+int gen_addgen(struct parse_string *p, const char *fmt, ...);
+
+int gen_dump_enum(const struct enum_struct *einfo,
+ struct parse_string *p,
+ const char *ptr,
+ unsigned indent);
+int gen_parse_enum(const struct enum_struct *einfo,
+ char *ptr,
+ const char *str);
+
+int gen_dump_struct(const struct parse_struct *pinfo,
+ struct parse_string *p,
+ const char *ptr,
+ unsigned indent);
+int gen_parse_struct(const struct parse_struct *pinfo,
+ char *ptr,
+ const char *str);
+
+#define DUMP_PARSE_DECL(type) \
+ int gen_dump_ ## type(struct parse_string *, const char *, unsigned); \
+ int gen_parse_ ## type(char *, const char *);
+
+DUMP_PARSE_DECL(char)
+DUMP_PARSE_DECL(int)
+DUMP_PARSE_DECL(unsigned)
+DUMP_PARSE_DECL(double)
+DUMP_PARSE_DECL(float)
+
+#define gen_dump_unsigned_char gen_dump_char
+#define gen_parse_unsigned_char gen_parse_char
--- /dev/null
+#!/usr/bin/perl -w
+# a simple system for generating C parse info
+# this can be used to write generic C structer load/save routines
+# Copyright 2002 Andrew Tridgell <genstruct@tridgell.net>
+# released under the GNU General Public License v2 or later
+
+use strict;
+
+my(%enum_done) = ();
+my(%struct_done) = ();
+
+###################################################
+# general handler
+sub handle_general($$$$$$$$)
+{
+ my($name) = shift;
+ my($ptr_count) = shift;
+ my($size) = shift;
+ my($element) = shift;
+ my($flags) = shift;
+ my($dump_fn) = shift;
+ my($parse_fn) = shift;
+ my($tflags) = shift;
+ my($array_len) = 0;
+ my($dynamic_len) = "NULL";
+
+ # handle arrays, currently treat multidimensional arrays as 1 dimensional
+ while ($element =~ /(.*)\[(.*?)\]$/) {
+ $element = $1;
+ if ($array_len == 0) {
+ $array_len = $2;
+ } else {
+ $array_len = "$2 * $array_len";
+ }
+ }
+
+ if ($flags =~ /_LEN\((\w*?)\)/) {
+ $dynamic_len = "\"$1\"";
+ }
+
+ if ($flags =~ /_NULLTERM/) {
+ $tflags = "FLAG_NULLTERM";
+ }
+
+ print OFILE "{\"$element\", $ptr_count, $size, offsetof(struct $name, $element), $array_len, $dynamic_len, $tflags, $dump_fn, $parse_fn},\n";
+}
+
+
+####################################################
+# parse one element
+sub parse_one($$$$)
+{
+ my($name) = shift;
+ my($type) = shift;
+ my($element) = shift;
+ my($flags) = shift;
+ my($ptr_count) = 0;
+ my($size) = "sizeof($type)";
+ my($tflags) = "0";
+
+ # enums get the FLAG_ALWAYS flag
+ if ($type =~ /^enum /) {
+ $tflags = "FLAG_ALWAYS";
+ }
+
+
+ # make the pointer part of the base type
+ while ($element =~ /^\*(.*)/) {
+ $ptr_count++;
+ $element = $1;
+ }
+
+ # convert spaces to _
+ $type =~ s/ /_/g;
+
+ my($dump_fn) = "gen_dump_$type";
+ my($parse_fn) = "gen_parse_$type";
+
+ handle_general($name, $ptr_count, $size, $element, $flags, $dump_fn, $parse_fn, $tflags);
+}
+
+####################################################
+# parse one element
+sub parse_element($$$)
+{
+ my($name) = shift;
+ my($element) = shift;
+ my($flags) = shift;
+ my($type);
+ my($data);
+
+ # pull the base type
+ if ($element =~ /^struct (\S*) (.*)/) {
+ $type = "struct $1";
+ $data = $2;
+ } elsif ($element =~ /^enum (\S*) (.*)/) {
+ $type = "enum $1";
+ $data = $2;
+ } elsif ($element =~ /^unsigned (\S*) (.*)/) {
+ $type = "unsigned $1";
+ $data = $2;
+ } elsif ($element =~ /^const (\S*) (.*)/) {
+ $type = $1;
+ $data = $2;
+ } elsif ($element =~ /^(\S*) (.*)/) {
+ $type = $1;
+ $data = $2;
+ } else {
+ die "Can't parse element '$element'";
+ }
+
+ # handle comma separated lists
+ while ($data =~ /(\S*),[\s]?(.*)/) {
+ parse_one($name, $type, $1, $flags);
+ $data = $2;
+ }
+ parse_one($name, $type, $data, $flags);
+}
+
+
+my($first_struct) = 1;
+
+####################################################
+# parse the elements of one structure
+sub parse_elements($$)
+{
+ my($name) = shift;
+ my($elements) = shift;
+
+ if ($first_struct) {
+ $first_struct = 0;
+ print "Parsing structs: $name";
+ } else {
+ print ", $name";
+ }
+
+ print OFILE "int gen_dump_struct_$name(struct parse_string *, const char *, unsigned);\n";
+ print OFILE "int gen_parse_struct_$name(char *, const char *);\n";
+
+ print OFILE "static const struct parse_struct pinfo_" . $name . "[] = {\n";
+
+ while ($elements =~ /^.*?([a-z].*?);\s*?(\S*?)\s*?$(.*)/msi) {
+ my($element) = $1;
+ my($flags) = $2;
+ $elements = $3;
+ parse_element($name, $element, $flags);
+ }
+
+ print OFILE "{NULL, 0, 0, 0, 0, NULL, 0, NULL, NULL}};\n";
+
+ print OFILE "
+int gen_dump_struct_$name(struct parse_string *p, const char *ptr, unsigned indent) {
+ return gen_dump_struct(pinfo_$name, p, ptr, indent);
+}
+int gen_parse_struct_$name(char *ptr, const char *str) {
+ return gen_parse_struct(pinfo_$name, ptr, str);
+}
+
+";
+}
+
+my($first_enum) = 1;
+
+####################################################
+# parse out the enum declarations
+sub parse_enum_elements($$)
+{
+ my($name) = shift;
+ my($elements) = shift;
+
+ if ($first_enum) {
+ $first_enum = 0;
+ print "Parsing enums: $name";
+ } else {
+ print ", $name";
+ }
+
+ print OFILE "static const struct enum_struct einfo_" . $name . "[] = {\n";
+
+ my(@enums) = split(/,/s, $elements);
+ for (my($i)=0; $i <= $#{@enums}; $i++) {
+ my($enum) = $enums[$i];
+ if ($enum =~ /\s*(\w*)/) {
+ my($e) = $1;
+ print OFILE "{\"$e\", $e},\n";
+ }
+ }
+
+ print OFILE "{NULL, 0}};\n";
+
+ print OFILE "
+int gen_dump_enum_$name(struct parse_string *p, const char *ptr, unsigned indent) {
+ return gen_dump_enum(einfo_$name, p, ptr, indent);
+}
+
+int gen_parse_enum_$name(char *ptr, const char *str) {
+ return gen_parse_enum(einfo_$name, ptr, str);
+}
+
+";
+}
+
+####################################################
+# parse out the enum declarations
+sub parse_enums($)
+{
+ my($data) = shift;
+
+ while ($data =~ /^GENSTRUCT\s+enum\s+(\w*?)\s*{(.*?)}\s*;(.*)/ms) {
+ my($name) = $1;
+ my($elements) = $2;
+ $data = $3;
+
+ if (!defined($enum_done{$name})) {
+ $enum_done{$name} = 1;
+ parse_enum_elements($name, $elements);
+ }
+ }
+
+ if (! $first_enum) {
+ print "\n";
+ }
+}
+
+####################################################
+# parse all the structures
+sub parse_structs($)
+{
+ my($data) = shift;
+
+ # parse into structures
+ while ($data =~ /^GENSTRUCT\s+struct\s+(\w+?)\s*{\s*(.*?)\s*}\s*;(.*)/ms) {
+ my($name) = $1;
+ my($elements) = $2;
+ $data = $3;
+ if (!defined($struct_done{$name})) {
+ $struct_done{$name} = 1;
+ parse_elements($name, $elements);
+ }
+ }
+
+ if (! $first_struct) {
+ print "\n";
+ } else {
+ print "No GENSTRUCT structures found?\n";
+ }
+}
+
+
+####################################################
+# parse a header file, generating a dumper structure
+sub parse_data($)
+{
+ my($data) = shift;
+
+ # collapse spaces
+ $data =~ s/[\t ]+/ /sg;
+ $data =~ s/\s*\n\s+/\n/sg;
+ # strip debug lines
+ $data =~ s/^\#.*?\n//smg;
+
+ parse_enums($data);
+ parse_structs($data);
+}
+
+
+#########################################
+# display help text
+sub ShowHelp()
+{
+ print "
+generator for C structure dumpers
+Copyright Andrew Tridgell <genstruct\@tridgell.net>
+
+Sample usage:
+ genstruct -o output.h gcc -E -O2 -g test.h
+
+Options:
+ --help this help page
+ -o OUTPUT place output in OUTPUT
+";
+ exit(0);
+}
+
+########################################
+# main program
+if ($ARGV[0] ne "-o" || $#ARGV < 2) {
+ ShowHelp();
+}
+
+shift;
+my($opt_ofile)=shift;
+
+open(OFILE, ">$opt_ofile") || die "can't open $opt_ofile";
+
+print OFILE "/* This is an automatically generated file - DO NOT EDIT! */\n\n";
+
+parse_data(`@ARGV -DGENSTRUCT=GENSTRUCT`);
+exit(0);
--- /dev/null
+/*
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+/*
+ automatic marshalling/unmarshalling system for C structures
+*/
+
+#define EXTERN
+#include "includes.h"
+#include "parsers/parse_info.h"
+
+/* load all the globals */
+void load_all_globals(const char *fname)
+{
+ struct all_globals a;
+ char *s;
+
+ s = file_load(fname, NULL);
+ if (!s) {
+ d_printf("Unable to load globals!\n");
+ return;
+ }
+ memset(&a, 0, sizeof(a));
+ gen_parse(pinfo_all_globals, (char *)&a, s);
+ free(s);
+
+ net_globals = *a.net_globals;
+ game_globals = *a.game_globals;
+ player_globals = *a.player_globals;
+ command_globals = *a.command_globals;
+ gics_globals = *a.gics_globals;
+ timeseal_globals = *a.timeseal_globals;
+
+ FREE(a.net_globals);
+ FREE(a.game_globals);
+ FREE(a.player_globals);
+ FREE(a.command_globals);
+ FREE(a.gics_globals);
+ FREE(a.timeseal_globals);
+}
+
+/* save all the globals */
+void save_all_globals(const char *fname)
+{
+ struct all_globals a, a2;
+ char *s, *s2;
+
+ memset(&a, 0, sizeof(a));
+ a.net_globals = &net_globals;
+ a.game_globals = &game_globals;
+ a.player_globals = &player_globals;
+ a.command_globals = &command_globals;
+ a.gics_globals = &gics_globals;
+ a.timeseal_globals = ×eal_globals;
+
+ s = gen_dump(pinfo_all_globals, (char *)&a, 0);
+ if (!s) {
+ d_printf("Unable to dump globals!\n");
+ return;
+ }
+ file_save(fname, s, strlen(s));
+ memset(&a2, 0, sizeof(a2));
+ gen_parse(pinfo_all_globals, (char *)&a2, s);
+ s2 = gen_dump(pinfo_all_globals, (char *)&a2, 0);
+ if (strcmp(s, s2)) {
+ d_printf("ERROR: globals parse mismatch!\n");
+ file_save("cmp.dat", s2, strlen(s2));
+ }
+ free(s);
+ free(s2);
+}
+
+/*
+ * adump - dump complete server state to globals.dat
+ */
+int com_adump(int p, param_list param)
+{
+ save_all_globals("globals.dat");
+ return COM_OK;
+}
+
+
+/*
+ marshall a player structure
+*/
+const char *marshall_player(const struct player *pp)
+{
+ return gen_dump(pinfo_player, (const char *)pp, 0);
+}
+
+/*
+ unmarshall a player structure
+*/
+int unmarshall_player(struct player *pp, const char *s)
+{
+ return gen_parse(pinfo_player, (char *)pp, s);
+}
+
+
+/*
+ marshall a game structure
+*/
+const char *marshall_game(const struct game *gg)
+{
+ return gen_dump(pinfo_game, (const char *)gg, 0);
+}
+
+/*
+ unmarshall a game structure
+*/
+int unmarshall_game(struct game *gg, const char *s)
+{
+ return gen_parse(pinfo_game, (char *)gg, s);
+}
+
+/*
+ marshall a news structure
+*/
+const char *marshall_news(const struct news *nn)
+{
+ return gen_dump(pinfo_news, (const char *)nn, 0);
+}
+
+/*
+ unmarshall a news structure
+*/
+int unmarshall_news(struct news *nn, const char *s)
+{
+ return gen_parse(pinfo_news, (char *)nn, s);
+}
+
+
+
+/*
+ custom dump/load functions
+*/
+int gen_dump_struct_in_addr(struct parse_string *p, const char *ptr, unsigned indent)
+{
+ return gen_addgen(p, "%s", inet_ntoa(*(struct in_addr *)ptr));
+}
+
+int gen_parse_struct_in_addr(char *ptr, const char *str)
+{
+ struct in_addr *a = (struct in_addr *)ptr;
+ if (inet_aton(str, a) == 0) {
+ /* probably an old style */
+ a->s_addr = atoi(str);
+ }
+ return 0;
+}
--- /dev/null
+/*
+ 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 2 of the License, 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.
+*/
+
+/*
+ pending.c
+
+ Sat Feb 10 - created - DAV
+
+*/
+#include "includes.h"
+
+extern const char *colorstr[];
+
+/* iterator for player p */
+static struct pending* next_pending(struct pending* current)
+{
+
+ if (current == NULL) {
+ d_printf("NULL pointer passed to next_pending\n");
+ return NULL;
+ } else return current->next;
+}
+
+/* deletor for pending - returns next item*/
+struct pending *delete_pending(struct pending *current)
+{
+ struct pending *p;
+
+ if (current == NULL) {
+ d_printf("NULL pointer passed to delete_pending\n");
+ return NULL;
+ }
+
+ player_globals.parray[current->whofrom].number_pend_from--;
+ player_globals.parray[current->whoto].number_pend_to--;
+
+ if (current->category != NULL) {
+ free(current->category);
+ }
+ if (current->board_type != NULL) {
+ free(current->board_type);
+ }
+
+ if (current == seek_globals.pendlist) {
+ seek_globals.pendlist = current->next;
+ free(current);
+ return seek_globals.pendlist;
+ }
+
+ for (p=seek_globals.pendlist; p && p->next != current; p=p->next) ;
+
+ if (!p) {
+ d_printf("current not on pending list??");
+ return NULL;
+ }
+
+ p->next = current->next;
+ free(current);
+ return p->next;
+}
+
+/* kills the whole pending list on shutdown */
+void destruct_pending(void)
+{
+ struct pending* current = seek_globals.pendlist;
+
+ while (current != NULL)
+ current = delete_pending(current);
+}
+
+struct pending *add_pending(int from,int to,int type)
+{
+ struct pending* new = (struct pending*) malloc(sizeof(struct pending));
+
+ new->whofrom = from;
+ new->whoto = to;
+ new->type = type;
+ new->next = seek_globals.pendlist;
+ new->category = NULL;
+ new->board_type = NULL;
+
+ player_globals.parray[from].number_pend_from++;
+ player_globals.parray[to].number_pend_to++;
+
+ seek_globals.pendlist = new;
+
+ return new;
+}
+
+static int check_current_pend(struct pending* current, int p, int p1, int type)
+{
+ if ((p != -1) && ((current->whofrom) != p))
+ return 0;
+ if (current->whoto != p1 && p1 != -1)
+ return 0;
+ if ((type == PEND_ALL) || (current->type == type))
+ return 1;
+ if ((type < 0) && (current->type != -type))
+ return 1;
+/* The above "if" allows a type of -PEND_SIMUL to match every request
+ EXCEPT simuls, for example. I'm doing this because Heringer does
+ not want to decline simul requests when he makes a move in a sumul.
+ -- hersco. */
+
+ return 0;
+}
+
+/* from p to p1 */
+struct pending *find_pend(int p, int p1, int type)
+{
+ struct player *pp = &player_globals.parray[p];
+ /* -ve type can be used to decline all but that type */
+ struct pending* current = seek_globals.pendlist;
+
+ if (((p != -1) && (!pp->number_pend_from)) ||
+ ((p1 != -1) && (!player_globals.parray[p1].number_pend_to)))
+ return NULL;
+
+ while (current != NULL) {
+ if (check_current_pend(current,p,p1, type))
+ return current;
+ current = next_pending(current);
+ }
+ return NULL;
+}
+
+/* from p to p1 */
+struct pending *add_request(int p, int p1, int type)
+{
+ struct player *pp = &player_globals.parray[p];
+ struct pending* new = NULL;
+
+ if ((pp->number_pend_from) &&
+ (player_globals.parray[p1].number_pend_to)) {
+ if ((new = find_pend(p, p1, type)) != NULL)
+ return new; /* Already exists */
+ }
+
+ if ((new = add_pending(p,p1,type)) == NULL)
+ return NULL;
+ return new;
+}
+
+/* removes all requests from p to p1 */
+void remove_request(int p, int p1, int type)
+{
+ struct pending* next;
+ struct pending* current = seek_globals.pendlist;
+
+ while (current != NULL) {
+ next = next_pending(current);
+ if (check_current_pend(current,p,p1,type))
+ delete_pending(current);
+ current = next;
+ }
+}
+
+/* made into 1 functions for speed */
+
+/* decline offers to p and withdraw offers from p */
+static void do_decline_withdraw_offers(int p,int p1, int offers, int partners, int wd)
+{
+ struct player *pp = &player_globals.parray[p];
+ struct pending* offer = seek_globals.pendlist;
+ int type, p2;
+ char *pName = pp->name, *p2Name;
+ int decline;
+
+ if ((wd & DO_DECLINE) && (wd & DO_WITHDRAW)) { /* cut search times */
+ if (((p != -1) && (!pp->number_pend_to)
+ && (!pp->number_pend_from))
+ || ((p1 != -1) && (!player_globals.parray[p1].number_pend_to)
+ && (!player_globals.parray[p1].number_pend_from)))
+ return;
+ }
+
+ if ((wd & DO_DECLINE) && (!(wd & DO_WITHDRAW))) { /* cut search times */
+ if (((p != -1) && (!pp->number_pend_to)) ||
+ ((p1 != -1) && (!player_globals.parray[p1].number_pend_from)))
+ return;
+ }
+
+ if ((!(wd & DO_DECLINE)) && (wd & DO_WITHDRAW)) { /* cut search times */
+ if (((p != -1) && (!pp->number_pend_from)) ||
+ ((p1 != -1) && (!player_globals.parray[p1].number_pend_to)))
+ return;
+ }
+
+ while (offer != NULL) {
+
+ decline = 0;
+ if ((wd & DO_DECLINE) && (check_current_pend(offer, p1, p, offers))) {
+ p2 = offer->whofrom;
+ decline = 1;
+ } else if ((wd & DO_WITHDRAW) && (check_current_pend(offer,p, p1, offers))) {
+ p2 = offer->whoto;
+ } else {
+ offer = offer->next;
+ continue;
+ }
+
+ type = offer->type;
+ p2Name = player_globals.parray[p2].name;
+
+ switch (type) {
+ case PEND_MATCH:
+ if (partners) {
+ if (offer->game_type != TYPE_BUGHOUSE) {
+ offer = offer->next;
+ continue;
+ } else if (decline) {
+ if (offer->whoto == p) {
+ pprintf(p,
+ "Either your opponent's partner or your partner has joined another match.\n");
+ pprintf_prompt(p,
+ "Removing the bughouse offer from %s.\n",
+ p2Name);
+
+ pprintf(p2,
+ "Either your opponent's partner or your partner has joined another match.\n");
+ pprintf_prompt(p2,
+ "Removing the bughouse offer to %s.\n",
+ pName);
+
+ } else {
+ pprintf_prompt(p,
+ "Your partner declines the bughouse offer from %s.\n",
+ p2Name);
+ pprintf_prompt(p2,
+ "%s declines the bughouse offer from your partner.\n",
+ pName);
+ }
+
+ } else {
+ if (offer->whofrom == p) {
+ pprintf(p,
+ "Either your opponent's partner or your partner has joined another match.\n");
+ pprintf_prompt(p,
+ "Removing the bughouse offer to %s.\n",
+ p2Name);
+
+ pprintf(p2,
+ "Either your opponent's partner or your partner has joined another match.\n");
+ pprintf_prompt(p2,
+ "Removing the bughouse offer from %s.\n",
+ pName);
+
+ } else {
+ pprintf_prompt(p,
+ "Your partner withdraws the bughouse offer to %s.\n",
+ p2Name);
+ pprintf_prompt(p2,
+ "%s withdraws the bughouse offer to your partner.\n",
+ pName);
+ }
+ }
+ } else {
+
+ if (decline) {
+ pprintf_prompt(p2, "\n%s declines the match offer.\n", pName);
+ pprintf(p, "You decline the match offer from %s.\n", p2Name);
+ } else {
+ pprintf_prompt(p2, "\n%s withdraws the match offer.\n", pName);
+ pprintf(p, "You withdraw the match offer to %s.\n", p2Name);
+ }
+ }
+ break;
+ case PEND_DRAW:
+ if (decline) {
+ pprintf_prompt(p2, "\n%s declines draw request.\n", pName);
+ pprintf(p, "You decline the draw request from %s.\n", p2Name);
+ } else {
+ pprintf_prompt(p2, "\n%s withdraws draw request.\n", pName);
+ pprintf(p, "You withdraw the draw request to %s.\n", p2Name);
+ }
+ break;
+
+ case PEND_PAUSE:
+ if (decline) {
+ pprintf_prompt(p2, "\n%s declines pause request.\n", pName);
+ pprintf(p, "You decline the pause request from %s.\n", p2Name);
+ } else {
+ pprintf_prompt(p2, "\n%s withdraws pause request.\n", pName);
+ pprintf(p, "You withdraw the pause request to %s.\n", p2Name);
+ }
+ break;
+
+ case PEND_UNPAUSE:
+ if (decline) {
+ pprintf_prompt(p2, "\n%s declines unpause request.\n", pName);
+ pprintf(p, "You decline the unpause request from %s.\n", p2Name);
+ } else {
+ pprintf_prompt(p2, "\n%s withdraws unpause request.\n", pName);
+ pprintf(p, "You withdraw the unpause request to %s.\n", p2Name);
+ }
+ break;
+
+ case PEND_ABORT:
+ if (decline) {
+ pprintf_prompt(p2, "\n%s declines abort request.\n", pName);
+ pprintf(p, "You decline the abort request from %s.\n", p2Name);
+ } else {
+ pprintf_prompt(p2, "\n%s withdraws abort request.\n", pName);
+ pprintf(p, "You withdraw the abort request to %s.\n", p2Name);
+ }
+ break;
+
+ case PEND_TAKEBACK:
+ if (decline) {
+ pprintf_prompt(p2, "\n%s declines the takeback request.\n", pName);
+ pprintf(p, "You decline the takeback request from %s.\n", p2Name);
+ } else {
+ pprintf_prompt(p2, "\n%s withdraws the takeback request.\n", pName);
+ pprintf(p, "You withdraw the takeback request to %s.\n", p2Name);
+ }
+ break;
+
+ case PEND_ADJOURN:
+ if (decline) {
+ pprintf_prompt(p2, "\n%s declines the adjourn request.\n", pName);
+ pprintf(p, "You decline the adjourn request from %s.\n", p2Name);
+ } else {
+ pprintf_prompt(p2, "\n%s withdraws the adjourn request.\n", pName);
+ pprintf(p, "You withdraw the adjourn request to %s.\n", p2Name);
+ }
+ break;
+
+ case PEND_SWITCH:
+ if (decline) {
+ pprintf_prompt(p2, "\n%s declines the switch sides request.\n", pName);
+ pprintf(p, "You decline the switch sides request from %s.\n", p2Name);
+ } else {
+ pprintf_prompt(p2, "\n%s withdraws the switch sides request.\n", pName);
+ pprintf(p, "You withdraw the switch sides request to %s.\n", p2Name);
+ }
+ break;
+
+ case PEND_SIMUL:
+ if (decline) {
+ pprintf_prompt(p2, "\n%s declines the simul offer.\n", pName);
+ pprintf(p, "You decline the simul offer from %s.\n", p2Name);
+ } else {
+ pprintf_prompt(p2, "\n%s withdraws the simul offer.\n", pName);
+ pprintf(p, "You withdraw the simul offer to %s.\n", p2Name);
+ }
+ break;
+
+ case PEND_PARTNER:
+ if (decline) {
+ pprintf_prompt(p2, "\n%s declines your partnership request.\n", pName);
+ pprintf(p, "You decline the partnership request from %s.\n", p2Name);
+ } else {
+ pprintf_prompt(p2, "\n%s withdraws partnership request.\n", pName);
+ pprintf(p, "You withdraw the partnership request to %s.\n", p2Name);
+ }
+ break;
+ }
+ offer = delete_pending(offer);
+ }
+}
+
+/* wd is DO_DECLINE to decline DO_WITHDRAW to withdraw and both for mutual */
+void decline_withdraw_offers(int p, int p1, int offerType,int wd)
+{
+ struct player *pp = &player_globals.parray[p];
+ /* First get rid of bughouse offers from partner. */
+ /* last param in if is a safety check - shouldn't happen */
+
+ int partner;
+
+ if (p1 == -1)
+ partner = -1;
+ else
+ partner = player_globals.parray[p1].partner;
+
+ if ((offerType == PEND_MATCH || offerType == PEND_ALL)
+ && pp->partner >= 0 && player_globals.parray[pp->partner].partner == p)
+ do_decline_withdraw_offers(pp->partner, partner , PEND_MATCH,1,wd);
+
+
+ do_decline_withdraw_offers(p, p1, offerType,0,wd);
+}
+
+/* find nth offer from p */
+static struct pending* find_nth_pendfrom(int p,int num)
+{
+ struct pending* current = seek_globals.pendlist;
+
+ while (num) {
+ if (check_current_pend(current,p,-1,PEND_ALL))
+ num--;
+ if (num > 0)
+ current = next_pending(current);
+ }
+ return current;
+}
+
+/* find nth offer to p */
+static struct pending* find_nth_pendto(int p,int num)
+{
+ struct pending* current = seek_globals.pendlist;
+
+ while (num) {
+ if (check_current_pend(current,-1,p,PEND_ALL))
+ num--;
+ if (num > 0)
+ current = next_pending(current);
+ }
+ return current;
+}
+
+static int WordToOffer (int p, char *Word, int *type, int *p1)
+{
+ /* Convert draw adjourn match takeback abort pause
+ simmatch switch partner or <name> to offer type. */
+ *p1 = -1;
+ if (!strcmp(Word, "match")) {
+ *type = PEND_MATCH;
+ } else if (!strcmp(Word, "draw")) {
+ *type = PEND_DRAW;
+ } else if (!strcmp(Word, "pause")) {
+ *type = PEND_PAUSE;
+ } else if (!strcmp(Word, "unpause")) {
+ *type = PEND_UNPAUSE;
+ } else if (!strcmp(Word, "abort")) {
+ *type = PEND_ABORT;
+ } else if (!strcmp(Word, "takeback")) {
+ *type = PEND_TAKEBACK;
+ } else if (!strcmp(Word, "adjourn")) {
+ *type = PEND_ADJOURN;
+ } else if (!strcmp(Word, "switch")) {
+ *type = PEND_SWITCH;
+ } else if (!strcmp(Word, "simul")) {
+ *type = PEND_SIMUL;
+ } else if (!strcmp(Word, "partner")) {
+ *type = PEND_PARTNER;
+ } else if (!strcmp(Word, "all")) {
+ } else {
+ *p1 = player_find_part_login(Word);
+ if (*p1 < 0) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", Word);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+int com_accept(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int type = -1;
+ int p1;
+ int number;
+ struct pending* current = NULL;
+
+ if (!(number = pp->number_pend_to)) {
+ pprintf(p, "You have no offers to accept.\n");
+ return COM_OK;
+ }
+
+ if (param[0].type == TYPE_NULL) {
+ if (number != 1) {
+ pprintf(p, "You have more than one offer to accept.\nUse \"pending\" to see them and \"accept n\" to choose which one.\n");
+ return COM_OK;
+ }
+ current = find_pend(-1,p,PEND_ALL);
+
+ } else if (param[0].type == TYPE_INT) {
+ if ((param[0].val.integer < 1) || (param[0].val.integer > number)) {
+ pprintf(p, "Out of range. Use \"pending\" to see the list of offers.\n");
+ return COM_OK;
+ }
+
+ current = find_nth_pendto(p,param[0].val.integer);
+
+ } else if (param[0].type == TYPE_WORD) {
+ if (!WordToOffer (p,param[0].val.word,&type,&p1))
+ return COM_OK;
+ if ((p1 < 0) && ((current = find_pend(-1, p, type)) == NULL)) {
+ pprintf(p, "There are no pending %s offers.\n", param[0].val.word);
+ return COM_OK;
+ } else if ((p1 >= 0) && (current = find_pend(p1, p, PEND_ALL)) == NULL) {
+ pprintf(p, "There are no pending offers from %s.\n", player_globals.parray[p1].name);
+ return COM_OK;
+ }
+ }
+
+ switch (current->type) {
+ case PEND_MATCH:
+ accept_match(current, p, current->whofrom);
+ return (COM_OK);
+ break;
+ case PEND_DRAW:
+ pcommand(p, "draw");
+ break;
+ case PEND_PAUSE:
+ pcommand(p, "pause");
+ break;
+ case PEND_UNPAUSE:
+ pcommand(p, "unpause");
+ break;
+ case PEND_ABORT:
+ pcommand(p, "abort");
+ break;
+ case PEND_TAKEBACK:
+ pcommand(p, "takeback %d", current->wtime);
+ break;
+ case PEND_SIMUL:
+ pcommand(p, "simmatch %s", player_globals.parray[current->whofrom].name);
+ break;
+ case PEND_SWITCH:
+ pcommand(p, "switch");
+ break;
+ case PEND_ADJOURN:
+ pcommand(p, "adjourn");
+ break;
+ case PEND_PARTNER:
+ pcommand(p, "partner %s", player_globals.parray[current->whofrom].name);
+ break;
+ }
+ return COM_OK_NOPROMPT;
+}
+
+static int com_decline_withdraw(int p, param_list param,int wd)
+{
+ struct player *pp = &player_globals.parray[p];
+ int type = -1;
+ int p1;
+ int number;
+ struct pending* current = seek_globals.pendlist;
+
+ if (wd & DO_DECLINE) {
+ if (!(number = pp->number_pend_to)) {
+ pprintf(p, "You have no pending offers from other players.\n");
+ return COM_OK;
+ }
+ } else {
+ if (!(number = pp->number_pend_from)) {
+ pprintf(p, "You have no pending offers to other players.\n");
+ return COM_OK;
+ }
+ }
+
+
+ if (param[0].type == TYPE_NULL) {
+ if (number == 1) {
+ if (wd & DO_DECLINE) {
+ current = find_pend(-1,p,PEND_ALL);
+ p1 = current->whofrom;
+ } else {
+ current = find_pend(p,-1,PEND_ALL);
+ p1 = current->whoto;
+ }
+ type = current->type;
+ } else {
+ if (wd & DO_DECLINE)
+ pprintf(p, "You have more than one pending offer.\nUse \"pending\" to see them and \"decline n\" to choose which one.\n");
+ else
+ pprintf(p, "You have more than one pending offer.\nUse \"pending\" to see them and \"withdraw n\" to choose which one.\n");
+ return COM_OK;
+ }
+
+ } else if (param[0].type == TYPE_INT) {
+ if ((param[0].val.integer < 1) || (param[0].val.integer > number)) {
+ pprintf(p, "Out of range. Use \"pending\" to see the list of offers.\n");
+ return COM_OK;
+ }
+ if (wd & DO_DECLINE) {
+ current = find_nth_pendto(p,param[0].val.integer);
+ p1 = current->whofrom;
+ } else {
+ current = find_nth_pendfrom(p,param[0].val.integer);
+ p1 = current->whoto;
+ }
+ type = current->type;
+
+ } else if (!WordToOffer (p, param[0].val.word, &type, &p1))
+ return COM_OK;
+
+ decline_withdraw_offers(p, p1, type,wd);
+ return COM_OK;
+}
+
+int com_decline(int p, param_list param)
+{
+ return com_decline_withdraw(p,param,DO_DECLINE);
+}
+
+int com_withdraw(int p, param_list param)
+{
+ return com_decline_withdraw(p,param,DO_WITHDRAW);
+}
+
+static void pend_print(int p, struct pending *pend)
+{
+
+ if (p == pend->whofrom) {
+ pprintf(p, "You are offering %s ", player_globals.parray[pend->whoto].name);
+ } else {
+ pprintf(p, "%s is offering ", player_globals.parray[pend->whofrom].name);
+ }
+
+ switch (pend->type) {
+ case PEND_MATCH:
+ pprintf(p, "a challenge: %s (%s) %s%s (%s) %s.\n",
+ player_globals.parray[pend->whofrom].name,
+ ratstrii(GetRating(&player_globals.parray[pend->whofrom], pend->game_type),
+ pend->whofrom),
+ colorstr[pend->seek_color + 1],
+ player_globals.parray[pend->whoto].name,
+ ratstrii(GetRating(&player_globals.parray[pend->whoto], pend->game_type),
+ pend->whoto),
+ game_str(pend->rated, pend->wtime * 60, pend->winc,
+ pend->btime * 60, pend->binc, pend->category, pend->board_type));
+ break;
+ case PEND_DRAW:
+ pprintf(p, "a draw.\n");
+ break;
+ case PEND_PAUSE:
+ pprintf(p, "to pause the clock.\n");
+ break;
+ case PEND_UNPAUSE:
+ pprintf(p, "to unpause the clock.\n");
+ break;
+ case PEND_ABORT:
+ pprintf(p, "to abort the game.\n");
+ break;
+ case PEND_TAKEBACK:
+ pprintf(p, "to takeback the last %d half moves.\n", pend->wtime);
+ break;
+ case PEND_SIMUL:
+ pprintf(p, "to play a simul match.\n");
+ break;
+ case PEND_SWITCH:
+ pprintf(p, "to switch sides.\n");
+ break;
+ case PEND_ADJOURN:
+ pprintf(p, "an adjournment.\n");
+ break;
+ case PEND_PARTNER:
+ pprintf(p, "to be bughouse partners.\n");
+ break;
+ }
+}
+
+int com_pending(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ struct pending* current = seek_globals.pendlist;
+ int num = 0;
+ int num2 = 0;
+ int total = 0;
+
+ if ((total = pp->number_pend_from)) {
+ while ((current != NULL) && (num != total)) {
+ if (check_current_pend(current,p,-1,PEND_ALL)) {
+ if (!num)
+ pprintf(p, "Offers TO other players:\n");
+ num++;
+ pprintf(p, " %d: ",num);
+ pend_print(p, current);
+ }
+ current = next_pending(current);
+ }
+ pprintf(p, "\nIf you wish to withdraw any of these offers type 'withdraw n'\nor just 'withdraw' if there is only one offer.\n\n");
+ } else
+ pprintf(p, "There are no offers pending TO other players.\n\n");
+
+ current = seek_globals.pendlist;
+
+ if ((total = pp->number_pend_to)) {
+ while ((current != NULL) && (num2 != total)) {
+ if (check_current_pend(current,-1,p,PEND_ALL)) {
+ if (!num2)
+ pprintf(p, "Offers FROM other players:\n");
+ num2++;
+ pprintf(p, " %d: ",num2);
+ pend_print(p, current);
+ }
+ current = next_pending(current);
+ }
+ pprintf(p, "\nIf you wish to accept any of these offers type 'accept n'\nor just 'accept' if there is only one offer.\n");
+ } else
+ pprintf(p, "There are no offers pending FROM other players.\n");
+
+ return COM_OK;
+}
+
+void pend_join_match (int p, int p1)
+{
+ struct player *pp = &player_globals.parray[p];
+ struct pending* current;
+ struct pending* next = seek_globals.pendlist;
+
+ if ((pp->number_pend_from == 0) && (pp->number_pend_to == 0)
+ && (player_globals.parray[p1].number_pend_from == 0) && (player_globals.parray[p1].number_pend_to == 0))
+ return;
+
+ while (next != NULL) {
+ current = next;
+ next = next_pending(current);
+ if (check_current_pend(current,p,-1,-PEND_PARTNER)) {
+ pprintf_prompt(current->whoto, "\n%s, who was challenging you, has joined a match with %s.\n", pp->name, player_globals.parray[p1].name);
+ pprintf(p, "Challenge to %s withdrawn.\n", player_globals.parray[current->whoto].name);
+ delete_pending(current);
+ continue;
+ }
+
+ if (check_current_pend(current,p1,-1,-PEND_PARTNER)) {
+ pprintf_prompt(current->whoto, "\n%s, who was challenging you, has joined a match with %s.\n", player_globals.parray[p1].name, pp->name);
+ pprintf(p1, "Challenge to %s withdrawn.\n", player_globals.parray[current->whoto].name);
+ delete_pending(current);
+ continue;
+ }
+
+ if (check_current_pend(current,-1,p,-PEND_PARTNER)) {
+ pprintf_prompt(current->whofrom, "\n%s, whom you were challenging, has joined a match with %s.\n", pp->name, player_globals.parray[p1].name);
+ pprintf(p, "Challenge from %s removed.\n", player_globals.parray[current->whofrom].name);
+ delete_pending(current);
+ continue;
+ }
+
+ if (check_current_pend(current,-1,p1,-PEND_PARTNER)) {
+ pprintf_prompt(current->whofrom, "\n%s, whom you were challenging, has joined a match with %s.\n", player_globals.parray[p1].name, pp->name);
+ pprintf(p1, "Challenge from %s removed.\n",
+ player_globals.parray[current->whofrom].name);
+ delete_pending(current);
+ continue;
+ }
+ }
+}
--- /dev/null
+/*
+ pending.h
+
+*/
+
+#ifndef _PENDING_H
+#define _PENDING_H
+
+#define PEND_MATCH 0
+#define PEND_DRAW 1
+#define PEND_ABORT 2
+#define PEND_TAKEBACK 3
+#define PEND_ADJOURN 4
+#define PEND_SWITCH 5
+#define PEND_SIMUL 6
+#define PEND_PAUSE 7
+#define PEND_PARTNER 8
+#define PEND_BUGHOUSE 9
+#define PEND_UNPAUSE 10
+#define PEND_ALL -1
+
+#define DO_DECLINE 0x01
+#define DO_WITHDRAW 0x02
+
+GENSTRUCT enum rated {UNRATED=0, RATED=1};
+
+GENSTRUCT struct pending {/*Params 1=wt 2=winc 3=bt 4=binc 5=rated 6=white*/
+ int type; /* 7=type */
+ int whoto; /* who is offered */
+ int whofrom; /* who offered it */
+ int wtime;
+ int winc;
+ int btime;
+ int binc;
+ enum rated rated;
+ int seek_color; /* for matches */
+ enum gametype game_type;
+ int status; /* for seek/sought */
+ char *category;
+ char *board_type;
+ struct pending *next;
+};
+
+#endif
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+#include "includes.h"
+
+static int player_zero(int p);
+
+static int get_empty_slot(void)
+{
+ int i;
+
+ for (i = 0; i < player_globals.p_num; i++) {
+ if (player_globals.parray[i].status == PLAYER_EMPTY)
+ return i;
+ }
+
+ if (i < player_globals.parray_size) {
+ player_globals.p_num++;
+ ZERO_STRUCT(player_globals.parray[i]);
+ player_globals.parray[i].status = PLAYER_EMPTY;
+ return i;
+ }
+
+ if (player_globals.parray_size >= config_get_int("MAX_PLAYERS", DEFAULT_MAX_PLAYER)) {
+ d_printf("Too many players connected!\n");
+ return -1;
+ }
+
+ player_globals.parray_size += 100;
+ player_globals.parray = (struct player *)realloc(player_globals.parray,
+ player_globals.parray_size * sizeof(struct player));
+
+ player_globals.p_num++;
+ ZERO_STRUCT(player_globals.parray[i]);
+ player_globals.parray[i].status = PLAYER_EMPTY;
+ return i;
+}
+
+int player_new(void)
+{
+ int new = get_empty_slot();
+
+ player_zero(new);
+ return new;
+}
+
+static void ResetStats(struct statistics *ss)
+{
+ ss->num = 0;
+ ss->win = 0;
+ ss->los = 0;
+ ss->dra = 0;
+ ss->rating = config_get_int("DEFAULT_RATING", DEFAULT_RATING);
+ ss->sterr = config_get_int("DEFAULT_RD", DEFAULT_RD);
+ ss->ltime = 0;
+ ss->best = 0;
+ ss->whenbest = 0;
+}
+
+static int player_zero(int p)
+{
+ struct player *pp = &player_globals.parray[p];
+
+ ZERO_STRUCTP(pp);
+
+ pp->prompt = config_get("DEFAULT_PROMPT");
+ pp->partner = -1;
+ pp->socket = -1;
+ pp->status = PLAYER_NEW;
+
+ ResetStats(&pp->s_stats);
+ ResetStats(&pp->b_stats);
+ ResetStats(&pp->l_stats);
+ ResetStats(&pp->w_stats);
+ ResetStats(&pp->bug_stats);
+
+ pp->d_time = config_get_int("DEFAULT_TIME", DEFAULT_TIME);
+ pp->d_inc = config_get_int("DEFAULT_INCREMENT", DEFAULT_INCREMENT);
+ pp->d_height = 24;
+ pp->d_width = 79;
+ pp->language = LANG_DEFAULT;
+ pp->promote = QUEEN;
+ pp->game = -1;
+ pp->last_channel = -1;
+ pp->ftell = -1;
+ pp->Flags = PFLAG_DEFAULT;
+ pp->opponent = -1;
+ return 0;
+}
+
+void player_free(struct player *pp)
+{
+ int i;
+
+ FREE(pp->login);
+ FREE(pp->more_text);
+ FREE(pp->name);
+ FREE(pp->passwd);
+ FREE(pp->fullName);
+ FREE(pp->emailAddress);
+ FREE(pp->prompt);
+ FREE(pp->formula);
+ FREE(pp->busy);
+ FREE(pp->last_tell);
+ FREE(pp->last_opponent);
+ FREE(pp->simul_info);
+ for (i = 0; i < pp->num_plan; i++)
+ FREE(pp->planLines[i]);
+ for (i = 0; i < pp->num_formula; i++)
+ FREE(pp->formulaLines[i]);
+ list_free(pp->lists);
+ for (i = 0; i < pp->numAlias; i++) {
+ FREE(pp->alias_list[i].comm_name);
+ FREE(pp->alias_list[i].alias);
+ }
+}
+
+int player_clear(int p)
+{
+ player_free(&player_globals.parray[p]);
+ player_zero(p);
+ return 0;
+}
+
+int player_remove(int p)
+{
+ struct player *pp = &player_globals.parray[p];
+ int i;
+
+ decline_withdraw_offers(p, -1, -1, DO_DECLINE | DO_WITHDRAW);
+ if (pp->simul_info != NULL)
+ /* Player disconnected in middle of simul */
+ for (i = 0; pp->simul_info != NULL
+ && i < pp->simul_info->numBoards; i++)
+ if (pp->simul_info->boards[i] >= 0)
+ game_disconnect(pp->simul_info->boards[i], p);
+
+ if ((pp->game >=0) && (pIsPlaying(p))) {
+ /* Player disconnected in the middle of a game! */
+ pprintf(pp->opponent, "Your opponent has lost contact or quit.");
+ game_disconnect(pp->game, p);
+ }
+ for (i = 0; i < player_globals.p_num; i++) {
+ if (player_globals.parray[i].status == PLAYER_EMPTY)
+ continue;
+ if (player_globals.parray[i].partner == p) {
+ pprintf_prompt (i, "Your partner has disconnected.\n");
+ decline_withdraw_offers(i, -1, PEND_BUGHOUSE, DO_DECLINE | DO_WITHDRAW);
+ player_globals.parray[i].partner = -1;
+ }
+ }
+ player_clear(p);
+ pp->status = PLAYER_EMPTY;
+
+ return 0;
+}
+
+/*
+ write a player file using the new generic marshalling format
+*/
+static int WritePlayerFile_v100(int p)
+{
+ struct player pp = player_globals.parray[p];
+ const char *s;
+ FILE *fp;
+
+ /* zero any elements we don't want to save */
+ memset(&pp, 0, offsetof(struct player, not_saved_marker));
+
+ /* marshall it into a string */
+ s = marshall_player(&pp);
+ if (!s) {
+ d_printf("Unable to marshall player structure for %s\n",
+ pp.name);
+ return -1;
+ }
+
+ fp = fopen_p("%s/%c/%s", "w",
+ PLAYER_DIR,
+ player_globals.parray[p].login[0],
+ player_globals.parray[p].login);
+ if (!fp) {
+ d_printf("CHESSD: Problem opening player file '%s' for write\n",
+ player_globals.parray[p].login);
+ free(s);
+ return -1;
+ }
+
+ /* and save it */
+ fprintf(fp, "v 100\n%s\n", s);
+ free(s);
+ fclose(fp);
+ return 0;
+}
+
+/*
+ read a player file using the new generic and extensible format
+*/
+static int ReadPlayerFile_v100(FILE *fp, int p)
+{
+ char *s, *s2;
+ struct player *pp = &player_globals.parray[p];
+
+ s = fd_load(fileno(fp), NULL);
+ if (!s) {
+ d_printf("Error reading player file for '%s'\n", pp->login);
+ return -1;
+ }
+
+ /* skip first line */
+ s2 = strchr(s, '\n');
+
+ /* the marshaller doesn't save zero elements, but some elements don't
+ default to zero. Make sure they get the right value */
+ memset(&pp->not_saved_marker, 0,
+ sizeof(struct player) - offsetof(struct player, not_saved_marker));
+
+ if (!s2 || unmarshall_player(pp, s2) != 0) {
+ d_printf("Error unmarshalling player data for '%s'!\n", pp->login);
+ free(s);
+ return -1;
+ }
+ free(s);
+
+ lists_validate(p);
+
+ return 0;
+}
+
+int player_read(int p, char *name)
+{
+ struct player *pp = &player_globals.parray[p];
+ char fname[MAX_FILENAME_SIZE];
+ char line[MAX_LINE_SIZE];
+ FILE *fp;
+ int version = 0;
+ int ret;
+
+ pp->login = stolower(strdup(name));
+
+ sprintf(fname, "%s/%c/%s", PLAYER_DIR, pp->login[0], pp->login);
+ fp = fopen_s(fname, "r");
+
+ if (pp->name)
+ free(pp->name);
+
+ if (!fp) { /* unregistered player */
+ pp->name = stolower(strdup(name));
+ PFlagOFF(p, PFLAG_REG);
+ return -1;
+ }
+
+ PFlagON(p, PFLAG_REG); /* lets load the file */
+ fgets(line, MAX_LINE_SIZE, fp); /* ok so which version file? */
+
+ if (line[0] == 'v') {
+ sscanf(line, "%*c %d", &version);
+ }
+
+ if (version == 9 || version == 100) {
+ /* its the new style */
+ ret = ReadPlayerFile_v100(fp, p);
+ } else {
+ /* fall back to the old style */
+ ret = player_read_old(p, fp, name, fname, version);
+ player_save(p); /* update to the new generic format */
+ }
+
+ fclose(fp);
+
+ return ret;
+}
+
+int player_save(int p)
+{
+ struct player *pp = &player_globals.parray[p];
+
+ if (!CheckPFlag(p, PFLAG_REG)) { /* Player not registered */
+ return -1;
+ }
+ if (pp->name == NULL) { /* fixes a bug if name is null */
+ pprintf(p, "WARNING: Your player file could not be updated, due to corrupt data.\n");
+ return -1;
+ }
+ if (strcasecmp(pp->login, pp->name)) {
+ pprintf(p, "WARNING: Your player file could not be updated, due to corrupt data.\n");
+ return -1;
+ }
+
+ return WritePlayerFile_v100(p);
+}
+
+int player_find(int fd)
+{
+ int i;
+
+ for (i = 0; i < player_globals.p_num; i++) {
+ if (player_globals.parray[i].status == PLAYER_EMPTY)
+ continue;
+ if (player_globals.parray[i].socket == fd)
+ return i;
+ }
+ return -1;
+}
+
+/* incorrectly named */
+int player_find_bylogin(const char *name)
+{
+ int i;
+
+ for (i = 0; i < player_globals.p_num; i++) {
+ if ((player_globals.parray[i].status == PLAYER_EMPTY) ||
+ (player_globals.parray[i].status == PLAYER_LOGIN) ||
+ (player_globals.parray[i].status == PLAYER_PASSWORD))
+ continue;
+ if (!player_globals.parray[i].login)
+ continue;
+ if (!strcasecmp(player_globals.parray[i].name, name))
+ return i;
+ }
+ return -1;
+}
+
+/* Now incorrectly named */
+int player_find_part_login(const char *name)
+{
+ int i;
+ int found = -1;
+
+ i = player_find_bylogin(name);
+ if (i >= 0)
+ return i;
+ for (i = 0; i < player_globals.p_num; i++) {
+ if ((player_globals.parray[i].status == PLAYER_EMPTY) ||
+ (player_globals.parray[i].status == PLAYER_LOGIN) ||
+ (player_globals.parray[i].status == PLAYER_PASSWORD))
+ continue;
+ if (!player_globals.parray[i].name)
+ continue;
+ if (!strncasecmp(player_globals.parray[i].name, name, strlen(name))) {
+ found = i;
+ break;
+ }
+ }
+
+ if(found < 0)
+ return -1;
+ else
+ return found;
+}
+
+int player_censored(int p, int p1)
+{
+ if (in_list(p, L_CENSOR, player_globals.parray[p1].login))
+ return 1;
+ else
+ return 0;
+}
+
+/* is p1 on p's notify list? */
+int player_notified(int p, int p1)
+{
+ struct player *pp = &player_globals.parray[p];
+ if (!CheckPFlag(p1, PFLAG_REG))
+ return 0;
+
+ /* possible bug: p has just arrived! */
+ if (!pp->name)
+ return 0;
+
+ return (in_list(p, L_NOTIFY, player_globals.parray[p1].login));
+}
+
+void player_notify_departure(int p)
+/* Notify those with notifiedby set on a departure */
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1;
+
+ if (!CheckPFlag(p, PFLAG_REG))
+ return;
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (CheckPFlag(p1, PFLAG_NOTIFYBY) && !player_notified(p1, p)
+ && player_notified(p, p1) && (player_globals.parray[p1].status == PLAYER_PROMPT)) {
+ Bell (p1);
+ pprintf(p1, "\nNotification: ");
+ pprintf_highlight(p1, "%s", pp->name);
+ pprintf_prompt(p1, " has departed and isn't on your notify list.\n");
+ }
+ }
+}
+
+int player_notify_present(int p)
+/* output Your arrival was notified by..... */
+/* also notify those with notifiedby set if necessary */
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1;
+ int count = 0;
+
+ if (!CheckPFlag(p, PFLAG_REG))
+ return count;
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if ((player_notified(p, p1)) && (player_globals.parray[p1].status == PLAYER_PROMPT)) {
+ if (!count) {
+ pprintf(p, "Present company includes:");
+ }
+ count++;
+ pprintf(p, " %s", player_globals.parray[p1].name);
+ if (CheckPFlag(p1, PFLAG_NOTIFYBY) && (!player_notified(p1, p))
+ && (player_globals.parray[p1].status == PLAYER_PROMPT)) {
+ Bell (p1);
+ pprintf(p1, "\nNotification: ");
+ pprintf_highlight(p1, "%s", pp->name);
+ pprintf_prompt(p1, " has arrived and isn't on your notify list.\n");
+ }
+ }
+ }
+ if (count)
+ pprintf(p, ".\n");
+ return count;
+}
+
+int player_notify(int p, char *note1, char *note2)
+/* notify those interested that p has arrived/departed */
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1, count = 0;
+
+ if (!CheckPFlag(p, PFLAG_REG))
+ return count;
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if ((player_notified(p1, p)) && (player_globals.parray[p1].status == PLAYER_PROMPT)) {
+ Bell (p1);
+ pprintf(p1, "\nNotification: ");
+ pprintf_highlight(p1, "%s", pp->name);
+ pprintf_prompt(p1, " has %s.\n", note1);
+ if (!count) {
+ pprintf(p, "Your %s was noted by:", note2);
+ }
+ count++;
+ pprintf(p, " %s", player_globals.parray[p1].name);
+ }
+ }
+ if (count)
+ pprintf(p, ".\n");
+ return count;
+}
+
+int showstored(int p)
+{
+ struct player *pp = &player_globals.parray[p];
+ DIR *dirp;
+ struct dirent *dp;
+
+ int c=0,p1;
+ char dname[MAX_FILENAME_SIZE];
+ multicol *m = multicol_start(50); /* Limit to 50, should be enough*/
+
+ sprintf(dname, "%s/%c", ADJOURNED_DIR, pp->login[0]);
+ dirp = opendir(dname);
+ if (!dirp) {
+ multicol_end(m);
+ return COM_OK;
+ }
+ for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
+ if (file_has_pname(dp->d_name, pp->login)) {
+ if (strcmp(file_wplayer(dp->d_name),pp->login) != 0) {
+ p1=player_find_bylogin(file_wplayer(dp->d_name));
+ } else {
+ p1=player_find_bylogin(file_bplayer(dp->d_name));
+ }
+ if (p1>=0) {
+ if (c<50)
+ multicol_store(m,player_globals.parray[p1].name);
+ pprintf(p1,"\nNotification: ");
+ pprintf_highlight(p1,"%s",pp->name);
+ pprintf_prompt(p1,", who has an adjourned game with you, has arrived.\n");
+ c++;
+ }
+ }
+ }
+ closedir(dirp);
+ if (c == 1) {
+ pprintf(p, "1 player, who has an adjourned game with you, is online:\007");
+ } else if (c > 1) {
+ pprintf(p, "\n%d players, who have an adjourned game with you, are online:\007",c);
+ }
+ if (c != 0)
+ multicol_pprint(m,p,pp->d_width,2);
+ multicol_end(m);
+
+ return COM_OK;
+}
+
+int player_count(int CountAdmins)
+{
+ int count;
+ int i;
+
+ for (count = 0, i = 0; i < player_globals.p_num; i++) {
+ if ((player_globals.parray[i].status == PLAYER_PROMPT) &&
+ (CountAdmins || !in_list(i, L_ADMIN, player_globals.parray[i].name)))
+ count++;
+ }
+ if (count > command_globals.player_high)
+ command_globals.player_high = count;
+
+ return count;
+}
+
+int player_idle(int p)
+{
+ struct player *pp = &player_globals.parray[p];
+ if (pp->status != PLAYER_PROMPT)
+ return time(0) - pp->logon_time;
+ else
+ return time(0) - pp->last_command_time;
+}
+
+int player_ontime(int p)
+{
+ struct player *pp = &player_globals.parray[p];
+ return time(0) - pp->logon_time;
+}
+
+static void write_p_inout(int inout, int p, char *file, int maxlines)
+{
+ struct player *pp = &player_globals.parray[p];
+ FILE *fp;
+
+ fp = fopen_s(file, "a");
+ if (!fp)
+ return;
+ fprintf(fp, "%d %s %d %d %s\n", inout, pp->name, (int) time(0),
+ BoolCheckPFlag(p, PFLAG_REG),
+ dotQuad(pp->thisHost));
+ fclose(fp);
+ if (maxlines)
+ truncate_file(file, maxlines);
+}
+
+void player_write_login(int p)
+{
+ struct player *pp = &player_globals.parray[p];
+ char fname[MAX_FILENAME_SIZE];
+
+ if (CheckPFlag(p, PFLAG_REG)) {
+ sprintf(fname, "%s/player_data/%c/%s.%s", STATS_DIR, pp->login[0], pp->login, STATS_LOGONS);
+ write_p_inout(P_LOGIN, p, fname, 8);
+ }
+ sprintf(fname, "%s/%s", STATS_DIR, STATS_LOGONS);
+ write_p_inout(P_LOGIN, p, fname, 30);
+ /* added complete login/logout log to "logons.log" file */
+ sprintf(fname, "%s/%s", STATS_DIR, "logons.log");
+ write_p_inout(P_LOGIN, p, fname, 0);
+}
+
+void player_write_logout(int p)
+{
+ struct player *pp = &player_globals.parray[p];
+ char fname[MAX_FILENAME_SIZE];
+
+ if (CheckPFlag(p, PFLAG_REG)) {
+ sprintf(fname, "%s/player_data/%c/%s.%s", STATS_DIR, pp->login[0], pp->login, STATS_LOGONS);
+ write_p_inout(P_LOGOUT, p, fname, 8);
+ }
+ sprintf(fname, "%s/%s", STATS_DIR, STATS_LOGONS);
+ write_p_inout(P_LOGOUT, p, fname, 30);
+ /* added complete login/logout log to "logons.log" file */
+ sprintf(fname, "%s/%s", STATS_DIR, "logons.log");
+ write_p_inout(P_LOGOUT, p, fname, 0);
+}
+
+int player_lastdisconnect(int p)
+{
+ struct player *pp = &player_globals.parray[p];
+ char fname[MAX_FILENAME_SIZE];
+ FILE *fp;
+ int inout, thetime, registered;
+ int last = 0;
+ char ipstr[20];
+ char loginName[MAX_LOGIN_NAME];
+
+ sprintf(fname, "%s/player_data/%c/%s.%s", STATS_DIR, pp->login[0], pp->login, STATS_LOGONS);
+ fp = fopen_s(fname, "r");
+ if (!fp)
+ return 0;
+ while (!feof(fp)) {
+ if (fscanf(fp, "%d %s %d %d %s\n", &inout, loginName, &thetime, ®istered, ipstr) != 5) {
+ d_printf( "CHESSD: Error in login info format. %s\n", fname);
+ fclose(fp);
+ return 0;
+ }
+ if (inout == P_LOGOUT)
+ last = thetime;
+ }
+ fclose(fp);
+ return last;
+}
+
+int player_is_observe(int p, int g)
+{
+ struct player *pp = &player_globals.parray[p];
+ int i;
+
+ for (i = 0; i < pp->num_observe; i++) {
+ if (pp->observe_list[i] == g)
+ break;
+ }
+ if (i == pp->num_observe)
+ return 0;
+ else
+ return 1;
+}
+
+int player_add_observe(int p, int g)
+{
+ struct player *pp = &player_globals.parray[p];
+ if (pp->num_observe == MAX_OBSERVE)
+ return -1;
+ pp->observe_list[pp->num_observe] = g;
+ pp->num_observe++;
+ return 0;
+}
+
+int player_remove_observe(int p, int g)
+{
+ struct player *pp = &player_globals.parray[p];
+ int i;
+
+ for (i = 0; i < pp->num_observe; i++) {
+ if (pp->observe_list[i] == g)
+ break;
+ }
+ if (i == pp->num_observe)
+ return -1; /* Not found! */
+ for (; i < pp->num_observe - 1; i++) {
+ pp->observe_list[i] = pp->observe_list[i + 1];
+ }
+ pp->num_observe--;
+ return 0;
+}
+
+int player_game_ended(int g)
+{
+ int p;
+
+ for (p = 0; p < player_globals.p_num; p++) {
+ struct player *pp = &player_globals.parray[p];
+ if (pp->status == PLAYER_EMPTY)
+ continue;
+ player_remove_observe(p, g);
+ }
+ remove_request(game_globals.garray[g].white, game_globals.garray[g].black, -1);
+ remove_request(game_globals.garray[g].black, game_globals.garray[g].white, -1);
+ player_save(game_globals.garray[g].white); /* Hawk: Added to save finger-info after each
+ game */
+ player_save(game_globals.garray[g].black);
+ return 0;
+}
+
+int player_goto_board(int p, int board_num)
+{
+ struct player *pp = &player_globals.parray[p];
+ int start, count = 0, on, g;
+
+ if (pp->simul_info == NULL)
+ return -1;
+
+ if (board_num < 0 || board_num >= pp->simul_info->numBoards)
+ return -1;
+ if (pp->simul_info->boards[board_num] < 0)
+ return -1;
+ pp->simul_info->onBoard = board_num;
+ pp->game = pp->simul_info->boards[board_num];
+ pp->opponent = game_globals.garray[pp->game].black;
+ if (pp->simul_info->numBoards == 1)
+ return 0;
+ send_board_to(pp->game, p);
+ start = pp->game;
+ on = pp->simul_info->onBoard;
+ do {
+ g = pp->simul_info->boards[on];
+ if (g >= 0) {
+ if (count == 0) {
+ Bell (game_globals.garray[g].black);
+ pprintf(game_globals.garray[g].black, "\n");
+ pprintf_highlight(game_globals.garray[g].black, "%s", pp->name);
+ pprintf_prompt(game_globals.garray[g].black, " is at your board!\n");
+ } else if (count == 1) {
+ Bell (game_globals.garray[g].black);
+ pprintf(game_globals.garray[g].black, "\n");
+ pprintf_highlight(game_globals.garray[g].black, "%s", pp->name);
+ pprintf_prompt(game_globals.garray[g].black, " will be at your board NEXT!\n");
+ } else {
+ pprintf(game_globals.garray[g].black, "\n");
+ pprintf_highlight(game_globals.garray[g].black, "%s", pp->name);
+ pprintf_prompt(game_globals.garray[g].black, " is %d boards away.\n", count);
+ }
+ count++;
+ }
+ on++;
+ if (on >= pp->simul_info->numBoards)
+ on = 0;
+ } while (start != pp->simul_info->boards[on]);
+ return 0;
+}
+
+int player_goto_next_board(int p)
+{
+ struct player *pp = &player_globals.parray[p];
+ int on;
+ int start;
+ int g;
+
+ if (pp->simul_info == NULL)
+ return -1;
+
+ on = pp->simul_info->onBoard;
+ start = on;
+ g = -1;
+ do {
+ on++;
+ if (on >= pp->simul_info->numBoards)
+ on = 0;
+ g = pp->simul_info->boards[on];
+ if (g >= 0)
+ break;
+ } while (start != on);
+ if (g == -1) {
+ pprintf(p, "\nMajor Problem! Can't find your next board.\n");
+ return -1;
+ }
+ return player_goto_board(p, on);
+}
+
+int player_goto_prev_board(int p)
+{
+ struct player *pp = &player_globals.parray[p];
+ int on;
+ int start;
+ int g;
+
+ if (pp->simul_info == NULL)
+ return -1;
+
+ on = pp->simul_info->onBoard;
+ start = on;
+ g = -1;
+ do {
+ --on;
+ if (on < 0)
+ on = (pp->simul_info->numBoards) - 1;
+ g = pp->simul_info->boards[on];
+ if (g >= 0)
+ break;
+ } while (start != on);
+ if (g == -1) {
+ pprintf(p, "\nMajor Problem! Can't find your previous board.\n");
+ return -1;
+ }
+ return player_goto_board(p, on);
+}
+
+int player_goto_simulgame_bynum(int p, int num)
+{
+ struct player *pp = &player_globals.parray[p];
+ int on;
+ int start;
+ int g;
+
+ if (pp->simul_info == NULL)
+ return -1;
+
+ on = pp->simul_info->onBoard;
+ start = on;
+ do {
+ on++;
+ if (on >= pp->simul_info->numBoards)
+ on = 0;
+ g = pp->simul_info->boards[on];
+ if (g == num)
+ break;
+ } while (start != on);
+ if (g != num) {
+ pprintf(p, "\nYou aren't playing that game!!\n");
+ return -1;
+ }
+ return player_goto_board(p, on);
+}
+
+int player_num_active_boards(int p)
+{
+ struct player *pp = &player_globals.parray[p];
+ int count = 0, i;
+
+ if (pp->simul_info == NULL)
+ return 0;
+
+ if (!pp->simul_info->numBoards)
+ return 0;
+ for (i = 0; i < pp->simul_info->numBoards; i++)
+ if (pp->simul_info->boards[i] >= 0)
+ count++;
+ return count;
+}
+
+static int player_num_results(int p, int result)
+{
+ struct player *pp = &player_globals.parray[p];
+ switch (result) {
+ case RESULT_WIN:
+ return pp->simul_info->num_wins;
+ case RESULT_DRAW:
+ return pp->simul_info->num_draws;
+ case RESULT_LOSS:
+ return pp->simul_info->num_losses;
+ default:
+ return -1;
+ }
+}
+
+static void new_simul_result(struct simul_info_t *sim, int result)
+{
+ switch (result) {
+ case RESULT_WIN:
+ sim->num_wins++;
+ return;
+ case RESULT_DRAW:
+ sim->num_draws++;
+ return;
+ case RESULT_LOSS:
+ sim->num_losses++;
+ return;
+ }
+}
+
+int player_simul_over(int p, int g, int result)
+{
+ struct player *pp = &player_globals.parray[p];
+ int on, ong, p1, which;
+ char tmp[1024];
+
+ if (pp->simul_info == NULL)
+ return -1;
+
+ for (which = 0; which < pp->simul_info->numBoards; which++) {
+ if (pp->simul_info->boards[which] == g) {
+ break;
+ }
+ }
+ if (which == pp->simul_info->numBoards) {
+ pprintf(p, "I can't find that game!\n");
+ return -1;
+ }
+ pprintf(p, "\nBoard %d has completed.\n", which + 1);
+ on = pp->simul_info->onBoard;
+ ong = pp->simul_info->boards[on];
+ pp->simul_info->boards[which] = -1;
+ new_simul_result(pp->simul_info, result);
+ if (player_num_active_boards(p) == 0) {
+ sprintf(tmp, "\n{Simul (%s vs. %d) is over.}\nResults: %d Wins, %d Losses, %d Draws, %d Aborts\n",
+ pp->name,
+ pp->simul_info->numBoards,
+ player_num_results(p, RESULT_WIN),
+ player_num_results(p, RESULT_LOSS),
+ player_num_results(p, RESULT_DRAW),
+ player_num_results(p, RESULT_ABORT));
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (pp->status != PLAYER_PROMPT)
+ continue;
+ if (!CheckPFlag(p1, PFLAG_GIN) && !player_is_observe(p1, g) && (p1 != p))
+ continue;
+ pprintf_prompt(p1, "%s", tmp);
+ }
+ pp->simul_info->numBoards = 0;
+ pprintf_prompt(p, "\nThat was the last board, thanks for playing.\n");
+ free(pp->simul_info);
+ pp->simul_info = NULL;
+ return 0;
+ }
+ if (ong == g) { /* This game is over */
+ player_goto_next_board(p);
+ } else {
+ player_goto_board(p, pp->simul_info->onBoard);
+ }
+ pprintf_prompt(p, "\nThere are %d boards left.\n",
+ player_num_active_boards(p));
+ return 0;
+}
+
+static void GetMsgFile (int p, char *fName)
+{
+ struct player *pp = &player_globals.parray[p];
+ sprintf(fName, "%s/player_data/%c/%s.%s", STATS_DIR, pp->login[0],
+ pp->login, STATS_MESSAGES);
+}
+
+int player_num_messages(int p)
+{
+ char fname[MAX_FILENAME_SIZE];
+
+ if (!CheckPFlag(p, PFLAG_REG))
+ return 0;
+ GetMsgFile (p, fname);
+ return lines_file(fname);
+}
+
+int player_add_message(int top, int fromp, char *message)
+{
+ char fname[MAX_FILENAME_SIZE];
+ FILE *fp;
+ char subj[256];
+ char messbody[1024];
+ time_t t = time(0);
+
+ if (!CheckPFlag(top, PFLAG_REG))
+ return -1;
+ if (!CheckPFlag(fromp, PFLAG_REG))
+ return -1;
+ GetMsgFile (top, fname);
+ if ((lines_file(fname) >= MAX_MESSAGES) && (player_globals.parray[top].adminLevel == 0))
+ return -1;
+ fp = fopen_s(fname, "a");
+ if (!fp)
+ return -1;
+ fprintf(fp, "%s at %s: %s\n", player_globals.parray[fromp].name, strltime(&t), message);
+ fclose(fp);
+ pprintf(fromp, "\nThe following message was sent ");
+ if (CheckPFlag(top, PFLAG_MAILMESS)) {
+ sprintf(subj, "FICS message from %s at FICS %s (Do not reply by mail)",
+ player_globals.parray[fromp].name,
+ config_get_tmp("SERVER_HOSTNAME"));
+ sprintf(messbody, "%s at %s: %s\n", player_globals.parray[fromp].name, strltime(&t), message);
+ mail_string_to_user(top, subj, messbody);
+ pprintf(fromp, "(and emailed) ");
+ }
+ pprintf(fromp, "to %s: \n %s\n", player_globals.parray[top].name, message);
+ return 0;
+}
+
+static int player_forward_message(int top, int fromp, char *message)
+{
+ char fname[MAX_FILENAME_SIZE];
+ FILE *fp;
+ char subj[256];
+ char messbody[1024];
+
+ if (!CheckPFlag(top, PFLAG_REG))
+ return -1;
+ if (!CheckPFlag(fromp, PFLAG_REG))
+ return -1;
+ GetMsgFile (top, fname);
+ if ((lines_file(fname) >= MAX_MESSAGES) && (player_globals.parray[top].adminLevel == 0))
+ return -1;
+ fp = fopen_s(fname, "a");
+ if (!fp)
+ return -1;
+ fprintf(fp, "FORWARDED MSG FROM %s : %s", player_globals.parray[fromp].name, message);
+ fclose(fp);
+ pprintf(fromp, "\nThe following message was forwarded ");
+ if (CheckPFlag(top, PFLAG_MAILMESS)) {
+ sprintf(subj, "FICS message from %s at FICS %s (Do not reply by mail)",
+ player_globals.parray[fromp].name,
+ config_get_tmp("SERVER_HOSTNAME"));
+ sprintf(messbody, "FORWARDED MSG FROM %s: %s\n", player_globals.parray[fromp].name, message);
+ mail_string_to_user(top, subj, messbody);
+ pprintf(fromp, "(and emailed) ");
+ }
+ pprintf(fromp, "to %s: \n %s\n", player_globals.parray[top].name, message);
+ return 0;
+}
+void SaveTextListEntry(textlist **Entry, char *string, int n)
+{
+ *Entry = (textlist *) malloc(sizeof(textlist));
+ (*Entry)->text = strdup(string);
+ (*Entry)->index = n;
+ (*Entry)->next = NULL;
+}
+
+static textlist *ClearTextListEntry(textlist *entry)
+{
+ textlist *ret = entry->next;
+ free(entry->text);
+ free(entry);
+ return ret;
+}
+
+void ClearTextList(textlist *head)
+{
+ textlist *cur;
+
+ for (cur = head; cur != NULL; cur = ClearTextListEntry(cur));
+}
+
+static int SaveThisMsg (int which, char *line)
+{
+ char Sender[MAX_LOGIN_NAME];
+ int p1;
+
+ if (which == 0) return 1;
+
+ sscanf (line, "%s", Sender);
+ if (which < 0) {
+ p1 = -which - 1;
+ return strcmp(Sender, player_globals.parray[p1].name);
+ }
+ else {
+ p1 = which - 1;
+ return !strcmp(Sender, player_globals.parray[p1].name);
+ }
+}
+
+static int LoadMsgs(int p, int which, textlist **Head)
+{
+ FILE *fp;
+ textlist **Cur = Head;
+ char fName[MAX_FILENAME_SIZE];
+ char line[MAX_LINE_SIZE];
+ int n=0, nSave=0;
+
+ *Head = NULL;
+ GetMsgFile (p, fName);
+ fp = fopen_s(fName, "r");
+ if (fp == NULL) {
+ return -1;
+ }
+ while (!feof(fp)) {
+ fgets(line, MAX_LINE_SIZE, fp);
+ if (feof(fp))
+ break;
+ if (SaveThisMsg(which, line)) {
+ SaveTextListEntry(Cur, line, ++n);
+ Cur = &(*Cur)->next;
+ nSave++;
+ }
+ else n++;
+ }
+ fclose (fp);
+ return nSave;
+}
+
+/* start > 0 and end > start (or end = 0) to save messages in range;
+ start < 0 and end < start (or end = 0) to clear messages in range;
+ if end = 0, range goes to end of file (not tested yet). */
+static int LoadMsgRange(int p, int start, int end, textlist **Head)
+{
+ FILE *fp;
+ char fName[MAX_FILENAME_SIZE];
+ char line[MAX_LINE_SIZE];
+ textlist **Cur = Head;
+ int n=1, nSave=0, nKill=0;
+
+ *Head = NULL;
+ GetMsgFile (p, fName);
+ fp = fopen (fName, "r");
+ if (fp == NULL) {
+ pprintf (p, "You have no messages.\n");
+ return -1;
+ }
+ for (n=1; n <= end || end <= 0; n++) {
+ fgets (line, MAX_LINE_SIZE, fp);
+ if (feof(fp))
+ break;
+ if ((start < 0 && (n < -start || n > -end)) || (start >= 0 && n >= start)) {
+ SaveTextListEntry (Cur, line, n);
+ Cur = &(*Cur)->next;
+ nSave++;
+ }
+ else nKill++;
+ }
+ fclose (fp);
+ if (start < 0) {
+ if (n <= -start)
+ pprintf (p, "You do not have a message %d.\n", -start);
+ return nKill;
+ } else {
+ if (n <= start)
+ pprintf (p, "You do not have a message %d.\n", start);
+ return nSave;
+ }
+}
+
+int ForwardMsgRange(char *p1, int p, int start, int end)
+{
+ /* p1 is player to and p is player from */
+ FILE *fp;
+ char fName[MAX_FILENAME_SIZE];
+ char line[MAX_LINE_SIZE];
+ int n=1, top, connected;
+
+ if (!FindPlayer(p, p1, &top, &connected))
+ return -1;
+ GetMsgFile (p, fName);
+ fp = fopen (fName, "r");
+ if (fp == NULL) {
+ pprintf (p, "You have no messages.\n");
+ return -1;
+ }
+ for (n=1; n <= end || end <= 0; n++) {
+ fgets (line, MAX_LINE_SIZE, fp);
+ if (feof(fp))
+ break;
+ if ((start < 0 && (n < -start || n > -end)) || (start >= 0 && n >= start)) {
+ player_forward_message(top, p, line);
+ }
+ }
+ fclose (fp);
+ if (start < 0) {
+ if (n <= -start)
+ pprintf (p, "You do not have a message %d.\n", -start);
+ return 0;
+ } else {
+ if (n <= start)
+ pprintf (p, "You do not have a message %d.\n", start);
+ return 0;
+ }
+}
+
+static int WriteMsgFile (int p, textlist *Head)
+{
+ char fName[MAX_FILENAME_SIZE];
+ FILE *fp;
+ textlist *Cur;
+
+ GetMsgFile (p, fName);
+ fp = fopen_s(fName, "w");
+ if (fp == NULL)
+ return 0;
+ for (Cur = Head; Cur != NULL; Cur = Cur->next)
+ fprintf(fp, "%s", Cur->text);
+ fclose(fp);
+ return 1;
+}
+
+int ClearMsgsBySender(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ textlist *Head;
+ int p1, connected;
+ int nFound;
+
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return -1;
+
+ nFound = LoadMsgs(p, -(p1+1), &Head);
+ if (nFound < 0) {
+ pprintf(p, "You have no messages.\n");
+ } else if (nFound == 0) {
+ pprintf(p, "You have no messages from %s.\n", player_globals.parray[p1].name);
+ } else {
+ if (WriteMsgFile (p, Head))
+ pprintf(p, "Messages from %s cleared.\n", player_globals.parray[p1].name);
+ else {
+ pprintf(p, "Problem writing message file; please contact an admin.\n");
+ d_printf( "Problem writing message file for %s.\n", pp->name);
+ }
+ ClearTextList(Head);
+ }
+ if (!connected)
+ player_remove(p1);
+ return nFound;
+}
+
+static void ShowTextList (int p, textlist *Head, int ShowIndex)
+{
+ textlist *CurMsg;
+
+ if (ShowIndex) {
+ for (CurMsg = Head; CurMsg != NULL; CurMsg = CurMsg->next)
+ pprintf(p, "%2d. %s", CurMsg->index, CurMsg->text);
+ }
+ else {
+ for (CurMsg = Head; CurMsg != NULL; CurMsg = CurMsg->next)
+ pprintf(p, "%s", CurMsg->text);
+ }
+}
+
+int player_show_messages(int p)
+{
+ textlist *Head;
+ int n;
+
+ n = LoadMsgs (p, 0, &Head);
+ if (n <= 0) {
+ pprintf (p, "You have no messages.\n");
+ return -1;
+ } else {
+ pprintf (p, "Messages:\n");
+ ShowTextList (p, Head, 1);
+ ClearTextList (Head);
+ return 0;
+ }
+}
+
+int ShowMsgsBySender(int p, param_list param)
+{
+ textlist *Head;
+ int p1, connected;
+ int nFrom;
+ int nTo = 0;
+
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return -1;
+
+ if (!CheckPFlag(p1, PFLAG_REG)) {
+ pprintf(p, "Player \"%s\" is unregistered and cannot send or receive messages.\n",
+ player_globals.parray[p1].name);
+ return -1; /* no need to disconnect */
+ }
+
+ if (p != p1) {
+ nTo = LoadMsgs(p1, p+1, &Head);
+ if (nTo <= 0) {
+ pprintf(p, "%s has no messages from you.\n", player_globals.parray[p1].name);
+ } else {
+ pprintf(p, "Messages to %s:\n", player_globals.parray[p1].name);
+ ShowTextList (p, Head, 0);
+ ClearTextList(Head);
+ }
+ }
+ nFrom = LoadMsgs(p, p1+1, &Head);
+ if (nFrom <= 0) {
+ pprintf(p, "\nYou have no messages from %s.\n", player_globals.parray[p1].name);
+ } else {
+ pprintf(p, "Messages from %s:\n", player_globals.parray[p1].name);
+ ShowTextList (p, Head, 1);
+ ClearTextList(Head);
+ }
+ if (!connected)
+ player_remove(p1);
+ return (nFrom > 0 || nTo > 0);
+}
+
+int ShowMsgRange (int p, int start, int end)
+{
+ textlist *Head;
+ int n;
+
+ n = LoadMsgRange (p, start, end, &Head);
+ if (n > 0) {
+ ShowTextList (p, Head, 1);
+ ClearTextList (Head);
+ }
+ return n;
+}
+
+int ClrMsgRange (int p, int start, int end)
+{
+ textlist *Head;
+ int n;
+
+ n = LoadMsgRange (p, -start, -end, &Head);
+ if (n > 0)
+ if (WriteMsgFile (p, Head))
+ pprintf (p, "Message %d cleared.\n", start);
+ if (n >= 0)
+ ClearTextList (Head);
+
+ return n;
+}
+
+int player_clear_messages(int p)
+{
+ char fname[MAX_FILENAME_SIZE];
+
+ if (!CheckPFlag(p, PFLAG_REG))
+ return -1;
+ GetMsgFile (p, fname);
+ unlink(fname);
+ return 0;
+}
+
+int player_search(int p, char *name)
+/*
+ * Find player matching the given string. First looks for exact match
+ * with a logged in player, then an exact match with a registered player,
+ * then a partial unique match with a logged in player, then a partial
+ * match with a registered player.
+ * Returns player number if the player is connected, negative (player number)
+ * if the player had to be connected, and 0 if no player was found
+ */
+{
+ int p1, count;
+ char *buffer[1000];
+ char pdir[MAX_FILENAME_SIZE];
+
+ /* exact match with connected player? */
+ if ((p1 = player_find_bylogin(name)) >= 0) {
+ return p1 + 1;
+ }
+ /* exact match with registered player? */
+ sprintf(pdir, "%s/%c", PLAYER_DIR, name[0]);
+ count = search_directory(pdir, name, buffer, 1000);
+ if (count > 0 && !strcmp(name, *buffer)) {
+ goto ReadPlayerFromFile; /* found an unconnected registered player */
+ }
+ /* partial match with connected player? */
+ if ((p1 = player_find_part_login(name)) >= 0) {
+ return p1 + 1;
+ } else if (p1 == -2) {
+ /* ambiguous; matches too many connected players. */
+ pprintf (p, "Ambiguous name '%s'; matches more than one player.\n", name);
+ return 0;
+ }
+ /* partial match with registered player? */
+ if (count < 1) {
+ pprintf(p, "There is no player matching that name.\n");
+ return 0;
+ }
+ if (count > 1) {
+ pprintf(p, "-- Matches: %d names --", count);
+ display_directory(p, buffer, count);
+ return(0);
+ }
+ReadPlayerFromFile:
+ p1 = player_new();
+ if (player_read(p1, *buffer)) {
+ player_remove(p1);
+ pprintf(p, "ERROR: a player named %s was expected but not found!\n",
+ *buffer);
+ pprintf(p, "Please tell an admin about this incident. Thank you.\n");
+ return 0;
+ }
+ return (-p1) - 1; /* negative to indicate player was not
+ connected */
+}
+
+
+int player_kill(char *name)
+{
+ char fname[MAX_FILENAME_SIZE], fname2[MAX_FILENAME_SIZE];
+
+ sprintf(fname, "%s/%c/%s", PLAYER_DIR, name[0], name);
+ sprintf(fname2, "%s/%c/.rem.%s", PLAYER_DIR, name[0], name);
+ rename(fname, fname2);
+ RemHist (name);
+ sprintf(fname, "%s/player_data/%c/%s.games", STATS_DIR, name[0], name);
+ sprintf(fname2, "%s/player_data/%c/.rem.%s.games", STATS_DIR, name[0], name);
+ rename(fname, fname2);
+ sprintf(fname, "%s/player_data/%c/%s.comments", STATS_DIR, name[0], name);
+ sprintf(fname2, "%s/player_data/%c/.rem.%s.comments", STATS_DIR, name[0], name);
+ rename(fname, fname2);
+
+ sprintf(fname, "%s/player_data/%c/%s.logons", STATS_DIR, name[0], name);
+ sprintf(fname2, "%s/player_data/%c/.rem.%s.logons", STATS_DIR, name[0], name);
+ rename(fname, fname2);
+ sprintf(fname, "%s/player_data/%c/%s.messages", STATS_DIR, name[0], name);
+ sprintf(fname2, "%s/player_data/%c/.rem.%s.messages", STATS_DIR, name[0], name);
+ rename(fname, fname2);
+ return 0;
+}
+
+int player_rename(char *name, char *newname)
+{
+ char fname[MAX_FILENAME_SIZE], fname2[MAX_FILENAME_SIZE];
+
+ sprintf(fname, "%s/%c/%s", PLAYER_DIR, name[0], name);
+ sprintf(fname2, "%s/%c/%s", PLAYER_DIR, newname[0], newname);
+ rename(fname, fname2);
+ sprintf(fname, "%s/player_data/%c/%s.games", STATS_DIR, name[0], name);
+ sprintf(fname2, "%s/player_data/%c/%s.games", STATS_DIR, newname[0], newname);
+ rename(fname, fname2);
+ sprintf(fname, "%s/player_data/%c/%s.comments", STATS_DIR, name[0], name);
+ sprintf(fname2, "%s/player_data/%c/%s.comments", STATS_DIR, newname[0], newname);
+ rename(fname, fname2);
+ sprintf(fname, "%s/player_data/%c/%s.logons", STATS_DIR, name[0], name);
+ sprintf(fname2, "%s/player_data/%c/%s.logons", STATS_DIR, newname[0], newname);
+ rename(fname, fname2);
+ sprintf(fname, "%s/player_data/%c/%s.messages", STATS_DIR, name[0], name);
+ sprintf(fname2, "%s/player_data/%c/%s.messages", STATS_DIR, newname[0], newname);
+ rename(fname, fname2);
+ return 0;
+}
+
+int player_reincarn(char *name, char *newname)
+{
+ char fname[MAX_FILENAME_SIZE], fname2[MAX_FILENAME_SIZE];
+
+ sprintf(fname, "%s/%c/%s", PLAYER_DIR, newname[0], newname);
+ sprintf(fname2, "%s/%c/.rem.%s", PLAYER_DIR, name[0], name);
+ rename(fname2, fname);
+ sprintf(fname, "%s/player_data/%c/%s.games", STATS_DIR, newname[0], newname);
+ sprintf(fname2, "%s/player_data/%c/.rem.%s.games", STATS_DIR, name[0], name);
+ rename(fname2, fname);
+ sprintf(fname, "%s/player_data/%c/%s.comments", STATS_DIR, newname[0], newname);
+ sprintf(fname2, "%s/player_data/%c/.rem.%s.comments", STATS_DIR, name[0], name);
+ rename(fname2, fname);
+ sprintf(fname, "%s/player_data/%c/%s.logons", STATS_DIR, newname[0], newname);
+ sprintf(fname2, "%s/player_data/%c/.rem.%s.logons", STATS_DIR, name[0], name);
+ rename(fname2, fname);
+ sprintf(fname, "%s/player_data/%c/%s.messages", STATS_DIR, newname[0], newname);
+ sprintf(fname2, "%s/player_data/%c/.rem.%s.messages", STATS_DIR, name[0], name);
+ rename(fname2, fname);
+ return 0;
+}
+
+int player_num_comments(int p)
+{
+ struct player *pp = &player_globals.parray[p];
+ char fname[MAX_FILENAME_SIZE];
+
+ if (!CheckPFlag(p, PFLAG_REG))
+ return 0;
+ sprintf(fname, "%s/player_data/%c/%s.%s", STATS_DIR, pp->login[0],
+ pp->login, "comments");
+ return lines_file(fname);
+}
+
+int player_add_comment(int p_by, int p_to, char *comment)
+{
+ char fname[MAX_FILENAME_SIZE];
+ FILE *fp;
+ time_t t = time(0);
+
+ if (!CheckPFlag(p_to, PFLAG_REG))
+ return -1;
+ sprintf(fname, "%s/player_data/%c/%s.%s", STATS_DIR, player_globals.parray[p_to].login[0],
+ player_globals.parray[p_to].login, "comments");
+ fp = fopen_s(fname, "a");
+ if (!fp)
+ return -1;
+ fprintf(fp, "%s at %s: %s\n", player_globals.parray[p_by].name, strltime(&t), comment);
+ fclose(fp);
+ player_globals.parray[p_to].num_comments = player_num_comments(p_to);
+ return 0;
+}
+
+int player_show_comments(int p, int p1)
+{
+ char fname[MAX_FILENAME_SIZE];
+
+ if (CheckPFlag(p1, PFLAG_REG)) {
+ sprintf(fname, "%s/player_data/%c/%s.%s", STATS_DIR, player_globals.parray[p1].login[0],
+ player_globals.parray[p1].login, "comments");
+ if (psend_file(p, NULL, fname))
+ pprintf(p, "There are no comments to show for %s.\n", player_globals.parray[p1].name);
+ if (player_globals.parray[p1].passwd[0] == '*')
+ pprintf(p, "%s's account is LOCKED.\n", player_globals.parray[p1].name);
+ if (in_list(p1, L_BAN, player_globals.parray[p1].name))
+ pprintf(p, "%s has been BANNED.\n", player_globals.parray[p1].name);
+ } else
+ pprintf(p, "Player \"%s\" is unregistered and cannot have comments.\n",
+ player_globals.parray[p1].name);
+ return 0;
+}
+
+/* returns 1 if player is head admin, 0 otherwise */
+int player_ishead(int p)
+{
+ struct player *pp = &player_globals.parray[p];
+ return (strcasecmp(pp->name, config_get_tmp("HEAD_ADMIN")) == 0);
+}
+
+/* GetRating chooses between blitz, standard and other ratings. */
+int GetRating(struct player *p, int gametype)
+{
+ if (gametype == TYPE_BLITZ) return (p->b_stats.rating);
+ else if (gametype == TYPE_STAND) return (p->s_stats.rating);
+ else if (gametype == TYPE_WILD) return (p->w_stats.rating);
+ else if (gametype == TYPE_LIGHT) return (p->l_stats.rating);
+ else if (gametype == TYPE_BUGHOUSE) return (p->bug_stats.rating);
+ else return 0;
+} /* end of function GetRating. */
+
+/* GetRD chooses between blitz, standard and other RD's. */
+double GetRD(struct player *p, int gametype)
+{
+ struct statistics *s;
+
+ switch(gametype) {
+ case TYPE_BLITZ: s = &p->b_stats; break;
+ case TYPE_STAND: s = &p->s_stats; break;
+ case TYPE_WILD: s = &p->w_stats; break;
+ case TYPE_LIGHT: s = &p->l_stats; break;
+ case TYPE_BUGHOUSE: s = &p->bug_stats; break;
+ default: return 0.0;
+ }
+ return (current_sterr(s->sterr, time(NULL)-(s->ltime)));
+} /* end of function GetRD. */
+
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+#ifndef _PLAYERDB_H
+#define _PLAYERDB_H
+
+#define MAX_OBSERVE 30 /* max # of games one person can observe */
+#define MAX_PLAN 10
+#define MAX_FORMULA 9
+#define MAX_CENSOR 50
+#define MAX_NOTIFY 80
+#define MAX_SIMUL 100
+#define MAX_MESSAGES 40
+#define MAX_INCHANNELS 16
+
+#define PLAYER_EMPTY 0
+#define PLAYER_NEW 1
+#define PLAYER_INQUEUE 2
+#define PLAYER_LOGIN 3
+#define PLAYER_PASSWORD 4
+#define PLAYER_PROMPT 5
+
+#define P_LOGIN 0
+#define P_LOGOUT 1
+
+#define SORT_BLITZ 0
+#define SORT_STAND 1
+#define SORT_ALPHA 2
+#define SORT_WILD 3
+
+GENSTRUCT struct statistics {
+ int num, win, los, dra, rating, ltime, best, whenbest;
+ double sterr;
+};
+
+GENSTRUCT struct simul_info_t {
+ int numBoards;
+ int onBoard;
+ int num_wins, num_draws, num_losses;
+ int boards[MAX_SIMUL];
+};
+
+#define PFLAG_REG 0x1
+#define PFLAG_OPEN 0x2
+#define PFLAG_ROPEN 0x4
+#define PFLAG_SIMOPEN 0x8
+#define PFLAG_FLIP 0x10
+#define PFLAG_ADMINLIGHT 0x20
+#define PFLAG_RATED 0x40
+#define PFLAG_BLACKSIDE 0x80 /* not done; replacing side. */
+#define PFLAG_LASTBLACK 0x100
+#define PFLAG_PIN 0x200
+#define PFLAG_GIN 0x400
+#define PFLAG_AVAIL 0x800 /* to be informed about who is available for games*/
+#define PFLAG_PRIVATE 0x1000
+#define PFLAG_JPRIVATE 0x2000
+#define PFLAG_AUTOMAIL 0x4000
+#define PFLAG_MAILMESS 0x8000
+#define PFLAG_SHOUT 0x10000
+#define PFLAG_CSHOUT 0x20000
+#define PFLAG_TELL 0x40000
+#define PFLAG_KIBITZ 0x80000
+#define PFLAG_NOTIFYBY 0x100000
+#define PFLAG_PGN 0x200000
+#define PFLAG_BELL 0x400000
+#define PFLAG_HIDEINFO 0x800000
+#define PFLAG_TOURNEY 0x1000000 /* Not coded yet. */
+#define PFLAG_ADS 0x2000000
+/* Note: we're starting the last byte, assuming a long int has 4 bytes;
+ If we run out, we probably should make a Flag1 and a Flag2. */
+
+#define PFLAG_DEFAULT (PFLAG_OPEN | PFLAG_ROPEN | PFLAG_SHOUT \
+ | PFLAG_CSHOUT | PFLAG_KIBITZ \
+ | PFLAG_ADMINLIGHT)
+
+/* PFLAG_SAVED will make a good mask. */
+#define PFLAG_SAVED (PFLAG_OPEN | PFLAG_ROPEN | PFLAG_RATED | PFLAG_BELL \
+ | PFLAG_PIN | PFLAG_GIN | PFLAG_AVAIL | PFLAG_PRIVATE \
+ | PFLAG_JPRIVATE | PFLAG_AUTOMAIL | PFLAG_MAILMESS \
+ | PFLAG_MAILMESS | PFLAG_SHOUT | PFLAG_CSHOUT \
+ | PFLAG_TELL | PFLAG_KIBITZ | PFLAG_NOTIFYBY | PFLAG_PGN)
+
+GENSTRUCT struct player {
+ /* This first block is not saved between logins */
+ char *login;
+ int socket;
+ int status;
+ int game;
+ int opponent; /* Only valid if game is >= 0 */
+ int side; /* Only valid if game is >= 0 */
+ int timeOfReg;
+ int totalTime;
+ int ftell; /* Are you forwarding tells? -1 if not else who from */
+ int logon_time;
+ int last_command_time;
+ int num_observe;
+ int observe_list[MAX_OBSERVE];
+ struct in_addr thisHost;
+ int lastshout_a;
+ int lastshout_b;
+ struct simul_info_t *simul_info;
+ int num_comments; /* number of lines in comments file */
+ int partner;
+ char *more_text;
+ int kiblevel;
+ int number_pend_from; /* not really necessary but are used to cut down */
+ int number_pend_to; /* search - DAV */
+ struct ivariables ivariables;
+ char *interface;
+
+ /* this is a dummy variable used to tell which bits are saved in the structure */
+ unsigned not_saved_marker;
+
+ unsigned Flags;
+ char *name;
+ char *passwd;
+ char *fullName;
+ char *emailAddress;
+ const char *prompt;
+ char *busy;
+ char *last_tell;
+ int last_channel;
+ char *last_opponent;
+ struct statistics s_stats;
+ struct statistics b_stats;
+ struct statistics w_stats;
+ struct statistics l_stats;
+ struct statistics bug_stats;
+ int d_time;
+ int d_inc;
+ int d_height;
+ int d_width;
+ int language;
+ int style;
+ int promote;
+ int adminLevel;
+ int availmin;
+ int availmax;
+ int num_plan;
+ char *planLines[MAX_PLAN];
+ int num_formula;
+ char *formulaLines[MAX_FORMULA];
+ char *formula;
+ int num_white;
+ int num_black;
+ struct in_addr lastHost;
+ int numAlias;
+ struct alias_type *alias_list; _LEN(numAlias)
+ int highlight;
+ struct List *lists;
+ int latest_news;
+ int admin_latest_news;
+};
+
+typedef struct textlist {
+ char *text;
+ int index;
+ struct textlist *next;
+} textlist;
+
+#endif /* _PLAYERDB_H */
+
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+#include "includes.h"
+
+/*
+ support for reading the old player formats
+ thank goodness I don't need to update this any more! It sure was a complex format.
+*/
+
+
+/* return 0 if corrupt */
+
+static int ReadV1PlayerFmt(int p,struct player *pp, FILE * fp, const char *file, int version)
+{
+
+ int i,size_cens, size_noplay, size_not, size_gnot, size_chan, len;
+ int bs,ss,ws,ls,bugs;
+ int bell, pgn, notifiedby, pin, gin, avail, private, jprivate;
+ int open, ropen, rated, tell, kib, shout, cshout, automail, mailmess;
+ int numAlias = 0;
+
+ char* tmp;
+ char tmp2[MAX_STRING_LENGTH];
+
+ fgets(tmp2, MAX_STRING_LENGTH, fp);
+ if (strcmp(tmp2,"NONE\n")) {
+ tmp2[strlen(tmp2)-1] = '\0';
+ pp->name = strdup (tmp2);
+ } else
+ pp->name = NULL;
+ fgets(tmp2, MAX_STRING_LENGTH, fp);
+ if (strcmp(tmp2,"NONE\n")) {
+ tmp2[strlen(tmp2)-1] = '\0';
+ pp->fullName = strdup (tmp2);
+ } else
+ pp->fullName = NULL;
+ fgets(tmp2, MAX_STRING_LENGTH, fp);
+ if (strcmp(tmp2,"NONE\n")) {
+ tmp2[strlen(tmp2)-1] = '\0';
+ pp->passwd = strdup (tmp2);
+ } else
+ pp->passwd = NULL;
+ fgets(tmp2, MAX_STRING_LENGTH, fp);
+ if (strcmp(tmp2,"NONE\n")) {
+ tmp2[strlen(tmp2)-1] = '\0';
+ pp->emailAddress = strdup (tmp2);
+ } else
+ pp->emailAddress = NULL;
+ if (fscanf(fp, "%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %d\n",
+
+ &pp->s_stats.num, &pp->s_stats.win, &pp->s_stats.los,
+ &pp->s_stats.dra, &pp->s_stats.rating, &ss,
+ &pp->s_stats.ltime, &pp->s_stats.best, &pp->s_stats.whenbest,
+
+ &pp->b_stats.num, &pp->b_stats.win, &pp->b_stats.los,
+ &pp->b_stats.dra, &pp->b_stats.rating, &bs,
+ &pp->b_stats.ltime, &pp->b_stats.best, &pp->b_stats.whenbest,
+
+ &pp->w_stats.num, &pp->w_stats.win, &pp->w_stats.los,
+ &pp->w_stats.dra, &pp->w_stats.rating, &ws,
+ &pp->w_stats.ltime, &pp->w_stats.best, &pp->w_stats.whenbest,
+
+ &pp->l_stats.num, &pp->l_stats.win, &pp->l_stats.los,
+ &pp->l_stats.dra, &pp->l_stats.rating, &ls,
+ &pp->l_stats.ltime, &pp->l_stats.best, &pp->l_stats.whenbest,
+
+ &pp->bug_stats.num, &pp->bug_stats.win, &pp->bug_stats.los,
+ &pp->bug_stats.dra, &pp->bug_stats.rating, &bugs,
+ &pp->bug_stats.ltime, &pp->bug_stats.best, &pp->bug_stats.whenbest,
+ &pp->lastHost.s_addr) != 46) {
+ d_printf("Player %s is corrupt\n",player_globals.parray[p].name);
+ free(pp->fullName);
+ free(pp->passwd);
+ free(pp->emailAddress);
+ pp->fullName = NULL;
+ pp->passwd = NULL;
+ pp->emailAddress = NULL;
+ return 0;
+ }
+
+ pp->b_stats.sterr = bs / 10.0;
+ pp->s_stats.sterr = ss / 10.0;
+ pp->w_stats.sterr = ws / 10.0;
+ pp->l_stats.sterr = ls / 10.0;
+ pp->bug_stats.sterr = bugs / 10.0;
+
+ fgets (tmp2, MAX_STRING_LENGTH, fp);
+ tmp2[strlen(tmp2)-1] = '\0';
+ pp->prompt = strdup(tmp2);
+ if (version == 1) {
+ if (fscanf (fp, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
+ &open, &rated, &ropen, &pp->timeOfReg,
+ &pp->totalTime, &bell, &pgn, ¬ifiedby,
+ &pin, &gin, &shout, &cshout,
+ &tell, &kib, &private, &jprivate,
+ &automail, &mailmess, &pp->style, &pp->d_time,
+ &pp->d_inc, &pp->d_height, &pp->d_width, &pp->language,
+ &pp->adminLevel, &pp->num_white, &pp->num_black, &pp->highlight,
+ &pp->num_comments,
+ &pp->num_plan, &pp->num_formula,&size_cens,
+ &size_not, &size_noplay,
+ &size_gnot, &numAlias, &size_chan) != 37) {
+ d_printf("Player %s is corrupt.\n",player_globals.parray[p].name);
+ free(pp->prompt);
+ pp->prompt = config_get("DEFAULT_PROMPT");
+ free(pp->fullName);
+ free(pp->passwd);
+ free(pp->emailAddress);
+ pp->fullName = NULL;
+ pp->passwd = NULL;
+ pp->emailAddress = NULL;
+ pp->num_plan = 0;
+ pp->num_formula = 0;
+ pp->adminLevel = 0;
+ return 0;
+ }
+ } else if (version == 2) {
+ if (fscanf (fp, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
+ &open, &rated, &ropen, &pp->timeOfReg,
+ &pp->totalTime, &bell, &pgn, ¬ifiedby,
+ &pin, &gin, &avail, &shout, &cshout,
+ &tell, &kib, &private, &jprivate,
+ &automail, &mailmess, &pp->style, &pp->d_time,
+ &pp->d_inc, &pp->d_height, &pp->d_width, &pp->language,
+ &pp->adminLevel, &pp->num_white, &pp->num_black, &pp->highlight,
+ &pp->num_comments,
+ &pp->num_plan, &pp->num_formula,&size_cens,
+ &size_not, &size_noplay,
+ &size_gnot, &numAlias, &size_chan) != 38) {
+ d_printf("Player %s is corrupt.\n",player_globals.parray[p].name);
+ free(pp->prompt);
+ pp->prompt = config_get("DEFAULT_PROMPT");
+ free(pp->fullName);
+ free(pp->passwd);
+ free(pp->emailAddress);
+ pp->fullName = NULL;
+ pp->passwd = NULL;
+ pp->emailAddress = NULL;
+ pp->num_plan = 0;
+ pp->num_formula = 0;
+ pp->adminLevel = 0;
+ return 0;
+ }
+ } else if (version > 2) {
+ if (fscanf (fp, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
+ &open, &rated, &ropen, &pp->timeOfReg,
+ &pp->totalTime, &bell, &pgn, ¬ifiedby,
+ &pin, &gin, &avail, &shout, &cshout,
+ &tell, &kib, &private, &jprivate,
+ &automail, &mailmess, &pp->style, &pp->d_time,
+ &pp->d_inc, &pp->d_height, &pp->d_width, &pp->language,
+ &pp->adminLevel, &pp->num_white, &pp->num_black, &pp->highlight,
+ &pp->num_comments,
+ &pp->num_plan, &pp->num_formula,&size_cens,
+ &size_not, &size_noplay,
+ &size_gnot, &numAlias, &size_chan, &pp->availmin, &pp->availmax) != 40) {
+ d_printf("Player %s is corrupt.\n",player_globals.parray[p].name);
+ free(pp->prompt);
+ pp->prompt = config_get("DEFAULT_PROMPT");
+ free(pp->fullName);
+ free(pp->passwd);
+ free(pp->emailAddress);
+ pp->fullName = NULL;
+ pp->passwd = NULL;
+ pp->emailAddress = NULL;
+ pp->num_plan = 0;
+ pp->num_formula = 0;
+ pp->adminLevel = 0;
+ return 0;
+ }
+ }
+ SetFlag(pp->Flags, PFLAG_OPEN, open);
+ SetFlag(pp->Flags, PFLAG_ROPEN, ropen);
+ SetFlag(pp->Flags, PFLAG_RATED, rated);
+ SetFlag(pp->Flags, PFLAG_BELL, bell);
+ SetFlag(pp->Flags, PFLAG_PGN, pgn);
+ SetFlag(pp->Flags, PFLAG_NOTIFYBY, notifiedby);
+ SetFlag(pp->Flags, PFLAG_PIN, pin);
+ SetFlag(pp->Flags, PFLAG_GIN, gin);
+ SetFlag(pp->Flags, PFLAG_AVAIL, avail);
+ SetFlag(pp->Flags, PFLAG_PRIVATE, private);
+ SetFlag(pp->Flags, PFLAG_JPRIVATE, jprivate);
+ SetFlag(pp->Flags, PFLAG_SHOUT, shout);
+ SetFlag(pp->Flags, PFLAG_CSHOUT, cshout);
+ SetFlag(pp->Flags, PFLAG_TELL, tell);
+ SetFlag(pp->Flags, PFLAG_KIBITZ, kib);
+ SetFlag(pp->Flags, PFLAG_AUTOMAIL, automail);
+ SetFlag(pp->Flags, PFLAG_MAILMESS, mailmess);
+
+ if (version > 3)
+ getc (fp); /* skip a dot */
+
+ if (pp->num_plan > 0) {
+ for (i = 0; i < pp->num_plan; i++) {
+ fgets(tmp2, MAX_LINE_SIZE, fp);
+ if (!(len = strlen(tmp2))) {
+ d_printf( "CHESSD: Error bad plan in file %s\n", file);
+ i--;
+ pp->num_plan--;
+ } else {
+ tmp2[len - 1] = '\0'; /* Get rid of '\n' */
+ pp->planLines[i] = (len > 1) ? strdup(tmp2) : NULL;
+ }
+ }
+ }
+ if (pp->num_formula > 0) {
+ for (i = 0; i < pp->num_formula; i++) {
+ fgets(tmp2, MAX_LINE_SIZE, fp);
+ if (!(len = strlen(tmp2))) {
+ d_printf( "CHESSD: Error bad formula in file %s\n", file);
+ i--;
+ pp->num_formula--;
+ } else {
+ tmp2[len - 1] = '\0'; /* Get rid of '\n' */
+ pp->formulaLines[i] = (len > 1) ? strdup(tmp2) : NULL;
+ }
+ }
+ }
+ fgets(tmp2, MAX_LINE_SIZE, fp);
+ tmp2[strlen(tmp2) - 1] = '\0';
+ if (!strcmp (tmp2,"NONE"))
+ pp->formula = NULL;
+ else
+ pp->formula = strdup(tmp2);
+
+ if (numAlias > 0) {
+ for (i = 0; i < numAlias; i++) {
+ fgets(tmp2, MAX_LINE_SIZE, fp);
+ if (!(len = strlen(tmp2))) {
+ d_printf( "CHESSD: Error bad alias in file %s\n", file);
+ i--;
+ } else {
+ tmp2[len - 1] = '\0'; /* Get rid of '\n' */
+ tmp = tmp2;
+ tmp = eatword(tmp2);
+ *tmp = '\0';
+ tmp++;
+ tmp = eatwhite(tmp);
+ alias_add(p, tmp2, tmp);
+ }
+ }
+ }
+
+ while (size_cens--) {
+ fscanf(fp,"%s",tmp2);
+ list_add(p, L_CENSOR, tmp2);
+ }
+
+ while(size_not--) {
+ fscanf(fp,"%s",tmp2);
+ list_add(p, L_NOTIFY, tmp2);
+ }
+
+ while(size_noplay--) {
+ fscanf(fp,"%s",tmp2);
+ list_add(p, L_NOPLAY, tmp2);
+ }
+
+ while(size_gnot--) {
+ fscanf(fp,"%s",tmp2);
+ list_add(p, L_GNOTIFY, tmp2);
+ }
+
+ while(size_chan--) {
+ fscanf(fp,"%s",tmp2);
+ list_add(p, L_CHANNEL, tmp2);
+ }
+ return 1;
+}
+
+static int got_attr_value_player(int p, char *attr, char *value, FILE * fp, const char *file)
+{
+ int i, len;
+ char tmp[MAX_LINE_SIZE], *tmp1;
+ int numAlias = 0;
+
+ if (!strcmp(attr, "name:")) {
+ player_globals.parray[p].name = strdup(value);
+ } else if (!strcmp(attr, "password:")) {
+ player_globals.parray[p].passwd = strdup(value);
+ } else if (!strcmp(attr, "fullname:")) {
+ player_globals.parray[p].fullName = strdup(value);
+ } else if (!strcmp(attr, "email:")) {
+ player_globals.parray[p].emailAddress = strdup(value);
+ } else if (!strcmp(attr, "prompt:")) {
+ player_globals.parray[p].prompt = strdup(value);
+ } else if (!strcmp(attr, "s_num:")) {
+ player_globals.parray[p].s_stats.num = atoi(value);
+ } else if (!strcmp(attr, "s_win:")) {
+ player_globals.parray[p].s_stats.win = atoi(value);
+ } else if (!strcmp(attr, "s_loss:")) {
+ player_globals.parray[p].s_stats.los = atoi(value);
+ } else if (!strcmp(attr, "s_draw:")) {
+ player_globals.parray[p].s_stats.dra = atoi(value);
+ } else if (!strcmp(attr, "s_rating:")) {
+ player_globals.parray[p].s_stats.rating = atoi(value);
+ } else if (!strcmp(attr, "s_sterr:")) {
+ player_globals.parray[p].s_stats.sterr = (atoi(value) / 10.0);
+ } else if (!strcmp(attr, "s_ltime:")) {
+ player_globals.parray[p].s_stats.ltime = atoi(value);
+ } else if (!strcmp(attr, "s_best:")) {
+ player_globals.parray[p].s_stats.best = atoi(value);
+ } else if (!strcmp(attr, "s_wbest:")) {
+ player_globals.parray[p].s_stats.whenbest = atoi(value);
+ } else if (!strcmp(attr, "b_num:")) {
+ player_globals.parray[p].b_stats.num = atoi(value);
+ } else if (!strcmp(attr, "b_win:")) {
+ player_globals.parray[p].b_stats.win = atoi(value);
+ } else if (!strcmp(attr, "b_loss:")) {
+ player_globals.parray[p].b_stats.los = atoi(value);
+ } else if (!strcmp(attr, "b_draw:")) {
+ player_globals.parray[p].b_stats.dra = atoi(value);
+ } else if (!strcmp(attr, "b_rating:")) {
+ player_globals.parray[p].b_stats.rating = atoi(value);
+ } else if (!strcmp(attr, "b_sterr:")) {
+ player_globals.parray[p].b_stats.sterr = (atoi(value) / 10.0);
+ } else if (!strcmp(attr, "b_ltime:")) {
+ player_globals.parray[p].b_stats.ltime = atoi(value);
+ } else if (!strcmp(attr, "b_best:")) {
+ player_globals.parray[p].b_stats.best = atoi(value);
+ } else if (!strcmp(attr, "b_wbest:")) {
+ player_globals.parray[p].b_stats.whenbest = atoi(value);
+ } else if (!strcmp(attr, "w_num:")) {
+ player_globals.parray[p].w_stats.num = atoi(value);
+ } else if (!strcmp(attr, "w_win:")) {
+ player_globals.parray[p].w_stats.win = atoi(value);
+ } else if (!strcmp(attr, "w_loss:")) {
+ player_globals.parray[p].w_stats.los = atoi(value);
+ } else if (!strcmp(attr, "w_draw:")) {
+ player_globals.parray[p].w_stats.dra = atoi(value);
+ } else if (!strcmp(attr, "w_rating:")) {
+ player_globals.parray[p].w_stats.rating = atoi(value);
+ } else if (!strcmp(attr, "w_sterr:")) {
+ player_globals.parray[p].w_stats.sterr = (atoi(value) / 10.0);
+ } else if (!strcmp(attr, "w_ltime:")) {
+ player_globals.parray[p].w_stats.ltime = atoi(value);
+ } else if (!strcmp(attr, "w_best:")) {
+ player_globals.parray[p].w_stats.best = atoi(value);
+ } else if (!strcmp(attr, "w_wbest:")) {
+ player_globals.parray[p].w_stats.whenbest = atoi(value);
+ } else if (!strcmp(attr, "open:")) {
+ SetPFlag(p, PFLAG_OPEN, atoi(value));
+ } else if (!strcmp(attr, "rated:")) {
+ SetPFlag(p, PFLAG_RATED, atoi(value));
+ } else if (!strcmp(attr, "ropen:")) {
+ SetPFlag(p, PFLAG_ROPEN, atoi(value));
+ } else if (!strcmp(attr, "bell:")) {
+ SetPFlag(p, PFLAG_BELL, atoi(value));
+ } else if (!strcmp(attr, "pgn:")) {
+ SetPFlag(p, PFLAG_PGN, atoi(value));
+ } else if (!strcmp(attr, "timeofreg:")) {
+ player_globals.parray[p].timeOfReg = atoi(value);
+ } else if (!strcmp(attr, "totaltime:")) {
+ player_globals.parray[p].totalTime = atoi(value);
+ } else if (!strcmp(attr, "notifiedby:")) {
+ SetPFlag(p, PFLAG_NOTIFYBY, atoi(value));
+ } else if (!strcmp(attr, "i_login:")) {
+ SetPFlag(p, PFLAG_PIN, atoi(value));
+ } else if (!strcmp(attr, "i_game:")) {
+ SetPFlag(p, PFLAG_GIN, atoi(value));
+ } else if (!strcmp(attr, "i_shout:")) {
+ SetPFlag(p, PFLAG_SHOUT, atoi(value));
+ } else if (!strcmp(attr, "i_cshout:")) {
+ SetPFlag(p, PFLAG_CSHOUT, atoi(value));
+ } else if (!strcmp(attr, "i_tell:")) {
+ SetPFlag(p, PFLAG_TELL, atoi(value));
+ } else if (!strcmp(attr, "i_kibitz:")) {
+ SetPFlag(p, PFLAG_KIBITZ, atoi(value));
+ } else if (!strcmp(attr, "kiblevel:")) {
+ player_globals.parray[p].kiblevel = atoi(value);
+ } else if (!strcmp(attr, "private:")) {
+ SetPFlag(p, PFLAG_PRIVATE, atoi(value));
+ } else if (!strcmp(attr, "jprivate:")) {
+ SetPFlag(p, PFLAG_JPRIVATE, atoi(value));
+ } else if (!strcmp(attr, "automail:")) {
+ SetPFlag(p, PFLAG_AUTOMAIL, atoi(value));
+ } else if (!strcmp(attr, "i_mailmess:")) {
+ SetPFlag(p, PFLAG_MAILMESS, atoi(value));
+ } else if (!strcmp(attr, "style:")) {
+ player_globals.parray[p].style = atoi(value);
+ } else if (!strcmp(attr, "d_time:")) {
+ player_globals.parray[p].d_time = atoi(value);
+ } else if (!strcmp(attr, "d_inc:")) {
+ player_globals.parray[p].d_inc = atoi(value);
+ } else if (!strcmp(attr, "d_height:")) {
+ player_globals.parray[p].d_height = atoi(value);
+ } else if (!strcmp(attr, "d_width:")) {
+ player_globals.parray[p].d_width = atoi(value);
+ } else if (!strcmp(attr, "language:")) {
+ player_globals.parray[p].language = atoi(value);
+ } else if (!strcmp(attr, "admin_level:")) {
+ player_globals.parray[p].adminLevel = atoi(value);
+ if (player_globals.parray[p].adminLevel >= ADMIN_ADMIN)
+ PFlagON(p, PFLAG_ADMINLIGHT);
+ } else if (!strcmp(attr, "i_admin:")) {
+/* player_globals.parray[p].i_admin = atoi(value); */
+ } else if (!strcmp(attr, "computer:")) {
+/* player_globals.parray[p].computer = atoi(value); */
+ } else if (!strcmp(attr, "black_games:")) {
+ player_globals.parray[p].num_black = atoi(value);
+ } else if (!strcmp(attr, "white_games:")) {
+ player_globals.parray[p].num_white = atoi(value);
+ } else if (!strcmp(attr, "uscf:")) {
+/* player_globals.parray[p].uscfRating = atoi(value); */
+ } else if (!strcmp(attr, "muzzled:")) { /* ignore these: obsolete */
+ } else if (!strcmp(attr, "cmuzzled:")) { /* ignore these: obsolete */
+ } else if (!strcmp(attr, "highlight:")) {
+ player_globals.parray[p].highlight = atoi(value);
+ } else if (!strcmp(attr, "network:")) {
+/* player_globals.parray[p].network_player = atoi(value); */
+ } else if (!strcmp(attr, "lasthost:")) {
+ player_globals.parray[p].lastHost.s_addr = atoi(value);
+ } else if (!strcmp(attr, "channel:")) {
+ list_addsub(p,"channel",value, 1);
+ } else if (!strcmp(attr, "num_comments:")) {
+ player_globals.parray[p].num_comments = atoi(value);
+ } else if (!strcmp(attr, "num_plan:")) {
+ player_globals.parray[p].num_plan = atoi(value);
+ if (player_globals.parray[p].num_plan > 0) {
+ for (i = 0; i < player_globals.parray[p].num_plan; i++) {
+ fgets(tmp, MAX_LINE_SIZE, fp);
+ if (!(len = strlen(tmp))) {
+ d_printf( "CHESSD: Error bad plan in file %s\n", file);
+ i--;
+ player_globals.parray[p].num_plan--;
+ } else {
+ tmp[len - 1] = '\0'; /* Get rid of '\n' */
+ player_globals.parray[p].planLines[i] = (len > 1) ? strdup(tmp) : NULL;
+ }
+ }
+ }
+ } else if (!strcmp(attr, "num_formula:")) {
+ player_globals.parray[p].num_formula = atoi(value);
+ if (player_globals.parray[p].num_formula > 0) {
+ for (i = 0; i < player_globals.parray[p].num_formula; i++) {
+ fgets(tmp, MAX_LINE_SIZE, fp);
+ if (!(len = strlen(tmp))) {
+ d_printf( "CHESSD: Error bad formula in file %s\n", file);
+ i--;
+ player_globals.parray[p].num_formula--;
+ } else {
+ tmp[len - 1] = '\0'; /* Get rid of '\n' */
+ player_globals.parray[p].formulaLines[i] = (len > 1) ? strdup(tmp) : NULL;
+ }
+ }
+ }
+ } else if (!strcmp(attr, "formula:")) {
+ player_globals.parray[p].formula = strdup(value);
+ } else if (!strcmp(attr, "num_alias:")) {
+ numAlias = atoi(value);
+ if (numAlias > 0) {
+ for (i = 0; i < numAlias; i++) {
+ fgets(tmp, MAX_LINE_SIZE, fp);
+ if (!(len = strlen(tmp))) {
+ d_printf( "CHESSD: Error bad alias in file %s\n", file);
+ i--;
+ } else {
+ tmp[len - 1] = '\0'; /* Get rid of '\n' */
+ tmp1 = tmp;
+ tmp1 = eatword(tmp1);
+ *tmp1 = '\0';
+ tmp1++;
+ tmp1 = eatwhite(tmp1);
+ alias_add(p, tmp, tmp1);
+ }
+ }
+ player_globals.parray[p].alias_list[i].comm_name = NULL;
+ }
+ } else if (!strcmp(attr, "num_censor:")) {
+ i = atoi(value);
+ while (i--) {
+ fgets(tmp, MAX_LINE_SIZE, fp);
+ if ((!(len = strlen(tmp))) || (len == 1)) { /* blank lines do occur!! */
+ d_printf( "CHESSD: Error bad censor in file %s\n", file);
+ } else {
+ tmp[len - 1] = '\0'; /* Get rid of '\n' */
+ list_add(p, L_CENSOR, tmp);
+ }
+ }
+ } else if (!strcmp(attr, "num_notify:")) {
+ i = atoi(value);
+ while(i--) {
+ fgets(tmp, MAX_LINE_SIZE, fp);
+ if ((!(len = strlen(tmp))) || (len == 1)) { /* blank lines do occur!! */
+ d_printf( "CHESSD: Error bad notify in file %s\n", file);
+ } else {
+ tmp[len - 1] = '\0'; /* Get rid of '\n' */
+ list_add(p, L_NOTIFY, tmp);
+ }
+ }
+ } else if (!strcmp(attr, "num_noplay:")) {
+ i = atoi(value);
+ while(i--) {
+ fgets(tmp, MAX_LINE_SIZE, fp);
+ if ((!(len = strlen(tmp))) || (len == 1)) { /* blank lines do occur!! */
+ d_printf( "CHESSD: Error bad noplay in file %s\n", file);
+ } else {
+ tmp[len - 1] = '\0'; /* Get rid of '\n' */
+ list_add(p, L_NOPLAY, tmp);
+ }
+ }
+ } else if (!strcmp(attr, "num_gnotify:")) {
+ i = atoi(value);
+ while(i--) {
+ fgets(tmp, MAX_LINE_SIZE, fp);
+ if ((!(len = strlen(tmp))) || (len == 1)) { /* blank lines do occur!! */
+ d_printf( "CHESSD: Error bad gnotify in file %s\n", file);
+ } else {
+ tmp[len - 1] = '\0'; /* Get rid of '\n' */
+ list_add(p, L_GNOTIFY, tmp);
+ }
+ }
+ } else if (!strcmp(attr, "num_follow:")) {
+ i = atoi(value);
+ while(i--) {
+ fgets(tmp, MAX_LINE_SIZE, fp);
+ if ((!(len = strlen(tmp))) || (len == 1)) { /* blank lines do occur!! */
+ d_printf( "CHESSD: Error bad follow in file %s\n", file);
+ } else {
+ tmp[len - 1] = '\0'; /* Get rid of '\n' */
+ list_add(p, L_FOLLOW, tmp);
+ }
+ }
+ } else {
+ d_printf( "CHESSD: Error bad attribute >%s< from file %s\n", attr, file);
+ }
+ return 0;
+}
+
+
+
+
+int player_read_old(int p, FILE *fp, const char *pname, const char *fname, int version)
+{
+ char line[MAX_LINE_SIZE];
+ char *attr, *value;
+ int len;
+
+ if (version > 4) { /* eg if two version of code running at diff sites */
+ pprintf(p, "Your account's version number is newer than that of the version running.\n");
+ pprintf(p, "Please see an admin.\n");
+ d_printf("Player %s's version number is incorrect for this version.\n",player_globals.parray[p].name);
+ PFlagOFF(p, PFLAG_REG);
+ player_globals.parray[p].name = strdup(pname);
+ return -1;
+ }
+ if (version > 0) {
+ if (!ReadV1PlayerFmt(p,&player_globals.parray[p], fp, fname, version)) {/* Quick method */
+ /* error in reading; make unreg */
+ PFlagOFF(p, PFLAG_REG);
+ PFlagOFF(p, PFLAG_RATED);
+ pprintf(p, "\n*** WARNING: Your Data file is corrupt. Please tell an admin ***\n");
+ return -1; /* other data has already been freed */
+ }
+ } else {
+ /* do it the old SLOW way */
+ do {
+ if (feof(fp))
+ break;
+ if ((len = strlen(line)) <= 1)
+ continue;
+ line[len - 1] = '\0';
+ attr = eatwhite(line);
+ if (attr[0] == '#')
+ continue; /* Comment */
+ value = eatword(attr);
+ if (!*value) {
+ d_printf( "CHESSD: Error reading file %s\n", fname);
+ continue;
+ }
+ *value = '\0';
+ value++;
+ value = eatwhite(value);
+ stolower(attr);
+ got_attr_value_player(p, attr, value, fp, fname);
+ fgets(line, MAX_LINE_SIZE, fp);
+ } while (!feof(fp));
+ }
+
+ if (!player_globals.parray[p].name) {
+ player_globals.parray[p].name = strdup(pname);
+ pprintf(p, "\n*** WARNING: Your Data file is corrupt. Please tell an admin ***\n");
+ }
+
+ return 0;
+}
+
+
+#if 0
+/* the old and tedious way of writing the player data */
+static void WritePlayerFile_old(FILE* fp, int p)
+{
+ int i;
+ struct player *pp = &player_globals.parray[p];
+
+ fprintf (fp, "v %d\n", 4);
+ if (pp->name == NULL) /* This should never happen! */
+ fprintf (fp,"NONE\n");
+ else
+ fprintf(fp, "%s\n", pp->name);
+ if (pp->fullName == NULL)
+ fprintf (fp,"NONE\n");
+ else
+ fprintf(fp, "%s\n", pp->fullName);
+ if (pp->passwd == NULL)
+ fprintf (fp,"NONE\n");
+ else
+ fprintf(fp, "%s\n", pp->passwd);
+ if (pp->emailAddress == NULL)
+ fprintf (fp,"NONE\n");
+ else
+ fprintf(fp, "%s\n", pp->emailAddress);
+ fprintf(fp, "%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %d\n",
+
+ pp->s_stats.num, pp->s_stats.win, pp->s_stats.los,
+ pp->s_stats.dra, pp->s_stats.rating, (int) (pp->s_stats.sterr * 10.0),
+ pp->s_stats.ltime, pp->s_stats.best, pp->s_stats.whenbest,
+
+ pp->b_stats.num, pp->b_stats.win, pp->b_stats.los,
+ pp->b_stats.dra, pp->b_stats.rating, (int) (pp->b_stats.sterr * 10.0),
+ pp->b_stats.ltime, pp->b_stats.best, pp->b_stats.whenbest,
+
+ pp->w_stats.num, pp->w_stats.win, pp->w_stats.los,
+ pp->w_stats.dra, pp->w_stats.rating, (int) (pp->w_stats.sterr * 10.0),
+ pp->w_stats.ltime, pp->w_stats.best, pp->w_stats.whenbest,
+
+ pp->l_stats.num, pp->l_stats.win, pp->l_stats.los,
+ pp->l_stats.dra, pp->l_stats.rating, (int) (pp->l_stats.sterr * 10.0),
+ pp->l_stats.ltime, pp->l_stats.best, pp->l_stats.whenbest,
+
+ pp->bug_stats.num, pp->bug_stats.win, pp->bug_stats.los,
+ pp->bug_stats.dra, pp->bug_stats.rating, (int) (pp->bug_stats.sterr * 10.0),
+ pp->bug_stats.ltime, pp->bug_stats.best, pp->bug_stats.whenbest,
+ pp->lastHost);
+
+ fprintf (fp, "%s\n", pp->prompt);
+ fprintf (fp, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
+ BoolCheckPFlag(p, PFLAG_OPEN), BoolCheckPFlag(p, PFLAG_RATED),
+ BoolCheckPFlag(p, PFLAG_ROPEN), pp->timeOfReg,
+ pp->totalTime, BoolCheckPFlag(p, PFLAG_BELL),
+ BoolCheckPFlag(p, PFLAG_PGN), BoolCheckPFlag(p, PFLAG_NOTIFYBY),
+ BoolCheckPFlag(p, PFLAG_PIN), BoolCheckPFlag(p, PFLAG_GIN),
+ BoolCheckPFlag(p, PFLAG_AVAIL), BoolCheckPFlag(p, PFLAG_SHOUT),
+ BoolCheckPFlag(p, PFLAG_CSHOUT), BoolCheckPFlag(p, PFLAG_TELL),
+ BoolCheckPFlag(p, PFLAG_KIBITZ), BoolCheckPFlag(p, PFLAG_PRIVATE),
+ BoolCheckPFlag(p, PFLAG_JPRIVATE), BoolCheckPFlag(p, PFLAG_AUTOMAIL),
+ BoolCheckPFlag(p, PFLAG_MAILMESS), pp->style,
+ pp->d_time, pp->d_inc, pp->d_height, pp->d_width, pp->language,
+ pp->adminLevel, pp->num_white, pp->num_black, pp->highlight,
+ pp->num_comments,
+ pp->num_plan, pp->num_formula,list_size(p, L_CENSOR),
+ list_size(p, L_NOTIFY), list_size(p, L_NOPLAY),
+ list_size(p, L_GNOTIFY), pp->numAlias, list_size(p, L_CHANNEL ), pp->availmin, pp->availmax);
+
+ fprintf (fp,"."); /* Dot before plan - stop ill affects of scanf */
+
+ for (i = 0; i < pp->num_plan; i++)
+ fprintf(fp, "%s\n", (pp->planLines[i] ? pp->planLines[i] : ""));
+ for (i = 0; i < pp->num_formula; i++)
+ fprintf(fp, "%s\n", (pp->formulaLines[i] ? pp->formulaLines[i] : ""));
+ if (player_globals.parray[p].formula != NULL)
+ fprintf(fp, "%s\n", pp->formula);
+ else
+ fprintf(fp, "NONE\n");
+ for (i = 0; i < pp->numAlias; i++)
+ fprintf(fp, "%s %s\n", pp->alias_list[i].comm_name,
+ pp->alias_list[i].alias);
+
+ list_print(fp, p, L_CENSOR);
+ list_print(fp, p, L_NOTIFY);
+ list_print(fp, p, L_NOPLAY);
+ list_print(fp, p, L_GNOTIFY);
+ list_print(fp, p, L_CHANNEL);
+}
+#endif
+
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+#include "includes.h"
+
+static double Ratings_B_Average;
+static double Ratings_B_StdDev;
+
+static double Ratings_S_Average;
+static double Ratings_S_StdDev;
+
+static double Ratings_L_Average;
+static double Ratings_L_StdDev;
+
+static double Ratings_Bug_Average;
+static double Ratings_Bug_StdDev;
+
+static double Ratings_W_Average;
+static double Ratings_W_StdDev;
+
+
+static double Rb_M = 0.0, Rb_S = 0.0, Rb_total = 0.0;
+static int Rb_count = 0;
+
+static double Rs_M = 0.0, Rs_S = 0.0, Rs_total = 0.0;
+static int Rs_count = 0;
+
+static double Rl_M = 0.0, Rl_S = 0.0, Rl_total = 0.0;
+static int Rl_count = 0;
+
+static double Rbug_M = 0.0, Rbug_S = 0.0, Rbug_total = 0.0;
+static int Rbug_count = 0;
+
+static double Rw_M = 0.0, Rw_S = 0.0, Rw_total = 0.0;
+static int Rw_count = 0;
+
+/*
+rateStruct bestS[MAX_BEST];
+int numS = 0;
+rateStruct bestB[MAX_BEST];
+int numB = 0;
+rateStruct bestW[MAX_BEST];
+int numW = 0;
+*/
+
+#define MAXHIST 30
+#define LOWESTHIST 800
+static int sHist[MAXHIST];
+static int bHist[MAXHIST];
+static int wHist[MAXHIST];
+static int lHist[MAXHIST];
+static int bugHist[MAXHIST];
+
+static int DisplayRank(int p, param_list param, int showComputers);
+static int DisplayTargetRank(int p, char *target, int show, int showComp);
+static int ShowFromString(char *s);
+static int DisplayRankedPlayers(int p, int start, int end,
+ int show, int showComp);
+static int Best(int p, param_list param, int ShowComp);
+
+static int is_active(int Games)
+{
+ return (Games >= PROVISIONAL);
+}
+
+
+static void rating_add(int rating, int type)
+{
+ int which;
+
+ which = (rating - LOWESTHIST) / 100;
+ if (which < 0)
+ which = 0;
+ if (which >= MAXHIST)
+ which = MAXHIST - 1;
+ if (type == TYPE_BLITZ) {
+ bHist[which] += 1;
+ Rb_count++;
+ Rb_total += rating;
+ if (Rb_count == 1) {
+ Rb_M = rating;
+ } else {
+ Rb_S = Rb_S + (rating - Rb_M) * (rating - Rb_M);
+ Rb_M = Rb_M + (rating - Rb_M) / (Rb_count);
+ }
+ Ratings_B_StdDev = sqrt(Rb_S / Rb_count);
+ Ratings_B_Average = Rb_total / (double) Rb_count;
+ } else if (type == TYPE_WILD) { /* TYPE_WILD */
+ wHist[which] += 1;
+ Rw_count++;
+ Rw_total += rating;
+ if (Rw_count == 1) {
+ Rw_M = rating;
+ } else {
+ Rw_S = Rw_S + (rating - Rw_M) * (rating - Rw_M);
+ Rw_M = Rw_M + (rating - Rw_M) / (Rw_count);
+ }
+ Ratings_W_StdDev = sqrt(Rw_S / Rw_count);
+ Ratings_W_Average = Rw_total / (double) Rw_count;
+ } else if (type == TYPE_LIGHT) { /* TYPE_LIGHT */
+ lHist[which] += 1;
+ Rl_count++;
+ Rl_total += rating;
+ if (Rl_count == 1) {
+ Rl_M = rating;
+ } else {
+ Rl_S = Rl_S + (rating - Rl_M) * (rating - Rl_M);
+ Rl_M = Rl_M + (rating - Rl_M) / (Rl_count);
+ }
+ Ratings_L_StdDev = sqrt(Rl_S / Rl_count);
+ Ratings_L_Average = Rl_total / (double) Rl_count;
+ } else if (type == TYPE_BUGHOUSE) { /* TYPE_BUGHOUSE */
+ bugHist[which] += 1;
+ Rbug_count++;
+ Rbug_total += rating;
+ if (Rbug_count == 1) {
+ Rbug_M = rating;
+ } else {
+ Rbug_S = Rbug_S + (rating - Rbug_M) * (rating - Rbug_M);
+ Rbug_M = Rbug_M + (rating - Rbug_M) / (Rbug_count);
+ }
+ Ratings_Bug_StdDev = sqrt(Rbug_S / Rbug_count);
+ Ratings_Bug_Average = Rbug_total / (double) Rbug_count;
+ } else { /* TYPE_STAND */
+ sHist[which] += 1;
+ Rs_count++;
+ Rs_total += rating;
+ if (Rs_count == 1) {
+ Rs_M = rating;
+ } else {
+ Rs_S = Rs_S + (rating - Rs_M) * (rating - Rs_M);
+ Rs_M = Rs_M + (rating - Rs_M) / (Rs_count);
+ }
+ Ratings_S_StdDev = sqrt(Rs_S / Rs_count);
+ Ratings_S_Average = Rs_total / (double) Rs_count;
+ }
+}
+
+static void rating_remove(int rating, int type)
+{
+ int which;
+
+ which = (rating - LOWESTHIST) / 100;
+ if (which < 0)
+ which = 0;
+ if (which >= MAXHIST)
+ which = MAXHIST - 1;
+ if (type == TYPE_BLITZ) {
+ bHist[which] = bHist[which] - 1;
+ if (bHist[which] < 0)
+ bHist[which] = 0;
+ if (Rb_count == 0)
+ return;
+ Rb_count--;
+ Rb_total -= rating;
+ if (Rb_count == 0) {
+ Rb_M = 0;
+ Rb_S = 0;
+ } else {
+ Rb_M = Rb_M - (rating - Rb_M) / (Rb_count);
+ Rb_S = Rb_S - (rating - Rb_M) * (rating - Rb_M);
+ /* added this 3.11.95 foxbat */ if (Rb_S < 0)
+ Rb_S = 0;
+ }
+ if (Rb_count) {
+ Ratings_B_StdDev = sqrt(Rb_S / Rb_count);
+ Ratings_B_Average = Rb_total / (double) Rb_count;
+ } else {
+ Ratings_B_StdDev = 0;
+ Ratings_B_Average = 0;
+ }
+ } else if (type == TYPE_WILD) { /* TYPE_WILD */
+ wHist[which] = wHist[which] - 1;
+ if (wHist[which] < 0)
+ wHist[which] = 0;
+ if (Rw_count == 0)
+ return;
+ Rw_count--;
+ Rw_total -= rating;
+ if (Rw_count == 0) {
+ Rw_M = 0;
+ Rw_S = 0;
+ } else {
+ Rw_M = Rw_M - (rating - Rw_M) / (Rw_count);
+ Rw_S = Rw_S - (rating - Rw_M) * (rating - Rw_M);
+ /* added this 3.10.95 foxbat */ if (Rw_S < 0)
+ Rw_S = 0;
+ }
+ if (Rw_count) {
+ Ratings_W_StdDev = sqrt(Rw_S / Rw_count);
+ Ratings_W_Average = Rw_total / (double) Rw_count;
+ } else {
+ Ratings_W_StdDev = 0;
+ Ratings_W_Average = 0;
+ }
+ } else if (type == TYPE_LIGHT) { /* TYPE_LIGHT */
+ lHist[which] = lHist[which] - 1;
+ if (lHist[which] < 0)
+ lHist[which] = 0;
+ if (Rl_count == 0)
+ return;
+ Rl_count--;
+ Rl_total -= rating;
+ if (Rl_count == 0) {
+ Rl_M = 0;
+ Rl_S = 0;
+ } else {
+ Rl_M = Rl_M - (rating - Rl_M) / (Rl_count);
+ Rl_S = Rl_S - (rating - Rl_M) * (rating - Rl_M);
+ if (Rl_S < 0)
+ Rl_S = 0;
+ }
+ if (Rl_count) {
+ Ratings_L_StdDev = sqrt(Rl_S / Rl_count);
+ Ratings_L_Average = Rl_total / (double) Rl_count;
+ } else {
+ Ratings_L_StdDev = 0;
+ Ratings_L_Average = 0;
+ }
+ } else if (type == TYPE_BUGHOUSE) { /* TYPE_BUGHOUSE */
+ bugHist[which] = bugHist[which] - 1;
+ if (bugHist[which] < 0)
+ bugHist[which] = 0;
+ if (Rbug_count == 0)
+ return;
+ Rbug_count--;
+ Rbug_total -= rating;
+ if (Rbug_count == 0) {
+ Rbug_M = 0;
+ Rbug_S = 0;
+ } else {
+ Rbug_M = Rbug_M - (rating - Rbug_M) / (Rbug_count);
+ Rbug_S = Rbug_S - (rating - Rbug_M) * (rating - Rbug_M);
+ if (Rbug_S < 0)
+ Rbug_S = 0;
+ }
+ if (Rbug_count) {
+ Ratings_Bug_StdDev = sqrt(Rbug_S / Rbug_count);
+ Ratings_Bug_Average = Rbug_total / (double) Rbug_count;
+ } else {
+ Ratings_Bug_StdDev = 0;
+ Ratings_Bug_Average = 0;
+ }
+ } else { /* TYPE_STAND */
+ sHist[which] = sHist[which] - 1;
+ if (sHist[which] < 0)
+ sHist[which] = 0;
+ if (Rs_count == 0)
+ return;
+ Rs_count--;
+ Rs_total -= rating;
+ if (Rs_count == 0) {
+ Rs_M = 0;
+ Rs_S = 0;
+ } else {
+ Rs_M = Rs_M - (rating - Rs_M) / (Rs_count);
+ Rs_S = Rs_S - (rating - Rs_M) * (rating - Rs_M);
+ /* added this 3.10.95 foxbat */ if (Rs_S < 0)
+ Rs_S = 0;
+ }
+ if (Rs_count) {
+ Ratings_S_StdDev = sqrt(Rs_S / Rs_count);
+ Ratings_S_Average = Rs_total / (double) Rs_count;
+ } else {
+ Ratings_S_StdDev = 0;
+ Ratings_S_Average = 0;
+ }
+ }
+}
+
+static void load_ratings(void)
+{
+ FILE *fp;
+ int i;
+
+ fp = fopen_p("%s/newratingsV%d_data", "r", STATS_DIR, STATS_VERSION);
+ if (!fp) {
+ d_printf( "CHESSD: Can't read ratings data!\n");
+ return;
+ }
+
+ fscanf(fp, "%lf %lf %lf %d", &Rb_M, &Rb_S, &Rb_total, &Rb_count);
+ fscanf(fp, "%lf %lf %lf %d", &Rs_M, &Rs_S, &Rs_total, &Rs_count);
+ fscanf(fp, "%lf %lf %lf %d", &Rw_M, &Rw_S, &Rw_total, &Rw_count);
+ fscanf(fp, "%lf %lf %lf %d", &Rl_M, &Rl_S, &Rl_total, &Rl_count);
+
+ for (i = 0; i < MAXHIST; i++) {
+ fscanf(fp, "%d %d %d %d", &sHist[i], &bHist[i], &wHist[i], &lHist[i]);
+ }
+ fclose(fp);
+ if (Rs_count) {
+ Ratings_S_StdDev = sqrt(Rs_S / Rs_count);
+ Ratings_S_Average = Rs_total / (double) Rs_count;
+ } else {
+ Ratings_S_StdDev = 0;
+ Ratings_S_Average = 0;
+ }
+ if (Rb_count) {
+ Ratings_B_StdDev = sqrt(Rb_S / Rb_count);
+ Ratings_B_Average = Rb_total / (double) Rb_count;
+ } else {
+ Ratings_B_StdDev = 0;
+ Ratings_B_Average = 0;
+ }
+ if (Rw_count) {
+ Ratings_W_StdDev = sqrt(Rw_S / Rw_count);
+ Ratings_W_Average = Rw_total / (double) Rw_count;
+ } else {
+ Ratings_W_StdDev = 0;
+ Ratings_W_Average = 0;
+ }
+ if (Rl_count) {
+ Ratings_L_StdDev = sqrt(Rl_S / Rl_count);
+ Ratings_L_Average = Rl_total / (double) Rl_count;
+ } else {
+ Ratings_L_StdDev = 0;
+ Ratings_L_Average = 0;
+ }
+}
+
+static void save_ratings(void)
+{
+ FILE *fp;
+ int i;
+
+ fp = fopen_p("%s/newratingsV%d_data", "w", STATS_DIR,STATS_VERSION);
+ if (!fp) {
+ d_printf( "CHESSD: Can't write ratings data!\n");
+ return;
+ }
+
+ fprintf(fp, "%10f %10f %10f %d\n", Rb_M, Rb_S, Rb_total, Rb_count);
+ fprintf(fp, "%10f %10f %10f %d\n", Rs_M, Rs_S, Rs_total, Rs_count);
+ fprintf(fp, "%10f %10f %10f %d\n", Rw_M, Rw_S, Rw_total, Rw_count);
+ fprintf(fp, "%10f %10f %10f %d\n", Rl_M, Rl_S, Rl_total, Rl_count);
+
+ for (i = 0; i < MAXHIST; i++) {
+ fprintf(fp, "%d %d %d %d\n", sHist[i], bHist[i], wHist[i], lHist[i]);
+ }
+ fclose(fp);
+}
+
+static void zero_stats(void)
+{
+ int i;
+ for (i = 0; i < MAXHIST; i++) {
+ sHist[i] = 0;
+ bHist[i] = 0;
+ wHist[i] = 0;
+ lHist[i] = 0;
+ }
+ Rb_M = 0.0, Rb_S = 0.0, Rb_total = 0.0;
+ Rb_count = 0;
+
+ Rs_M = 0.0, Rs_S = 0.0, Rs_total = 0.0;
+ Rs_count = 0;
+
+ Rw_M = 0.0, Rw_S = 0.0, Rw_total = 0.0;
+ Rw_count = 0;
+
+ Rl_M = 0.0, Rl_S = 0.0, Rl_total = 0.0;
+ Rl_count = 0;
+}
+
+void ratings_init(void)
+{
+ zero_stats();
+ load_ratings();
+}
+
+static int Round (double x)
+{
+ return (x < 0 ? (int) (x - 0.5) : (int) (x + 0.5));
+}
+
+/* Constants for Glicko system */
+#define Gd 1.483
+#define Gv 0.0005828166666667 /* (0.187)^2 / 60 */
+#define Gr0 1720
+#define Gs0 350
+#define Gq 0.00575646273249 /* ln(10.0)/400.0 */
+#define Gp 0.000010072398601964 /* (3 * Gq / PI)^2 */
+#define GBq 0.00287823136624 /* ln(10.0)/800.0 */
+#define GBp (9 * GBq * GBq / (3.141592653589 * 3.141592653589))
+/* End of Glicko system variables */
+
+static double Gf(double ss)
+{
+ return (1.0 / sqrt(1.0 + Gp * ss * ss));
+}
+
+/* Confusing but economical: calculate error and attenuation function together */
+static double GE(int r, int rr, double ss, double *fss)
+{
+ *fss = Gf(ss);
+ return (1.0 / (1.0 + pow(10.0, (rr - r) * (*fss) / 400.0)));
+}
+
+static double GBf(double sp, double ss, double ssp)
+{
+ return (1.0 / sqrt(1.0 + GBp * (ss*ss + sp*sp + ssp*ssp)));
+}
+
+/* Confusing but economical: calculate error and attenuation function together */
+static double GBE(int r, int rp, int rr, int rrp,
+ double sp, double ss, double ssp, double *fss)
+{
+ *fss = GBf(sp, ss, ssp);
+ return (1.0 / (1.0 + pow(10.0, (rr + rrp - r - rp) * (*fss) / 800.0)));
+}
+
+double current_sterr(double s, long t)
+{
+ double new;
+
+ if (t < 0)
+ t = 0; /* this shouldn't happen */
+ new = sqrt(s * s + Gd * Gd * log(1.0 + t / 60.0)); /* log formula */
+ /* new = sqrt(s * s + Gv * t); */ /* linear formula */
+ if (new > Gs0)
+ new = Gs0;
+ return (new);
+}
+
+static void UpdateStats(struct statistics *p_stats, int *r, double *s, int now)
+{
+ /* Calculate effective pre-game sterrs. ltime==0 implies never had sterr. */
+
+ *s = current_sterr(p_stats->sterr, now - p_stats->ltime);
+
+ /* pre-game ratings */
+ *r = (p_stats->rating == 0 && p_stats->num == 0) ? Gr0
+ : p_stats->rating;
+ return;
+}
+
+static void GetCurrentStats (int p, int *r, double *s, int *new,
+ int *rPart, double *sPart, int type, int now)
+{
+ struct player *pp = &player_globals.parray[p];
+ struct statistics *p_stats = NULL;
+ struct statistics *part_stats; /* for bughouse. */
+
+ switch (type) {
+ case TYPE_BLITZ:
+ p_stats = &pp->b_stats;
+ break;
+ case TYPE_STAND:
+ p_stats = &pp->s_stats;
+ break;
+ case TYPE_WILD:
+ p_stats = &pp->w_stats;
+ break;
+ case TYPE_LIGHT:
+ p_stats = &pp->l_stats;
+ break;
+ case TYPE_BUGHOUSE:
+ p_stats = &pp->bug_stats;
+ part_stats = &player_globals.parray[pp->partner].bug_stats;
+ UpdateStats(part_stats, rPart, sPart, now);
+ break;
+ }
+ /* Calculate effective pre-game sterrs. ltime==0 implies never had sterr. */
+ UpdateStats(p_stats, r, s, now);
+ if (p_stats->rating == 0 && p_stats->num == 0)
+ *new = 1;
+ else *new = 0;
+}
+
+/* Calculates new rating and standard error. By vek. The person */
+/* who invented the ratings system is Mark E. Glickman, Ph.D. */
+/* His e-mail address is glickman@hustat.harvard.edu as of April '95. */
+/* Postscript copy of the note I coded this from should be available */
+/* for ftp from ics.onenet.net, if not elsewhere. */
+
+void rating_sterr_delta(int p1, int p2, int type, int gtime, int result,
+ int *deltarating, double *newsterr)
+{
+
+ double s1, s2, s1part, s2part;
+ int r1, r2, r1part, r2part, new; /* Initial sterrs and ratings */
+ double q, E, fs2, denominator, GK, w; /* Parts of fancy formulas */
+ double delta; /* Result to return */
+
+ GetCurrentStats (p2, &r2, &s2, &new, &r2part, &s2part, type, gtime);
+ GetCurrentStats (p1, &r1, &s1, &new, &r1part, &s1part, type, gtime);
+
+ /* now crunch */
+ if (result == RESULT_WIN) {
+ w = 1.0;
+ } else if (result == RESULT_DRAW) {
+ w = 0.5;
+ } else {
+ w = 0.0;
+ }
+ if (type != TYPE_BUGHOUSE) {
+ q = Gq;
+ E = GE(r1, r2, s2, &fs2); /* side effect: calculate fs2 */
+ } else {
+ q = GBq;
+ E = GBE(r1, r1part, r2, r2part, s1part, s2, s2part, &fs2);
+ }
+ denominator = 1.0 / (s1 * s1) + q * q * fs2 * fs2 * E * (1.0 - E);
+ GK = q * fs2 / denominator;
+
+ delta = GK * (w - E);
+ if (new)
+ *deltarating = Round(Gr0 + delta);
+ else
+ *deltarating = Round(delta); /* Returned values: deltarating,
+ newsterr */
+ *newsterr = 1.0 / sqrt(denominator);
+}
+
+int rating_update(int g, int link_game)
+{
+ int wDelta, bDelta;
+ double wSigma, bSigma; /* vek */
+
+ int wRes, bRes;
+ struct statistics *w_stats;
+ struct statistics *b_stats;
+
+ int gtime;
+
+ int inprogress = (g == player_globals.parray[game_globals.garray[g].black].game);
+ /* if this is adjudication of stored game, be quiet about ratings change */
+
+ if (game_globals.garray[g].type == TYPE_BLITZ) {
+ w_stats = &player_globals.parray[game_globals.garray[g].white].b_stats;
+ b_stats = &player_globals.parray[game_globals.garray[g].black].b_stats;
+ } else if (game_globals.garray[g].type == TYPE_STAND) {
+ w_stats = &player_globals.parray[game_globals.garray[g].white].s_stats;
+ b_stats = &player_globals.parray[game_globals.garray[g].black].s_stats;
+ } else if (game_globals.garray[g].type == TYPE_WILD) {
+ w_stats = &player_globals.parray[game_globals.garray[g].white].w_stats;
+ b_stats = &player_globals.parray[game_globals.garray[g].black].w_stats;
+ } else if (game_globals.garray[g].type == TYPE_LIGHT) {
+ w_stats = &player_globals.parray[game_globals.garray[g].white].l_stats;
+ b_stats = &player_globals.parray[game_globals.garray[g].black].l_stats;
+ } else if (game_globals.garray[g].type == TYPE_BUGHOUSE) {
+ w_stats = &player_globals.parray[game_globals.garray[g].white].bug_stats;
+ b_stats = &player_globals.parray[game_globals.garray[g].black].bug_stats;
+ } else {
+ d_printf( "CHESSD: Can't update untimed ratings!\n");
+ return -1;
+ }
+
+ switch (game_globals.garray[g].result) {
+ case END_CHECKMATE:
+ case END_RESIGN:
+ case END_FLAG:
+ case END_ADJWIN:
+ if (game_globals.garray[g].winner == WHITE) {
+ wRes = RESULT_WIN;
+ bRes = RESULT_LOSS;
+ } else {
+ bRes = RESULT_WIN;
+ wRes = RESULT_LOSS;
+ }
+ break;
+ case END_AGREEDDRAW:
+ case END_REPETITION:
+ case END_50MOVERULE:
+ case END_STALEMATE:
+ case END_NOMATERIAL:
+ case END_BOTHFLAG:
+ case END_ADJDRAW:
+ case END_FLAGNOMATERIAL:
+ wRes = bRes = RESULT_DRAW;
+ break;
+ default:
+ d_printf( "CHESSD: Update undecided game %d?\n", game_globals.garray[g].result);
+ return -1;
+ }
+ /* Use end time, not start time; important for adjourned games. */
+ /* gtime = untenths(game_globals.garray[g].timeOfStart); */
+ gtime = time(0);
+ rating_sterr_delta(game_globals.garray[g].white, game_globals.garray[g].black,
+ game_globals.garray[g].type, gtime, wRes,
+ &wDelta, &wSigma);
+
+ rating_sterr_delta(game_globals.garray[g].black, game_globals.garray[g].white,
+ game_globals.garray[g].type, gtime, bRes,
+ &bDelta, &bSigma);
+
+ /* hersco, 1/23/96: We now know rating changes for these players;
+ update partners' game. */
+ if (link_game >= 0) {
+ game_globals.garray[link_game].winner = CToggle(game_globals.garray[g].winner);
+ game_globals.garray[link_game].result = game_globals.garray[g].result;
+ rating_update (link_game, -1); /* but don't recurse any deeper. */
+ }
+ /* vek: Update time of last rated game played, for future ratings calcs. */
+ /* Kept independently for blitz and standard. */
+ w_stats->ltime = gtime;
+ b_stats->ltime = gtime;
+ /* end vek add 4/5/95 */
+
+ if (wRes == RESULT_WIN) {
+ w_stats->win++;
+ } else if (wRes == RESULT_LOSS) {
+ w_stats->los++;
+ } else {
+ w_stats->dra++;
+ }
+ w_stats->num++;
+ if (bRes == RESULT_WIN) {
+ b_stats->win++;
+ } else if (bRes == RESULT_LOSS) {
+ b_stats->los++;
+ } else {
+ b_stats->dra++;
+ }
+ b_stats->num++;
+ rating_remove(w_stats->rating, game_globals.garray[g].type);
+ rating_remove(b_stats->rating, game_globals.garray[g].type);
+
+ if (inprogress) {
+ pprintf(game_globals.garray[g].white, "%s rating adjustment: %d ",
+ TypeStrings[game_globals.garray[g].type], w_stats->rating);
+ pprintf(game_globals.garray[g].black, "%s rating adjustment: %d ",
+ TypeStrings[game_globals.garray[g].type], b_stats->rating);
+ }
+ if (wDelta < -1000) {
+ pprintf(game_globals.garray[g].white, "not changed due to bug (way too small)! sorry!\n");
+ d_printf( "CHESSD: Got too small ratings bug for %s (w) vs. %s\n",
+ player_globals.parray[game_globals.garray[g].white].login, player_globals.parray[game_globals.garray[g].black].login);
+ } else if (wDelta > 3000) {
+ pprintf(game_globals.garray[g].white, "not changed due to bug (way too big)! sorry!\n");
+ d_printf( "CHESSD: Got too big ratings bug for %s (w) vs. %s\n",
+ player_globals.parray[game_globals.garray[g].white].login, player_globals.parray[game_globals.garray[g].black].login);
+ } else {
+ w_stats->rating += wDelta;
+ w_stats->sterr = wSigma;
+ }
+
+ if (bDelta < -1000) {
+ pprintf(game_globals.garray[g].black, "not changed due to bug (way too small)! sorry! ");
+ d_printf( "CHESSD: Got too small ratings bug for %s (b) vs. %s\n",
+ player_globals.parray[game_globals.garray[g].black].login, player_globals.parray[game_globals.garray[g].white].login);
+ } else if (bDelta > 3000) {
+ pprintf(game_globals.garray[g].black, "not changed due to bug (way too big)! sorry! ");
+ d_printf( "CHESSD: Got too big ratings bug for %s (b) vs. %s\n",
+ player_globals.parray[game_globals.garray[g].black].login, player_globals.parray[game_globals.garray[g].white].login);
+ } else {
+ b_stats->rating += bDelta;
+ b_stats->sterr = bSigma;
+ } /* error messages down to vek */
+
+ rating_add(w_stats->rating, game_globals.garray[g].type);
+ rating_add(b_stats->rating, game_globals.garray[g].type);
+
+ if ((w_stats->rating > w_stats->best) && (is_active(w_stats->num))) {
+ w_stats->best = w_stats->rating;
+ w_stats->whenbest = time(NULL);
+ }
+ if ((b_stats->rating > b_stats->best) && (is_active(b_stats->num))) {
+ b_stats->best = b_stats->rating;
+ b_stats->whenbest = time(NULL);
+ }
+
+/* ratings are saved later - DAV */
+
+/* foxbat 3.11.95 */
+ if (game_globals.garray[g].type == TYPE_BLITZ) {
+ Rb_count++;
+ Rb_total += (w_stats->rating + b_stats->rating) / 2.0;
+ } else if (game_globals.garray[g].type == TYPE_STAND) {
+ Rs_count++;
+ Rs_total += (w_stats->rating + b_stats->rating) / 2.0;
+ } else if (game_globals.garray[g].type == TYPE_LIGHT) {
+ Rl_count++;
+ Rl_total += (w_stats->rating + b_stats->rating) / 2.0;
+ } else if (game_globals.garray[g].type == TYPE_BUGHOUSE) {
+ Rbug_count++;
+ Rbug_total += (w_stats->rating + b_stats->rating) / 2.0;
+ } else if (game_globals.garray[g].type == TYPE_WILD) {
+ Rw_count++;
+ Rw_total += (w_stats->rating + b_stats->rating) / 2.0;
+ }
+/* end add */
+ if (inprogress) {
+ pprintf(game_globals.garray[g].white, "--> %d\n", w_stats->rating);
+ pprintf(game_globals.garray[g].black, "--> %d\n", b_stats->rating);
+ }
+ save_ratings();
+ UpdateRank(game_globals.garray[g].type, player_globals.parray[game_globals.garray[g].white].name,
+ w_stats, player_globals.parray[game_globals.garray[g].white].name);
+ UpdateRank(game_globals.garray[g].type, player_globals.parray[game_globals.garray[g].black].name,
+ b_stats, player_globals.parray[game_globals.garray[g].black].name);
+ return 0;
+}
+
+static void ShowAssess (int p, int p1, int p2, int type1, int type2)
+{
+ int p3, p4;
+ int win1, win2, win3, win4;
+ int draw1, draw2, draw3, draw4;
+ int loss1, loss2, loss3, loss4;
+ double newsterr1, newsterr2, newsterr3, newsterr4;
+ int nowtime = time(0);
+ char line[100]; /* should never need any more than 80. */
+
+ if (type1 == TYPE_BUGHOUSE) {
+ p3 = player_globals.parray[p1].partner;
+ p4 = player_globals.parray[p2].partner;
+ type2 = type1;
+ if (!CheckPFlag(p3, PFLAG_REG) || !CheckPFlag(p4, PFLAG_REG)) {
+ pprintf (p, "Bughouse with unregistered partners cannot be rated.\n");
+ return;
+ }
+ } else {
+ p3 = p1;
+ p4 = p2;
+ }
+ rating_sterr_delta(p1, p2, type1, nowtime, RESULT_WIN, &win1, &newsterr1);
+ rating_sterr_delta(p1, p2, type1, nowtime, RESULT_DRAW, &draw1, &newsterr1);
+ rating_sterr_delta(p1, p2, type1, nowtime, RESULT_LOSS, &loss1, &newsterr1);
+ rating_sterr_delta(p2, p1, type1, nowtime, RESULT_WIN, &win2, &newsterr2);
+ rating_sterr_delta(p2, p1, type1, nowtime, RESULT_DRAW, &draw2, &newsterr2);
+ rating_sterr_delta(p2, p1, type1, nowtime, RESULT_LOSS, &loss2, &newsterr2);
+
+ if (type2 >= 0) {
+ rating_sterr_delta(p3,p4, type2, nowtime,RESULT_WIN, &win3, &newsterr3);
+ rating_sterr_delta(p3,p4, type2, nowtime,RESULT_DRAW, &draw3, &newsterr3);
+ rating_sterr_delta(p3,p4, type2, nowtime,RESULT_LOSS, &loss3, &newsterr3);
+ rating_sterr_delta(p4,p3, type2, nowtime,RESULT_WIN, &win4, &newsterr4);
+ rating_sterr_delta(p4,p3, type2, nowtime,RESULT_DRAW, &draw4, &newsterr4);
+ rating_sterr_delta(p4,p3, type2, nowtime,RESULT_LOSS, &loss4, &newsterr4);
+ }
+ sprintf (line, "%7s", "");
+ if (type1 != TYPE_BUGHOUSE) {
+ CenterText (&line[7], TypeStrings[type1], 35, 1);
+ if (type2 >= 0) {
+ strcat (line, " ");
+ CenterText (&line[44], TypeStrings[type2], 35, 0);
+ }
+ }
+ else {
+ CenterText (&line[7], "Bughouse", 72, 0);
+ }
+ pprintf (p, "\n%s\n", line);
+
+ sprintf (line, "%7s", "");
+ CenterText (&line[7], player_globals.parray[p1].name, 17, 1);
+ strcat (line, " ");
+ CenterText (&line[25], player_globals.parray[p2].name, 17, 1);
+ if (type2 >= 0) {
+ strcat (line, " ");
+ CenterText (&line[44], player_globals.parray[p3].name, 17, 1);
+ strcat (line, " ");
+ CenterText (&line[62], player_globals.parray[p4].name, 17, 0);
+ }
+ pprintf (p, "%s\n", line);
+ pprintf (p, "%7s (%4s RD %5.1f) ",
+ "", ratstrii(GetRating(&player_globals.parray[p1], type1), p1),
+ GetRD(&player_globals.parray[p1], type1));
+ pprintf (p, " (%4s RD %5.1f)",
+ ratstrii(GetRating(&player_globals.parray[p2], type1), p2),
+ GetRD(&player_globals.parray[p2], type1));
+ if (type2 >= 0) {
+ pprintf (p, " (%4s RD %5.1f)",
+ ratstrii(GetRating(&player_globals.parray[p3], type2), p3),
+ GetRD(&player_globals.parray[p3], type2));
+ pprintf (p, " (%4s RD %5.1f)",
+ ratstrii(GetRating(&player_globals.parray[p4], type2), p4),
+ GetRD(&player_globals.parray[p4], type2));
+ }
+ pprintf (p, "\n%7s%9d %17d", "Win:", win1, loss2);
+ if (type2 >= 0)
+ pprintf (p, " %17d %17d", win3, loss4);
+ pprintf (p, "\n%7s%9d %17d", "Draw:", draw1, draw2);
+ if (type2 >= 0)
+ pprintf (p, " %17d %17d", draw3, draw4);
+ pprintf (p, "\n%7s%9d %17d", "Loss:", loss1, win2);
+ if (type2 >= 0)
+ pprintf (p, " %17d %17d", loss3, win4);
+ pprintf (p, "\n%7s%10.1f %17.1f", "New RD:", newsterr1, newsterr2);
+ if (type2 >= 0)
+ pprintf (p, " %17.1f %17.1f", newsterr3, newsterr4);
+ pprintf(p, "\n");
+}
+
+int com_assess(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1 = p, p2, g, gametype = -1;
+ int p1_connected = 1, p2_connected = 1;
+
+/* Hawk: Now assess can be used with players not */
+/* logged on -- I wonder if anyone doesn't */
+/* get just a bit confused here :) */
+
+ if (param[0].type == TYPE_NULL) {
+ g = pp->game;
+ if (g < 0) {
+ pprintf(p, "You are not playing or examining a game.\n");
+ return COM_OK;
+ } else if ((game_globals.garray[g].status == GAME_EXAMINE) || (game_globals.garray[g].status == GAME_SETUP)) {
+ gametype = game_globals.garray[g].type;
+ if (!strcmp(game_globals.garray[g].black_name, pp->name)) {
+ if (game_globals.garray[g].rated) {
+ pcommand(p, "assess %s %s %s\n", game_globals.garray[g].black_name,
+ game_globals.garray[g].white_name, TypeStrings[gametype]);
+ return COM_OK_NOPROMPT;
+ } else {
+ pprintf(p, "You are not involved in a rated game.\n");
+ }
+ } else {
+ if (game_globals.garray[g].rated) {
+ pcommand(p, "assess %s %s %s\n", game_globals.garray[g].white_name,
+ game_globals.garray[g].black_name, TypeStrings[gametype]);
+ return COM_OK_NOPROMPT;
+ } else {
+ pprintf(p, "You are not involved in a rated game.\n");
+ }
+ }
+ return COM_OK;
+ } else {
+ p2 = pp->opponent;
+ gametype = game_globals.garray[g].type;
+ }
+ } else if (param[0].type == TYPE_INT) {
+ if (param[1].type != TYPE_NULL) {
+ pprintf(p, "Assess <game number> cannot use other parameters.\n");
+ return COM_OK;
+ }
+ g = param[0].val.integer - 1;
+ if (g < 0 || g >= game_globals.g_num) {
+ pprintf (p, "There is no game %d.\n", g+1);
+ return COM_OK;
+ }
+ gametype = game_globals.garray[g].type;
+ pcommand(p, "assess %s %s %s\n", game_globals.garray[g].white_name,
+ game_globals.garray[g].black_name, TypeStrings[gametype]);
+ return COM_OK_NOPROMPT;
+ } else {
+ if (!FindPlayer(p, param[0].val.word, &p2, &p2_connected)) {
+ pprintf(p, "No user named \"%s\" was found.\n", param[0].val.word);
+ return COM_OK;
+ }
+ if (param[1].type != TYPE_NULL) {
+ p1 = p2;
+ p1_connected = p2_connected;
+ if (!FindPlayer(p, param[1].val.word, &p2, &p2_connected)) {
+ pprintf(p, "No user named \"%s\" was found.\n", param[1].val.word);
+ if (!p1_connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ if (param[2].type == TYPE_WORD) {
+ param[2].val.word[0] = toupper(param[2].val.word[0]);
+ for (gametype = 0; gametype < NUM_GAMETYPES; gametype++)
+ if (!strcmp(TypeStrings[gametype], param[2].val.word))
+ break;
+ }
+ }
+ }
+ if (gametype >= NUM_GAMETYPES) {
+ pprintf(p, "There is no game type %s.\n", param[2].val.word);
+ } else if (p1 == p2) {
+ pprintf(p, "You can't assess the same players.\n");
+ } else if (!CheckPFlag(p1, PFLAG_REG) || !CheckPFlag(p2, PFLAG_REG)) {
+ pprintf(p, "You can only assess games between registered players.\n");
+ } else if (gametype >= 0) {
+ if (gametype == TYPE_BUGHOUSE
+ && (player_globals.parray[p1].partner < 0 || player_globals.parray[p2].partner < 0)) {
+ pprintf(p, "You can only assess bughouse games if both players have partners.\n");
+ } else if (gametype == TYPE_UNTIMED || gametype == TYPE_NONSTANDARD) {
+ pprintf (p, "%s games are never rated.\n", TypeStrings[gametype]);
+ } else {
+ ShowAssess (p, p1, p2, gametype, -1);
+ }
+ } else {
+ ShowAssess (p, p1, p2, TYPE_BLITZ, TYPE_STAND);
+ ShowAssess (p, p1, p2, TYPE_LIGHT, TYPE_WILD);
+ if (player_globals.parray[p1].partner >= 0 && player_globals.parray[p2].partner >= 0
+ && player_globals.parray[p1].partner != p2)
+ ShowAssess (p, p1, p2, TYPE_BUGHOUSE, TYPE_BUGHOUSE);
+ }
+ if (!p1_connected)
+ player_remove(p1);
+ if (!p2_connected)
+ player_remove(p2);
+ return COM_OK;
+}
+
+
+int com_best(int p, param_list param)
+{
+ return Best(p, param, 1);
+}
+
+int com_hbest(int p, param_list param)
+{
+ return Best(p, param, 0);
+}
+
+#if 0
+int com_best(int p, param_list param)
+{
+ int i;
+
+ pprintf(p, "Standard Blitz Wild\n");
+ for (i = 0; i < MAX_BEST; i++) {
+ if ((i >= numS) && (i >= numB))
+ break;
+ if (i < numS) {
+ pprintf(p, "%4d %-17s ", bestS[i].rating, bestS[i].name);
+ } else {
+ pprintf(p, " ");
+ }
+ if (i < numB) {
+ pprintf(p, "%4d %-17s ", bestB[i].rating, bestB[i].name);
+ } else {
+ pprintf(p, " ");
+ }
+ if (i < numW) {
+ pprintf(p, "%4d %-17s\n", bestW[i].rating, bestW[i].name);
+ } else {
+ pprintf(p, "\n");
+ }
+ }
+ return COM_OK;
+}
+#endif
+
+int com_statistics(int p, param_list param)
+{
+ pprintf(p, " Standard Blitz Lightning Wild\n");
+ pprintf(p, "average: %7.2f %7.2f %7.2f %7.2f\n", Ratings_S_Average, Ratings_B_Average, Ratings_L_Average, Ratings_W_Average);
+ pprintf(p, "std dev: %7.2f %7.2f %7.2f %7.2f\n", Ratings_S_StdDev, Ratings_B_StdDev, Ratings_L_StdDev, Ratings_W_StdDev);
+ pprintf(p, "number : %7d %7d %7d %7d\n", Rs_count, Rb_count, Rl_count, Rw_count);
+ return COM_OK;
+}
+
+int com_fixrank(int p, param_list param)
+{
+ int p1, connected;
+
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+ UpdateRank(TYPE_BLITZ, player_globals.parray[p1].name, &player_globals.parray[p1].b_stats,
+ player_globals.parray[p1].name);
+ UpdateRank(TYPE_STAND, player_globals.parray[p1].name, &player_globals.parray[p1].s_stats,
+ player_globals.parray[p1].name);
+ UpdateRank(TYPE_WILD, player_globals.parray[p1].name, &player_globals.parray[p1].w_stats,
+ player_globals.parray[p1].name);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+int com_rank(int p, param_list param)
+{
+ return DisplayRank(p, param, 1);
+}
+
+int com_hrank(int p, param_list param)
+{
+ return DisplayRank(p, param, 0);
+}
+
+static int DisplayRank(int p, param_list param, int showComputers)
+{
+ struct player *pp = &player_globals.parray[p];
+ int start, end, target, connected;
+ int show = SHOW_BLITZ | SHOW_STANDARD | SHOW_WILD;
+
+ if (param[0].type == TYPE_NULL) {
+ DisplayTargetRank(p, pp->name, show, showComputers);
+ return COM_OK;
+ } else if (isdigit(param[0].val.word[0])) {
+ end = -1;
+ sscanf(param[0].val.word, "%d-%d", &start, &end);
+ if (end > 0 && (param[1].type != TYPE_NULL))
+ show = ShowFromString(param[1].val.word);
+ DisplayRankedPlayers(p, start, end, show, showComputers);
+ return COM_OK;
+ } else {
+ target = player_search(p, param[0].val.word);
+ if (target == 0) {
+ pprintf(p, "Target %s not found.\n", param[0].val.word);
+ return COM_OK;
+ }
+ connected = (target > 0);
+ if (!connected)
+ target = -target - 1;
+ else
+ target--;
+
+ if (param[1].type != TYPE_NULL)
+ show = ShowFromString(param[1].val.word);
+ DisplayTargetRank(p, player_globals.parray[target].name, show, showComputers);
+ if (!connected)
+ player_remove(target);
+ return COM_OK;
+ }
+}
+
+/* CompareStats returns 1 if s1 comes first, -1 if s2 comes first, and 0
+ if neither takes precedence. */
+#if 0
+static int CompareStats(char *name1, statistics *s1,
+ char *name2, statistics *s2)
+{
+ int i, l1;
+
+ if (s1 == NULL)
+ if (s2 == NULL)
+ return 0;
+ else
+ return -1;
+ else if (s2 == NULL)
+ return 1;
+
+ if (s1->rating > s2->rating)
+ return 1;
+ if (s1->rating < s2->rating)
+ return -1;
+ l1 = strlen(name1);
+ for (i = 0; i < l1; i++) {
+ if (name2[i] == '\0')
+ return -1;
+ if (tolower(name1[i]) < tolower(name2[i]))
+ return 1;
+ if (tolower(name1[i]) > tolower(name2[i]))
+ return -1;
+ }
+ if (name2[i] != '\0')
+ return 1;
+/* if (s1->sterr < s2->sterr) return 1;
+ if (s1->sterr > s2->sterr) return -1;
+ if (s1->num > s2->num) return 1;
+ if (s1->num < s2->num) return -1;
+*/
+ d_printf( "Duplicate entries found: %s.\n", name1);
+ return 0;
+}
+#endif
+static int GetRankFileName(char *out, int type)
+{
+ switch (type) {
+ case TYPE_BLITZ:
+ sprintf(out, "%s/rank.blitz", STATS_DIR);
+ return type;
+ case TYPE_STAND:
+ sprintf(out, "%s/rank.std", STATS_DIR);
+ return type;
+ case TYPE_WILD:
+ sprintf(out, "%s/rank.wild", STATS_DIR);
+ return type;
+ default:
+ return -1;
+ }
+}
+
+/* loon: Turning this off 28 Oct 1995 (temporary:)) since we're lagged
+ into outer space */
+void UpdateRank(int type, char *addName,
+ struct statistics *sNew, char *delName)
+{}
+
+#if 0
+void UpdateRank(int type, char *addName,
+ struct statistics *sNew, char *delName)
+{
+ char RankFile[MAX_FILENAME_SIZE];
+ char TmpRankFile[MAX_FILENAME_SIZE];
+ char line[MAX_RANK_LINE];
+ char login[MAX_LOGIN_NAME];
+
+ int comp;
+ statistics sCur;
+ FILE *fp;
+ FILE *fptemp;
+
+ if (GetRankFileName(RankFile, type) < 0)
+ return;
+ fp = fopen_s(RankFile, "r");
+ if (fp == NULL) {
+ d_printf( "Can't open rank file to update.\n");
+ return;
+ }
+ sprintf(TmpRankFile, "%s/tmpRank", sdir);
+ fptemp = fopen_s(TmpRankFile, "w");
+ if (fptemp == NULL) {
+ d_printf("Unable to open rank file for updating.\n");
+ fclose (fp);
+ return;
+ }
+ while (fgets(line, MAX_RANK_LINE - 1, fp)) {
+ sscanf(line, "%s %d %d %d", login, &sCur.rating,
+ &sCur.num, &comp);
+ if (delName != NULL && !strcasecmp(delName, login)) { /* Kill name. */
+ delName = NULL;
+ continue;
+ }
+ if (addName != NULL && CompareStats(addName, sNew, login, &sCur) > 0) {
+ int computer = in_list(-1, L_COMPUTER, addName);
+ fprintf(fptemp, "%s %d %d %d\n", addName, sNew->rating,
+ sNew->num, computer);
+ addName = NULL;
+ }
+ fprintf(fptemp, "%s %d %d %d\n", login, sCur.rating, sCur.num, comp);
+ }
+ fclose(fptemp);
+ fclose(fp);
+
+ rename(TmpRankFile, RankFile);
+}
+#endif
+
+static void DisplayRankHead(int p, int show)
+{
+ char Line[MAX_STRING_LENGTH];
+
+ Line[0] = '\0';
+ if (CheckFlag(show, SHOW_BLITZ))
+ strcat(Line, " Blitz ");
+ if (CheckFlag(show, SHOW_STANDARD))
+ strcat(Line, " Standard ");
+ if (CheckFlag(show, SHOW_WILD))
+ strcat(Line, " Wild");
+ pprintf(p, "%s\n\n", Line);
+}
+
+static int CountRankLine(int countComp, char *loginName,
+ int num, int is_computer)
+{
+ if (loginName == NULL || loginName[0] == '\0')
+ return 0;
+ return (countComp || !is_computer) && (is_active(num));
+}
+
+static int GetRank(FILE * fp, char *target, int countComp)
+{
+ int count = 0;
+ int nGames, is_computer;
+ int playerFound = 0;
+ char line[MAX_RANK_LINE];
+ char login[MAX_LOGIN_NAME];
+
+ while (fgets(line, MAX_RANK_LINE - 1, fp) && !playerFound) {
+ sscanf(line, "%s %*d %d %d", login, &nGames, &is_computer);
+ if ((playerFound = !strcasecmp(login, target))
+ || CountRankLine(countComp, login, nGames, is_computer))
+ count++;
+ }
+ return (playerFound ? count : -1);
+}
+
+static void PositionFilePtr(FILE * fp, int count, int *last,
+ int *nTied, int showComp)
+{
+ int i, rating, nGames, is_computer;
+ char login[MAX_LOGIN_NAME];
+ char line[MAX_RANK_LINE];
+
+ if (fp == NULL)
+ return;
+ rewind(fp);
+ for (i = 1; i < count; i++) {
+ do {
+ fgets(line, MAX_RANK_LINE - 1, fp);
+ if (feof(fp))
+ break;
+ sscanf(line, "%s %d %d %d", login, &rating, &nGames, &is_computer);
+ } while (!CountRankLine(showComp, login, nGames, is_computer));
+ if (rating != *last) {
+ *nTied = 1;
+ *last = rating;
+ } else
+ (*nTied)++;
+ }
+}
+
+static int ShowRankEntry(int p, FILE * fp, int count, int comp,
+ char *target, int *lastRating, int *nTied)
+{
+ char newLine[MAX_RANK_LINE];
+ char login[MAX_LOGIN_NAME];
+ int rating, findable, nGames, is_comp;
+
+ findable = (count > 0) && !feof(fp);
+ if (findable) {
+ do {
+ fgets(newLine, MAX_RANK_LINE - 1, fp);
+ if (feof(fp))
+ findable = 0;
+ else if (newLine[0] != '\0')
+ sscanf(newLine, "%s %d %d %d",
+ login, &rating, &nGames, &is_comp);
+ else
+ login[0] = '\0';
+ } while (!CountRankLine(comp, login, nGames, is_comp) && findable
+ && strcasecmp(login, target));
+ }
+ if (findable) {
+ if (!strcasecmp(login, target)
+ && !CountRankLine(comp, login, nGames, is_comp)) {
+ pprintf_highlight(p, "---- %-12.12s %4s", login, ratstr(rating));
+ pprintf(p, " ");
+ return 0;
+ } else if (*lastRating == rating && *nTied < 1) {
+ pprintf(p, " ");
+ if (!strcasecmp(login, target))
+ pprintf_highlight(p, "%-12.12s %4s", login, ratstr(rating));
+ else
+ pprintf(p, "%-12.12s %4s", login, ratstr(rating));
+ pprintf(p, " ");
+ return 1;
+ } else {
+ if (*nTied >= 1) {
+ if (*lastRating == rating)
+ count -= *nTied;
+ *nTied = -1;
+ }
+ if (!strcasecmp(login, target))
+ pprintf_highlight(p, "%4d. %-12.12s %4s",
+ count, login, ratstr(rating));
+ else
+ pprintf(p, "%4d. %-12.12s %4s",
+ count, login, ratstr(rating));
+ pprintf(p, " ");
+ *lastRating = rating;
+ return 1;
+ }
+ } else {
+ pprintf(p, "%25s", "");
+ return 1;
+ }
+}
+
+static int CountAbove(int num, int blitz, int std, int wild, int which)
+{
+ int max = blitz;
+
+ if (max < std)
+ max = std;
+ if (max < wild)
+ max = wild;
+ return (max <= (num + 1) / 2 ? max - 1 : (num + 1) / 2);
+}
+
+static int ShowRankLines(int p, FILE * fb, FILE * fs, FILE * fw, int bCount,
+ int sCount, int wCount, int n, int showComp, int show, char *target)
+{
+ int lastBlitz = 9999, nTiedBlitz = 0;
+ int lastStd = 9999, nTiedStd = 0;
+ int lastWild = 9999, nTiedWild = 0;
+ int i;
+
+ if (n <= 0)
+ return 0;
+ if (CheckFlag(show, SHOW_BLITZ)) {
+ PositionFilePtr(fb, bCount, &lastBlitz, &nTiedBlitz, showComp);
+ if (feof(fb))
+ FlagOFF(show, SHOW_BLITZ);
+ }
+ if (CheckFlag(show, SHOW_STANDARD)) {
+ PositionFilePtr(fs, sCount, &lastStd, &nTiedStd, showComp);
+ if (feof(fs))
+ FlagOFF(show, SHOW_STANDARD);
+ }
+ if (CheckFlag(show, SHOW_WILD)) {
+ PositionFilePtr(fw, wCount, &lastWild, &nTiedWild, showComp);
+ if (feof(fw))
+ FlagOFF(show, SHOW_WILD);
+ }
+ if (!CheckFlag(show, SHOW_BLITZ | SHOW_STANDARD | SHOW_WILD))
+ return 0;
+ DisplayRankHead(p, show);
+
+ for (i = 0; i < n && show; i++) {
+ if (CheckFlag(show, SHOW_BLITZ))
+ bCount += ShowRankEntry(p, fb, bCount, showComp, target,
+ &lastBlitz, &nTiedBlitz);
+ if (CheckFlag(show, SHOW_STANDARD))
+ sCount += ShowRankEntry(p, fs, sCount, showComp, target,
+ &lastStd, &nTiedStd);
+ if (CheckFlag(show, SHOW_WILD))
+ wCount += ShowRankEntry(p, fw, wCount, showComp, target,
+ &lastWild, &nTiedWild);
+ pprintf(p, "\n");
+ }
+ return 1;
+}
+
+static int DisplayTargetRank(int p, char *target, int show, int showComp)
+{
+ int numToShow = 20;
+ int blitzRank = -1, blitzCount;
+ int stdRank = -1, stdCount;
+ int wildRank = -1, wildCount;
+ int numAbove;
+ char Path[MAX_FILENAME_SIZE];
+ FILE *fb = NULL, *fs = NULL, *fw = NULL;
+
+ if (CheckFlag(show, SHOW_BLITZ)) {
+ GetRankFileName(Path, TYPE_BLITZ);
+ fb = (FILE *) fopen_s(Path, "r");
+ if (fb != NULL)
+ blitzRank = GetRank(fb, target, showComp);
+ if (blitzRank < 0)
+ FlagOFF(show, SHOW_BLITZ);
+ }
+ if (CheckFlag(show, SHOW_STANDARD)) {
+ GetRankFileName(Path, TYPE_STAND);
+ fs = (FILE *) fopen_s(Path, "r");
+ if (fs != NULL)
+ stdRank = GetRank(fs, target, showComp);
+ if (stdRank < 0)
+ FlagOFF(show, SHOW_STANDARD);
+ }
+ if (CheckFlag(show, SHOW_WILD)) {
+ GetRankFileName(Path, TYPE_WILD);
+ if (CheckFlag(show, SHOW_WILD))
+ fw = (FILE *) fopen_s(Path, "r");
+ if (fw != NULL)
+ wildRank = GetRank(fw, target, showComp);
+ if (wildRank < 0)
+ FlagOFF(show, SHOW_WILD);
+ }
+ if (!CheckFlag(show, SHOW_BLITZ | SHOW_STANDARD | SHOW_WILD)) {
+ pprintf(p, "No ratings to show.\n");
+ if (fb != NULL) fclose(fb);
+ if (fs != NULL) fclose(fs);
+ if (fw != NULL) fclose(fw);
+ return (0);
+ }
+ numAbove = CountAbove(numToShow, blitzRank, stdRank, wildRank, show);
+ blitzCount = blitzRank - numAbove;
+ stdCount = stdRank - numAbove;
+ wildCount = wildRank - numAbove;
+
+ ShowRankLines(p, fb, fs, fw, blitzCount, stdCount, wildCount,
+ numToShow, showComp, show, target);
+ if (fb != NULL) fclose(fb);
+ if (fs != NULL) fclose(fs);
+ if (fw != NULL) fclose(fw);
+ return (1);
+}
+
+static int DisplayRankedPlayers(int p, int start, int end,
+ int show, int showComp)
+{
+ int num = end - start + 1;
+ FILE *fb = NULL, *fs = NULL, *fw = NULL;
+ char Path[MAX_FILENAME_SIZE];
+
+ if (start <= 0)
+ start = 1;
+ if (num <= 0)
+ return 0;
+ if (num > 100)
+ num = 100;
+ if (CheckFlag(show, SHOW_BLITZ)) {
+ GetRankFileName(Path, TYPE_BLITZ);
+ fb = (FILE *) fopen_s(Path, "r");
+ if (fb == NULL)
+ FlagOFF(show, SHOW_BLITZ);
+ }
+ if (CheckFlag(show, SHOW_STANDARD)) {
+ GetRankFileName(Path, TYPE_STAND);
+ fs = (FILE *) fopen_s(Path, "r");
+ if (fs == NULL)
+ FlagOFF(show, SHOW_STANDARD);
+ }
+ if (CheckFlag(show, SHOW_WILD)) {
+ GetRankFileName(Path, TYPE_WILD);
+ fw = (FILE *) fopen_s(Path, "r");
+ if (fw == NULL)
+ FlagOFF(show, SHOW_WILD);
+ }
+ ShowRankLines(p, fb, fs, fw, start, start, start,
+ num, showComp, show, "");
+ if (fb)
+ fclose(fb);
+ if (fs)
+ fclose(fs);
+ if (fw)
+ fclose(fw);
+ return 1;
+}
+
+static int ShowFromString(char *s)
+{
+ int i, len = strlen(s);
+ int show = 0;
+
+ if (s == NULL || s[0] == '\0')
+ return SHOW_BLITZ | SHOW_STANDARD | SHOW_WILD;
+ for (i = 0; i < len; i++) {
+ switch (s[i]) {
+ case 'b':
+ FlagON(show, SHOW_BLITZ);
+ break;
+ case 's':
+ FlagON(show, SHOW_STANDARD);
+ break;
+ case 'w':
+ FlagON(show, SHOW_WILD);
+ break;
+ }
+ }
+ return (show);
+}
+
+static int Best(int p, param_list param, int ShowComp)
+{
+ int show = SHOW_BLITZ | SHOW_STANDARD | SHOW_WILD;
+
+ if (param[0].type != TYPE_NULL)
+ show = ShowFromString(param[0].val.word);
+
+ DisplayRankedPlayers(p, 1, 20, show, ShowComp);
+ return COM_OK;
+}
+
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+#ifndef _RATINGS_H
+#define _RATINGS_H
+
+#define STATS_VERSION 2
+
+#define RESULT_WIN 0
+#define RESULT_DRAW 1
+#define RESULT_LOSS 2
+#define RESULT_ABORT 3
+
+#define PROVISIONAL 20
+
+#define MAX_RANK_LINE 50
+#define MAX_BEST 20
+
+#define SHOW_BLITZ 0x1
+#define SHOW_STANDARD 0x2
+#define SHOW_WILD 0x4
+
+typedef struct rateStruct {
+ char name[MAX_LOGIN_NAME];
+ int rating;
+} rateStruct;
+
+#endif /* _RATINGS_H */
+
--- /dev/null
+/*
+ load/unload local variables
+
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+#include "includes.h"
+
+static void variable_reload(void)
+{
+ if (config_open() != 0) {
+ d_printf("CHESSD: config database open failed\n");
+ exit(1);
+ }
+
+ news_open();
+ commands_init();
+ ratings_init();
+ wild_init();
+ book_open();
+
+ init_userstat();
+}
+
+/* initialise variables that can be re-initialised on code reload */
+void initial_load(void)
+{
+ command_globals.startuptime = time(0);
+
+ seek_globals.quota_time = 60;
+ command_globals.player_high = 0;
+ command_globals.game_high = 0;
+ srandom(command_globals.startuptime);
+ variable_reload();
+}
+
+/* initialise variables that can be re-initialised on code reload */
+void reload_open(void)
+{
+ load_all_globals("globals.dat");
+ variable_reload();
+}
+
+
+/* initialise variables that can be re-initialised on code reload */
+void reload_close(void)
+{
+ news_close();
+ config_close();
+ book_close();
+ lists_close();
+ save_all_globals("globals.dat");
+ m_free_all();
+}
--- /dev/null
+/*
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+#include "includes.h"
+
+enum { SEEKOPEN = 0, SEEKCLOSED };
+
+/* The values of the follwing enums cannot be changed as they will end up */
+/* Being seen by the client- we can add values later but the ones */
+/* Here, after being documented, have to be here forever */
+enum { LIGHTNING = 0, STANDARD, BLITZ, UNTIMED };
+
+#undef BLACK
+#undef WHITE
+enum { BLACK = 0, WHITE};
+
+
+static int get_empty_seekslot(void);
+static char *form_ad(struct pending * ad, int i);
+
+int com_seek(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1, count = 0;
+ int num; /* sought ID */
+ char *msgtxt;
+ char board[1], category[1];
+
+
+ srandom(time(0));
+#if 0
+ if (!CheckPFlag(p, PFLAG_REG)) {
+ pprintf(p, "Only registered players can use the seek command.\n");
+ return COM_OK;
+ }
+#endif
+
+ if ((pp->game >= 0) && ((game_globals.garray[pp->game].status == GAME_EXAMINE) || (game_globals.garray[pp->game].status == GAME_SETUP))) {
+ pprintf(p, "ERROR: You can't seek a game while you are examining one.\n");
+ return COM_OK;
+ }
+ if (pp->game >= 0) {
+ pprintf(p, "ERROR: You can't seek a game while you are playing one.\n");
+ return COM_OK;
+ }
+ num = get_empty_seekslot();
+ if (num == -1) {
+ pprintf(p, "ERROR: Sorry, all available slots for seek are closed.\n");
+ return COM_OK;
+ }
+ seek_globals.ads[num].status = SEEKCLOSED;
+ seek_globals.ads[num].whofrom = p;
+
+ if (param[0].type == TYPE_INT)
+ seek_globals.ads[num].wtime = param[0].val.integer; /* White time */
+ else
+ seek_globals.ads[num].wtime = pp->d_time;
+
+ if (param[1].type == TYPE_INT)
+ seek_globals.ads[num].winc = param[1].val.integer; /* White increment */
+ else
+ seek_globals.ads[num].winc = pp->d_inc;
+
+ seek_globals.ads[num].btime = seek_globals.ads[num].wtime; /* Black time */
+ seek_globals.ads[num].binc = seek_globals.ads[num].winc; /* Black increment */
+
+ if (param[2].type == TYPE_INT) {
+ if (param[2].val.integer == UNRATED || !CheckPFlag(p, PFLAG_REG) || seek_globals.ads[num].wtime == 0)
+ seek_globals.ads[num].rated = UNRATED; /* unrated */
+ else if (param[2].val.integer == RATED)
+ seek_globals.ads[num].rated = RATED; /* rated */
+ } else
+ seek_globals.ads[num].rated = BoolCheckPFlag(p, PFLAG_RATED);
+
+
+ if (param[3].type == TYPE_INT) {
+ if (param[3].val.integer == WHITE)
+ seek_globals.ads[num].seek_color = WHITE;
+ else if (param[3].val.word[0] == BLACK)
+ seek_globals.ads[num].seek_color = BLACK;
+ } else
+ seek_globals.ads[num].seek_color = random() % 2;
+
+ category[0]='\0';
+ board[0]='\0';
+ /* FIXME- use proper values */
+ seek_globals.ads[num].category = strdup(category);
+ seek_globals.ads[num].board_type = strdup(board);
+
+ seek_globals.ads[num].next = NULL;
+
+ msgtxt = form_ad(&seek_globals.ads[num], num);
+
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if ((p1 == p) || !CheckPFlag(p1, PFLAG_ADS)
+ || (player_globals.parray[p1].status != PLAYER_PROMPT)
+ || (player_censored(p1, p)))
+ continue;
+ count++;
+ pprintf(p1, "%s", msgtxt);
+ }
+ pprintf(p, "%s", msgtxt);
+ free(msgtxt);
+
+ return COM_OK;
+}
+
+int com_play(int p, param_list param)
+{
+ int game;
+
+ game = param[0].val.integer;
+
+ if (seek_globals.ads[game].status != SEEKCLOSED) {
+ pprintf(p, "ERROR: Either that game has already started or "
+ "it is no longer available.\n");
+ return COM_OK;
+ }
+ if (!CheckPFlag(p, PFLAG_REG) && seek_globals.ads[game].rated == 1) {
+ pprintf(p, "ERROR: Unregistred users cannot play rated games.\n");
+ return COM_OK;
+ }
+ if (seek_globals.ads[game].whofrom == p) {
+ pprintf(p, "ERROR: You cannot respond to your own seek ads\n");
+ return COM_OK;
+ }
+ seek_globals.ads[game].whoto = p;
+
+ decline_withdraw_offers(p, -1, PEND_ALL, DO_DECLINE | DO_WITHDRAW);
+ decline_withdraw_offers(seek_globals.ads[game].whofrom, -1, PEND_ALL, DO_DECLINE | DO_WITHDRAW);
+
+ accept_match(&seek_globals.ads[game], p, seek_globals.ads[game].whofrom);
+#if 0
+ free(seek_globals.ads[game].category);
+ free(seek_globals.ads[game].board_type);
+#endif
+return 0;
+}
+
+int com_sought(int p, param_list param)
+{
+ int i;
+
+ for (i = 0; i < seek_globals.max_ads; i++) {
+ if (seek_globals.ads[i].status == SEEKCLOSED) {
+ char *msgtxt = form_ad(&seek_globals.ads[i], i);
+ pprintf(p, "%s", msgtxt);
+ free(msgtxt);
+ }
+ }
+ return COM_OK;
+}
+
+
+int com_unseek(int p, param_list param)
+{
+ /* TODO: need to add parameters */
+ withdraw_seeks(p);
+ return COM_OK;
+}
+
+void withdraw_seeks(int p)
+{
+ int i, p1;
+
+ for (i = 0; i < seek_globals.max_ads; i++) {
+ if (seek_globals.ads[i].whofrom == p &&
+ seek_globals.ads[i].status == SEEKCLOSED) {
+ seek_globals.ads[i].status = SEEKOPEN;
+
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if ((p1 == p) || (player_globals.parray[p1].status != PLAYER_PROMPT) ||
+ (player_censored(p1, p)) || !CheckPFlag(p1,PFLAG_ADS))
+ continue;
+ pprintf_prompt(p1, "AD_DESTROY: %d\n", i);
+ }
+ pprintf(p, "AD_DESTROY: %d\n", i);
+ FREE(seek_globals.ads[i].category);
+ FREE(seek_globals.ads[i].board_type);
+ }
+ }
+}
+
+static int get_empty_seekslot(void)
+{
+ int i;
+
+ for (i = 0; i < seek_globals.max_ads; i++) {
+ if (seek_globals.ads[i].status != SEEKCLOSED)
+ return i;
+ }
+
+ if (seek_globals.max_ads >= config_get_int("MAX_SOUGHT", DEFAULT_MAX_SOUGHT)) {
+ d_printf("Too many seeks! please raise MAX_SOUGHT\n");
+ return -1;
+ }
+
+ seek_globals.max_ads += 100;
+ seek_globals.ads = (struct pending *)realloc(seek_globals.ads,
+ seek_globals.max_ads * sizeof(struct pending));
+
+ ZERO_STRUCT(seek_globals.ads[i]);
+ return i;
+
+}
+
+static char *form_ad(struct pending * ad, int i)
+{
+
+ char *final;
+ int rating, total, type;
+
+ total = ad->wtime * 60 + ad->winc * 40;
+
+ if(total == 0) {
+ type = UNTIMED;
+ rating = player_globals.parray[ad->whofrom].l_stats.rating;
+ } else if (total < 180) {
+ type = LIGHTNING;
+ rating = player_globals.parray[ad->whofrom].l_stats.rating;
+ } else if (total >= 900) {
+ type = STANDARD;
+ rating = player_globals.parray[ad->whofrom].s_stats.rating;
+ } else {
+ type = BLITZ;
+ rating = player_globals.parray[ad->whofrom].b_stats.rating;
+ }
+
+ asprintf(&final, "%3u %4u %-17s %3u %3u %-7s %-10s\n",
+ i,
+ rating,
+ player_globals.parray[ad->whofrom].name,
+ ad->wtime,
+ ad->winc,
+ ad->rated?"rated":"unrated",
+ TypeStrings[ad->seek_color]);
+
+ return final;
+}
--- /dev/null
+/*
+ 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 2 of the License, 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.
+*/
+
+/* setup.c
+
+ Contains stuff for setting up boards in examine mode
+
+*/
+
+#include "includes.h"
+
+static int check_valid_square(char* square)
+{
+ if (strlen (square) == 2) {
+ if ( (square[0] <= 'a') && (square[0] >= 'h')
+ && (square[1] <= '1') && (square [1] >= '8') )
+ return 0;
+ return 1;
+ } else
+ return 0;
+}
+
+/* Check the position is valid
+ ie two kings - one white one black
+ ie no pawns on 1st or 8th ranks
+ only the king that is to move may be in check,
+ checkmate and stalemate */
+
+static int validate_position (int p,struct game_state_t *b)
+{
+ int r,f,check;
+ int white_k = 0;
+ int black_k = 0;
+
+ for (f = 0; (f < 8); f++) {
+ for (r = 0; (r < 8); r++) {
+ if (b->board[f][r] == W_KING) {
+ white_k += 1;
+ if (white_k == 2) {
+ pprintf (p,"You can only have one white king.\n");
+ return 0;
+ }
+ }
+ if (b->board[f][r] == B_KING) {
+ black_k += 1;
+ if (black_k == 2) {
+ pprintf (p,"You can only have one black king.\n");
+ return 0;
+ }
+ }
+ if (((b->board[f][r] == W_PAWN) || (b->board[f][r] == B_PAWN)) &&
+ ((r == 0) || (r == 7))) {
+ pprintf (p,"Pawns cannot be placed on the first or eighth rank.\n");
+ return 0;
+ }
+ }
+ }
+ if (!white_k) {
+ pprintf (p,"There is no white king.\n");
+ return 0;
+ }
+ if (!black_k) {
+ pprintf (p,"There is no black king.\n");
+ return 0;
+ }
+ if (b->onMove == WHITE) { pprintf(p, "WHITE to move\n"); }
+ else if (b->onMove == BLACK) { pprintf(p, "BLACK to move\n"); }
+ else pprintf(p, "ERROR!!\n");
+ check = in_check(b);
+ if (check) {
+ pprintf (p,"Only the player to move may be in check.\n");
+ return 0;
+ }
+ if (!has_legal_move(b)) {
+ b->onMove = CToggle(b->onMove);
+ if (in_check(b)) {
+ pprintf (p, "%s is checkmated.\n",
+ b->onMove == WHITE ? "BLACK" : "WHITE");
+ } else {
+ pprintf (p, "%s is stalemated.\n",
+ b->onMove == WHITE ? "BLACK" : "WHITE");
+ }
+ b->onMove = CToggle(b->onMove);
+ }
+ return 1; /* valid position */
+}
+
+int com_setup (int p,param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int gamenum;
+
+ if ((pp->game <0) || (game_globals.garray[pp->game].status != GAME_SETUP)) {
+ if (param[0].type == TYPE_NULL) {
+ if (pp->game >= 0)
+ if (game_globals.garray[pp->game].status == GAME_EXAMINE) {
+ game_free (pp->game);
+ game_globals.garray[pp->game].status = GAME_SETUP;
+ game_globals.garray[pp->game].numHalfMoves = 0;
+ game_globals.garray[pp->game].totalHalfMoves = 0;
+ game_globals.garray[pp->game].revertHalfMove = 0;
+ pprintf (p,"Entering examine(setup) mode.\n");
+ return COM_OK;
+ }
+ pcommand (p,"examine setup");
+ return COM_OK_NOPROMPT;
+ } else {
+ pprintf(p, "You are not setting up a position.\n");
+ return COM_OK;
+ }
+ }
+ gamenum = game_globals.garray[pp->game].game_state.gameNum;
+ if (param[0].type != TYPE_NULL) {
+ if (!strcmp("clear",param[0].val.word)) {
+ board_clear(&(game_globals.garray[pp->game].game_state));
+ game_globals.garray[pp->game].game_state.gameNum = gamenum;
+ send_board_to(pp->game, p);
+ pprintf (p,"Board cleared.\n");
+ return COM_OK;
+ } else if (!strcmp("start",param[0].val.word)) {
+ board_standard(&(game_globals.garray[pp->game].game_state));
+ game_globals.garray[pp->game].game_state.gameNum = gamenum;
+ send_board_to(pp->game, p);
+ pprintf (p,"Board set up as starting position.\n");
+ return COM_OK;
+ } else if (!strcmp("fen",param[0].val.word) && param[1].type != TYPE_NULL) {
+ FEN_to_board(param[1].val.string, &(game_globals.garray[pp->game].game_state));
+ game_globals.garray[pp->game].game_state.gameNum = gamenum;
+ send_board_to(pp->game, p);
+ pprintf (p,"Board set up by FEN.\n");
+ return COM_OK;
+ } else if (!strcmp("done",param[0].val.word)) {
+ if (validate_position (p,&(game_globals.garray[pp->game].game_state))) {
+ game_globals.garray[pp->game].status = GAME_EXAMINE;
+ pprintf(p,"Game is validated - entering examine mode.\n");
+ MakeFENpos(pp->game, game_globals.garray[pp->game].FENstartPos);
+ } else
+ pprintf(p,"The position is not valid - staying in setup mode.\n");
+ return COM_OK;
+ } else { /* try to load a category of board */
+ if (param[1].type != TYPE_NULL) {
+ if (!board_init (pp->game,&(game_globals.garray[pp->game].game_state),param[0].val.word,param[1].val.word)) {
+ game_globals.garray[pp->game].game_state.gameNum = gamenum;
+ send_board_to(pp->game, p);
+ pprintf (p,"Board set up as %s %s.\n",param[0].val.word,param[1].val.word);
+ } else {
+ pprintf (p,"Board %s %s is unavailable.\n",param[0].val.word,param[1].val.word);
+ game_globals.garray[pp->game].game_state.gameNum = gamenum;
+ }
+ return COM_OK;
+ }
+ }
+ }
+ pprintf (p, "You have supplied an incorrect parameter to setup.\n");
+ return COM_OK;
+}
+
+int com_tomove (int p,param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ if ((pp->game <0) || (game_globals.garray[pp->game].status != GAME_SETUP)) {
+ if (pp->game >= 0)
+ if (game_globals.garray[pp->game].status == GAME_EXAMINE) {
+ pprintf (p,"This game is active - type 'setup' to allow editing.\n");
+ return COM_OK;
+ }
+ pprintf(p, "You are not setting up a position.\n");
+ return COM_OK;
+ }
+ if (!strcmp("white",param[0].val.word))
+ game_globals.garray[pp->game].game_state.onMove = WHITE;
+ else if (!strcmp("black",param[0].val.word))
+ game_globals.garray[pp->game].game_state.onMove = BLACK;
+ else {
+ pprintf (p,"Please type: tomove white or tomove black\n");
+ return COM_OK;
+ }
+ pcommand (p,"refresh");
+ return COM_OK_NOPROMPT;
+}
+
+int com_clrsquare (int p,param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ if ((pp->game <0) || (game_globals.garray[pp->game].status != GAME_SETUP)) {
+ if (pp->game >= 0)
+ if (game_globals.garray[pp->game].status == GAME_EXAMINE) {
+ pprintf (p,"This game is active - type 'setup' to allow editing.\n");
+ return COM_OK;
+ }
+ pprintf(p, "You are not setting up a position.\n");
+ return COM_OK;
+ }
+
+ if (!check_valid_square(param[0].val.word)) {
+ pprintf (p,"You must specify a square.");
+ return COM_OK;
+ }
+
+ pcommand (p,"x@%s",param[0].val.word);
+ return COM_OK_NOPROMPT;
+}
+
+/* allows the following
+
+ x@rf or X@rf - clear a square
+ P@rf - drop a white pawn
+ p@rf - drop a black pawn
+ wp@rf - drop a white pawn
+ bp@rf - drop a black pawn
+ can replace the @ with a * - some people do not have a @ key
+*/
+
+/* having to check before then after is lame - will change this later */
+int is_drop(char* dropstr)
+{
+
+ int len = strlen (dropstr);
+
+ if ((len < 4) || (len > 5))
+ return 0;
+
+/*check x@e3 */
+
+ if ((dropstr[0] == 'x') || (dropstr[0] == 'X')) {
+ if (!((dropstr[1] == '@') || (dropstr[1] == '*')))
+ return 0;
+ if (!check_valid_square(dropstr+2))
+ return 0;
+
+/*check wp@e3 */
+
+ } else if (dropstr[0] == 'w') {
+ if (!((dropstr[1] == 'p') || (dropstr[1] == 'r') || (dropstr[1] == 'n') || (dropstr[1] == 'b') || (dropstr[1] == 'q') || (dropstr[1] == 'k')))
+ return 0;
+ if (!((dropstr[2] == '@') || (dropstr[2] == '*')))
+ return 0;
+ if (!check_valid_square(dropstr+3))
+ return 0;
+
+/* check bp@e3 */
+
+ } else if (len == 5) { /* so b@e2 and bb@e2 aren't confused */
+ if (dropstr[0] == 'b') {
+ if (!((dropstr[1] == 'p') || (dropstr[1] == 'r') || (dropstr[1] == 'n') || (dropstr[1] == 'b') || (dropstr[1] == 'q') || (dropstr[1] == 'k')))
+ return 0;
+ if (!((dropstr[2] == '@') || (dropstr[2] == '*')))
+ return 0;
+ if (!check_valid_square(dropstr+3))
+ return 0;
+ } else return 0; /* Exhausted 5 char possibilities */
+
+/* check p@e3 and P@e3 */
+
+ } else if ((dropstr[0] == 'p') || (dropstr[0] == 'r') || (dropstr[0] == 'n') || (dropstr[0] == 'b') || (dropstr[0] == 'q') || (dropstr[0] == 'k') ||
+ (dropstr[0] == 'P') || (dropstr[0] == 'R') || (dropstr[0] == 'N') || (dropstr[0] == 'B') || (dropstr[0] == 'Q') || (dropstr[0] == 'K')) {
+
+ if (!((dropstr[1] == '@') || (dropstr[1] == '*')))
+ return 0;
+ if (!check_valid_square(dropstr+2))
+ return 0;
+ } else return 0;
+ return 1; /* valid drop */
+}
+
+static void getsquare(char* square,int *f, int *r)
+{
+ *f = square[0] - 'a';
+ *r = square[1] - '1';
+}
+
+int attempt_drop(int p,int g,char* dropstr)
+{
+ int len = strlen (dropstr);
+ int color;
+ int piece = 0;
+ int f;
+ int r;
+
+ if ((len < 4) || (len > 5))
+ return 0;
+
+/*check x@e3 */
+
+ if ((dropstr[0] == 'x') || (dropstr[0] == 'X')) { /* as x must be clear */
+ getsquare(dropstr+2,&f,&r);
+ piece = NOPIECE;
+
+/*check wp@e3 */
+
+ } else if (dropstr[0] == 'w') {
+ piece = CharToPiece(dropstr[1]) & 0x07;
+ color = WHITE;
+ getsquare(dropstr+3,&f,&r);
+
+/* check bp@e3 */
+
+ } else if (len == 5) { /* check length to avoid b@e2 and bb@e2 being confused */
+ if (dropstr[0] == 'b') {
+ piece = CharToPiece(dropstr[1]) | BLACK;
+ getsquare(dropstr+3,&f,&r);
+ }
+
+/* check p@e3 and P@e3 */
+
+ } else {
+ if (!((dropstr[1] == '@') || (dropstr[1] == '*')))
+ return 0;
+ else {
+ piece = CharToPiece(dropstr[0]);
+ getsquare(dropstr+2,&f,&r);
+ }
+ }
+
+ game_globals.garray[g].game_state.board[f][r] = piece;
+ return 1; /* valid drop */
+}
--- /dev/null
+/*
+ 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 2 of the License, 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.
+*/
+
+/* shutdown.c
+ Contains stuff related to shutdowns
+
+*/
+
+#include "includes.h"
+
+static int shutdownTime = 0;
+static int lastTimeLeft;
+static int shutdownStartTime;
+static char downer[1024];
+static char reason[1024];
+
+void output_shut_mess(void)
+{
+ time_t shuttime = time(0);
+ d_printf( "CHESSD: Shutting down at %s\n", strltime(&shuttime));
+}
+
+static void ShutDown(void)
+{
+ int p1;
+ time_t shuttime = time(0);
+
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (player_globals.parray[p1].status != PLAYER_PROMPT)
+ continue;
+ pprintf(p1, "\n\n **** Server shutdown ordered by %s. ****\n",
+ downer);
+ if (reason[0] != '\0')
+ pprintf(p1, "\n **** We are going down because: %s. ****\n",
+ reason);
+ }
+ TerminateCleanup();
+ d_printf( "CHESSD: Shut down ordered at %s by %s.\n",
+ strltime(&shuttime), downer);
+
+ output_shut_mess();
+ net_close();
+ exit(0);
+}
+
+void ShutHeartBeat(void)
+{
+ int t = time(0);
+ int p1;
+ int timeLeft;
+ int crossing = 0;
+
+ if (!shutdownTime)
+ return;
+ if (!lastTimeLeft)
+ lastTimeLeft = shutdownTime;
+ timeLeft = shutdownTime - (t - shutdownStartTime);
+ if ((lastTimeLeft > 3600) && (timeLeft <= 3600))
+ crossing = 1;
+ if ((lastTimeLeft > 2400) && (timeLeft <= 2400))
+ crossing = 1;
+ if ((lastTimeLeft > 1200) && (timeLeft <= 1200))
+ crossing = 1;
+ if ((lastTimeLeft > 600) && (timeLeft <= 600))
+ crossing = 1;
+ if ((lastTimeLeft > 300) && (timeLeft <= 300))
+ crossing = 1;
+ if ((lastTimeLeft > 120) && (timeLeft <= 120))
+ crossing = 1;
+ if ((lastTimeLeft > 60) && (timeLeft <= 60))
+ crossing = 1;
+ if ((lastTimeLeft > 10) && (timeLeft <= 10))
+ crossing = 1;
+ if (crossing) {
+ d_printf(
+ "CHESSD: **** Server going down in %d minutes and %d seconds. ****\n\n",
+ timeLeft / 60,
+ timeLeft - ((timeLeft / 60) * 60));
+ if (reason[0] != '\0')
+ d_printf("CHESSD: We are going down because: %s.\n",reason);
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (player_globals.parray[p1].status != PLAYER_PROMPT)
+ continue;
+ pprintf(p1,
+ "\n\n **** Server going down in %d minutes and %d seconds. ****\n",
+ timeLeft / 60,
+ timeLeft - ((timeLeft / 60) * 60));
+ if (reason[0] != '\0')
+ pprintf_prompt(p1,"\n **** We are going down because: %s. ****\n",reason);
+ else
+ pprintf_prompt(p1,"\n");
+ }
+ }
+ lastTimeLeft = timeLeft;
+ if (timeLeft <= 0) {
+ ShutDown();
+ }
+}
+
+int check_and_print_shutdown(int p)
+
+ /* Tells a user if they is to be a shutdown */
+ /* returns 0 if there is not to be one, 1 if there is to be one */
+ /* for whenshut command */
+
+{
+
+
+ int timeLeft;
+ int t = time(0);
+
+ if (!shutdownTime)
+ return 0; /* no shut down */
+
+ timeLeft = shutdownTime - (t - shutdownStartTime);
+
+ pprintf(p,
+ "\n **** Server going down in %d minutes and %d seconds. ****\n",
+ timeLeft / 60,
+ timeLeft - ((timeLeft / 60) * 60));
+ if (reason[0] != '\0')
+ pprintf(p, "\n **** We are going down because: %s. ****\n", reason);
+ return 1;
+}
+
+
+/*
+ * shutdown
+ *
+ * Usage: shutdown [now,cancel,time]
+ *
+ * This command shutsdown the server. If the parameter is omitted or
+ * is 'now' then the server is immediately halted cleanly. If a time is
+ * given then a countdown commences and the server is halted when time is
+ * up. If 'cancel' is given then the countdown is stopped.
+ */
+int com_shutdown(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ char *ptr;
+ int p1, secs;
+
+ strcpy(downer, pp->name);
+ shutdownStartTime = time(0);
+ if (shutdownTime) { /* Cancel any pending shutdowns */
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (player_globals.parray[p1].status != PLAYER_PROMPT)
+ continue;
+ pprintf(p1, "\n\n **** Server shutdown canceled by %s. ****\n", downer);
+ }
+ shutdownTime = 0;
+ if (param[0].type == TYPE_NULL)
+ return COM_OK;
+ }
+ /* Work out how soon to shut down */
+ if (param[0].type == TYPE_NULL)
+ shutdownTime = 300;
+ else {
+ if (!strcmp(param[0].val.word, "now"))
+ shutdownTime = 0;
+ else if (!strcmp(param[0].val.word, "cancel"))
+ return COM_OK;
+ else {
+ ptr = param[0].val.word;
+ shutdownTime = secs = 0;
+ p1 = 2;
+ while (*ptr) {
+ switch (*ptr) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ secs = secs * 10 + *ptr - '0';
+ break;
+ case ':':
+ if (p1--) {
+ shutdownTime = shutdownTime * 60 + secs;
+ secs = 0;
+ break;
+ }
+ default:
+ shutdownTime = 0;
+ pprintf(p, "I don't know what you mean by %s\n", param[0].val.word);
+ return COM_OK;
+ }
+ ptr++;
+ }
+ shutdownTime = shutdownTime * 60 + secs;
+ }
+ }
+ if (shutdownTime <= 0)
+ ShutDown();
+ if (param[1].type == TYPE_STRING)
+ strcpy (reason,param[1].val.string);
+ else
+ reason[0] = '\0'; /* No reason - perhaps admin is in a bad mood? :) */
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (player_globals.parray[p1].status != PLAYER_PROMPT)
+ continue;
+ pprintf(p1, "\n\n **** Server shutdown ordered by %s. ****\n", downer);
+ if (reason[0] != '\0')
+ pprintf(p1, " **** We are going down because: %s. ****\n",reason);
+ pprintf(p1,
+ " **** Server going down in %d minutes and %d seconds. ****\n",
+ shutdownTime / 60, shutdownTime % 60);
+ if (p != p1) /* fix double prompt - DAV */
+ pprintf_prompt (p1,"\n");
+ else
+ pprintf (p1,"\n");
+ }
+ lastTimeLeft = 0;
+ return COM_OK;
+}
+
+int com_whenshut(int p, param_list param)
+
+{
+ if (check_and_print_shutdown(p) == 0) {
+ pprintf (p,"No shutdown currently in progress\n");
+ }
+ return COM_OK;
+}
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+#include "includes.h"
+
+static int on_channel(int ch, int p);
+
+static int CheckShoutQuota(int p)
+{
+ struct player *pp = &player_globals.parray[p];
+ int timeleft = time(0) - pp->lastshout_a;
+
+ if ((timeleft < seek_globals.quota_time) && (pp->adminLevel == 0))
+ return (seek_globals.quota_time - timeleft);
+
+ return 0;
+}
+
+int com_shout(int p, param_list param)
+{
+ int p1, count = 0, timeleft = CheckShoutQuota(p);
+ struct player *pp = &player_globals.parray[p];
+
+ if (!CheckPFlag(p, PFLAG_REG)) {
+ pprintf(p, "Only registered players can use the shout command.\n");
+ return COM_OK;
+ }
+ if (in_list(p, L_MUZZLE, pp->login)) {
+ pprintf(p, "You are muzzled.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_NULL) {
+ if (timeleft)
+ pprintf(p, "Next shout available in %d seconds.\n", timeleft);
+ else
+ pprintf(p, "Your next shout is ready for use.\n");
+ return COM_OK;
+ }
+ if (timeleft) {
+ pprintf(p, "Shout not sent. Next shout in %d seconds.\n", timeleft);
+ return COM_OK;
+ }
+
+ pp->lastshout_a = pp->lastshout_b;
+ pp->lastshout_b = time(0);
+ if (!printablestring(param[0].val.string)) {
+ pprintf(p, "Your message contains some unprintable character(s).\n");
+ return COM_OK;
+ }
+
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if ((p1 == p) || (player_globals.parray[p1].status != PLAYER_PROMPT) ||
+ (!CheckPFlag(p1, PFLAG_SHOUT)) || (player_censored(p1, p)))
+ continue;
+ count++;
+ pprintf_prompt(p1, "\n%s shouts: %s\n",pp->name,param[0].val.string);
+ }
+
+ pprintf(p, "(%d) %s shouts: %s\n", count, pp->name,
+ param[0].val.string);
+
+ if (!CheckPFlag(p, PFLAG_SHOUT))
+ pprintf (p, "You are not listening to shouts.\n");
+ if ((timeleft = CheckShoutQuota(p)))
+ pprintf(p, "Next shout in %d second(s).\n", timeleft);
+
+ return COM_OK;
+}
+
+int com_cshout(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1, count = 0;
+
+ if (!CheckPFlag(p, PFLAG_REG)) {
+ pprintf(p, "Only registered players can use the cshout command.\n");
+ return COM_OK;
+ }
+ if (in_list(p, L_CMUZZLE, pp->login)) {
+ pprintf(p, "You are c-muzzled.\n");
+ return COM_OK;
+ }
+ if (!printablestring(param[0].val.string)) {
+ pprintf(p, "Your message contains some unprintable character(s).\n");
+ return COM_OK;
+ }
+
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if ((p1 == p) || (player_globals.parray[p1].status != PLAYER_PROMPT) ||
+ (!CheckPFlag(p1, PFLAG_CSHOUT)) || (player_censored(p1, p)))
+ continue;
+ count++;
+ pprintf_prompt(p1, "\n%s c-shouts: %s\n", pp->name,
+ param[0].val.string);
+ }
+ pprintf(p, "(%d) %s c-shouts: %s\n", count, pp->name,
+ param[0].val.string);
+ if (!CheckPFlag(p, PFLAG_CSHOUT))
+ pprintf (p, "You are not listening to c-shouts.\n");
+
+ return COM_OK;
+}
+
+int com_it(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1, count = 0, timeleft = CheckShoutQuota(p);
+
+ if (!CheckPFlag(p, PFLAG_REG)) {
+ pprintf(p, "Only registered players can use the it command.\n");
+ return COM_OK;
+ }
+ if (in_list(p, L_MUZZLE, pp->login)) {
+ pprintf(p, "You are muzzled.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_NULL) {
+ if (timeleft)
+ pprintf(p, "Next shout available in %d seconds.\n", timeleft);
+ else
+ pprintf(p, "Your next shout is ready for use.\n");
+
+ return COM_OK;
+ }
+ if (timeleft) {
+ pprintf(p, "Shout not sent. Next shout in %d seconds.\n", timeleft);
+ return COM_OK;
+ }
+ pp->lastshout_a = pp->lastshout_b;
+ pp->lastshout_b = time(0);
+
+ if (!printablestring(param[0].val.string)) {
+ pprintf(p, "Your message contains some unprintable character(s).\n");
+ return COM_OK;
+ }
+
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if ((p1 == p) || (player_globals.parray[p1].status != PLAYER_PROMPT) ||
+ (!CheckPFlag(p1, PFLAG_SHOUT)) || (player_censored(p1, p)))
+ continue;
+ count++;
+ if ((!strncmp(param[0].val.string, "\'", 1)) ||
+ (!strncmp(param[0].val.string, ",", 1)) ||
+ (!strncmp(param[0].val.string, ".", 1)))
+ pprintf_prompt(p1, "\n--> %s%s\n", pp->name,
+ param[0].val.string);
+ else
+ pprintf_prompt(p1, "\n--> %s %s\n", pp->name,
+ param[0].val.string);
+ }
+ if ((!strncmp(param[0].val.string, "\'", 1)) ||
+ (!strncmp(param[0].val.string, ",", 1)) ||
+ (!strncmp(param[0].val.string, ".", 1)))
+ pprintf(p, "--> %s%s\n", pp->name, param[0].val.string);
+ else
+ pprintf(p, "--> %s %s\n", pp->name, param[0].val.string);
+
+ if ((timeleft = CheckShoutQuota(p)))
+ pprintf(p, "Next shout in %d second(s).\n", timeleft);
+
+ return COM_OK;
+}
+
+static int tell(int p, int p1, const char *msg, int why, int ch)
+{
+ struct player *pp = &player_globals.parray[p];
+ char tmp[MAX_LINE_SIZE];
+ int rating, rating1, p2;
+
+ if (!printablestring(msg)) {
+ pprintf(p, "Your message contains some unprintable character(s).\n");
+ return COM_OK;
+ }
+
+ if (!CheckPFlag(p1, PFLAG_TELL) && !CheckPFlag(p, PFLAG_REG)) {
+ pprintf(p, "Player \"%s\" isn't listening to unregistered tells.\n",
+ player_globals.parray[p1].name);
+ return COM_OK;
+ }
+ if (player_censored(p1, p)) {
+ if (pp->adminLevel == 0) {
+ if (why != TELL_KIBITZ && why != TELL_WHISPER && why != TELL_CHANNEL)
+ pprintf(p, "Player \"%s\" is censoring you.\n", player_globals.parray[p1].name);
+ return COM_OK;
+ } else
+ pprintf(p, "Told \"%s\", who is censoring you.\n", player_globals.parray[p1].name);
+ }
+
+ switch (why) {
+ case TELL_SAY:
+ pprintf_highlight(p1, "\n%s", pp->name);
+ pprintf_prompt(p1, " says: %s\n", msg);
+ break;
+ case TELL_WHISPER:
+ case TELL_KIBITZ:
+ rating = GetRating(&player_globals.parray[p], TYPE_BLITZ);
+ if (rating < (rating1 = (GetRating(&player_globals.parray[p], TYPE_STAND))))
+ rating = rating1;
+ if (in_list(p, L_FM, pp->name))
+ pprintf(p1, "\n%s(FM)", pp->name);
+ else if (in_list(p, L_IM, pp->name))
+ pprintf(p1, "\n%s(IM)", pp->name);
+ else if (in_list(p, L_GM, pp->name))
+ pprintf(p1, "\n%s(GM)", pp->name);
+ else if (in_list(p, L_WGM, pp->name))
+ pprintf(p1, "\n%s(WGM)", pp->name);
+ else if ((pp->adminLevel >= 10)
+ && CheckPFlag(p, PFLAG_ADMINLIGHT))
+ pprintf(p1, "\n%s(*)", pp->name);
+ else if ((rating >= player_globals.parray[p1].kiblevel) ||
+ ((pp->adminLevel >= 10)
+ && CheckPFlag(p, PFLAG_ADMINLIGHT)))
+ if (!CheckPFlag(p, PFLAG_REG))
+ pprintf(p1, "\n%s(++++)", pp->name);
+ else if (rating != 0)
+ if (in_list(p, L_COMPUTER, pp->name))
+ pprintf(p1, "\n%s(%d)(C)", pp->name, rating);
+ else
+ pprintf(p1, "\n%s(%d)", pp->name, rating);
+ else
+ pprintf(p1, "\n%s(----)", pp->name);
+ else break;
+
+ if (why == TELL_WHISPER)
+ pprintf_prompt(p1, " whispers: %s\n", msg);
+ else
+ pprintf_prompt(p1, " kibitzes: %s\n", msg);
+
+ break;
+ case TELL_CHANNEL:
+ pprintf(p1, "\n%s", pp->name);
+ if ((pp->adminLevel >= 10)
+ && CheckPFlag(p, PFLAG_ADMINLIGHT) && (ch == 1))
+ pprintf(p1, "(*)");
+ pprintf_prompt(p1, "(%d): %s\n", ch, msg);
+ break;
+ case TELL_LTELL:
+ pprintf_prompt(p1, "\n%s tells you: %s\n", pp->name, msg);
+ break;
+
+ case TELL_TELL:
+ default:
+ if (player_globals.parray[p1].highlight)
+ pprintf_highlight(p1, "\n%s", pp->name);
+ else
+ pprintf(p1, "\n%s", pp->name);
+
+ if ((pp->adminLevel >= 10) && CheckPFlag(p, PFLAG_ADMINLIGHT))
+ pprintf(p1,"(*)");
+
+ pprintf_prompt(p1, " tells you: %s\n", msg);
+
+/* let's test for forwarding of tells */
+
+ if ((pp->ftell == p1) || (player_globals.parray[p1].ftell == p)) {
+ for (p2 = 0; p2 < player_globals.p_num; p2++) {
+ if ((p2 == p) || (p2 == p1) || (player_globals.parray[p2].status != PLAYER_PROMPT))
+ continue;
+ if (on_channel(0, p2))
+ pprintf (p2,"\nFwd tell: %s told %s: %s\n", pp->name,
+ player_globals.parray[p1].name, msg);
+ }
+ }
+
+ break;
+ }
+
+ tmp[0] = '\0';
+
+ if (!(player_globals.parray[p1].busy == NULL))
+ sprintf(tmp, ", who %s (idle: %s)", player_globals.parray[p1].busy,
+ hms_desc(player_idle(p1)));
+ else
+ if (((player_idle(p1) % 3600) / 60) > 2)
+ sprintf(tmp, ", who has been idle %s", hms_desc(player_idle(p1)));
+
+ if ((why == TELL_SAY) || (why == TELL_TELL) || (why == TELL_LTELL)) {
+ pprintf(p, "(told %s%s)\n", player_globals.parray[p1].name,
+ (((player_globals.parray[p1].game>=0) && (game_globals.garray[player_globals.parray[p1].game].status == GAME_EXAMINE))
+ ? ", who is examining a game" :
+ ((player_globals.parray[p1].game>=0) && (game_globals.garray[player_globals.parray[p1].game].status == GAME_SETUP))
+ ? ", who is setting up a position" :
+ (player_globals.parray[p1].game >= 0 && (player_globals.parray[p1].game != pp->game))
+ ? ", who is playing" : tmp));
+ }
+
+ if (why == TELL_TELL || why == TELL_SAY) {
+ FREE(pp->last_tell);
+ pp->last_tell = strdup(player_globals.parray[p1].login);
+ }
+
+ return COM_OK;
+}
+
+int com_ptell(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ char tmp[MAX_LINE_SIZE];
+ int p1;
+
+ if (pp->partner < 0) {
+ pprintf (p, "You do not have a partner at present.\n");
+ return COM_OK;
+ }
+
+ p1 = pp->partner;
+ if ((p1 < 0) || (player_globals.parray[p1].status == PLAYER_PASSWORD)
+ || (player_globals.parray[p1].status == PLAYER_LOGIN)) {
+ pprintf(p, "Your partner is not logged in.\n");
+ return COM_OK;
+ }
+
+ if (player_globals.parray[p1].highlight)
+ pprintf_highlight(p1, "\n%s", pp->name);
+ else
+ pprintf(p1, "\n%s", pp->name);
+
+ pprintf_prompt(p1, " (your partner) tells you: %s\n", param[0].val.string);
+ tmp[0] = '\0';
+ if (!(player_globals.parray[p1].busy == NULL))
+ sprintf(tmp, ", who %s (idle: %s)", player_globals.parray[p1].busy,
+ hms_desc(player_idle(p1)));
+ else
+ if (((player_idle(p1) % 3600) / 60) > 2)
+ sprintf(tmp, ", who has been idle %s", hms_desc(player_idle(p1)));
+
+ pprintf(p, "(told %s%s)\n", player_globals.parray[p1].name,
+ (((player_globals.parray[p1].game>=0) && (game_globals.garray[player_globals.parray[p1].game].status == GAME_EXAMINE))
+ ? ", who is examining a game" :
+ ((player_globals.parray[p1].game>=0) && (game_globals.garray[player_globals.parray[p1].game].status == GAME_SETUP))
+ ? ", who is setting up a position" :
+ (player_globals.parray[p1].game >= 0 && (player_globals.parray[p1].game != pp->game))
+ ? ", who is playing" : tmp));
+
+ return COM_OK;
+}
+
+static int chtell(int p, int ch, char *msg)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1, count = 0;
+
+ if ((ch == 0) && (pp->adminLevel < ADMIN_ADMIN)) {
+ pprintf(p, "Only admins may send tells to channel 0.\n");
+ return COM_OK;
+ }
+
+ if (ch < 0) {
+ pprintf(p, "The lowest channel number is 0.\n");
+ return COM_OK;
+ }
+
+ if (ch >= MAX_CHANNELS) {
+ pprintf(p, "The maximum channel number is %d.\n", MAX_CHANNELS - 1);
+ return COM_OK;
+ }
+
+ if ((ch == 1) && (in_list(p, L_C1MUZZLE, pp->login))) {
+ pprintf (p, "You have been prevented from sending tells to channel 1.\n");
+ return COM_OK;
+ }
+
+ if ((ch == 24) && (in_list(p, L_C24MUZZLE, pp->login))) {
+ pprintf (p, "You have been prevented from sending tells to channel 24.\n");
+ return COM_OK;
+ }
+
+ if ((ch == 46) && (in_list(p, L_C46MUZZLE, pp->login))) {
+ pprintf (p, "You have been prevented from sending tells to channel 46.\n");
+ return COM_OK;
+ }
+
+ if ((ch == 49) && (in_list(p, L_C49MUZZLE, pp->login))) {
+ pprintf (p, "You have been prevented from sending tells to channel 49.\n");
+ return COM_OK;
+ }
+
+ if ((ch == 50) && (in_list(p, L_C50MUZZLE, pp->login))) {
+ pprintf (p, "You have been prevented from sending tells to channel 50.\n");
+ return COM_OK;
+ }
+
+ if ((ch == 51) && (in_list(p, L_C51MUZZLE, pp->login))) {
+ pprintf (p, "You have been prevented from sending tells to channel 51.\n");
+ return COM_OK;
+ }
+
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if ((p1 == p) || (player_globals.parray[p1].status != PLAYER_PROMPT))
+ continue;
+ if ((on_channel(ch, p1)) && (!player_censored(p1, p))
+ && (CheckPFlag(p, PFLAG_REG) || CheckPFlag(p1, PFLAG_TELL))) {
+ tell(p, p1, msg, TELL_CHANNEL, ch);
+ if (!player_censored(p1, p))
+ count++;
+ }
+ }
+
+ if (count)
+ pp->last_channel = ch;
+
+ pprintf(p, "%s(%d): %s\n", pp->name, ch, msg);
+ if (!on_channel(ch, p))
+ pprintf(p, " (You're not listening to channel %d.)\n", ch);
+
+ return COM_OK;
+}
+
+int com_whisper(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int g, p1, count = 0;
+
+ if (!pp->num_observe && pp->game < 0) {
+ pprintf(p, "You are not playing or observing a game.\n");
+ return COM_OK;
+ }
+ if (!CheckPFlag(p, PFLAG_REG) && (pp->game == -1)) {
+ pprintf(p, "You must be registered to whisper other people's games.\n");
+ return COM_OK;
+ }
+ if (pp->game >= 0)
+ g = pp->game;
+ else
+ g = pp->observe_list[0];
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if ((p1 == p) || (player_globals.parray[p1].status != PLAYER_PROMPT))
+ continue;
+ if (player_is_observe(p1, g) ||
+ (game_globals.garray[g].link >= 0 && player_is_observe(p1, game_globals.garray[g].link)
+ && player_globals.parray[p1].game != game_globals.garray[g].link)) {
+ tell(p, p1, param[0].val.string, TELL_WHISPER, 0);
+ if ((pp->adminLevel >= ADMIN_ADMIN) || !game_globals.garray[g].private || !player_censored(p1, p))
+ count++;
+ }
+ }
+ pprintf(p, "whispered to %d.\n", count);
+ return COM_OK;
+}
+
+int com_kibitz(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int g, p1, count = 0;
+
+ if (!pp->num_observe && pp->game < 0) {
+ pprintf(p, "You are not playing or observing a game.\n");
+ return COM_OK;
+ }
+ if (!CheckPFlag(p, PFLAG_REG) && (pp->game == -1)) {
+ pprintf(p, "You must be registered to kibitz other people's games.\n");
+ return COM_OK;
+ }
+ if (pp->game >= 0)
+ g = pp->game;
+ else
+ g = pp->observe_list[0];
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if ((p1 == p) || (player_globals.parray[p1].status != PLAYER_PROMPT))
+ continue;
+ if ((player_is_observe(p1, g) || player_globals.parray[p1].game == g
+ || (game_globals.garray[g].link >= 0
+ && (player_is_observe(p1, game_globals.garray[g].link)
+ || player_globals.parray[p1].game == game_globals.garray[g].link)))
+ && CheckPFlag(p1, PFLAG_KIBITZ)) {
+ tell(p, p1, param[0].val.string, TELL_KIBITZ, 0);
+ if ((pp->adminLevel >= ADMIN_ADMIN) ||
+ !game_globals.garray[g].private || (player_globals.parray[p1].game == g) || !player_censored(p1, p))
+ count++;
+ }
+ }
+ pprintf(p, "kibitzed to %d.\n", count);
+ return COM_OK;
+}
+
+/*
+ like tell() but takes a player name
+*/
+static int tell_s(int p, const char *who, const char *msg, int why, int ch)
+{
+ int p1;
+
+ p1 = player_find_part_login(who);
+ if ((p1 < 0) || (player_globals.parray[p1].status == PLAYER_PASSWORD)
+ || (player_globals.parray[p1].status == PLAYER_LOGIN)) {
+ if (why != TELL_LTELL) {
+ pprintf(p, "No user named '%s' is logged in.\n", who);
+ }
+ return COM_OK;
+ }
+
+ return tell(p, p1, msg, why, ch);
+}
+
+int com_tell(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ char *who;
+
+ if (param[0].type == TYPE_NULL)
+ return COM_BADPARAMETERS;
+ if (param[0].type != TYPE_WORD) {
+ return chtell(p, param[0].val.integer, param[1].val.string);
+ }
+
+ who = param[0].val.word;
+ stolower(who);
+
+ if (strcmp(who, ".") == 0) {
+ if (!pp->last_tell) {
+ pprintf(p, "No previous tell.\n");
+ return COM_OK;
+ }
+ who = pp->last_tell;
+ }
+
+ if (strcmp(who, ",") == 0) {
+ if (pp->last_channel == -1) {
+ pprintf(p, "No previous channel.\n");
+ return COM_OK;
+ }
+ return chtell(p, pp->last_channel, param[1].val.string);
+ }
+
+ return tell_s(p, who, param[1].val.string, TELL_TELL, 0);
+}
+
+
+/* tell all players in a named list */
+int com_ltell(int p, param_list param)
+{
+ struct List *gl;
+ int i;
+
+ gl = list_findpartial(p, param[0].val.word, 0);
+ if (!gl) {
+ pprintf(p,"Can't find that list\n");
+ return COM_OK;
+ }
+
+ for (i=0;i<gl->numMembers;i++) {
+ tell_s(p, gl->m_member[i], param[1].val.string, TELL_LTELL, 0);
+ }
+
+ return COM_OK;
+}
+
+
+int com_xtell(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1;
+ char *msg, tmp[2048];
+
+ msg = param[1].val.string;
+ p1 = player_find_part_login(param[0].val.word);
+ if ((p1 < 0) || (player_globals.parray[p1].status == PLAYER_PASSWORD)
+ || (player_globals.parray[p1].status == PLAYER_LOGIN)) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ if (!printablestring(msg)) {
+ pprintf(p, "Your message contains some unprintable character(s).\n");
+ return COM_OK;
+ }
+ if (!CheckPFlag(p1, PFLAG_TELL) && !CheckPFlag(p, PFLAG_REG)) {
+ pprintf(p, "Player \"%s\" isn't listening to unregistered tells.\n",
+ player_globals.parray[p1].name);
+ return COM_OK;
+ }
+ if ((player_censored(p1, p)) && (pp->adminLevel == 0)) {
+ pprintf(p, "Player \"%s\" is censoring you.\n", player_globals.parray[p1].name);
+ return COM_OK;
+ }
+ if (player_globals.parray[p1].highlight)
+ pprintf_highlight(p1, "\n%s", pp->name);
+ else
+ pprintf(p1, "\n%s", pp->name);
+
+ pprintf_prompt(p1, " tells you: %s\n", msg);
+
+ tmp[0] = '\0';
+ if (!(player_globals.parray[p1].busy == NULL))
+ sprintf(tmp, ", who %s (idle: %s)", player_globals.parray[p1].busy,
+ hms_desc(player_idle(p1)));
+ else
+ if (((player_idle(p1) % 3600) / 60) > 2)
+ sprintf(tmp, ", who has been idle %s", hms_desc(player_idle(p1)));
+
+ pprintf(p, "(told %s%s)\n", player_globals.parray[p1].name,
+ (((player_globals.parray[p1].game>=0) && (game_globals.garray[player_globals.parray[p1].game].status == GAME_EXAMINE))
+ ? ", who is examining a game" :
+ ((player_globals.parray[p1].game>=0) && (game_globals.garray[player_globals.parray[p1].game].status == GAME_SETUP))
+ ? ", who is setting up a position" :
+ (player_globals.parray[p1].game >= 0 && (player_globals.parray[p1].game != pp->game))
+ ? ", who is playing" : tmp));
+ return COM_OK;
+}
+
+int com_say(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ if (pp->opponent < 0) {
+ if (!pp->last_opponent) {
+ pprintf(p, "No one to say anything to, try tell.\n");
+ return COM_OK;
+ }
+ return tell_s(p, pp->last_opponent, param[0].val.string, TELL_SAY, 0);
+ }
+ return tell(p, pp->opponent, param[0].val.string, TELL_SAY, 0);
+}
+
+int com_inchannel(int p, param_list param)
+{
+ int p1,count = 0;
+ char tmp[18];
+
+ if (param[0].type == TYPE_NULL) {
+ pprintf (p,"inchannel [no params] has been removed\n");
+ pprintf (p,"Please use inchannel [name] or inchannel [number]\n");
+ return COM_OK;
+ }
+
+ if (param[0].type == TYPE_WORD) {
+ p1 = player_find_part_login(param[0].val.word);
+ if ((p1 < 0) || (player_globals.parray[p1].status != PLAYER_PROMPT)) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ pprintf (p,"%s is in the following channels:",player_globals.parray[p1].name);
+ if (list_channels (p,p1))
+ pprintf (p," No channels found for %s.\n",player_globals.parray[p1].name);
+ return COM_OK;
+ } else if (param[0].val.integer >= MAX_CHANNELS) {
+ pprintf (p, "No such channel; the largest channel number is %d.\n",
+ MAX_CHANNELS - 1);
+ return COM_OK;
+ } else {
+ sprintf (tmp,"%d",param[0].val.integer);
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (player_globals.parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (in_list(p1,L_CHANNEL,tmp)) {
+ if (!count)
+ pprintf(p,"Channel %d:",param[0].val.integer);
+ pprintf (p," %s", player_globals.parray[p1].name);
+ if ((player_globals.parray[p1].adminLevel >= 10)
+ && CheckPFlag(p1, PFLAG_ADMINLIGHT)
+ && (param[0].val.integer < 2))
+ pprintf(p, "(*)");
+ count++;
+ }
+ }
+ if (!count)
+ pprintf(p,"Channel %d is empty.\n",param[0].val.integer);
+ else
+ pprintf (p,"\n%d %s in channel %d.\n",count,(count == 1 ? "person is" : "people are"),param[0].val.integer);
+ return COM_OK;
+ }
+}
+
+static int com_sendmessage(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1, connected = 1;
+
+ if (!CheckPFlag(p, PFLAG_REG)) {
+ pprintf(p, "You are not registered and cannot send messages.\n");
+ return COM_OK;
+ }
+
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+
+ if (!CheckPFlag(p1, PFLAG_REG)) {
+ pprintf(p, "Player \"%s\" is unregistered and cannot receive messages.\n",
+ player_globals.parray[p1].name);
+ return COM_OK;
+ }
+
+ if ((player_censored(p1, p)) && (pp->adminLevel == 0)) {
+ pprintf(p, "Player \"%s\" is censoring you.\n", player_globals.parray[p1].name);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ if (player_add_message(p1, p, param[1].val.string)) {
+ pprintf(p, "Couldn't send message to %s. Message buffer full.\n",
+ player_globals.parray[p1].name);
+ } else {
+ if (connected) {
+ pprintf(p1, "\n%s just sent you a message:\n", pp->name);
+ pprintf_prompt(p1, " %s\n", param[1].val.string);
+ }
+ }
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+int com_messages(int p, param_list param)
+{
+ int start;
+
+ if (!CheckPFlag(p, PFLAG_REG)) {
+ pprintf (p, "Unregistered players may not send or receive messages.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_NULL) {
+ player_show_messages (p);
+ } else if (param[0].type == TYPE_WORD) {
+ if (param[1].type != TYPE_NULL)
+ return com_sendmessage(p, param);
+ else ShowMsgsBySender(p, param);
+ } else {
+ start = param[0].val.integer;
+ ShowMsgRange (p, start, start);
+ }
+ return COM_OK;
+}
+
+int com_forwardmess(int p, param_list param)
+{
+ if (!CheckPFlag(p, PFLAG_REG)) {
+ pprintf (p, "Unregistered players may not send or receive messages.\n");
+ return COM_OK;
+ }
+
+ ForwardMsgRange(param[0].val.word, p, param[1].val.integer, param[1].val.integer);
+
+ return COM_OK;
+}
+
+int com_clearmessages(int p, param_list param)
+{
+ if (player_num_messages(p) <= 0) {
+ pprintf(p, "You have no messages.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_NULL) {
+ pprintf(p, "Messages cleared.\n");
+ player_clear_messages(p);
+ } else if (param[0].type == TYPE_WORD)
+ ClearMsgsBySender(p, param);
+ else if (param[0].type == TYPE_INT)
+ ClrMsgRange (p, param[0].val.integer, param[0].val.integer);
+
+ return COM_OK;
+}
+
+int com_znotify(int p, param_list param)
+{
+ int p1, count = 0;
+
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (player_notified(p, p1) && player_globals.parray[p1].status == PLAYER_PROMPT) {
+ if (!count)
+ pprintf(p, "Present company on your notify list:\n ");
+ pprintf(p, " %s", player_globals.parray[p1].name);
+ count++;
+ }
+ }
+ if (!count)
+ pprintf(p, "No one from your notify list is logged on.");
+ pprintf(p, "\n");
+
+ count = 0;
+ for (p1 = 0; p1 < player_globals.p_num; p1++) {
+ if (player_notified(p1, p) && player_globals.parray[p1].status == PLAYER_PROMPT) {
+ if (!count)
+ pprintf(p,
+ "The following players have you on their notify list:\n ");
+ pprintf(p, " %s", player_globals.parray[p1].name);
+ count++;
+ }
+ }
+ if (!count)
+ pprintf(p, "No one logged in has you on their notify list.");
+ pprintf(p, "\n");
+
+ return COM_OK;
+}
+
+int com_qtell(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1;
+ char tmp[MAX_STRING_LENGTH];
+ char dummy[2];
+ char buffer1[MAX_STRING_LENGTH]; /* no highlight and no bell */
+ char buffer2[MAX_STRING_LENGTH]; /* no highlight and bell */
+ char buffer3[MAX_STRING_LENGTH]; /* highlight and no bell */
+ char buffer4[MAX_STRING_LENGTH]; /* highlight and and bell */
+ int i,count;
+
+ if (!in_list(p, L_TD, pp->name)) {
+ pprintf(p, "Only TD programs are allowed to use this command.\n");
+ return COM_OK;
+ }
+ strcpy(buffer1, ":\0");
+ strcpy(buffer2, ":\0");
+ strcpy(buffer3, ":\0");
+ strcpy(buffer4, ":\0");
+
+ sprintf(tmp, "%s", param[1].val.string);
+ for (i = 0, count = 0; ((tmp[i] != '\0') && (count < 1029));) {
+ if ((tmp[i] == '\\') && (tmp[i + 1] == 'n')) {
+ strcat(buffer1, "\n:");
+ strcat(buffer2, "\n:");
+ strcat(buffer3, "\n:");
+ strcat(buffer4, "\n:");
+ count += 2;
+ i += 2;
+ } else if ((tmp[i] == '\\') && (tmp[i + 1] == 'b')) {
+ strcat(buffer2, "\007");
+ strcat(buffer4, "\007");
+ count++;
+ i += 2;
+ } else if ((tmp[i] == '\\') && (tmp[i + 1] == 'H')) {
+ strcat(buffer3, "\033[7m");
+ strcat(buffer4, "\033[7m");
+ count += 4;
+ i += 2;
+ } else if ((tmp[i] == '\\') && (tmp[i + 1] == 'h')) {
+ strcat(buffer3, "\033[0m");
+ strcat(buffer4, "\033[0m");
+ count += 4;
+ i += 2;
+ } else {
+ dummy[0] = tmp[i];
+ dummy[1] = '\0';
+ strcat(buffer1, dummy);
+ strcat(buffer2, dummy);
+ strcat(buffer3, dummy);
+ strcat(buffer4, dummy);
+ count++;
+ i++;
+ }
+ }
+
+ if (param[0].type == TYPE_WORD) {
+ if ((p1 = player_find_bylogin(param[0].val.word)) < 0) {
+ pprintf(p, "*qtell %s 1*\n", param[0].val.word);
+ return COM_OK;
+ }
+ pprintf_prompt(p1, "\n%s\n", (player_globals.parray[p1].highlight && CheckPFlag(p1, PFLAG_BELL)) ? buffer4 :
+ (player_globals.parray[p1].highlight && !CheckPFlag(p1, PFLAG_BELL)) ? buffer3 :
+ (!player_globals.parray[p1].highlight && CheckPFlag(p1, PFLAG_BELL)) ? buffer2 :
+ buffer1);
+ pprintf(p, "*qtell %s 0*\n", player_globals.parray[p1].name);
+
+ } else {
+ int p1;
+ int ch = param[0].val.integer;
+
+ if (ch == 0) {
+ pprintf(p, "*qtell %d 1*\n", param[0].val.integer);
+ return COM_OK;
+ }
+ if (ch < 0) {
+ pprintf(p, "*qtell %d 1*\n", param[0].val.integer);
+ return COM_OK;
+ }
+ if (ch >= MAX_CHANNELS) {
+ pprintf(p, "*qtell %d 1*\n", param[0].val.integer);
+ return COM_OK;
+ }
+ sprintf (tmp,"%d",param[0].val.integer);
+ for (p1 = 0; p1 < player_globals.p_num ; p1++) {
+ if ((p1 == p) || (player_censored(p1, p)) || (player_globals.parray[p1].status != PLAYER_PROMPT))
+ continue;
+ if (in_list(p1,L_CHANNEL,tmp))
+ pprintf_prompt(p1, "\n%s\n", (player_globals.parray[p1].highlight && CheckPFlag(p1, PFLAG_BELL)) ? buffer4 :
+ (player_globals.parray[p1].highlight && !CheckPFlag(p1, PFLAG_BELL)) ? buffer3 :
+ (!player_globals.parray[p1].highlight && CheckPFlag(p1, PFLAG_BELL)) ? buffer2 :
+ buffer1);
+ }
+ pprintf(p, "*qtell %d 0*\n", param[0].val.integer);
+ }
+ return COM_OK;
+}
+
+static int on_channel(int ch, int p)
+{
+ char tmp[10]; /* 9 digits ought to be enough :) */
+
+ sprintf (tmp,"%d",ch);
+ return in_list(p, L_CHANNEL,tmp); /* since needs ch converted to a string
+ kept hidden from view */
+}
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+/* Revision history:
+ name yy/mm/dd Change
+ hersco and Marsalis 95/07/24 Created
+*/
+
+#ifndef _TALKPROC_H
+#define _TALKPROC_H
+
+#define MAX_CHANNELS 256
+#define TELL_TELL 0
+#define TELL_SAY 1
+#define TELL_WHISPER 2
+#define TELL_KIBITZ 3
+#define TELL_CHANNEL 4
+#define TELL_LTELL 5
+
+#endif /* _TALKPROC_H */
--- /dev/null
+/spinlock.h/1.1/Tue Jun 11 09:03:58 2002//
+/spinlock.c/1.2/Fri Jun 21 14:46:30 2002//
+/tdb.c/1.3/Thu Jul 22 07:04:41 2004//
+/tdb.h/1.2/Thu Jul 22 07:04:41 2004//
+D
--- /dev/null
+lasker/src/tdb
--- /dev/null
+/*
+ Unix SMB/CIFS implementation.
+ Samba database functions
+ Copyright (C) Anton Blanchard 2001
+
+ 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 2 of the License, 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.
+*/
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if STANDALONE
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <time.h>
+#include "tdb.h"
+#include "spinlock.h"
+
+#define DEBUG
+#else
+#include "includes.h"
+#endif
+
+#ifdef USE_SPINLOCKS
+
+/*
+ * ARCH SPECIFIC
+ */
+
+#if defined(SPARC_SPINLOCKS)
+
+static inline int __spin_trylock(spinlock_t *lock)
+{
+ unsigned int result;
+
+ asm volatile("ldstub [%1], %0"
+ : "=r" (result)
+ : "r" (lock)
+ : "memory");
+
+ return (result == 0) ? 0 : EBUSY;
+}
+
+static inline void __spin_unlock(spinlock_t *lock)
+{
+ asm volatile("":::"memory");
+ *lock = 0;
+}
+
+static inline void __spin_lock_init(spinlock_t *lock)
+{
+ *lock = 0;
+}
+
+static inline int __spin_is_locked(spinlock_t *lock)
+{
+ return (*lock != 0);
+}
+
+#elif defined(POWERPC_SPINLOCKS)
+
+static inline int __spin_trylock(spinlock_t *lock)
+{
+ unsigned int result;
+
+ __asm__ __volatile__(
+"1: lwarx %0,0,%1\n\
+ cmpwi 0,%0,0\n\
+ li %0,0\n\
+ bne- 2f\n\
+ li %0,1\n\
+ stwcx. %0,0,%1\n\
+ bne- 1b\n\
+ isync\n\
+2:" : "=&r"(result)
+ : "r"(lock)
+ : "cr0", "memory");
+
+ return (result == 1) ? 0 : EBUSY;
+}
+
+static inline void __spin_unlock(spinlock_t *lock)
+{
+ asm volatile("eieio":::"memory");
+ *lock = 0;
+}
+
+static inline void __spin_lock_init(spinlock_t *lock)
+{
+ *lock = 0;
+}
+
+static inline int __spin_is_locked(spinlock_t *lock)
+{
+ return (*lock != 0);
+}
+
+#elif defined(INTEL_SPINLOCKS)
+
+static inline int __spin_trylock(spinlock_t *lock)
+{
+ int oldval;
+
+ asm volatile("xchgl %0,%1"
+ : "=r" (oldval), "=m" (*lock)
+ : "0" (0)
+ : "memory");
+
+ return oldval > 0 ? 0 : EBUSY;
+}
+
+static inline void __spin_unlock(spinlock_t *lock)
+{
+ asm volatile("":::"memory");
+ *lock = 1;
+}
+
+static inline void __spin_lock_init(spinlock_t *lock)
+{
+ *lock = 1;
+}
+
+static inline int __spin_is_locked(spinlock_t *lock)
+{
+ return (*lock != 1);
+}
+
+#elif defined(MIPS_SPINLOCKS)
+
+static inline unsigned int load_linked(unsigned long addr)
+{
+ unsigned int res;
+
+ __asm__ __volatile__("ll\t%0,(%1)"
+ : "=r" (res)
+ : "r" (addr));
+
+ return res;
+}
+
+static inline unsigned int store_conditional(unsigned long addr, unsigned int value)
+{
+ unsigned int res;
+
+ __asm__ __volatile__("sc\t%0,(%2)"
+ : "=r" (res)
+ : "0" (value), "r" (addr));
+ return res;
+}
+
+static inline int __spin_trylock(spinlock_t *lock)
+{
+ unsigned int mw;
+
+ do {
+ mw = load_linked(lock);
+ if (mw)
+ return EBUSY;
+ } while (!store_conditional(lock, 1));
+
+ asm volatile("":::"memory");
+
+ return 0;
+}
+
+static inline void __spin_unlock(spinlock_t *lock)
+{
+ asm volatile("":::"memory");
+ *lock = 0;
+}
+
+static inline void __spin_lock_init(spinlock_t *lock)
+{
+ *lock = 0;
+}
+
+static inline int __spin_is_locked(spinlock_t *lock)
+{
+ return (*lock != 0);
+}
+
+#else
+#error Need to implement spinlock code in spinlock.c
+#endif
+
+/*
+ * OS SPECIFIC
+ */
+
+static void yield_cpu(void)
+{
+ struct timespec tm;
+
+#ifdef USE_SCHED_YIELD
+ sched_yield();
+#else
+ /* Linux will busy loop for delays < 2ms on real time tasks */
+ tm.tv_sec = 0;
+ tm.tv_nsec = 2000000L + 1;
+ nanosleep(&tm, NULL);
+#endif
+}
+
+static int this_is_smp(void)
+{
+ return 0;
+}
+
+/*
+ * GENERIC
+ */
+
+static int smp_machine = 0;
+
+static inline void __spin_lock(spinlock_t *lock)
+{
+ int ntries = 0;
+
+ while(__spin_trylock(lock)) {
+ while(__spin_is_locked(lock)) {
+ if (smp_machine && ntries++ < MAX_BUSY_LOOPS)
+ continue;
+ yield_cpu();
+ }
+ }
+}
+
+static void __read_lock(tdb_rwlock_t *rwlock)
+{
+ int ntries = 0;
+
+ while(1) {
+ __spin_lock(&rwlock->lock);
+
+ if (!(rwlock->count & RWLOCK_BIAS)) {
+ rwlock->count++;
+ __spin_unlock(&rwlock->lock);
+ return;
+ }
+
+ __spin_unlock(&rwlock->lock);
+
+ while(rwlock->count & RWLOCK_BIAS) {
+ if (smp_machine && ntries++ < MAX_BUSY_LOOPS)
+ continue;
+ yield_cpu();
+ }
+ }
+}
+
+static void __write_lock(tdb_rwlock_t *rwlock)
+{
+ int ntries = 0;
+
+ while(1) {
+ __spin_lock(&rwlock->lock);
+
+ if (rwlock->count == 0) {
+ rwlock->count |= RWLOCK_BIAS;
+ __spin_unlock(&rwlock->lock);
+ return;
+ }
+
+ __spin_unlock(&rwlock->lock);
+
+ while(rwlock->count != 0) {
+ if (smp_machine && ntries++ < MAX_BUSY_LOOPS)
+ continue;
+ yield_cpu();
+ }
+ }
+}
+
+static void __write_unlock(tdb_rwlock_t *rwlock)
+{
+ __spin_lock(&rwlock->lock);
+
+#ifdef DEBUG
+ if (!(rwlock->count & RWLOCK_BIAS))
+ fprintf(stderr, "bug: write_unlock\n");
+#endif
+
+ rwlock->count &= ~RWLOCK_BIAS;
+ __spin_unlock(&rwlock->lock);
+}
+
+static void __read_unlock(tdb_rwlock_t *rwlock)
+{
+ __spin_lock(&rwlock->lock);
+
+#ifdef DEBUG
+ if (!rwlock->count)
+ fprintf(stderr, "bug: read_unlock\n");
+
+ if (rwlock->count & RWLOCK_BIAS)
+ fprintf(stderr, "bug: read_unlock\n");
+#endif
+
+ rwlock->count--;
+ __spin_unlock(&rwlock->lock);
+}
+
+/* TDB SPECIFIC */
+
+/* lock a list in the database. list -1 is the alloc list */
+int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type)
+{
+ tdb_rwlock_t *rwlocks;
+
+ if (!tdb->map_ptr) return -1;
+ rwlocks = (tdb_rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks);
+
+ switch(rw_type) {
+ case F_RDLCK:
+ __read_lock(&rwlocks[list+1]);
+ break;
+
+ case F_WRLCK:
+ __write_lock(&rwlocks[list+1]);
+ break;
+
+ default:
+ return TDB_ERRCODE(TDB_ERR_LOCK, -1);
+ }
+ return 0;
+}
+
+/* unlock the database. */
+int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type)
+{
+ tdb_rwlock_t *rwlocks;
+
+ if (!tdb->map_ptr) return -1;
+ rwlocks = (tdb_rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks);
+
+ switch(rw_type) {
+ case F_RDLCK:
+ __read_unlock(&rwlocks[list+1]);
+ break;
+
+ case F_WRLCK:
+ __write_unlock(&rwlocks[list+1]);
+ break;
+
+ default:
+ return TDB_ERRCODE(TDB_ERR_LOCK, -1);
+ }
+
+ return 0;
+}
+
+int tdb_create_rwlocks(int fd, unsigned int hash_size)
+{
+ unsigned size, i;
+ tdb_rwlock_t *rwlocks;
+
+ size = (hash_size + 1) * sizeof(tdb_rwlock_t);
+ rwlocks = malloc(size);
+ if (!rwlocks)
+ return -1;
+
+ for(i = 0; i < hash_size+1; i++) {
+ __spin_lock_init(&rwlocks[i].lock);
+ rwlocks[i].count = 0;
+ }
+
+ /* Write it out (appending to end) */
+ if (write(fd, rwlocks, size) != size) {
+ free(rwlocks);
+ return -1;
+ }
+ smp_machine = this_is_smp();
+ free(rwlocks);
+ return 0;
+}
+
+int tdb_clear_spinlocks(TDB_CONTEXT *tdb)
+{
+ tdb_rwlock_t *rwlocks;
+ unsigned i;
+
+ if (tdb->header.rwlocks == 0) return 0;
+ if (!tdb->map_ptr) return -1;
+
+ /* We're mmapped here */
+ rwlocks = (tdb_rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks);
+ for(i = 0; i < tdb->header.hash_size+1; i++) {
+ __spin_lock_init(&rwlocks[i].lock);
+ rwlocks[i].count = 0;
+ }
+ return 0;
+}
+#else
+int tdb_create_rwlocks(int fd, unsigned int hash_size) { return 0; }
+int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type) { return -1; }
+int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type) { return -1; }
+
+/* Non-spinlock version: remove spinlock pointer */
+int tdb_clear_spinlocks(TDB_CONTEXT *tdb)
+{
+ tdb_off off = (tdb_off)((char *)&tdb->header.rwlocks
+ - (char *)&tdb->header);
+
+ tdb->header.rwlocks = 0;
+ if (lseek(tdb->fd, off, SEEK_SET) != off
+ || write(tdb->fd, (void *)&tdb->header.rwlocks,
+ sizeof(tdb->header.rwlocks))
+ != sizeof(tdb->header.rwlocks))
+ return -1;
+ return 0;
+}
+#endif
--- /dev/null
+#ifndef __SPINLOCK_H__
+#define __SPINLOCK_H__
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "tdb.h"
+
+#ifdef USE_SPINLOCKS
+
+#define RWLOCK_BIAS 0x1000UL
+
+/* OS SPECIFIC */
+#define MAX_BUSY_LOOPS 1000
+#undef USE_SCHED_YIELD
+
+/* ARCH SPECIFIC */
+/* We should make sure these are padded to a cache line */
+#if defined(SPARC_SPINLOCKS)
+typedef volatile char spinlock_t;
+#elif defined(POWERPC_SPINLOCKS)
+typedef volatile unsigned long spinlock_t;
+#elif defined(INTEL_SPINLOCKS)
+typedef volatile int spinlock_t;
+#elif defined(MIPS_SPINLOCKS)
+typedef volatile unsigned long spinlock_t;
+#else
+#error Need to implement spinlock code in spinlock.h
+#endif
+
+typedef struct {
+ spinlock_t lock;
+ volatile int count;
+} tdb_rwlock_t;
+
+int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type);
+int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type);
+int tdb_create_rwlocks(int fd, unsigned int hash_size);
+int tdb_clear_spinlocks(TDB_CONTEXT *tdb);
+
+#else /* !USE_SPINLOCKS */
+#if 0
+#define tdb_create_rwlocks(fd, hash_size) 0
+#define tdb_spinlock(tdb, list, rw_type) (-1)
+#define tdb_spinunlock(tdb, list, rw_type) (-1)
+#else
+int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type);
+int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type);
+int tdb_create_rwlocks(int fd, unsigned int hash_size);
+#endif
+int tdb_clear_spinlocks(TDB_CONTEXT *tdb);
+#endif
+
+#endif
--- /dev/null
+ /*
+ Unix SMB/CIFS implementation.
+ Samba database functions
+ Copyright (C) Andrew Tridgell 1999-2000
+ Copyright (C) Luke Kenneth Casson Leighton 2000
+ Copyright (C) Paul `Rusty' Russell 2000
+ Copyright (C) Jeremy Allison 2000
+
+ 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 2 of the License, 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.
+*/
+#ifdef STANDALONE
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include "tdb.h"
+#include "spinlock.h"
+#else
+#include "includes.h"
+#endif
+
+#define TDB_MAGIC_FOOD "TDB file\n"
+#define TDB_VERSION (0x26011967 + 6)
+#define TDB_MAGIC (0x26011999U)
+#define TDB_FREE_MAGIC (~TDB_MAGIC)
+#define TDB_DEAD_MAGIC (0xFEE1DEAD)
+#define TDB_ALIGNMENT 4
+#define MIN_REC_SIZE (2*sizeof(struct list_struct) + TDB_ALIGNMENT)
+#define DEFAULT_HASH_SIZE 131
+#define TDB_PAGE_SIZE 0x2000
+#define FREELIST_TOP (sizeof(struct tdb_header))
+#define TDB_ALIGN(x,a) (((x) + (a)-1) & ~((a)-1))
+#define TDB_BYTEREV(x) (((((x)&0xff)<<24)|((x)&0xFF00)<<8)|(((x)>>8)&0xFF00)|((x)>>24))
+#define TDB_DEAD(r) ((r)->magic == TDB_DEAD_MAGIC)
+#define TDB_BAD_MAGIC(r) ((r)->magic != TDB_MAGIC && !TDB_DEAD(r))
+#define TDB_HASH_TOP(hash) (FREELIST_TOP + (BUCKET(hash)+1)*sizeof(tdb_off))
+
+/* NB assumes there is a local variable called "tdb" that is the
+ * current context, also takes doubly-parenthesized print-style
+ * argument. */
+#define TDB_LOG(x) (tdb->log_fn?((tdb->log_fn x),0) : 0)
+
+/* lock offsets */
+#define GLOBAL_LOCK 0
+#define ACTIVE_LOCK 4
+
+#ifndef MAP_FILE
+#define MAP_FILE 0
+#endif
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+/* free memory if the pointer is valid and zero the pointer */
+#ifndef SAFE_FREE
+#define SAFE_FREE(x) do { if ((x) != NULL) {free((x)); (x)=NULL;} } while(0)
+#endif
+
+#define BUCKET(hash) ((hash) % tdb->header.hash_size)
+TDB_DATA tdb_null;
+
+/* all contexts, to ensure no double-opens (fcntl locks don't nest!) */
+static TDB_CONTEXT *tdbs = NULL;
+
+static int tdb_munmap(TDB_CONTEXT *tdb)
+{
+ if (tdb->flags & TDB_INTERNAL)
+ return 0;
+
+#ifdef HAVE_MMAP
+ if (tdb->map_ptr) {
+ int ret = munmap(tdb->map_ptr, tdb->map_size);
+ if (ret != 0)
+ return ret;
+ }
+#endif
+ tdb->map_ptr = NULL;
+ return 0;
+}
+
+static void tdb_mmap(TDB_CONTEXT *tdb)
+{
+ if (tdb->flags & TDB_INTERNAL)
+ return;
+
+#ifdef HAVE_MMAP
+ if (!(tdb->flags & TDB_NOMMAP)) {
+ tdb->map_ptr = mmap(NULL, tdb->map_size,
+ PROT_READ|(tdb->read_only? 0:PROT_WRITE),
+ MAP_SHARED|MAP_FILE, tdb->fd, 0);
+
+ /*
+ * NB. When mmap fails it returns MAP_FAILED *NOT* NULL !!!!
+ */
+
+ if (tdb->map_ptr == MAP_FAILED) {
+ tdb->map_ptr = NULL;
+ TDB_LOG((tdb, 2, "tdb_mmap failed for size %d (%s)\n",
+ tdb->map_size, strerror(errno)));
+ }
+ } else {
+ tdb->map_ptr = NULL;
+ }
+#else
+ tdb->map_ptr = NULL;
+#endif
+}
+
+/* Endian conversion: we only ever deal with 4 byte quantities */
+static void *convert(void *buf, u32 size)
+{
+ u32 i, *p = buf;
+ for (i = 0; i < size / 4; i++)
+ p[i] = TDB_BYTEREV(p[i]);
+ return buf;
+}
+#define DOCONV() (tdb->flags & TDB_CONVERT)
+#define CONVERT(x) (DOCONV() ? convert(&x, sizeof(x)) : &x)
+
+/* the body of the database is made of one list_struct for the free space
+ plus a separate data list for each hash value */
+struct list_struct {
+ tdb_off next; /* offset of the next record in the list */
+ tdb_len rec_len; /* total byte length of record */
+ tdb_len key_len; /* byte length of key */
+ tdb_len data_len; /* byte length of data */
+ u32 full_hash; /* the full 32 bit hash of the key */
+ u32 magic; /* try to catch errors */
+ /* the following union is implied:
+ union {
+ char record[rec_len];
+ struct {
+ char key[key_len];
+ char data[data_len];
+ }
+ u32 totalsize; (tailer)
+ }
+ */
+};
+
+/* a byte range locking function - return 0 on success
+ this functions locks/unlocks 1 byte at the specified offset.
+
+ On error, errno is also set so that errors are passed back properly
+ through tdb_open(). */
+static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset,
+ int rw_type, int lck_type, int probe)
+{
+ struct flock fl;
+ int ret;
+
+ if (tdb->flags & TDB_NOLOCK)
+ return 0;
+ if (tdb->read_only) {
+ errno = EACCES;
+ return -1;
+ }
+
+ fl.l_type = rw_type;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = offset;
+ fl.l_len = 1;
+ fl.l_pid = 0;
+
+ do {
+ ret = fcntl(tdb->fd,lck_type,&fl);
+ } while (ret == -1 && errno == EINTR);
+
+ if (ret == -1) {
+ if (!probe) {
+ TDB_LOG((tdb, 5,"tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d\n",
+ tdb->fd, offset, rw_type, lck_type));
+ }
+ /* errno set by fcntl */
+ return TDB_ERRCODE(TDB_ERR_LOCK, -1);
+ }
+ return 0;
+}
+
+/* lock a list in the database. list -1 is the alloc list */
+static int tdb_lock(TDB_CONTEXT *tdb, int list, int ltype)
+{
+ if (list < -1 || list >= (int)tdb->header.hash_size) {
+ TDB_LOG((tdb, 0,"tdb_lock: invalid list %d for ltype=%d\n",
+ list, ltype));
+ return -1;
+ }
+ if (tdb->flags & TDB_NOLOCK)
+ return 0;
+
+ /* Since fcntl locks don't nest, we do a lock for the first one,
+ and simply bump the count for future ones */
+ if (tdb->locked[list+1].count == 0) {
+ if (!tdb->read_only && tdb->header.rwlocks) {
+ if (tdb_spinlock(tdb, list, ltype)) {
+ TDB_LOG((tdb, 0, "tdb_lock spinlock failed on list ltype=%d\n",
+ list, ltype));
+ return -1;
+ }
+ } else if (tdb_brlock(tdb,FREELIST_TOP+4*list,ltype,F_SETLKW, 0)) {
+ TDB_LOG((tdb, 0,"tdb_lock failed on list %d ltype=%d (%s)\n",
+ list, ltype, strerror(errno)));
+ return -1;
+ }
+ tdb->locked[list+1].ltype = ltype;
+ }
+ tdb->locked[list+1].count++;
+ return 0;
+}
+
+/* unlock the database: returns void because it's too late for errors. */
+ /* changed to return int it may be interesting to know there
+ has been an error --simo */
+static int tdb_unlock(TDB_CONTEXT *tdb, int list, int ltype)
+{
+ int ret = -1;
+
+ if (tdb->flags & TDB_NOLOCK)
+ return 0;
+
+ /* Sanity checks */
+ if (list < -1 || list >= (int)tdb->header.hash_size) {
+ TDB_LOG((tdb, 0, "tdb_unlock: list %d invalid (%d)\n", list, tdb->header.hash_size));
+ return ret;
+ }
+
+ if (tdb->locked[list+1].count==0) {
+ TDB_LOG((tdb, 0, "tdb_unlock: count is 0\n"));
+ return ret;
+ }
+
+ if (tdb->locked[list+1].count == 1) {
+ /* Down to last nested lock: unlock underneath */
+ if (!tdb->read_only && tdb->header.rwlocks) {
+ ret = tdb_spinunlock(tdb, list, ltype);
+ } else {
+ ret = tdb_brlock(tdb, FREELIST_TOP+4*list, F_UNLCK, F_SETLKW, 0);
+ }
+ } else {
+ ret = 0;
+ }
+ tdb->locked[list+1].count--;
+
+ if (ret)
+ TDB_LOG((tdb, 0,"tdb_unlock: An error occurred unlocking!\n"));
+ return ret;
+}
+
+/* This is based on the hash algorithm from gdbm */
+static u32 tdb_hash(TDB_DATA *key)
+{
+ u32 value; /* Used to compute the hash value. */
+ u32 i; /* Used to cycle through random values. */
+
+ /* Set the initial value from the key size. */
+ for (value = 0x238F13AF * key->dsize, i=0; i < key->dsize; i++)
+ value = (value + (key->dptr[i] << (i*5 % 24)));
+
+ return (1103515243 * value + 12345);
+}
+
+/* check for an out of bounds access - if it is out of bounds then
+ see if the database has been expanded by someone else and expand
+ if necessary
+ note that "len" is the minimum length needed for the db
+*/
+static int tdb_oob(TDB_CONTEXT *tdb, tdb_off len, int probe)
+{
+ struct stat st;
+ if (len <= tdb->map_size)
+ return 0;
+ if (tdb->flags & TDB_INTERNAL) {
+ if (!probe) {
+ TDB_LOG((tdb, 0,"tdb_oob len %d beyond internal malloc size %d\n",
+ (int)len, (int)tdb->map_size));
+ }
+ return TDB_ERRCODE(TDB_ERR_IO, -1);
+ }
+
+ if (fstat(tdb->fd, &st) == -1)
+ return TDB_ERRCODE(TDB_ERR_IO, -1);
+
+ if (st.st_size < (size_t)len) {
+ if (!probe) {
+ TDB_LOG((tdb, 0,"tdb_oob len %d beyond eof at %d\n",
+ (int)len, (int)st.st_size));
+ }
+ return TDB_ERRCODE(TDB_ERR_IO, -1);
+ }
+
+ /* Unmap, update size, remap */
+ if (tdb_munmap(tdb) == -1)
+ return TDB_ERRCODE(TDB_ERR_IO, -1);
+ tdb->map_size = st.st_size;
+ tdb_mmap(tdb);
+ return 0;
+}
+
+/* write a lump of data at a specified offset */
+static int tdb_write(TDB_CONTEXT *tdb, tdb_off off, const void *buf, tdb_len len)
+{
+ if (tdb_oob(tdb, off + len, 0) != 0)
+ return -1;
+
+ if (tdb->map_ptr)
+ memcpy(off + (char *)tdb->map_ptr, buf, len);
+#ifdef HAVE_PWRITE
+ else if (pwrite(tdb->fd, buf, len, off) != (ssize_t)len) {
+#else
+ else if (lseek(tdb->fd, off, SEEK_SET) != off
+ || write(tdb->fd, buf, len) != (ssize_t)len) {
+#endif
+ TDB_LOG((tdb, 0,"tdb_write failed at %d len=%d (%s)\n",
+ off, len, strerror(errno)));
+ return TDB_ERRCODE(TDB_ERR_IO, -1);
+ }
+ return 0;
+}
+
+/* read a lump of data at a specified offset, maybe convert */
+static int tdb_read(TDB_CONTEXT *tdb,tdb_off off,void *buf,tdb_len len,int cv)
+{
+ if (tdb_oob(tdb, off + len, 0) != 0)
+ return -1;
+
+ if (tdb->map_ptr)
+ memcpy(buf, off + (char *)tdb->map_ptr, len);
+#ifdef HAVE_PREAD
+ else if (pread(tdb->fd, buf, len, off) != (ssize_t)len) {
+#else
+ else if (lseek(tdb->fd, off, SEEK_SET) != off
+ || read(tdb->fd, buf, len) != (ssize_t)len) {
+#endif
+ TDB_LOG((tdb, 0,"tdb_read failed at %d len=%d (%s)\n",
+ off, len, strerror(errno)));
+ return TDB_ERRCODE(TDB_ERR_IO, -1);
+ }
+ if (cv)
+ convert(buf, len);
+ return 0;
+}
+
+/* read a lump of data, allocating the space for it */
+static char *tdb_alloc_read(TDB_CONTEXT *tdb, tdb_off offset, tdb_len len)
+{
+ char *buf;
+
+ if (!(buf = malloc(len))) {
+ TDB_LOG((tdb, 0,"tdb_alloc_read malloc failed len=%d (%s)\n",
+ len, strerror(errno)));
+ return TDB_ERRCODE(TDB_ERR_OOM, buf);
+ }
+ if (tdb_read(tdb, offset, buf, len, 0) == -1) {
+ SAFE_FREE(buf);
+ return NULL;
+ }
+ return buf;
+}
+
+/* read/write a tdb_off */
+static int ofs_read(TDB_CONTEXT *tdb, tdb_off offset, tdb_off *d)
+{
+ return tdb_read(tdb, offset, (char*)d, sizeof(*d), DOCONV());
+}
+static int ofs_write(TDB_CONTEXT *tdb, tdb_off offset, tdb_off *d)
+{
+ tdb_off off = *d;
+ return tdb_write(tdb, offset, CONVERT(off), sizeof(*d));
+}
+
+/* read/write a record */
+static int rec_read(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec)
+{
+ if (tdb_read(tdb, offset, rec, sizeof(*rec),DOCONV()) == -1)
+ return -1;
+ if (TDB_BAD_MAGIC(rec)) {
+ TDB_LOG((tdb, 0,"rec_read bad magic 0x%x at offset=%d\n", rec->magic, offset));
+ return TDB_ERRCODE(TDB_ERR_CORRUPT, -1);
+ }
+ return tdb_oob(tdb, rec->next+sizeof(*rec), 0);
+}
+static int rec_write(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec)
+{
+ struct list_struct r = *rec;
+ return tdb_write(tdb, offset, CONVERT(r), sizeof(r));
+}
+
+/* read a freelist record and check for simple errors */
+static int rec_free_read(TDB_CONTEXT *tdb, tdb_off off, struct list_struct *rec)
+{
+ if (tdb_read(tdb, off, rec, sizeof(*rec),DOCONV()) == -1)
+ return -1;
+
+ if (rec->magic == TDB_MAGIC) {
+ /* this happens when a app is showdown while deleting a record - we should
+ not completely fail when this happens */
+ TDB_LOG((tdb, 0,"rec_free_read non-free magic at offset=%d - fixing\n",
+ rec->magic, off));
+ rec->magic = TDB_FREE_MAGIC;
+ tdb_write(tdb, off, rec, sizeof(*rec));
+ }
+
+ if (rec->magic != TDB_FREE_MAGIC) {
+ TDB_LOG((tdb, 0,"rec_free_read bad magic 0x%x at offset=%d\n",
+ rec->magic, off));
+ return TDB_ERRCODE(TDB_ERR_CORRUPT, -1);
+ }
+ if (tdb_oob(tdb, rec->next+sizeof(*rec), 0) != 0)
+ return -1;
+ return 0;
+}
+
+/* update a record tailer (must hold allocation lock) */
+static int update_tailer(TDB_CONTEXT *tdb, tdb_off offset,
+ const struct list_struct *rec)
+{
+ tdb_off totalsize;
+
+ /* Offset of tailer from record header */
+ totalsize = sizeof(*rec) + rec->rec_len;
+ return ofs_write(tdb, offset + totalsize - sizeof(tdb_off),
+ &totalsize);
+}
+
+static tdb_off tdb_dump_record(TDB_CONTEXT *tdb, tdb_off offset)
+{
+ struct list_struct rec;
+ tdb_off tailer_ofs, tailer;
+
+ if (tdb_read(tdb, offset, (char *)&rec, sizeof(rec), DOCONV()) == -1) {
+ printf("ERROR: failed to read record at %u\n", offset);
+ return 0;
+ }
+
+ printf(" rec: offset=%u next=%d rec_len=%d key_len=%d data_len=%d full_hash=0x%x magic=0x%x\n",
+ offset, rec.next, rec.rec_len, rec.key_len, rec.data_len, rec.full_hash, rec.magic);
+
+ tailer_ofs = offset + sizeof(rec) + rec.rec_len - sizeof(tdb_off);
+ if (ofs_read(tdb, tailer_ofs, &tailer) == -1) {
+ printf("ERROR: failed to read tailer at %u\n", tailer_ofs);
+ return rec.next;
+ }
+
+ if (tailer != rec.rec_len + sizeof(rec)) {
+ printf("ERROR: tailer does not match record! tailer=%u totalsize=%u\n",
+ (unsigned)tailer, (unsigned)(rec.rec_len + sizeof(rec)));
+ }
+ return rec.next;
+}
+
+static int tdb_dump_chain(TDB_CONTEXT *tdb, int i)
+{
+ tdb_off rec_ptr, top;
+
+ top = TDB_HASH_TOP(i);
+
+ if (tdb_lock(tdb, i, F_WRLCK) != 0)
+ return -1;
+
+ if (ofs_read(tdb, top, &rec_ptr) == -1)
+ return tdb_unlock(tdb, i, F_WRLCK);
+
+ if (rec_ptr)
+ printf("hash=%d\n", i);
+
+ while (rec_ptr) {
+ rec_ptr = tdb_dump_record(tdb, rec_ptr);
+ }
+
+ return tdb_unlock(tdb, i, F_WRLCK);
+}
+
+void tdb_dump_all(TDB_CONTEXT *tdb)
+{
+ int i;
+ for (i=0;i<tdb->header.hash_size;i++) {
+ tdb_dump_chain(tdb, i);
+ }
+ printf("freelist:\n");
+ tdb_dump_chain(tdb, -1);
+}
+
+int tdb_printfreelist(TDB_CONTEXT *tdb)
+{
+ int ret;
+ long total_free = 0;
+ tdb_off offset, rec_ptr;
+ struct list_struct rec;
+
+ if ((ret = tdb_lock(tdb, -1, F_WRLCK)) != 0)
+ return ret;
+
+ offset = FREELIST_TOP;
+
+ /* read in the freelist top */
+ if (ofs_read(tdb, offset, &rec_ptr) == -1) {
+ return 0;
+ }
+
+ printf("freelist top=[0x%08x]\n", rec_ptr );
+ while (rec_ptr) {
+ if (tdb_read(tdb, rec_ptr, (char *)&rec, sizeof(rec), DOCONV()) == -1) {
+ return -1;
+ }
+
+ if (rec.magic != TDB_FREE_MAGIC) {
+ printf("bad magic 0x%08x in free list\n", rec.magic);
+ return -1;
+ }
+
+ printf("entry offset=[0x%08x], rec.rec_len = [0x%08x (%d)]\n", rec.next, rec.rec_len, rec.rec_len );
+ total_free += rec.rec_len;
+
+ /* move to the next record */
+ rec_ptr = rec.next;
+ }
+ printf("total rec_len = [0x%08x (%d)]\n", (int)total_free,
+ (int)total_free);
+
+ return tdb_unlock(tdb, -1, F_WRLCK);
+}
+
+/* Remove an element from the freelist. Must have alloc lock. */
+static int remove_from_freelist(TDB_CONTEXT *tdb, tdb_off off, tdb_off next)
+{
+ tdb_off last_ptr, i;
+
+ /* read in the freelist top */
+ last_ptr = FREELIST_TOP;
+ while (ofs_read(tdb, last_ptr, &i) != -1 && i != 0) {
+ if (i == off) {
+ /* We've found it! */
+ return ofs_write(tdb, last_ptr, &next);
+ }
+ /* Follow chain (next offset is at start of record) */
+ last_ptr = i;
+ }
+ TDB_LOG((tdb, 0,"remove_from_freelist: not on list at off=%d\n", off));
+ return TDB_ERRCODE(TDB_ERR_CORRUPT, -1);
+}
+
+/* Add an element into the freelist. Merge adjacent records if
+ neccessary. */
+static int tdb_free(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec)
+{
+ tdb_off right, left;
+
+ /* Allocation and tailer lock */
+ if (tdb_lock(tdb, -1, F_WRLCK) != 0)
+ return -1;
+
+ /* set an initial tailer, so if we fail we don't leave a bogus record */
+ if (update_tailer(tdb, offset, rec) != 0) {
+ TDB_LOG((tdb, 0, "tdb_free: upfate_tailer failed!\n"));
+ goto fail;
+ }
+
+ /* Look right first (I'm an Australian, dammit) */
+ right = offset + sizeof(*rec) + rec->rec_len;
+ if (right + sizeof(*rec) <= tdb->map_size) {
+ struct list_struct r;
+
+ if (tdb_read(tdb, right, &r, sizeof(r), DOCONV()) == -1) {
+ TDB_LOG((tdb, 0, "tdb_free: right read failed at %u\n", right));
+ goto left;
+ }
+
+ /* If it's free, expand to include it. */
+ if (r.magic == TDB_FREE_MAGIC) {
+ if (remove_from_freelist(tdb, right, r.next) == -1) {
+ TDB_LOG((tdb, 0, "tdb_free: right free failed at %u\n", right));
+ goto left;
+ }
+ rec->rec_len += sizeof(r) + r.rec_len;
+ }
+ }
+
+left:
+ /* Look left */
+ left = offset - sizeof(tdb_off);
+ if (left > TDB_HASH_TOP(tdb->header.hash_size-1)) {
+ struct list_struct l;
+ tdb_off leftsize;
+
+ /* Read in tailer and jump back to header */
+ if (ofs_read(tdb, left, &leftsize) == -1) {
+ TDB_LOG((tdb, 0, "tdb_free: left offset read failed at %u\n", left));
+ goto update;
+ }
+ left = offset - leftsize;
+
+ /* Now read in record */
+ if (tdb_read(tdb, left, &l, sizeof(l), DOCONV()) == -1) {
+ TDB_LOG((tdb, 0, "tdb_free: left read failed at %u (%u)\n", left, leftsize));
+ goto update;
+ }
+
+ /* If it's free, expand to include it. */
+ if (l.magic == TDB_FREE_MAGIC) {
+ if (remove_from_freelist(tdb, left, l.next) == -1) {
+ TDB_LOG((tdb, 0, "tdb_free: left free failed at %u\n", left));
+ goto update;
+ } else {
+ offset = left;
+ rec->rec_len += leftsize;
+ }
+ }
+ }
+
+update:
+ if (update_tailer(tdb, offset, rec) == -1) {
+ TDB_LOG((tdb, 0, "tdb_free: update_tailer failed at %u\n", offset));
+ goto fail;
+ }
+
+ /* Now, prepend to free list */
+ rec->magic = TDB_FREE_MAGIC;
+
+ if (ofs_read(tdb, FREELIST_TOP, &rec->next) == -1 ||
+ rec_write(tdb, offset, rec) == -1 ||
+ ofs_write(tdb, FREELIST_TOP, &offset) == -1) {
+ TDB_LOG((tdb, 0, "tdb_free record write failed at offset=%d\n", offset));
+ goto fail;
+ }
+
+ /* And we're done. */
+ tdb_unlock(tdb, -1, F_WRLCK);
+ return 0;
+
+ fail:
+ tdb_unlock(tdb, -1, F_WRLCK);
+ return -1;
+}
+
+
+/* expand a file. we prefer to use ftruncate, as that is what posix
+ says to use for mmap expansion */
+static int expand_file(TDB_CONTEXT *tdb, tdb_off size, tdb_off addition)
+{
+ char buf[1024];
+#if HAVE_FTRUNCATE_EXTEND
+ if (ftruncate(tdb->fd, size+addition) != 0) {
+ TDB_LOG((tdb, 0, "expand_file ftruncate to %d failed (%s)\n",
+ size+addition, strerror(errno)));
+ return -1;
+ }
+#else
+ char b = 0;
+
+#ifdef HAVE_PWRITE
+ if (pwrite(tdb->fd, &b, 1, (size+addition) - 1) != 1) {
+#else
+ if (lseek(tdb->fd, (size+addition) - 1, SEEK_SET) != (size+addition) - 1 ||
+ write(tdb->fd, &b, 1) != 1) {
+#endif
+ TDB_LOG((tdb, 0, "expand_file to %d failed (%s)\n",
+ size+addition, strerror(errno)));
+ return -1;
+ }
+#endif
+
+ /* now fill the file with something. This ensures that the file isn't sparse, which would be
+ very bad if we ran out of disk. This must be done with write, not via mmap */
+ memset(buf, 0x42, sizeof(buf));
+ while (addition) {
+ int n = addition>sizeof(buf)?sizeof(buf):addition;
+#ifdef HAVE_PWRITE
+ int ret = pwrite(tdb->fd, buf, n, size);
+#else
+ int ret;
+ if (lseek(tdb->fd, size, SEEK_SET) != size)
+ return -1;
+ ret = write(tdb->fd, buf, n);
+#endif
+ if (ret != n) {
+ TDB_LOG((tdb, 0, "expand_file write of %d failed (%s)\n",
+ n, strerror(errno)));
+ return -1;
+ }
+ addition -= n;
+ size += n;
+ }
+ return 0;
+}
+
+
+/* expand the database at least size bytes by expanding the underlying
+ file and doing the mmap again if necessary */
+static int tdb_expand(TDB_CONTEXT *tdb, tdb_off size)
+{
+ struct list_struct rec;
+ tdb_off offset;
+
+ if (tdb_lock(tdb, -1, F_WRLCK) == -1) {
+ TDB_LOG((tdb, 0, "lock failed in tdb_expand\n"));
+ return -1;
+ }
+
+ /* must know about any previous expansions by another process */
+ tdb_oob(tdb, tdb->map_size + 1, 1);
+
+ /* always make room for at least 10 more records, and round
+ the database up to a multiple of TDB_PAGE_SIZE */
+ size = TDB_ALIGN(tdb->map_size + size*10, TDB_PAGE_SIZE) - tdb->map_size;
+
+ if (!(tdb->flags & TDB_INTERNAL))
+ tdb_munmap(tdb);
+
+ /*
+ * We must ensure the file is unmapped before doing this
+ * to ensure consistency with systems like OpenBSD where
+ * writes and mmaps are not consistent.
+ */
+
+ /* expand the file itself */
+ if (!(tdb->flags & TDB_INTERNAL)) {
+ if (expand_file(tdb, tdb->map_size, size) != 0)
+ goto fail;
+ }
+
+ tdb->map_size += size;
+
+ if (tdb->flags & TDB_INTERNAL)
+ tdb->map_ptr = realloc(tdb->map_ptr, tdb->map_size);
+ else {
+ /*
+ * We must ensure the file is remapped before adding the space
+ * to ensure consistency with systems like OpenBSD where
+ * writes and mmaps are not consistent.
+ */
+
+ /* We're ok if the mmap fails as we'll fallback to read/write */
+ tdb_mmap(tdb);
+ }
+
+ /* form a new freelist record */
+ memset(&rec,'\0',sizeof(rec));
+ rec.rec_len = size - sizeof(rec);
+
+ /* link it into the free list */
+ offset = tdb->map_size - size;
+ if (tdb_free(tdb, offset, &rec) == -1)
+ goto fail;
+
+ tdb_unlock(tdb, -1, F_WRLCK);
+ return 0;
+ fail:
+ tdb_unlock(tdb, -1, F_WRLCK);
+ return -1;
+}
+
+/* allocate some space from the free list. The offset returned points
+ to a unconnected list_struct within the database with room for at
+ least length bytes of total data
+
+ 0 is returned if the space could not be allocated
+ */
+static tdb_off tdb_allocate(TDB_CONTEXT *tdb, tdb_len length,
+ struct list_struct *rec)
+{
+ tdb_off rec_ptr, last_ptr, newrec_ptr;
+ struct list_struct newrec;
+
+ if (tdb_lock(tdb, -1, F_WRLCK) == -1)
+ return 0;
+
+ /* Extra bytes required for tailer */
+ length += sizeof(tdb_off);
+
+ again:
+ last_ptr = FREELIST_TOP;
+
+ /* read in the freelist top */
+ if (ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1)
+ goto fail;
+
+ /* keep looking until we find a freelist record big enough */
+ while (rec_ptr) {
+ if (rec_free_read(tdb, rec_ptr, rec) == -1)
+ goto fail;
+
+ if (rec->rec_len >= length) {
+ /* found it - now possibly split it up */
+ if (rec->rec_len > length + MIN_REC_SIZE) {
+ /* Length of left piece */
+ length = TDB_ALIGN(length, TDB_ALIGNMENT);
+
+ /* Right piece to go on free list */
+ newrec.rec_len = rec->rec_len
+ - (sizeof(*rec) + length);
+ newrec_ptr = rec_ptr + sizeof(*rec) + length;
+
+ /* And left record is shortened */
+ rec->rec_len = length;
+ } else
+ newrec_ptr = 0;
+
+ /* Remove allocated record from the free list */
+ if (ofs_write(tdb, last_ptr, &rec->next) == -1)
+ goto fail;
+
+ /* Update header: do this before we drop alloc
+ lock, otherwise tdb_free() might try to
+ merge with us, thinking we're free.
+ (Thanks Jeremy Allison). */
+ rec->magic = TDB_MAGIC;
+ if (rec_write(tdb, rec_ptr, rec) == -1)
+ goto fail;
+
+ /* Did we create new block? */
+ if (newrec_ptr) {
+ /* Update allocated record tailer (we
+ shortened it). */
+ if (update_tailer(tdb, rec_ptr, rec) == -1)
+ goto fail;
+
+ /* Free new record */
+ if (tdb_free(tdb, newrec_ptr, &newrec) == -1)
+ goto fail;
+ }
+
+ /* all done - return the new record offset */
+ tdb_unlock(tdb, -1, F_WRLCK);
+ return rec_ptr;
+ }
+ /* move to the next record */
+ last_ptr = rec_ptr;
+ rec_ptr = rec->next;
+ }
+ /* we didn't find enough space. See if we can expand the
+ database and if we can then try again */
+ if (tdb_expand(tdb, length + sizeof(*rec)) == 0)
+ goto again;
+ fail:
+ tdb_unlock(tdb, -1, F_WRLCK);
+ return 0;
+}
+
+/* initialise a new database with a specified hash size */
+static int tdb_new_database(TDB_CONTEXT *tdb, int hash_size)
+{
+ struct tdb_header *newdb;
+ int size, ret = -1;
+
+ /* We make it up in memory, then write it out if not internal */
+ size = sizeof(struct tdb_header) + (hash_size+1)*sizeof(tdb_off);
+ if (!(newdb = calloc(size, 1)))
+ return TDB_ERRCODE(TDB_ERR_OOM, -1);
+
+ /* Fill in the header */
+ newdb->version = TDB_VERSION;
+ newdb->hash_size = hash_size;
+#ifdef USE_SPINLOCKS
+ newdb->rwlocks = size;
+#endif
+ if (tdb->flags & TDB_INTERNAL) {
+ tdb->map_size = size;
+ tdb->map_ptr = (char *)newdb;
+ memcpy(&tdb->header, newdb, sizeof(tdb->header));
+ /* Convert the `ondisk' version if asked. */
+ CONVERT(*newdb);
+ return 0;
+ }
+ if (lseek(tdb->fd, 0, SEEK_SET) == -1)
+ goto fail;
+
+ if (ftruncate(tdb->fd, 0) == -1)
+ goto fail;
+
+ /* This creates an endian-converted header, as if read from disk */
+ CONVERT(*newdb);
+ memcpy(&tdb->header, newdb, sizeof(tdb->header));
+ /* Don't endian-convert the magic food! */
+ memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1);
+ if (write(tdb->fd, newdb, size) != size)
+ ret = -1;
+ else
+ ret = tdb_create_rwlocks(tdb->fd, hash_size);
+
+ fail:
+ SAFE_FREE(newdb);
+ return ret;
+}
+
+/* Returns 0 on fail. On success, return offset of record, and fills
+ in rec */
+static tdb_off tdb_find(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash,
+ struct list_struct *r)
+{
+ tdb_off rec_ptr;
+
+ /* read in the hash top */
+ if (ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1)
+ return 0;
+
+ /* keep looking until we find the right record */
+ while (rec_ptr) {
+ if (rec_read(tdb, rec_ptr, r) == -1)
+ return 0;
+
+ if (!TDB_DEAD(r) && hash==r->full_hash && key.dsize==r->key_len) {
+ char *k;
+ /* a very likely hit - read the key */
+ k = tdb_alloc_read(tdb, rec_ptr + sizeof(*r),
+ r->key_len);
+ if (!k)
+ return 0;
+
+ if (memcmp(key.dptr, k, key.dsize) == 0) {
+ SAFE_FREE(k);
+ return rec_ptr;
+ }
+ SAFE_FREE(k);
+ }
+ rec_ptr = r->next;
+ }
+ return TDB_ERRCODE(TDB_ERR_NOEXIST, 0);
+}
+
+/* If they do lockkeys, check that this hash is one they locked */
+static int tdb_keylocked(TDB_CONTEXT *tdb, u32 hash)
+{
+ u32 i;
+ if (!tdb->lockedkeys)
+ return 1;
+ for (i = 0; i < tdb->lockedkeys[0]; i++)
+ if (tdb->lockedkeys[i+1] == hash)
+ return 1;
+ return TDB_ERRCODE(TDB_ERR_NOLOCK, 0);
+}
+
+/* As tdb_find, but if you succeed, keep the lock */
+static tdb_off tdb_find_lock(TDB_CONTEXT *tdb, TDB_DATA key, int locktype,
+ struct list_struct *rec)
+{
+ u32 hash, rec_ptr;
+
+ hash = tdb_hash(&key);
+ if (!tdb_keylocked(tdb, hash))
+ return 0;
+ if (tdb_lock(tdb, BUCKET(hash), locktype) == -1)
+ return 0;
+ if (!(rec_ptr = tdb_find(tdb, key, hash, rec)))
+ tdb_unlock(tdb, BUCKET(hash), locktype);
+ return rec_ptr;
+}
+
+enum TDB_ERROR tdb_error(TDB_CONTEXT *tdb)
+{
+ return tdb->ecode;
+}
+
+static struct tdb_errname {
+ enum TDB_ERROR ecode; const char *estring;
+} emap[] = { {TDB_SUCCESS, "Success"},
+ {TDB_ERR_CORRUPT, "Corrupt database"},
+ {TDB_ERR_IO, "IO Error"},
+ {TDB_ERR_LOCK, "Locking error"},
+ {TDB_ERR_OOM, "Out of memory"},
+ {TDB_ERR_EXISTS, "Record exists"},
+ {TDB_ERR_NOLOCK, "Lock exists on other keys"},
+ {TDB_ERR_NOEXIST, "Record does not exist"} };
+
+/* Error string for the last tdb error */
+const char *tdb_errorstr(TDB_CONTEXT *tdb)
+{
+ u32 i;
+ for (i = 0; i < sizeof(emap) / sizeof(struct tdb_errname); i++)
+ if (tdb->ecode == emap[i].ecode)
+ return emap[i].estring;
+ return "Invalid error code";
+}
+
+/* update an entry in place - this only works if the new data size
+ is <= the old data size and the key exists.
+ on failure return -1
+*/
+static int tdb_update(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf)
+{
+ struct list_struct rec;
+ tdb_off rec_ptr;
+ int ret = -1;
+
+ /* find entry */
+ if (!(rec_ptr = tdb_find_lock(tdb, key, F_WRLCK, &rec)))
+ return -1;
+
+ /* must be long enough key, data and tailer */
+ if (rec.rec_len < key.dsize + dbuf.dsize + sizeof(tdb_off)) {
+ tdb->ecode = TDB_SUCCESS; /* Not really an error */
+ goto out;
+ }
+
+ if (tdb_write(tdb, rec_ptr + sizeof(rec) + rec.key_len,
+ dbuf.dptr, dbuf.dsize) == -1)
+ goto out;
+
+ if (dbuf.dsize != rec.data_len) {
+ /* update size */
+ rec.data_len = dbuf.dsize;
+ ret = rec_write(tdb, rec_ptr, &rec);
+ } else
+ ret = 0;
+ out:
+ tdb_unlock(tdb, BUCKET(rec.full_hash), F_WRLCK);
+ return ret;
+}
+
+/* find an entry in the database given a key */
+TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key)
+{
+ tdb_off rec_ptr;
+ struct list_struct rec;
+ TDB_DATA ret;
+
+ /* find which hash bucket it is in */
+ if (!(rec_ptr = tdb_find_lock(tdb,key,F_RDLCK,&rec)))
+ return tdb_null;
+
+ ret.dptr = tdb_alloc_read(tdb, rec_ptr + sizeof(rec) + rec.key_len,
+ rec.data_len);
+ ret.dsize = rec.data_len;
+ tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK);
+ return ret;
+}
+
+/* check if an entry in the database exists
+
+ note that 1 is returned if the key is found and 0 is returned if not found
+ this doesn't match the conventions in the rest of this module, but is
+ compatible with gdbm
+*/
+int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key)
+{
+ struct list_struct rec;
+
+ if (tdb_find_lock(tdb, key, F_RDLCK, &rec) == 0)
+ return 0;
+ tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK);
+ return 1;
+}
+
+/* record lock stops delete underneath */
+static int lock_record(TDB_CONTEXT *tdb, tdb_off off)
+{
+ return off ? tdb_brlock(tdb, off, F_RDLCK, F_SETLKW, 0) : 0;
+}
+/*
+ Write locks override our own fcntl readlocks, so check it here.
+ Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not
+ an error to fail to get the lock here.
+*/
+
+static int write_lock_record(TDB_CONTEXT *tdb, tdb_off off)
+{
+ struct tdb_traverse_lock *i;
+ for (i = &tdb->travlocks; i; i = i->next)
+ if (i->off == off)
+ return -1;
+ return tdb_brlock(tdb, off, F_WRLCK, F_SETLK, 1);
+}
+
+/*
+ Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not
+ an error to fail to get the lock here.
+*/
+
+static int write_unlock_record(TDB_CONTEXT *tdb, tdb_off off)
+{
+ return tdb_brlock(tdb, off, F_UNLCK, F_SETLK, 0);
+}
+/* fcntl locks don't stack: avoid unlocking someone else's */
+static int unlock_record(TDB_CONTEXT *tdb, tdb_off off)
+{
+ struct tdb_traverse_lock *i;
+ u32 count = 0;
+
+ if (off == 0)
+ return 0;
+ for (i = &tdb->travlocks; i; i = i->next)
+ if (i->off == off)
+ count++;
+ return (count == 1 ? tdb_brlock(tdb, off, F_UNLCK, F_SETLKW, 0) : 0);
+}
+
+/* actually delete an entry in the database given the offset */
+static int do_delete(TDB_CONTEXT *tdb, tdb_off rec_ptr, struct list_struct*rec)
+{
+ tdb_off last_ptr, i;
+ struct list_struct lastrec;
+
+ if (tdb->read_only) return -1;
+
+ if (write_lock_record(tdb, rec_ptr) == -1) {
+ /* Someone traversing here: mark it as dead */
+ rec->magic = TDB_DEAD_MAGIC;
+ return rec_write(tdb, rec_ptr, rec);
+ }
+ if (write_unlock_record(tdb, rec_ptr) != 0)
+ return -1;
+
+ /* find previous record in hash chain */
+ if (ofs_read(tdb, TDB_HASH_TOP(rec->full_hash), &i) == -1)
+ return -1;
+ for (last_ptr = 0; i != rec_ptr; last_ptr = i, i = lastrec.next)
+ if (rec_read(tdb, i, &lastrec) == -1)
+ return -1;
+
+ /* unlink it: next ptr is at start of record. */
+ if (last_ptr == 0)
+ last_ptr = TDB_HASH_TOP(rec->full_hash);
+ if (ofs_write(tdb, last_ptr, &rec->next) == -1)
+ return -1;
+
+ /* recover the space */
+ if (tdb_free(tdb, rec_ptr, rec) == -1)
+ return -1;
+ return 0;
+}
+
+/* Uses traverse lock: 0 = finish, -1 = error, other = record offset */
+static int tdb_next_lock(TDB_CONTEXT *tdb, struct tdb_traverse_lock *tlock,
+ struct list_struct *rec)
+{
+ int want_next = (tlock->off != 0);
+
+ /* No traversal allows if you've called tdb_lockkeys() */
+ if (tdb->lockedkeys)
+ return TDB_ERRCODE(TDB_ERR_NOLOCK, -1);
+
+ /* Lock each chain from the start one. */
+ for (; tlock->hash < tdb->header.hash_size; tlock->hash++) {
+ if (tdb_lock(tdb, tlock->hash, F_WRLCK) == -1)
+ return -1;
+
+ /* No previous record? Start at top of chain. */
+ if (!tlock->off) {
+ if (ofs_read(tdb, TDB_HASH_TOP(tlock->hash),
+ &tlock->off) == -1)
+ goto fail;
+ } else {
+ /* Otherwise unlock the previous record. */
+ if (unlock_record(tdb, tlock->off) != 0)
+ goto fail;
+ }
+
+ if (want_next) {
+ /* We have offset of old record: grab next */
+ if (rec_read(tdb, tlock->off, rec) == -1)
+ goto fail;
+ tlock->off = rec->next;
+ }
+
+ /* Iterate through chain */
+ while( tlock->off) {
+ tdb_off current;
+ if (rec_read(tdb, tlock->off, rec) == -1)
+ goto fail;
+ if (!TDB_DEAD(rec)) {
+ /* Woohoo: we found one! */
+ if (lock_record(tdb, tlock->off) != 0)
+ goto fail;
+ return tlock->off;
+ }
+ /* Try to clean dead ones from old traverses */
+ current = tlock->off;
+ tlock->off = rec->next;
+ if (do_delete(tdb, current, rec) != 0)
+ goto fail;
+ }
+ tdb_unlock(tdb, tlock->hash, F_WRLCK);
+ want_next = 0;
+ }
+ /* We finished iteration without finding anything */
+ return TDB_ERRCODE(TDB_SUCCESS, 0);
+
+ fail:
+ tlock->off = 0;
+ if (tdb_unlock(tdb, tlock->hash, F_WRLCK) != 0)
+ TDB_LOG((tdb, 0, "tdb_next_lock: On error unlock failed!\n"));
+ return -1;
+}
+
+/* traverse the entire database - calling fn(tdb, key, data) on each element.
+ return -1 on error or the record count traversed
+ if fn is NULL then it is not called
+ a non-zero return value from fn() indicates that the traversal should stop
+ */
+int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *state)
+{
+ TDB_DATA key, dbuf;
+ struct list_struct rec;
+ struct tdb_traverse_lock tl = { NULL, 0, 0 };
+ int ret, count = 0;
+
+ /* This was in the initializaton, above, but the IRIX compiler
+ * did not like it. crh
+ */
+ tl.next = tdb->travlocks.next;
+
+ /* fcntl locks don't stack: beware traverse inside traverse */
+ tdb->travlocks.next = &tl;
+
+ /* tdb_next_lock places locks on the record returned, and its chain */
+ while ((ret = tdb_next_lock(tdb, &tl, &rec)) > 0) {
+ count++;
+ /* now read the full record */
+ key.dptr = tdb_alloc_read(tdb, tl.off + sizeof(rec),
+ rec.key_len + rec.data_len);
+ if (!key.dptr) {
+ ret = -1;
+ if (tdb_unlock(tdb, tl.hash, F_WRLCK) != 0)
+ goto out;
+ if (unlock_record(tdb, tl.off) != 0)
+ TDB_LOG((tdb, 0, "tdb_traverse: key.dptr == NULL and unlock_record failed!\n"));
+ goto out;
+ }
+ key.dsize = rec.key_len;
+ dbuf.dptr = key.dptr + rec.key_len;
+ dbuf.dsize = rec.data_len;
+
+ /* Drop chain lock, call out */
+ if (tdb_unlock(tdb, tl.hash, F_WRLCK) != 0) {
+ ret = -1;
+ goto out;
+ }
+ if (fn && fn(tdb, key, dbuf, state)) {
+ /* They want us to terminate traversal */
+ ret = count;
+ if (unlock_record(tdb, tl.off) != 0) {
+ TDB_LOG((tdb, 0, "tdb_traverse: unlock_record failed!\n"));;
+ ret = -1;
+ }
+ tdb->travlocks.next = tl.next;
+ SAFE_FREE(key.dptr);
+ return count;
+ }
+ SAFE_FREE(key.dptr);
+ }
+out:
+ tdb->travlocks.next = tl.next;
+ if (ret < 0)
+ return -1;
+ else
+ return count;
+}
+
+/* find the first entry in the database and return its key */
+TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb)
+{
+ TDB_DATA key;
+ struct list_struct rec;
+
+ /* release any old lock */
+ if (unlock_record(tdb, tdb->travlocks.off) != 0)
+ return tdb_null;
+ tdb->travlocks.off = tdb->travlocks.hash = 0;
+
+ if (tdb_next_lock(tdb, &tdb->travlocks, &rec) <= 0)
+ return tdb_null;
+ /* now read the key */
+ key.dsize = rec.key_len;
+ key.dptr =tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),key.dsize);
+ if (tdb_unlock(tdb, BUCKET(tdb->travlocks.hash), F_WRLCK) != 0)
+ TDB_LOG((tdb, 0, "tdb_firstkey: error occurred while tdb_unlocking!\n"));
+ return key;
+}
+
+/* find the next entry in the database, returning its key */
+TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA oldkey)
+{
+ u32 oldhash;
+ TDB_DATA key = tdb_null;
+ struct list_struct rec;
+ char *k = NULL;
+
+ /* Is locked key the old key? If so, traverse will be reliable. */
+ if (tdb->travlocks.off) {
+ if (tdb_lock(tdb,tdb->travlocks.hash,F_WRLCK))
+ return tdb_null;
+ if (rec_read(tdb, tdb->travlocks.off, &rec) == -1
+ || !(k = tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),
+ rec.key_len))
+ || memcmp(k, oldkey.dptr, oldkey.dsize) != 0) {
+ /* No, it wasn't: unlock it and start from scratch */
+ if (unlock_record(tdb, tdb->travlocks.off) != 0)
+ return tdb_null;
+ if (tdb_unlock(tdb, tdb->travlocks.hash, F_WRLCK) != 0)
+ return tdb_null;
+ tdb->travlocks.off = 0;
+ }
+
+ SAFE_FREE(k);
+ }
+
+ if (!tdb->travlocks.off) {
+ /* No previous element: do normal find, and lock record */
+ tdb->travlocks.off = tdb_find_lock(tdb, oldkey, F_WRLCK, &rec);
+ if (!tdb->travlocks.off)
+ return tdb_null;
+ tdb->travlocks.hash = BUCKET(rec.full_hash);
+ if (lock_record(tdb, tdb->travlocks.off) != 0) {
+ TDB_LOG((tdb, 0, "tdb_nextkey: lock_record failed (%s)!\n", strerror(errno)));
+ return tdb_null;
+ }
+ }
+ oldhash = tdb->travlocks.hash;
+
+ /* Grab next record: locks chain and returned record,
+ unlocks old record */
+ if (tdb_next_lock(tdb, &tdb->travlocks, &rec) > 0) {
+ key.dsize = rec.key_len;
+ key.dptr = tdb_alloc_read(tdb, tdb->travlocks.off+sizeof(rec),
+ key.dsize);
+ /* Unlock the chain of this new record */
+ if (tdb_unlock(tdb, tdb->travlocks.hash, F_WRLCK) != 0)
+ TDB_LOG((tdb, 0, "tdb_nextkey: WARNING tdb_unlock failed!\n"));
+ }
+ /* Unlock the chain of old record */
+ if (tdb_unlock(tdb, BUCKET(oldhash), F_WRLCK) != 0)
+ TDB_LOG((tdb, 0, "tdb_nextkey: WARNING tdb_unlock failed!\n"));
+ return key;
+}
+
+/* delete an entry in the database given a key */
+int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key)
+{
+ tdb_off rec_ptr;
+ struct list_struct rec;
+ int ret;
+
+ if (!(rec_ptr = tdb_find_lock(tdb, key, F_WRLCK, &rec)))
+ return -1;
+ ret = do_delete(tdb, rec_ptr, &rec);
+ if (tdb_unlock(tdb, BUCKET(rec.full_hash), F_WRLCK) != 0)
+ TDB_LOG((tdb, 0, "tdb_delete: WARNING tdb_unlock failed!\n"));
+ return ret;
+}
+
+/* store an element in the database, replacing any existing element
+ with the same key
+
+ return 0 on success, -1 on failure
+*/
+int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
+{
+ struct list_struct rec;
+ u32 hash;
+ tdb_off rec_ptr;
+ char *p = NULL;
+ int ret = 0;
+
+ /* find which hash bucket it is in */
+ hash = tdb_hash(&key);
+ if (!tdb_keylocked(tdb, hash))
+ return -1;
+ if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1)
+ return -1;
+
+ /* check for it existing, on insert. */
+ if (flag == TDB_INSERT) {
+ if (tdb_exists(tdb, key)) {
+ tdb->ecode = TDB_ERR_EXISTS;
+ goto fail;
+ }
+ } else {
+ /* first try in-place update, on modify or replace. */
+ if (tdb_update(tdb, key, dbuf) == 0)
+ goto out;
+ if (flag == TDB_MODIFY && tdb->ecode == TDB_ERR_NOEXIST)
+ goto fail;
+ }
+ /* reset the error code potentially set by the tdb_update() */
+ tdb->ecode = TDB_SUCCESS;
+
+ /* delete any existing record - if it doesn't exist we don't
+ care. Doing this first reduces fragmentation, and avoids
+ coalescing with `allocated' block before it's updated. */
+ if (flag != TDB_INSERT)
+ tdb_delete(tdb, key);
+
+ /* Copy key+value *before* allocating free space in case malloc
+ fails and we are left with a dead spot in the tdb. */
+
+ if (!(p = (char *)malloc(key.dsize + dbuf.dsize))) {
+ tdb->ecode = TDB_ERR_OOM;
+ goto fail;
+ }
+
+ memcpy(p, key.dptr, key.dsize);
+ memcpy(p+key.dsize, dbuf.dptr, dbuf.dsize);
+
+ /* now we're into insert / modify / replace of a record which
+ * we know could not be optimised by an in-place store (for
+ * various reasons). */
+ if (!(rec_ptr = tdb_allocate(tdb, key.dsize + dbuf.dsize, &rec)))
+ goto fail;
+
+ /* Read hash top into next ptr */
+ if (ofs_read(tdb, TDB_HASH_TOP(hash), &rec.next) == -1)
+ goto fail;
+
+ rec.key_len = key.dsize;
+ rec.data_len = dbuf.dsize;
+ rec.full_hash = hash;
+ rec.magic = TDB_MAGIC;
+
+ /* write out and point the top of the hash chain at it */
+ if (rec_write(tdb, rec_ptr, &rec) == -1
+ || tdb_write(tdb, rec_ptr+sizeof(rec), p, key.dsize+dbuf.dsize)==-1
+ || ofs_write(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) {
+ /* Need to tdb_unallocate() here */
+ goto fail;
+ }
+ out:
+ SAFE_FREE(p);
+ tdb_unlock(tdb, BUCKET(hash), F_WRLCK);
+ return ret;
+fail:
+ ret = -1;
+ goto out;
+}
+
+static int tdb_already_open(dev_t device,
+ ino_t ino)
+{
+ TDB_CONTEXT *i;
+
+ for (i = tdbs; i; i = i->next) {
+ if (i->device == device && i->inode == ino) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/* open the database, creating it if necessary
+
+ The open_flags and mode are passed straight to the open call on the
+ database file. A flags value of O_WRONLY is invalid. The hash size
+ is advisory, use zero for a default value.
+
+ Return is NULL on error, in which case errno is also set. Don't
+ try to call tdb_error or tdb_errname, just do strerror(errno).
+
+ @param name may be NULL for internal databases. */
+TDB_CONTEXT *tdb_open(const char *name, int hash_size, int tdb_flags,
+ int open_flags, mode_t mode)
+{
+ return tdb_open_ex(name, hash_size, tdb_flags, open_flags, mode, NULL);
+}
+
+
+TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
+ int open_flags, mode_t mode,
+ tdb_log_func log_fn)
+{
+ TDB_CONTEXT *tdb;
+ struct stat st;
+ int rev = 0, locked;
+ unsigned char *vp;
+ u32 vertest;
+
+ if (!(tdb = calloc(1, sizeof *tdb))) {
+ /* Can't log this */
+ errno = ENOMEM;
+ goto fail;
+ }
+ tdb->fd = -1;
+ tdb->name = NULL;
+ tdb->map_ptr = NULL;
+ tdb->lockedkeys = NULL;
+ tdb->flags = tdb_flags;
+ tdb->open_flags = open_flags;
+ tdb->log_fn = log_fn;
+
+ if ((open_flags & O_ACCMODE) == O_WRONLY) {
+ TDB_LOG((tdb, 0, "tdb_open_ex: can't open tdb %s write-only\n",
+ name));
+ errno = EINVAL;
+ goto fail;
+ }
+
+ if (hash_size == 0)
+ hash_size = DEFAULT_HASH_SIZE;
+ if ((open_flags & O_ACCMODE) == O_RDONLY) {
+ tdb->read_only = 1;
+ /* read only databases don't do locking or clear if first */
+ tdb->flags |= TDB_NOLOCK;
+ tdb->flags &= ~TDB_CLEAR_IF_FIRST;
+ }
+
+ /* internal databases don't mmap or lock, and start off cleared */
+ if (tdb->flags & TDB_INTERNAL) {
+ tdb->flags |= (TDB_NOLOCK | TDB_NOMMAP);
+ tdb->flags &= ~TDB_CLEAR_IF_FIRST;
+ if (tdb_new_database(tdb, hash_size) != 0) {
+ TDB_LOG((tdb, 0, "tdb_open_ex: tdb_new_database failed!"));
+ goto fail;
+ }
+ goto internal;
+ }
+
+ if ((tdb->fd = open(name, open_flags, mode)) == -1) {
+ TDB_LOG((tdb, 5, "tdb_open_ex: could not open file %s: %s\n",
+ name, strerror(errno)));
+ goto fail; /* errno set by open(2) */
+ }
+
+ /* ensure there is only one process initialising at once */
+ if (tdb_brlock(tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0) == -1) {
+ TDB_LOG((tdb, 0, "tdb_open_ex: failed to get global lock on %s: %s\n",
+ name, strerror(errno)));
+ goto fail; /* errno set by tdb_brlock */
+ }
+
+ /* we need to zero database if we are the only one with it open */
+ if ((locked = (tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0) == 0))
+ && (tdb_flags & TDB_CLEAR_IF_FIRST)) {
+ open_flags |= O_CREAT;
+ if (ftruncate(tdb->fd, 0) == -1) {
+ TDB_LOG((tdb, 0, "tdb_open_ex: "
+ "failed to truncate %s: %s\n",
+ name, strerror(errno)));
+ goto fail; /* errno set by ftruncate */
+ }
+ }
+
+ if (read(tdb->fd, &tdb->header, sizeof(tdb->header)) != sizeof(tdb->header)
+ || strcmp(tdb->header.magic_food, TDB_MAGIC_FOOD) != 0
+ || (tdb->header.version != TDB_VERSION
+ && !(rev = (tdb->header.version==TDB_BYTEREV(TDB_VERSION))))) {
+ /* its not a valid database - possibly initialise it */
+ if (!(open_flags & O_CREAT) || tdb_new_database(tdb, hash_size) == -1) {
+ errno = EIO; /* ie bad format or something */
+ goto fail;
+ }
+ rev = (tdb->flags & TDB_CONVERT);
+ }
+ vp = (unsigned char *)&tdb->header.version;
+ vertest = (((u32)vp[0]) << 24) | (((u32)vp[1]) << 16) |
+ (((u32)vp[2]) << 8) | (u32)vp[3];
+ tdb->flags |= (vertest==TDB_VERSION) ? TDB_BIGENDIAN : 0;
+ if (!rev)
+ tdb->flags &= ~TDB_CONVERT;
+ else {
+ tdb->flags |= TDB_CONVERT;
+ convert(&tdb->header, sizeof(tdb->header));
+ }
+ if (fstat(tdb->fd, &st) == -1)
+ goto fail;
+
+ /* Is it already in the open list? If so, fail. */
+ if (tdb_already_open(st.st_dev, st.st_ino)) {
+ TDB_LOG((tdb, 2, "tdb_open_ex: "
+ "%s (%d,%d) is already open in this process\n",
+ name, st.st_dev, st.st_ino));
+ errno = EBUSY;
+ goto fail;
+ }
+
+ if (!(tdb->name = (char *)strdup(name))) {
+ errno = ENOMEM;
+ goto fail;
+ }
+
+ tdb->map_size = st.st_size;
+ tdb->device = st.st_dev;
+ tdb->inode = st.st_ino;
+ tdb->locked = calloc(tdb->header.hash_size+1, sizeof(tdb->locked[0]));
+ if (!tdb->locked) {
+ TDB_LOG((tdb, 2, "tdb_open_ex: "
+ "failed to allocate lock structure for %s\n",
+ name));
+ errno = ENOMEM;
+ goto fail;
+ }
+ tdb_mmap(tdb);
+ if (locked) {
+ if (!tdb->read_only)
+ if (tdb_clear_spinlocks(tdb) != 0) {
+ TDB_LOG((tdb, 0, "tdb_open_ex: "
+ "failed to clear spinlock\n"));
+ goto fail;
+ }
+ if (tdb_brlock(tdb, ACTIVE_LOCK, F_UNLCK, F_SETLK, 0) == -1) {
+ TDB_LOG((tdb, 0, "tdb_open_ex: "
+ "failed to take ACTIVE_LOCK on %s: %s\n",
+ name, strerror(errno)));
+ goto fail;
+ }
+ }
+ /* leave this lock in place to indicate it's in use */
+ if (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1)
+ goto fail;
+
+ internal:
+ /* Internal (memory-only) databases skip all the code above to
+ * do with disk files, and resume here by releasing their
+ * global lock and hooking into the active list. */
+ if (tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0) == -1)
+ goto fail;
+ tdb->next = tdbs;
+ tdbs = tdb;
+ return tdb;
+
+ fail:
+ { int save_errno = errno;
+
+ if (!tdb)
+ return NULL;
+
+ if (tdb->map_ptr) {
+ if (tdb->flags & TDB_INTERNAL)
+ SAFE_FREE(tdb->map_ptr);
+ else
+ tdb_munmap(tdb);
+ }
+ SAFE_FREE(tdb->name);
+ if (tdb->fd != -1)
+ if (close(tdb->fd) != 0)
+ TDB_LOG((tdb, 5, "tdb_open_ex: failed to close tdb->fd on error!\n"));
+ SAFE_FREE(tdb->locked);
+ SAFE_FREE(tdb);
+ errno = save_errno;
+ return NULL;
+ }
+}
+
+/* close a database */
+int tdb_close(TDB_CONTEXT *tdb)
+{
+ TDB_CONTEXT **i;
+ int ret = 0;
+
+ if (tdb->map_ptr) {
+ if (tdb->flags & TDB_INTERNAL)
+ SAFE_FREE(tdb->map_ptr);
+ else
+ tdb_munmap(tdb);
+ }
+ SAFE_FREE(tdb->name);
+ if (tdb->fd != -1)
+ ret = close(tdb->fd);
+ SAFE_FREE(tdb->locked);
+ SAFE_FREE(tdb->lockedkeys);
+
+ /* Remove from contexts list */
+ for (i = &tdbs; *i; i = &(*i)->next) {
+ if (*i == tdb) {
+ *i = tdb->next;
+ break;
+ }
+ }
+
+ memset(tdb, 0, sizeof(*tdb));
+ SAFE_FREE(tdb);
+
+ return ret;
+}
+
+/* lock/unlock entire database */
+int tdb_lockall(TDB_CONTEXT *tdb)
+{
+ u32 i;
+
+ /* There are no locks on read-only dbs */
+ if (tdb->read_only)
+ return TDB_ERRCODE(TDB_ERR_LOCK, -1);
+ if (tdb->lockedkeys)
+ return TDB_ERRCODE(TDB_ERR_NOLOCK, -1);
+ for (i = 0; i < tdb->header.hash_size; i++)
+ if (tdb_lock(tdb, i, F_WRLCK))
+ break;
+
+ /* If error, release locks we have... */
+ if (i < tdb->header.hash_size) {
+ u32 j;
+
+ for ( j = 0; j < i; j++)
+ tdb_unlock(tdb, j, F_WRLCK);
+ return TDB_ERRCODE(TDB_ERR_NOLOCK, -1);
+ }
+
+ return 0;
+}
+void tdb_unlockall(TDB_CONTEXT *tdb)
+{
+ u32 i;
+ for (i=0; i < tdb->header.hash_size; i++)
+ tdb_unlock(tdb, i, F_WRLCK);
+}
+
+int tdb_lockkeys(TDB_CONTEXT *tdb, u32 number, TDB_DATA keys[])
+{
+ u32 i, j, hash;
+
+ /* Can't lock more keys if already locked */
+ if (tdb->lockedkeys)
+ return TDB_ERRCODE(TDB_ERR_NOLOCK, -1);
+ if (!(tdb->lockedkeys = malloc(sizeof(u32) * (number+1))))
+ return TDB_ERRCODE(TDB_ERR_OOM, -1);
+ /* First number in array is # keys */
+ tdb->lockedkeys[0] = number;
+
+ /* Insertion sort by bucket */
+ for (i = 0; i < number; i++) {
+ hash = tdb_hash(&keys[i]);
+ for (j = 0; j < i && BUCKET(tdb->lockedkeys[j+1]) < BUCKET(hash); j++);
+ memmove(&tdb->lockedkeys[j+2], &tdb->lockedkeys[j+1], sizeof(u32) * (i-j));
+ tdb->lockedkeys[j+1] = hash;
+ }
+ /* Finally, lock in order */
+ for (i = 0; i < number; i++)
+ if (tdb_lock(tdb, i, F_WRLCK))
+ break;
+
+ /* If error, release locks we have... */
+ if (i < number) {
+ for ( j = 0; j < i; j++)
+ tdb_unlock(tdb, j, F_WRLCK);
+ SAFE_FREE(tdb->lockedkeys);
+ return TDB_ERRCODE(TDB_ERR_NOLOCK, -1);
+ }
+ return 0;
+}
+
+/* Unlock the keys previously locked by tdb_lockkeys() */
+void tdb_unlockkeys(TDB_CONTEXT *tdb)
+{
+ u32 i;
+ for (i = 0; i < tdb->lockedkeys[0]; i++)
+ tdb_unlock(tdb, tdb->lockedkeys[i+1], F_WRLCK);
+ SAFE_FREE(tdb->lockedkeys);
+}
+
+/* lock/unlock one hash chain. This is meant to be used to reduce
+ contention - it cannot guarantee how many records will be locked */
+int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key)
+{
+ return tdb_lock(tdb, BUCKET(tdb_hash(&key)), F_WRLCK);
+}
+
+int tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key)
+{
+ return tdb_unlock(tdb, BUCKET(tdb_hash(&key)), F_WRLCK);
+}
+
+
+/* register a loging function */
+void tdb_logging_function(TDB_CONTEXT *tdb, void (*fn)(TDB_CONTEXT *, int , const char *, ...))
+{
+ tdb->log_fn = fn;
+}
+
+
+/* reopen a tdb - this is used after a fork to ensure that we have an independent
+ seek pointer from our parent and to re-establish locks */
+int tdb_reopen(TDB_CONTEXT *tdb)
+{
+ struct stat st;
+
+ if (tdb_munmap(tdb) != 0) {
+ TDB_LOG((tdb, 0, "tdb_reopen: munmap failed (%s)\n", strerror(errno)));
+ goto fail;
+ }
+ if (close(tdb->fd) != 0)
+ TDB_LOG((tdb, 0, "tdb_reopen: WARNING closing tdb->fd failed!\n"));
+ tdb->fd = open(tdb->name, tdb->open_flags & ~(O_CREAT|O_TRUNC), 0);
+ if (tdb->fd == -1) {
+ TDB_LOG((tdb, 0, "tdb_reopen: open failed (%s)\n", strerror(errno)));
+ goto fail;
+ }
+ if (fstat(tdb->fd, &st) != 0) {
+ TDB_LOG((tdb, 0, "tdb_reopen: fstat failed (%s)\n", strerror(errno)));
+ goto fail;
+ }
+ if (st.st_ino != tdb->inode || st.st_dev != tdb->device) {
+ TDB_LOG((tdb, 0, "tdb_reopen: file dev/inode has changed!\n"));
+ goto fail;
+ }
+ tdb_mmap(tdb);
+ if (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1) {
+ TDB_LOG((tdb, 0, "tdb_reopen: failed to obtain active lock\n"));
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ tdb_close(tdb);
+ return -1;
+}
+
+/* reopen all tdb's */
+int tdb_reopen_all(void)
+{
+ TDB_CONTEXT *tdb;
+
+ for (tdb=tdbs; tdb; tdb = tdb->next) {
+ if (tdb_reopen(tdb) != 0) return -1;
+ }
+
+ return 0;
+}
--- /dev/null
+#ifndef __TDB_H__
+#define __TDB_H__
+
+/*
+ Unix SMB/CIFS implementation.
+ Samba database functions
+ Copyright (C) Andrew Tridgell 1999
+
+ 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 2 of the License, 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.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* flags to tdb_store() */
+#define TDB_REPLACE 1
+#define TDB_INSERT 2
+#define TDB_MODIFY 3
+
+/* flags for tdb_open() */
+#define TDB_DEFAULT 0 /* just a readability place holder */
+#define TDB_CLEAR_IF_FIRST 1
+#define TDB_INTERNAL 2 /* don't store on disk */
+#define TDB_NOLOCK 4 /* don't do any locking */
+#define TDB_NOMMAP 8 /* don't use mmap */
+#define TDB_CONVERT 16 /* convert endian (internal use) */
+#define TDB_BIGENDIAN 32 /* header is big-endian (internal use) */
+
+#define TDB_ERRCODE(code, ret) ((tdb->ecode = (code)), ret)
+
+/* error codes */
+enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK,
+ TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOEXIST, TDB_ERR_NOLOCK };
+
+#ifndef u32
+#define u32 unsigned
+#endif
+
+typedef struct {
+ const char *dptr;
+ size_t dsize;
+} TDB_DATA;
+
+typedef u32 tdb_len;
+typedef u32 tdb_off;
+
+/* this is stored at the front of every database */
+struct tdb_header {
+ char magic_food[32]; /* for /etc/magic */
+ u32 version; /* version of the code */
+ u32 hash_size; /* number of hash entries */
+ tdb_off rwlocks;
+ tdb_off reserved[31];
+};
+
+struct tdb_lock_type {
+ u32 count;
+ u32 ltype;
+};
+
+struct tdb_traverse_lock {
+ struct tdb_traverse_lock *next;
+ u32 off;
+ u32 hash;
+};
+
+/* this is the context structure that is returned from a db open */
+typedef struct tdb_context {
+ char *name; /* the name of the database */
+ void *map_ptr; /* where it is currently mapped */
+ int fd; /* open file descriptor for the database */
+ tdb_len map_size; /* how much space has been mapped */
+ int read_only; /* opened read-only */
+ struct tdb_lock_type *locked; /* array of chain locks */
+ enum TDB_ERROR ecode; /* error code for last tdb error */
+ struct tdb_header header; /* a cached copy of the header */
+ u32 flags; /* the flags passed to tdb_open */
+ u32 *lockedkeys; /* array of locked keys: first is #keys */
+ struct tdb_traverse_lock travlocks; /* current traversal locks */
+ struct tdb_context *next; /* all tdbs to avoid multiple opens */
+ dev_t device; /* uniquely identifies this tdb */
+ ino_t inode; /* uniquely identifies this tdb */
+ void (*log_fn)(struct tdb_context *tdb, int level, const char *, ...); /* logging function */
+ int open_flags; /* flags used in the open - needed by reopen */
+} TDB_CONTEXT;
+
+typedef int (*tdb_traverse_func)(TDB_CONTEXT *, TDB_DATA, TDB_DATA, void *);
+typedef void (*tdb_log_func)(TDB_CONTEXT *, int , const char *, ...);
+
+TDB_CONTEXT *tdb_open(const char *name, int hash_size, int tdb_flags,
+ int open_flags, mode_t mode);
+TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
+ int open_flags, mode_t mode,
+ tdb_log_func log_fn);
+
+int tdb_reopen(TDB_CONTEXT *tdb);
+int tdb_reopen_all(void);
+void tdb_logging_function(TDB_CONTEXT *tdb, tdb_log_func);
+enum TDB_ERROR tdb_error(TDB_CONTEXT *tdb);
+const char *tdb_errorstr(TDB_CONTEXT *tdb);
+TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key);
+int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key);
+int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag);
+int tdb_close(TDB_CONTEXT *tdb);
+TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb);
+TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key);
+int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *state);
+int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key);
+int tdb_lockkeys(TDB_CONTEXT *tdb, u32 number, TDB_DATA keys[]);
+void tdb_unlockkeys(TDB_CONTEXT *tdb);
+int tdb_lockall(TDB_CONTEXT *tdb);
+void tdb_unlockall(TDB_CONTEXT *tdb);
+
+/* Low level locking functions: use with care */
+int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key);
+int tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key);
+
+/* Debug functions. Not used in production. */
+void tdb_dump_all(TDB_CONTEXT *tdb);
+int tdb_printfreelist(TDB_CONTEXT *tdb);
+
+extern TDB_DATA tdb_null;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* tdb.h */
--- /dev/null
+/*
+ Copyright 2002 Andrew Tridgell <tridge@samba.org>
+
+ 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 2 of the License, 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.
+ */
+
+/* glue code that connects the chess server to the external timeseal
+ * decoder */
+
+#include "includes.h"
+
+/*
+ send a string to the decoder sub-process and return the modified (decoded) string
+ the return value is the decoded timestamp. It will be zero if the decoder didn't
+ recognise the input as valid timeseal data
+ */
+static unsigned decode(unsigned char *s)
+{
+ char line[1024];
+ char *p;
+ unsigned t = 0;
+
+ /* send the encoded data to the decoder process */
+ dprintf(timeseal_globals.decoder_conn, "%s\n", s);
+
+ if (!fd_gets(line, sizeof(line), timeseal_globals.decoder_conn)) {
+ d_printf("Bad result from timeseal decoder? (t=%u)\n", t);
+ close(timeseal_globals.decoder_conn);
+ timeseal_globals.decoder_conn = -1;
+ return 0;
+ }
+ line[strlen(line)-1] = 0;
+
+ p = strchr(line, ':');
+ if (!p) {
+ d_printf("Badly formed timeseal decoder line: [%s]\n", line);
+ close(timeseal_globals.decoder_conn);
+ timeseal_globals.decoder_conn = -1;
+ return 0;
+ }
+
+ t = atoi(line);
+ strcpy(s, p+2);
+
+ return t;
+}
+
+/*
+ initialise the timeseal decoder sub-process
+*/
+void timeseal_init(const char *path)
+{
+ int fd[2];
+ pid_t pid;
+
+ /* use a socketpair to get a bi-directional pipe with large buffers */
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) != 0) {
+ d_printf("Failed to create socket pair!\n");
+ exit(1);
+ }
+
+ pid = fork();
+
+ if (pid == 0) {
+ close(fd[1]);
+ close(0);
+ close(1);
+ close(2);
+ dup2(fd[0], 0);
+ dup2(fd[0], 1);
+ open("/dev/null", O_WRONLY); /* stderr */
+ execl(path, "[timeseal]", NULL);
+ exit(1);
+ }
+
+ timeseal_globals.decoder_conn = fd[1];
+ close(fd[0]);
+}
+
+
+/*
+ parse a command line from a user on *con that may be timeseal encoded.
+ return 1 if the command should be processed further, 0 if the command
+ should be discarded
+ */
+int timeseal_parse(char *command, struct connection_t *con)
+{
+ unsigned t;
+
+ /* do we have a decoder sub-process? */
+ if (timeseal_globals.decoder_conn <= 0) return 1;
+
+ /* are they using timeseal on this connection? */
+ if (!con->timeseal_init && !con->timeseal) return 1;
+
+ t = decode(command);
+
+ if (t == 0) {
+ /* this wasn't encoded using timeseal */
+ d_printf("Non-timeseal data [%s]\n", command);
+ con->timeseal_init = 0;
+ return 1;
+ }
+
+ if (con->timeseal_init) {
+ con->timeseal_init = 0;
+ con->timeseal = 1;
+ d_printf("Connected with timeseal %s\n", command);
+ if (strncmp(command, "TIMESTAMP|", 10) == 0) {
+ return 0;
+ }
+ }
+
+ con->time = t;
+
+ /* now check for the special move time tag */
+ if (strcmp(command, "\ 29") == 0) {
+ int p = player_find(con->fd);
+ struct player *pp = &player_globals.parray[p];
+ if (p >= 0 && pp->game >= 0) {
+ int g = pp->game;
+ if (game_globals.garray[g].game_state.onMove !=
+ pp->side) {
+ return 0;
+ }
+ if (pp->side == WHITE) {
+ if (game_globals.garray[g].wTimeWhenReceivedMove == 0) {
+ game_globals.garray[g].wTimeWhenReceivedMove = t;
+ }
+ } else {
+ if (game_globals.garray[g].bTimeWhenReceivedMove == 0) {
+ game_globals.garray[g].bTimeWhenReceivedMove = t;
+ }
+ }
+ if (game_globals.garray[g].flag_pending != FLAG_NONE) {
+ ExecuteFlagCmd(p, net_globals.con[pp->socket]);
+ }
+ }
+ /* we have processed this special tag - don't process it further */
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ used to call flag on players with timeseal
+ */
+void ExecuteFlagCmd(int p, struct connection_t *con)
+{
+ struct player *pp = &player_globals.parray[p];
+ struct game *gg;
+
+ if (pp->game == -1) {
+ return;
+ }
+
+ gg = &game_globals.garray[pp->game];
+
+ if (pp->side == WHITE) {
+ gg->wRealTime -= con->time - gg->wTimeWhenReceivedMove;
+ gg->wTimeWhenReceivedMove = con->time;
+ if (gg->wRealTime < 0) {
+ pcommand(pp->opponent, "flag");
+ }
+ } else if (pp->side == BLACK) {
+ gg->bRealTime -= con->time - gg->wTimeWhenReceivedMove;
+ gg->bTimeWhenReceivedMove = con->time;
+ if (gg->bRealTime < 0) {
+ pcommand(pp->opponent, "flag");
+ }
+ }
+
+ game_update_time(pp->game);
+ gg->flag_pending = FLAG_NONE;
+}
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+
+#include "includes.h"
+
+static int safestring(char *str);
+
+char *eatword(char *str)
+{
+ while (*str && !isspace(*str))
+ str++;
+ return str;
+}
+
+char *eatwhite(char *str)
+{
+ while (*str && isspace(*str))
+ str++;
+ return str;
+}
+
+char *eattailwhite(char *str)
+{
+ int len;
+ if (str == NULL)
+ return NULL;
+
+ len = strlen(str);
+ while (len > 0 && isspace(str[len - 1]))
+ len--;
+ str[len] = '\0';
+ return (str);
+}
+
+char *nextword(char *str)
+{
+ return eatwhite(eatword(str));
+}
+
+int mail_string_to_address(char *addr, char *subj, char *str)
+{
+ int fd;
+ char template[] = SPOOL_DIR;
+
+ fd = mkstemp(template);
+ if (fd == -1) {
+ d_printf("Failed to create spool file\n");
+ return -1;
+ }
+
+ dprintf(fd, "To: %s\nSubject: %s\n\n%s\n", addr, subj, str);
+ close(fd);
+
+ return 0;
+}
+
+int mail_string_to_user(int p, char *subj, char *str)
+{
+ struct player *pp = &player_globals.parray[p];
+ if (pp->emailAddress &&
+ pp->emailAddress[0] &&
+ safestring(pp->emailAddress)) {
+ return mail_string_to_address(pp->emailAddress, subj, str);
+ }
+ return -1;
+}
+
+
+/* Process a command for a user */
+int pcommand(int p, char *comstr,...)
+{
+ struct player *pp = &player_globals.parray[p];
+ char *tmp;
+ int retval;
+ int current_socket = pp->socket;
+ va_list ap;
+
+ va_start(ap, comstr);
+ vasprintf(&tmp, comstr, ap);
+ va_end(ap);
+ retval = process_input(current_socket, tmp);
+ free(tmp);
+ if (retval == COM_LOGOUT) {
+ process_disconnection(current_socket);
+ net_close_connection(current_socket);
+ }
+ return retval;
+}
+
+static int vpprintf(int p, int do_formatting, char *format,va_list ap)
+{
+ struct player *pp = &player_globals.parray[p];
+ char *tmp = NULL;
+ int retval;
+
+ retval = vasprintf(&tmp, format, ap);
+ if (retval != 0) {
+ net_send_string(pp->socket,
+ tmp,
+ do_formatting,
+ pp->d_width + 1);
+ }
+ if (tmp) {
+ free(tmp);
+ }
+
+ return retval;
+}
+
+int pprintf(int p, char *format,...)
+{
+ int retval;
+ va_list ap;
+ va_start(ap, format);
+ retval = vpprintf(p, 1, format, ap);
+ va_end(ap);
+ return retval;
+}
+
+static void pprintf_dohightlight(int p)
+{
+ struct player *pp = &player_globals.parray[p];
+ if (pp->highlight & 0x01)
+ pprintf(p, "\033[7m");
+ if (pp->highlight & 0x02)
+ pprintf(p, "\033[1m");
+ if (pp->highlight & 0x04)
+ pprintf(p, "\033[4m");
+ if (pp->highlight & 0x08)
+ pprintf(p, "\033[2m");
+}
+
+int pprintf_highlight(int p, char *format,...)
+{
+ struct player *pp = &player_globals.parray[p];
+ int retval;
+ va_list ap;
+
+ pprintf_dohightlight(p);
+ va_start(ap, format);
+ retval = vpprintf(p, 1, format, ap);
+ va_end(ap);
+ if (pp->highlight)
+ pprintf(p, "\033[0m");
+ return retval;
+}
+
+static void sprintf_dohightlight(int p, char *s)
+{
+ struct player *pp = &player_globals.parray[p];
+ if (pp->highlight & 0x01)
+ strcat(s, "\033[7m");
+ if (pp->highlight & 0x02)
+ strcat(s, "\033[1m");
+ if (pp->highlight & 0x04)
+ strcat(s, "\033[4m");
+ if (pp->highlight & 0x08)
+ strcat(s, "\033[2m");
+}
+
+/*
+ like pprintf() but with paging for long messages
+*/
+int pprintf_more(int p, char *format,...)
+{
+ struct player *pp = &player_globals.parray[p];
+ char *s = NULL;
+ va_list ap;
+ va_start(ap, format);
+ vasprintf(&s, format, ap);
+ va_end(ap);
+
+ FREE(pp->more_text);
+ pp->more_text = s;
+
+ return pmore_text(p);
+}
+
+int psprintf_highlight(int p, char *s, char *format,...)
+{
+ struct player *pp = &player_globals.parray[p];
+ int retval;
+ va_list ap;
+
+ va_start(ap, format);
+ if (pp->highlight) {
+ sprintf_dohightlight(p, s);
+ retval = vsprintf(s + strlen(s), format, ap);
+ strcat(s, "\033[0m");
+ } else {
+ retval = vsprintf(s, format, ap);
+ }
+ va_end(ap);
+ return retval;
+}
+
+int pprintf_prompt(int p, char *format,...)
+{
+ int retval;
+ va_list ap;
+ va_start(ap, format);
+ retval = vpprintf(p, 1, format, ap);
+ va_end(ap);
+ send_prompt(p);
+ return retval;
+}
+
+/* send a prompt to p */
+void send_prompt(int p)
+{
+ struct player *pp = &player_globals.parray[p];
+ const char *prompt = pp->prompt;
+ pprintf(p, "%s%s",
+ prompt,
+ isspace(prompt[strlen(prompt)-1])?"":" ");
+}
+
+int pprintf_noformat(int p, char *format,...)
+{
+ int retval;
+ va_list ap;
+ va_start(ap, format);
+ retval = vpprintf(p, 0, format, ap);
+ va_end(ap);
+ return retval;
+}
+
+void Bell (int p)
+{
+ if (CheckPFlag(p, PFLAG_BELL))
+ pprintf (p, "\a");
+ return;
+}
+
+int psend_raw_file(int p, char *dir, char *file)
+{
+ struct player *pp = &player_globals.parray[p];
+ FILE *fp;
+ char tmp[MAX_LINE_SIZE];
+ int num;
+
+ fp = fopen_p("%s/%s", "r", dir, file);
+
+ if (!fp)
+ return -1;
+ while ((num = fread(tmp, sizeof(char), MAX_LINE_SIZE - 1, fp)) > 0) {
+ tmp[num] = '\0';
+ net_send_string(pp->socket, tmp, 1, pp->d_width + 1);
+ }
+ fclose(fp);
+ return 0;
+}
+
+/*
+ send a file a page at a time
+*/
+int psend_file(int p, const char *dir, const char *file)
+{
+ struct player *pp = &player_globals.parray[p];
+ char *fname;
+
+ if (strstr(file, "..")) {
+ pprintf(p,"Trying to be tricky, are we?\n");
+ return 0;
+ }
+
+ if (dir) {
+ asprintf(&fname,"%s/%s",dir,file);
+ } else {
+ fname = strdup(file);
+ }
+
+ FREE(pp->more_text);
+ pp->more_text = file_load(fname, NULL);
+ if (!pp->more_text) {
+ return -1;
+ }
+
+ free(fname);
+
+ return pmore_text(p);
+}
+
+/*
+ * Marsalis added on 8/27/95 so that [next] does not
+ * appear in the logout process for those that have
+ * a short screen height. (Fixed due to complaint
+ * in Bug's messages).
+ */
+int psend_logoutfile(int p, char *dir, char *file)
+{
+ return psend_file(p, dir, file);
+}
+
+/*
+ continue with text from a previous command
+*/
+int pmore_text(int p)
+{
+ struct player *pp = &player_globals.parray[p];
+ int lcount = pp->d_height - 1;
+
+ if (!pp->more_text) {
+ pprintf(p, "There is no more.\n");
+ return -1;
+ }
+
+ while (pp->more_text && lcount--) {
+ char *s = strndup(pp->more_text, strcspn(pp->more_text, "\n")+1);
+ int len = strlen(s);
+ net_send_string(pp->socket, s, 1, pp->d_width + 1);
+ s = strdup(pp->more_text+len);
+ FREE(pp->more_text);
+ if (s[0]) {
+ pp->more_text = s;
+ } else {
+ free(s);
+ }
+ }
+
+ if (pp->more_text) {
+ pprintf(p, "Type [next] to see next page.\n");
+ }
+
+ return 0;
+}
+
+char *stolower(char *str)
+{
+ int i;
+
+ if (!str)
+ return NULL;
+ for (i = 0; str[i]; i++) {
+ if (isupper(str[i])) {
+ str[i] = tolower(str[i]);
+ }
+ }
+ return str;
+}
+
+static int safechar(int c)
+{
+ return (isprint(c) && !strchr(">!&*?/<|`$;", c));
+}
+
+static int safestring(char *str)
+{
+ int i;
+
+ if (!str)
+ return 1;
+ for (i = 0; str[i]; i++) {
+ if (!safechar(str[i]))
+ return 0;
+ }
+ return 1;
+}
+
+int alphastring(char *str)
+{
+ int i;
+
+ if (!str)
+ return 1;
+ for (i = 0; str[i]; i++) {
+ if (!isalpha(str[i])) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+int printablestring(const char *str)
+{
+ int i;
+
+ if (!str)
+ return 1;
+ for (i = 0; str[i]; i++) {
+ if ((!isprint(str[i])) && (str[i] != '\t') && (str[i] != '\n'))
+ return 0;
+ }
+ return 1;
+}
+
+char *hms_desc(int t)
+{
+static char tstr[80];
+int days, hours, mins, secs;
+
+ days = (t / (60*60*24));
+ hours = ((t % (60*60*24)) / (60*60));
+ mins = (((t % (60*60*24)) % (60*60)) / 60);
+ secs = (((t % (60*60*24)) % (60*60)) % 60);
+ if ((days==0) && (hours==0) && (mins==0)) {
+ sprintf(tstr, "%d sec%s",
+ secs, (secs==1) ? "" : "s");
+ } else if ((days==0) && (hours==0)) {
+/* sprintf(tstr, "%d min%s, %d sec%s",
+ mins, (mins==1) ? "" : "s",
+ secs, (secs==1) ? "" : "s"); */
+ sprintf(tstr, "%d min%s",
+ mins, (mins==1) ? "" : "s");
+ } else if (days==0) {
+ sprintf(tstr, "%d hr%s, %d min%s, %d "
+ "sec%s",
+ hours, (hours==1) ? "" : "s",
+ mins, (mins==1) ? "" : "s",
+ secs, (secs==1) ? "" : "s");
+ } else {
+ sprintf(tstr, "%d day%s, %d hour%s, %d minute%s "
+ "and %d second%s",
+ days, (days==1) ? "" : "s",
+ hours, (hours==1) ? "" : "s",
+ mins, (mins==1) ? "" : "s",
+ secs, (secs==1) ? "" : "s");
+ }
+ return tstr;
+}
+
+char *hms(int t, int showhour, int showseconds, int spaces)
+{
+ static char tstr[20];
+ char tmp[10];
+ int h, m, s;
+
+ h = t / 3600;
+ t = t % 3600;
+ m = t / 60;
+ s = t % 60;
+ if (h || showhour) {
+ if (spaces)
+ sprintf(tstr, "%d : %02d", h, m);
+ else
+ sprintf(tstr, "%d:%02d", h, m);
+ } else {
+ sprintf(tstr, "%d", m);
+ }
+ if (showseconds) {
+ if (spaces)
+ sprintf(tmp, " : %02d", s);
+ else
+ sprintf(tmp, ":%02d", s);
+ strcat(tstr, tmp);
+ }
+ return tstr;
+}
+
+/* This is used only for relative timeing since it reports seconds since
+ * about 5:00pm on Feb 16, 1994
+ */
+unsigned tenth_secs(void)
+{
+ struct timeval tp;
+ struct timezone tzp;
+
+ gettimeofday(&tp, &tzp);
+/* .1 seconds since 1970 almost fills a 32 bit int! So lets subtract off
+ * the time right now */
+ return ((tp.tv_sec - 331939277) * 10L) + (tp.tv_usec / 100000);
+}
+
+/* This is to translate tenths-secs time back into 1/1/70 time in full
+ * seconds, because vek didn't read utils.c when he programmed new ratings.
+ 1 sec since 1970 fits into a 32 bit int OK.
+*/
+int untenths(unsigned tenths)
+{
+ return (tenths / 10 + 331939277 + 0xffffffff / 10 + 1);
+}
+
+char *tenth_str(unsigned t, int spaces)
+{
+ return hms((t + 5) / 10, 0, 1, spaces); /* Round it */
+}
+
+#define MAX_TRUNC_SIZE 100
+
+/* Warning, if lines in the file are greater than 1024 bytes in length, this
+ won't work! */
+/* nasty bug fixed by mann, 3-12-95 */
+int truncate_file(char *file, int lines)
+{
+ FILE *fp;
+ int bptr = 0, trunc = 0, i;
+ char tBuf[MAX_TRUNC_SIZE][MAX_LINE_SIZE];
+
+ if (lines > MAX_TRUNC_SIZE)
+ lines = MAX_TRUNC_SIZE;
+ fp = fopen_s(file, "r");
+ if (!fp)
+ return 1;
+ while (!feof(fp)) {
+ fgets(tBuf[bptr], MAX_LINE_SIZE, fp);
+ if (feof(fp))
+ break;
+ if (tBuf[bptr][strlen(tBuf[bptr]) - 1] != '\n') { /* Line too long */
+ fclose(fp);
+ return -1;
+ }
+ bptr++;
+ if (bptr == lines) {
+ trunc = 1;
+ bptr = 0;
+ }
+ }
+ fclose(fp);
+ if (trunc) {
+ fp = fopen_s(file, "w");
+ for (i = 0; i < lines; i++) {
+ fputs(tBuf[bptr], fp);
+ bptr++;
+ if (bptr == lines) {
+ bptr = 0;
+ }
+ }
+ fclose(fp);
+ }
+ return 0;
+}
+
+/* Warning, if lines in the file are greater than 1024 bytes in length, this
+ won't work! */
+int lines_file(char *file)
+{
+ FILE *fp;
+ int lcount = 0;
+ char tmp[MAX_LINE_SIZE];
+
+ fp = fopen_s(file, "r");
+ if (!fp)
+ return 0;
+ while (!feof(fp)) {
+ if (fgets(tmp, MAX_LINE_SIZE, fp))
+ lcount++;
+ }
+ fclose(fp);
+ return lcount;
+}
+
+int file_has_pname(char *fname, char *plogin)
+{
+ if (!strcmp(file_wplayer(fname), plogin))
+ return 1;
+ if (!strcmp(file_bplayer(fname), plogin))
+ return 1;
+ return 0;
+}
+
+char *file_wplayer(char *fname)
+{
+ static char tmp[MAX_FILENAME_SIZE];
+ char *ptr;
+ strcpy(tmp, fname);
+ ptr = rindex(tmp, '-');
+ if (!ptr)
+ return "";
+ *ptr = '\0';
+ return tmp;
+}
+
+char *file_bplayer(char *fname)
+{
+ char *ptr;
+
+ ptr = rindex(fname, '-');
+ if (!ptr)
+ return "";
+ return ptr + 1;
+}
+
+/*
+ make a human readable IP
+*/
+char *dotQuad(struct in_addr a)
+{
+ return inet_ntoa(a);
+}
+
+int file_exists(char *fname)
+{
+ FILE *fp;
+
+ fp = fopen_s(fname, "r");
+ if (!fp)
+ return 0;
+ fclose(fp);
+ return 1;
+}
+
+char *ratstr(int rat)
+{
+ static int on = 0;
+ static char tmp[20][10];
+
+ if (on == 20)
+ on = 0;
+ if (rat) {
+ sprintf(tmp[on], "%4d", rat);
+ } else {
+ sprintf(tmp[on], "----");
+
+ }
+ on++;
+ return tmp[on - 1];
+}
+
+char *ratstrii(int rat, int p)
+{
+ static int on = 0;
+ static char tmp[20][10];
+
+ if (on == 20)
+ on = 0;
+ if (rat) {
+ sprintf(tmp[on], "%4d", rat);
+ } else if (CheckPFlag(p, PFLAG_REG)) {
+ sprintf(tmp[on], "----");
+ } else {
+ sprintf(tmp[on], "++++");
+ }
+ on++;
+ return tmp[on - 1];
+}
+
+struct t_tree {
+ struct t_tree *left, *right;
+ char name; /* Not just 1 char - space for whole name */
+}; /* is allocated. Maybe a little cheesy? */
+
+struct t_dirs {
+ struct t_dirs *left, *right;
+ time_t mtime; /* dir's modification time */
+ struct t_tree *files;
+ char name; /* ditto */
+};
+
+static char **t_buffer = NULL; /* pointer to next space in return buffer */
+static int t_buffersize = 0; /* size of return buffer */
+
+/* fill t_buffer with anything matching "want*" in file tree t_tree */
+static void t_sft(const char *want, struct t_tree *t)
+{
+ if (t) {
+ int cmp = strncmp(want, &t->name, strlen(want));
+ if (cmp <= 0) /* if want <= this one, look left */
+ t_sft(want, t->left);
+ if (t_buffersize && (cmp == 0)) { /* if a match, add it to buffer */
+ t_buffersize--;
+ *t_buffer++ = &(t->name);
+ }
+ if (cmp >= 0) /* if want >= this one, look right */
+ t_sft(want, t->right);
+ }
+}
+
+/* delete file tree t_tree */
+static void t_cft(struct t_tree **t)
+{
+ if (*t) {
+ t_cft(&(*t)->left);
+ t_cft(&(*t)->right);
+ free(*t);
+ *t = NULL;
+ }
+}
+
+/* make file tree for dir d */
+static void t_mft(struct t_dirs *d)
+{
+ DIR *dirp;
+ struct dirent *dp;
+ struct t_tree **t;
+
+ if ((dirp = opendir(&(d->name))) == NULL) {
+ d_printf( "CHESSD:mft() couldn't opendir.\n");
+ } else {
+ while ((dp = readdir(dirp))) {
+ t = &d->files;
+ if (dp->d_name[0] != '.') { /* skip anything starting with . */
+ while (*t) {
+ if (strcmp(dp->d_name, &(*t)->name) < 0) {
+ t = &(*t)->left;
+ } else {
+ t = &(*t)->right;
+ }
+ }
+ *t = malloc(sizeof(struct t_tree) + strlen(dp->d_name));
+ (*t)->right = (*t)->left = NULL;
+ strcpy(&(*t)->name, dp->d_name);
+ }
+ }
+ closedir(dirp);
+ }
+}
+
+int search_directory(const char *dir, const char *filter, char **buffer, int buffersize)
+{
+/* dir = directory to search
+ filter = what to search for
+ buffer = where to store pointers to matches
+ buffersize = how many pointers will fit inside buffer */
+
+ static struct t_dirs *ramdirs = NULL;
+ struct t_dirs **i;
+ int cmp;
+ static char nullify = '\0';
+ struct stat statbuf;
+
+ t_buffer = buffer;
+ t_buffersize = buffersize;
+
+ if (!stat(dir, &statbuf)) {
+ if (filter == NULL) /* NULL becomes pointer to null string */
+ filter = &nullify;
+ i = &ramdirs;
+ while (*i) { /* find dir in dir tree */
+ cmp = strcmp(dir, &(*i)->name);
+ if (cmp == 0)
+ break;
+ else if (cmp < 0)
+ i = &(*i)->left;
+ else
+ i = &(*i)->right;
+ }
+ if (!*i) { /* if dir isn't in dir tree, add him */
+ *i = malloc(sizeof(struct t_dirs) + strlen(dir));
+ (*i)->left = (*i)->right = NULL;
+ (*i)->files = NULL;
+ strcpy(&(*i)->name, dir);
+ }
+ if ((*i)->files) { /* delete any obsolete file tree */
+ if ((*i)->mtime != statbuf.st_mtime) {
+ t_cft(&(*i)->files);
+ }
+ }
+ if ((*i)->files == NULL) { /* if no file tree for him, make one */
+ (*i)->mtime = statbuf.st_mtime;
+ t_mft(*i);
+ }
+ t_sft(filter, (*i)->files); /* finally, search for matches */
+ }
+ return (buffersize - t_buffersize);
+}
+
+int display_directory(int p, char **buffer, int count)
+/* buffer contains 'count' string pointers */
+{
+ struct player *pp = &player_globals.parray[p];
+ int i;
+ multicol *m = multicol_start(count);
+
+ for (i = 0; (i < count); i++)
+ multicol_store(m, *buffer++);
+ multicol_pprint(m, p, pp->d_width, 1);
+ multicol_end(m);
+ return (i);
+}
+
+void CenterText (char *target, const char *text, int width, int pad)
+{
+ int left, len;
+ char *format;
+
+ len = strlen(text);
+ left = (width + 1 - len) / 2; /* leading blank space. */
+
+ if (pad)
+ asprintf (&format, "%%%ds%%-%ds", left, width-left); /* e.g. "%5s%-10s" */
+ else
+ asprintf (&format, "%%%ds%%s", left); /* e.g. "%5s%s" */
+ sprintf (target, format, "", text);
+
+ free(format);
+
+ return;
+}
+
+/* block a signal */
+void block_signal(int signum)
+{
+ sigset_t set;
+ sigemptyset(&set);
+ sigaddset(&set,signum);
+ sigprocmask(SIG_BLOCK,&set,NULL);
+}
+
+/* unblock a signal */
+void unblock_signal(int signum)
+{
+ sigset_t set;
+ sigemptyset(&set);
+ sigaddset(&set,signum);
+ sigprocmask(SIG_UNBLOCK,&set,NULL);
+}
+
+
+int file_copy(const char *src, const char *dest)
+{
+ int fd1, fd2, n;
+ char buf[1024];
+
+ fd1 = open(src, O_RDONLY);
+ if (fd1 == -1) return -1;
+
+ unlink(dest);
+ fd2 = open(dest, O_WRONLY|O_CREAT|O_EXCL, 0644);
+ if (fd2 == -1) {
+ close(fd1);
+ return -1;
+ }
+
+ while ((n = read(fd1, buf, sizeof(buf))) > 0) {
+ if (write(fd2, buf, n) != n) {
+ close(fd2);
+ close(fd1);
+ unlink(dest);
+ return -1;
+ }
+ }
+
+ close(fd1);
+ close(fd2);
+ return 0;
+}
+
+
+#ifndef HAVE_DPRINTF
+ int dprintf(int fd, const char *format, ...)
+{
+ va_list ap;
+ char *ptr = NULL;
+ int ret = 0;
+
+ va_start(ap, format);
+ vasprintf(&ptr, format, ap);
+ va_end(ap);
+
+ if (ptr) {
+ ret = write(fd, ptr, strlen(ptr));
+ free(ptr);
+ }
+
+ return ret;
+}
+#endif
+
+
+#ifndef HAVE_STRNLEN_X
+/*
+ some platforms don't have strnlen
+*/
+size_t strnlen(const char *s, size_t n)
+{
+ int i;
+ for (i=0; s[i] && i<n; i++) /* noop */ ;
+ return i;
+}
+#endif
+
+/* day as a string */
+const char *strday(time_t *t)
+{
+ struct tm *stm = localtime(t);
+ static char tstr[100];
+
+ strftime(tstr, sizeof(tstr), "%a %b %e", stm);
+ return tstr;
+}
+
+
+static const char *strtime(struct tm * stm, short gmt)
+{
+ static char tstr[100];
+
+ if (gmt)
+ strftime(tstr, sizeof(tstr), "%a %b %e, %H:%M GMT %Y", stm);
+ else
+ strftime(tstr, sizeof(tstr), "%a %b %e, %H:%M %Z %Y", stm);
+ return (tstr);
+}
+
+const char *strltime(time_t *clock)
+{
+ struct tm *stm = localtime(clock);
+ return strtime(stm, 0);
+}
+
+const char *strgtime(time_t *clock)
+{
+ struct tm *stm = gmtime(clock);
+ return strtime(stm, 1);
+}
+
+/* useful debug utility */
+void d_printf(const char *fmt, ...)
+{
+ va_list ap;
+ time_t t = time(NULL);
+ fprintf(stderr,"%s ", strltime(&t));
+ va_start(ap, fmt);
+ vfprintf(stderr,fmt,ap);
+ va_end(ap);
+}
+
+
+/* append something to admin.log */
+static void admin_printf(const char *fmt, ...)
+{
+ int fd;
+ va_list ap;
+ time_t t = time(NULL);
+
+ fd = open("admin.log", O_APPEND | O_CREAT | O_RDWR, 0600);
+ if (fd == -1) {
+ d_printf("Failed to open admin.log - %s\n", strerror(errno));
+ return;
+ }
+
+ dprintf(fd,"%s ", strltime(&t));
+ va_start(ap, fmt);
+ vdprintf(fd,fmt,ap);
+ va_end(ap);
+
+ close(fd);
+}
+
+/*
+ log an admin command
+*/
+void admin_log(struct player *pp, const char *command, param_list params)
+{
+ char *s;
+ char *s2;
+ int i;
+
+ asprintf(&s, "%s: %s", pp->login, command);
+
+ if (!s) return;
+ for (i=0; params[i].type != TYPE_NULL; i++) {
+ switch (params[i].type) {
+ case TYPE_INT:
+ asprintf(&s2, "%s %d", s, params[i].val.integer);
+ break;
+ case TYPE_STRING:
+ asprintf(&s2, "%s %s", s, params[i].val.string);
+ break;
+ case TYPE_WORD:
+ asprintf(&s2, "%s %s", s, params[i].val.word);
+ break;
+ }
+
+ free(s);
+ s = s2;
+ if (!s) return;
+ }
+
+ admin_printf("%s\n", s);
+ free(s);
+}
+
+/*
+ save a lump of data into a file.
+ return 0 on success
+*/
+int file_save(const char *fname, void *data, size_t length)
+{
+ int fd;
+ unlink(fname);
+ fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
+ if (fd == -1) {
+ return -1;
+ }
+ if (write(fd, data, length) != length) {
+ close(fd);
+ unlink(fname);
+ return -1;
+ }
+ close(fd);
+ return 0;
+}
+
+/*
+ load a file into memory from a fd.
+*/
+char *fd_load(int fd, size_t *size)
+{
+ struct stat sbuf;
+ char *p;
+
+ if (fstat(fd, &sbuf) != 0) return NULL;
+
+ p = (char *)malloc(sbuf.st_size+1);
+ if (!p) return NULL;
+
+ if (pread(fd, p, sbuf.st_size, 0) != sbuf.st_size) {
+ free(p);
+ return NULL;
+ }
+ p[sbuf.st_size] = 0;
+
+ if (size) *size = sbuf.st_size;
+
+ return p;
+}
+
+/*
+ load a file into memory
+*/
+char *file_load(const char *fname, size_t *size)
+{
+ int fd;
+ char *p;
+
+ if (!fname || !*fname) return NULL;
+
+ fd = open(fname,O_RDONLY);
+ if (fd == -1) return NULL;
+
+ p = fd_load(fd, size);
+ close(fd);
+
+ return p;
+}
+
+/*
+ this is like fgets() but operates on a file descriptor
+*/
+char *fd_gets(char *line, size_t maxsize, int fd)
+{
+ char c;
+ int n = 0;
+ while (n < (maxsize-1) && read(fd, &c, 1) == 1) {
+ line[n++] = c;
+ if (c == '\n') break;
+ }
+ line[n] = 0;
+ return n?line:NULL;
+}
+
+
+/*
+ like fopen() but uses printf style arguments for the file name
+*/
+FILE *fopen_p(const char *fmt, const char *mode, ...)
+{
+ char *s = NULL;
+ FILE *f;
+ va_list ap;
+ va_start(ap, mode);
+ vasprintf(&s, fmt, ap);
+ va_end(ap);
+ if (!s) return NULL;
+ if (strstr(s, "..")) {
+ d_printf("Invalid filename [%s]\n", s);
+ free(s);
+ return NULL;
+ }
+ f = fopen(s, mode);
+ free(s);
+ return f;
+}
+
+/*
+ like fopen() but doesn't allow opening of filenames containing '..'
+*/
+FILE *fopen_s(const char *fname, const char *mode)
+{
+ return fopen_p("%s", mode, fname);
+}
+
+
+#ifndef HAVE_STRLCPY
+/**
+ * Like strncpy but does not 0 fill the buffer and always null
+ * terminates.
+ *
+ * @param bufsize is the size of the destination buffer.
+ *
+ * @return index of the terminating byte.
+ **/
+ size_t strlcpy(char *d, const char *s, size_t bufsize)
+{
+ size_t len = strlen(s);
+ size_t ret = len;
+ if (bufsize <= 0) return 0;
+ if (len >= bufsize) len = bufsize-1;
+ memcpy(d, s, len);
+ d[len] = 0;
+ return ret;
+}
+#endif
+
+
+/*
+ set an integer value in a TDB
+*/
+int tdb_set_int(TDB_CONTEXT *tdb, const char *name, int value)
+{
+ TDB_DATA key, data;
+ int ret;
+
+ key.dptr = strdup(name);
+ key.dsize = strlen(name)+1;
+
+ data.dptr = (char *)&value;
+ data.dsize = sizeof(value);
+
+ ret = tdb_store(tdb, key, data, TDB_REPLACE);
+ free(key.dptr);
+ return ret;
+}
+
+/*
+ get an integer value from a TDB. Return def_value if its not there
+*/
+int tdb_get_int(TDB_CONTEXT *tdb, const char *name, int def_value)
+{
+ TDB_DATA key, data;
+ int ret;
+
+ key.dptr = strdup(name);
+ key.dsize = strlen(name)+1;
+
+ data = tdb_fetch(tdb, key);
+ free(key.dptr);
+
+ if (!data.dptr) {
+ return def_value;
+ }
+
+ ret = *(int *)data.dptr;
+ free(data.dptr);
+
+ return ret;
+}
+
+
+/*
+ set a string value in a TDB
+*/
+int tdb_set_string(TDB_CONTEXT *tdb, const char *name, const char *value)
+{
+ TDB_DATA key, data;
+ int ret;
+
+ key.dptr = strdup(name);
+ key.dsize = strlen(name)+1;
+
+ data.dptr = strdup(value);
+ data.dsize = strlen(value)+1;
+
+ ret = tdb_store(tdb, key, data, TDB_REPLACE);
+ free(key.dptr);
+ free(data.dptr);
+ return ret;
+}
+
+/*
+ get a string value from a TDB. Caller frees.
+*/
+const char *tdb_get_string(TDB_CONTEXT *tdb, const char *name)
+{
+ TDB_DATA key, data;
+
+ key.dptr = strdup(name);
+ key.dsize = strlen(name)+1;
+
+ data = tdb_fetch(tdb, key);
+ free(key.dptr);
+ if (!data.dptr) {
+ return NULL;
+ }
+ return data.dptr;
+}
+
+/*
+ delete a value from a TDB by string
+*/
+int tdb_delete_string(TDB_CONTEXT *tdb, const char *name)
+{
+ TDB_DATA key;
+ int ret;
+
+ key.dptr = strdup(name);
+ key.dsize = strlen(name)+1;
+
+ ret = tdb_delete(tdb, key);
+ free(key.dptr);
+ return ret;
+}
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+#ifndef _UTILS_H
+#define _UTILS_H
+
+#define MAX_WORD_SIZE 1024
+
+/* Maximum length of an output line */
+#define MAX_LINE_SIZE 1024
+
+/* Maximum size of a filename */
+#ifdef FILENAME_MAX
+# define MAX_FILENAME_SIZE FILENAME_MAX
+#else
+# define MAX_FILENAME_SIZE 1024
+#endif
+
+#define FlagON(VAR, FLAG) (VAR |= (FLAG))
+#define FlagOFF(VAR, FLAG) (VAR &= ~(FLAG))
+#define CheckFlag(VAR, FLAG) ((VAR) & (FLAG))
+#define BoolCheckFlag(VAR, FLAG) (CheckFlag(VAR, FLAG) ? 1 : 0)
+#define ToggleFlag(VAR, FLAG) (VAR ^= (FLAG))
+#define SetFlag(VAR, FLAG, VALUE) ((VALUE) ? FlagON(VAR, FLAG) : FlagOFF(VAR, FLAG))
+
+#define PFlagON(WHO, FLAG) FlagON(player_globals.parray[WHO].Flags, FLAG)
+#define PFlagOFF(WHO, FLAG) FlagOFF(player_globals.parray[WHO].Flags, FLAG)
+#define CheckPFlag(WHO, FLAG) CheckFlag(player_globals.parray[WHO].Flags, FLAG)
+#define BoolCheckPFlag(WHO, FLAG) BoolCheckFlag(player_globals.parray[WHO].Flags, FLAG)
+#define TogglePFlag(WHO, FLAG) ToggleFlag(player_globals.parray[WHO].Flags, FLAG)
+#define SetPFlag(WHO, FLAG, VALUE) ((VALUE) ? PFlagON(WHO, FLAG) : PFlagOFF(WHO, FLAG))
+
+
+#endif /* _UTILS_H */
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+#include "includes.h"
+
+static int set_boolean_flag(int p, char *val, unsigned long flag)
+{
+ int v = -1;
+
+ if (val == NULL) {
+ TogglePFlag(p, flag);
+ v = BoolCheckPFlag(p, flag);
+ return (v);
+ }
+ if (sscanf(val, "%d", &v) != 1) {
+ stolower(val);
+ if (!strcmp(val, "off") || !strcmp(val, "false"))
+ v = 0;
+ else if (!strcmp(val, "on") || !strcmp(val, "true"))
+ v = 1;
+ }
+ SetPFlag(p, flag, v);
+ return v;
+}
+
+static int set_availinfo(int p, char *var, char *val)
+{
+ int v = set_boolean_flag(p, val, PFLAG_AVAIL);
+
+ if (v < 0)
+ return VAR_BADVAL;
+ pprintf(p, "availinfo set to %d.\n", BoolCheckPFlag(p, PFLAG_AVAIL));
+
+ if (v > 0)
+ pprintf(p, "You will receive info on who is available to play.\n");
+ else
+ pprintf(p, "You are no longer receiving info on who is available to play.\n");
+ return VAR_OK;
+}
+
+static int set_availmax(int p, char *var, char *val)
+{
+ struct player *pp = &player_globals.parray[p];
+ int v = -1;
+
+ if (!val)
+ return VAR_BADVAL;
+ if (sscanf(val, "%d", &v) != 1)
+ return VAR_BADVAL;
+ if ((v < 0) || (v > 9999))
+ return VAR_BADVAL;
+
+ if (v < pp->availmin) {
+ pprintf(p, "You can't set availmax to less than availmin.\n");
+ return VAR_OK;
+ }
+
+ if ((pp->availmax = v)) {
+ pprintf(p, "You will be notified of availability with blitz ratings %d - %d.\n",pp->availmin,v);
+ } else
+ pprintf(p, "You will be notified of all available players.\n");
+ return VAR_OK;
+}
+
+static int set_availmin(int p, char *var, char *val)
+{
+ struct player *pp = &player_globals.parray[p];
+ int v = -1;
+
+ if (!val)
+ return VAR_BADVAL;
+ if (sscanf(val, "%d", &v) != 1)
+ return VAR_BADVAL;
+ if ((v < 0) || (v > 9999))
+ return VAR_BADVAL;
+
+ if (v > pp->availmax) {
+ pprintf(p, "You can't set availmin to more than availmax.\n");
+ return VAR_OK;
+ }
+
+ pp->availmin = v;
+ pprintf(p, "You will be notified of availability with blitz ratings %d - %d.\n",v,pp->availmax);
+ return VAR_OK;
+}
+
+static int set_open(int p, char *var, char *val)
+{
+ struct player *pp = &player_globals.parray[p];
+ int v = set_boolean_flag(p, val, PFLAG_OPEN);
+
+ if (v < 0)
+ return VAR_BADVAL;
+ if (v > 0) {
+ pprintf(p, "You are now open to receive match requests.\n");
+ announce_avail (p);
+ } else {
+ decline_withdraw_offers(p, -1, PEND_MATCH,DO_DECLINE | DO_WITHDRAW);
+ pprintf(p, "You are no longer receiving match requests.\n");
+ if (pp->game < 0)
+ announce_notavail (p);
+ }
+ return VAR_OK;
+}
+
+static int set_tourney(int p, char *var, char *val)
+{
+ struct player *pp = &player_globals.parray[p];
+ int v = set_boolean_flag(p, val, PFLAG_TOURNEY);
+
+ if (v < 0)
+ return VAR_BADVAL;
+ if (v > 0) {
+ decline_withdraw_offers(p, -1, PEND_MATCH,DO_DECLINE | DO_WITHDRAW);
+ pprintf(p, "Your tournament variable is now set.\n");
+ announce_notavail (p);
+ } else {
+ pprintf(p, "Your tournament variable is no longer set.\n");
+ if (pp->game < 0)
+ announce_avail (p);
+ }
+ return VAR_OK;
+}
+
+static int set_sopen(int p, char *var, char *val)
+{
+ int v = set_boolean_flag(p, val, PFLAG_SIMOPEN);
+
+ if (v < 0)
+ return VAR_BADVAL;
+ pprintf(p, "sopen set to %d.\n", v);
+
+ if (v > 0)
+ pprintf(p, "You are now open to receive simul requests.\n");
+ else
+ pprintf(p, "You are no longer receiving simul requests.\n");
+ decline_withdraw_offers(p, -1, PEND_SIMUL,DO_DECLINE);
+ return VAR_OK;
+}
+
+static int set_ropen(int p, char *var, char *val)
+{
+ if (set_boolean_flag(p, val, PFLAG_ROPEN) < 0)
+ return VAR_BADVAL;
+ pprintf(p, "ropen set to %d.\n", BoolCheckPFlag(p, PFLAG_ROPEN));
+ return VAR_OK;
+}
+
+static int set_rated(int p, char *var, char *val)
+{
+ if (!CheckPFlag(p, PFLAG_REG)) {
+ pprintf(p, "You cannot change your rated status.\n");
+ return VAR_OK;
+ }
+ if (set_boolean_flag(p, val, PFLAG_RATED) < 0)
+ return VAR_BADVAL;
+ pprintf(p, "rated set to %d.\n", BoolCheckPFlag(p, PFLAG_RATED));
+ return VAR_OK;
+}
+
+static int set_shout(int p, char *var, char *val)
+{
+ if (set_boolean_flag(p, val, PFLAG_SHOUT) < 0)
+ return VAR_BADVAL;
+ if (CheckPFlag(p, PFLAG_SHOUT))
+ pprintf(p, "You will now hear shouts.\n");
+ else
+ pprintf(p, "You will not hear shouts.\n");
+ return VAR_OK;
+}
+
+static int set_ads(int p, char *var, char *val)
+{
+ if (set_boolean_flag(p, val, PFLAG_ADS) < 0)
+ return VAR_BADVAL;
+ if (CheckPFlag(p, PFLAG_ADS))
+ pprintf(p, "You will now hear ads.\n");
+ else
+ pprintf(p, "You will not hear ads.\n");
+ return VAR_OK;
+}
+
+static int set_cshout(int p, char *var, char *val)
+{
+ if (set_boolean_flag(p, val, PFLAG_CSHOUT) < 0)
+ return VAR_BADVAL;
+ if (CheckPFlag(p, PFLAG_CSHOUT))
+ pprintf(p, "You will now hear cshouts.\n");
+ else
+ pprintf(p, "You will not hear cshouts.\n");
+ return VAR_OK;
+}
+
+static int set_kibitz(int p, char *var, char *val)
+{
+ if (set_boolean_flag(p, val, PFLAG_KIBITZ) < 0)
+ return VAR_BADVAL;
+ if (CheckPFlag(p, PFLAG_KIBITZ))
+ pprintf(p, "You will now hear kibitzes.\n");
+ else
+ pprintf(p, "You will not hear kibitzes.\n");
+ return VAR_OK;
+}
+static int set_kiblevel(int p, char *var, char *val)
+{
+ struct player *pp = &player_globals.parray[p];
+ int v = -1;
+
+ if (!val)
+ return VAR_BADVAL;
+ if (sscanf(val, "%d", &v) != 1)
+ return VAR_BADVAL;
+ if ((v < 0) || (v > 9999))
+ return VAR_BADVAL;
+ pp->kiblevel = v;
+ pprintf(p, "Kibitz level now set to: %d.\n", v);
+ return VAR_OK;
+}
+
+static int set_tell(int p, char *var, char *val)
+{
+ if (set_boolean_flag(p, val, PFLAG_TELL) < 0)
+ return VAR_BADVAL;
+ if (CheckPFlag(p, PFLAG_TELL))
+ pprintf(p, "You will now hear tells from unregistered users.\n");
+ else
+ pprintf(p, "You will not hear tells from unregistered users.\n");
+ return VAR_OK;
+}
+
+static int set_notifiedby(int p, char *var, char *val)
+{
+ if (set_boolean_flag(p, val, PFLAG_NOTIFYBY) < 0)
+ return VAR_BADVAL;
+ if (CheckPFlag(p, PFLAG_NOTIFYBY))
+ pprintf(p, "You will now hear if people notify you, but you don't notify them.\n");
+ else
+ pprintf(p, "You will not hear if people notify you, but you don't notify them.\n");
+ return VAR_OK;
+}
+
+static int set_pinform(int p, char *var, char *val)
+{
+ if (set_boolean_flag(p, val, PFLAG_PIN) < 0)
+ return VAR_BADVAL;
+ if (CheckPFlag(p, PFLAG_PIN))
+ pprintf(p, "You will now hear logins/logouts.\n");
+ else
+ pprintf(p, "You will not hear logins/logouts.\n");
+ return VAR_OK;
+}
+
+static int set_ginform(int p, char *var, char *val)
+{
+ if (set_boolean_flag(p, val, PFLAG_GIN) < 0)
+ return VAR_BADVAL;
+ if (CheckPFlag(p, PFLAG_GIN))
+ pprintf(p, "You will now hear game results.\n");
+ else
+ pprintf(p, "You will not hear game results.\n");
+ return VAR_OK;
+}
+
+static int set_private(int p, char *var, char *val)
+{
+ if (set_boolean_flag(p, val, PFLAG_PRIVATE) < 0)
+ return VAR_BADVAL;
+ if (CheckPFlag(p, PFLAG_PRIVATE))
+ pprintf(p, "Your games will be private.\n");
+ else
+ pprintf(p, "Your games may not be private.\n");
+ return VAR_OK;
+}
+
+static int set_jprivate(int p, char *var, char *val)
+{
+ if (!CheckPFlag(p, PFLAG_REG)) {
+ pprintf(p, "Unregistered players may not keep a journal.\n");
+ return VAR_OK;
+ }
+
+ if (set_boolean_flag(p, val, PFLAG_JPRIVATE) < 0)
+ return VAR_BADVAL;
+ if (CheckPFlag(p, PFLAG_JPRIVATE))
+ pprintf(p, "Your journal will be private.\n");
+ else
+ pprintf(p, "Your journal will not be private.\n");
+ return VAR_OK;
+}
+
+static int set_automail(int p, char *var, char *val)
+{
+ if (set_boolean_flag(p, val, PFLAG_AUTOMAIL) < 0)
+ return VAR_BADVAL;
+ if (CheckPFlag(p, PFLAG_AUTOMAIL))
+ pprintf(p, "Your games will be mailed to you.\n");
+ else
+ pprintf(p, "Your games will not be mailed to you.\n");
+ return VAR_OK;
+}
+
+static int set_mailmess(int p, char *var, char *val)
+{
+ if (!CheckPFlag(p, PFLAG_REG)) {
+ pprintf(p, "Unregistered players may not receive messages.\n");
+ return VAR_OK;
+ }
+ if (set_boolean_flag(p, val, PFLAG_MAILMESS) < 0)
+ return VAR_BADVAL;
+ if (CheckPFlag(p, PFLAG_MAILMESS))
+ pprintf(p, "Your messages will be mailed to you.\n");
+ else
+ pprintf(p, "Your messages will not be mailed to you.\n");
+ return VAR_OK;
+}
+
+static int set_pgn(int p, char *var, char *val)
+{
+ if (set_boolean_flag(p, val, PFLAG_PGN) < 0)
+ return VAR_BADVAL;
+ if (CheckPFlag(p, PFLAG_PGN))
+ pprintf(p, "Games will now be mailed to you in PGN.\n");
+ else
+ pprintf(p, "Games will now be mailed to you in FICS format.\n");
+ return VAR_OK;
+}
+
+static int set_bell(int p, char *var, char *val)
+{
+ if (set_boolean_flag(p, val, PFLAG_BELL) < 0)
+ return VAR_BADVAL;
+ if (CheckPFlag(p, PFLAG_BELL))
+ pprintf(p, "Bell on.\n");
+ else
+ pprintf(p, "Bell off.\n");
+ return VAR_OK;
+}
+
+static int set_highlight(int p, char *var, char *val)
+{
+ struct player *pp = &player_globals.parray[p];
+ int v = -1;
+
+ if (!val)
+ return VAR_BADVAL;
+ if (sscanf(val, "%d", &v) != 1)
+ return VAR_BADVAL;
+ if ((v < 0) || (v > 15))
+ return VAR_BADVAL;
+
+ if ((pp->highlight = v)) {
+ pprintf(p, "Highlight is now style ");
+ pprintf_highlight(p, "%d", v);
+ pprintf(p, ".\n");
+ } else
+ pprintf(p, "Highlight is off.\n");
+ return VAR_OK;
+}
+
+static int set_style(int p, char *var, char *val)
+{
+ struct player *pp = &player_globals.parray[p];
+ int v = -1;
+
+ if (!val)
+ return VAR_BADVAL;
+ if (sscanf(val, "%d", &v) != 1)
+ return VAR_BADVAL;
+ if ((v < 1) || (v > MAX_STYLES))
+ return VAR_BADVAL;
+ pp->style = v - 1;
+ pprintf(p, "Style %d set.\n", v);
+ return VAR_OK;
+}
+
+static int set_flip(int p, char *var, char *val)
+{
+ if (set_boolean_flag(p, val, PFLAG_FLIP) < 0)
+ return VAR_BADVAL;
+ if (CheckPFlag(p, PFLAG_FLIP))
+ pprintf(p, "Flip on.\n");
+ else
+ pprintf(p, "Flip off.\n");
+ return VAR_OK;
+}
+/* Was pointless as this is what notes are for
+static int set_uscf(int p, char *var, char *val)
+{
+ int v = -1;
+
+ if (!val)
+ return VAR_BADVAL;
+ if (sscanf(val, "%d", &v) != 1)
+ return VAR_BADVAL;
+ if ((v < 0) || (v > 3000))
+ return VAR_BADVAL;
+ pp->uscfRating = v;
+ pprintf(p, "USCF Rating set to %d.\n", v);
+ return VAR_OK;
+}
+*/
+static int set_time(int p, char *var, char *val)
+{
+ struct player *pp = &player_globals.parray[p];
+ int v = -1;
+
+ if (!val)
+ return VAR_BADVAL;
+ if (sscanf(val, "%d", &v) != 1)
+ return VAR_BADVAL;
+ if ((v < 0) || (v > 240))
+ return VAR_BADVAL;
+ pp->d_time = v;
+ pprintf(p, "Default time set to %d.\n", v);
+ return VAR_OK;
+}
+
+static int set_inc(int p, char *var, char *val)
+{
+ struct player *pp = &player_globals.parray[p];
+ int v = -1;
+
+ if (!val)
+ return VAR_BADVAL;
+ if (sscanf(val, "%d", &v) != 1)
+ return VAR_BADVAL;
+ if ((v < 0) || (v > 300))
+ return VAR_BADVAL;
+ pp->d_inc = v;
+ pprintf(p, "Default increment set to %d.\n", v);
+ return VAR_OK;
+}
+
+static int set_height(int p, char *var, char *val)
+{
+ struct player *pp = &player_globals.parray[p];
+ int v = -1;
+
+ if (!val)
+ return VAR_BADVAL;
+ if (sscanf(val, "%d", &v) != 1)
+ return VAR_BADVAL;
+ if ((v < 5) || (v > 240))
+ return VAR_BADVAL;
+ pp->d_height = v;
+ pprintf(p, "Height set to %d.\n", v);
+ return VAR_OK;
+}
+
+static int set_width(int p, char *var, char *val)
+{
+ struct player *pp = &player_globals.parray[p];
+ int v = -1;
+
+ if (!val)
+ return VAR_BADVAL;
+ if (sscanf(val, "%d", &v) != 1)
+ return VAR_BADVAL;
+ if ((v < 32) || (v > 10000))
+ return VAR_BADVAL;
+ pp->d_width = v;
+ pprintf(p, "Width set to %d.\n", v);
+ return VAR_OK;
+}
+
+const char *Language(int i)
+{
+ static const char *Lang[NUM_LANGS] = {"English", "Spanish", "French", "Danish"};
+ return Lang[i];
+}
+
+static int set_language (int p, char *var, char *val)
+{
+ struct player *pp = &player_globals.parray[p];
+ int i, len, gotIt = -1;
+
+ if (!val)
+ return VAR_BADVAL;
+ len = strlen(val);
+ for (i=0; i < NUM_LANGS; i++) {
+ if (strncasecmp(val, Language(i), len))
+ continue;
+ if (gotIt >= 0)
+ return VAR_BADVAL;
+ else gotIt = i;
+ }
+ if (gotIt < 0)
+ return VAR_BADVAL;
+ pp->language = gotIt;
+ pprintf(p, "Language set to %s.\n", Language(gotIt));
+ return VAR_OK;
+}
+
+static int set_promote(int p, char *var, char *val)
+{
+ struct player *pp = &player_globals.parray[p];
+ if (!val)
+ return VAR_BADVAL;
+ stolower(val);
+ switch (val[0]) {
+ case 'q':
+ pp->promote = QUEEN;
+ pprintf(p, "Promotion piece set to QUEEN.\n");
+ break;
+ case 'r':
+ pp->promote = ROOK;
+ pprintf(p, "Promotion piece set to ROOK.\n");
+ break;
+ case 'b':
+ pp->promote = BISHOP;
+ pprintf(p, "Promotion piece set to BISHOP.\n");
+ break;
+ case 'n':
+ case 'k':
+ pp->promote = KNIGHT;
+ pprintf(p, "Promotion piece set to KNIGHT.\n");
+ break;
+ default:
+ return VAR_BADVAL;
+ }
+ return VAR_OK;
+}
+
+
+static int set_interface(int p, char *var, char *val)
+{
+ struct player *pp = &player_globals.parray[p];
+ if (!val) {
+ FREE(pp->interface);
+ return VAR_OK;
+ }
+ if (!printablestring(val))
+ return VAR_BADVAL;
+ FREE(pp->interface);
+ asprintf(&pp->interface, "%s", val);
+ return VAR_OK;
+}
+
+static int set_prompt(int p, char *var, char *val)
+{
+ struct player *pp = &player_globals.parray[p];
+ char *prompt;
+ if (!val) {
+ free(pp->prompt);
+ pp->prompt = config_get("DEFAULT_PROMPT");
+ return VAR_OK;
+ }
+ if (!printablestring(val))
+ return VAR_BADVAL;
+ free(pp->prompt);
+ asprintf(&prompt, "%s", val);
+ pp->prompt = prompt;
+ return VAR_OK;
+}
+
+static int RePartner (int p, int new)
+{
+ struct player *pp = &player_globals.parray[p];
+ int pOld;
+
+ if (p < 0)
+ return -1;
+ pOld = pp->partner;
+ if (pOld >= 0) {
+ if (player_globals.parray[pOld].partner == p) {
+ if (new >= 0)
+ pprintf_prompt (pOld, "Your partner has just chosen a new partner.\n");
+ else {
+ pprintf (pOld, "Your partner has unset his/her partner variable.\n");
+ pprintf_prompt (pOld, "You are no longer %s's partner.\n",pp->name);
+ }
+ decline_withdraw_offers (pOld, -1, PEND_BUGHOUSE,DO_DECLINE | DO_WITHDRAW);
+ player_globals.parray[pOld].partner = -1;
+ }
+ }
+ decline_withdraw_offers(p, -1, PEND_BUGHOUSE,DO_DECLINE | DO_WITHDRAW);
+ decline_withdraw_offers(p, -1, PEND_PARTNER,DO_DECLINE | DO_WITHDRAW);
+ pp->partner = new;
+ return new;
+}
+
+int com_partner(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int pNew;
+ struct pending* pend;
+
+ if (param[0].type == TYPE_NULL) {
+ if (pp->partner >= 0)
+ pprintf (p, "You no longer have a bughouse partner.\n");
+ else pprintf (p, "You do not have a bughouse partner.\n");
+ RePartner(p, -1);
+ return COM_OK;
+ }
+ /* OK, we're trying to set a new partner. */
+ pNew = player_find_part_login(param[0].val.word);
+ if (pNew < 0 || player_globals.parray[pNew].status == PLAYER_PASSWORD
+ || player_globals.parray[pNew].status == PLAYER_LOGIN) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ if (pNew == p) {
+ pprintf(p, "You can't be your own bughouse partner.\n");
+ return COM_OK;
+ }
+ /* Now we know a legit partner has been chosen. Is an offer pending? */
+ if ((pend = find_pend(pNew, p, PEND_PARTNER)) != NULL) {
+ pprintf (p, "You agree to be %s's partner.\n", player_globals.parray[pNew].name);
+ Bell (pNew);
+ pprintf_prompt (pNew, "%s agrees to be your partner.\n", pp->name);
+
+ delete_pending (pend);
+
+ /* Make the switch. */
+ RePartner (p, pNew);
+ RePartner (pNew, p);
+ return COM_OK;
+ }
+ /* This is just an offer. Make sure a new partner is needed. */
+ if (player_globals.parray[pNew].partner >= 0) {
+ pprintf(p, "%s already has a partner.\n", player_globals.parray[pNew].name);
+ return COM_OK;
+ }
+ pprintf(pNew, "\n");
+ pprintf_highlight(pNew, "%s", pp->name);
+ Bell (pNew);
+ pprintf(pNew, " offers to be your bughouse partner; ");
+ pprintf_prompt(pNew, "type \"partner %s\" to accept.\n", pp->name);
+ pprintf(p, "Making a partnership offer to %s.\n", player_globals.parray[pNew].name);
+ add_request(p, pNew, PEND_PARTNER);
+
+ return COM_OK;
+}
+
+static int set_busy(int p, char *var, char *val)
+{
+ struct player *pp = &player_globals.parray[p];
+ if (!val) {
+ if (pp->busy != NULL) {
+ free (pp->busy);
+ pp->busy = NULL;
+ }
+ pprintf(p, "Your \"busy\" string was cleared.\n");
+ return VAR_OK;
+ }
+ if ((val) && (!printablestring(val)))
+ return VAR_BADVAL;
+ pp->busy = strdup(val);
+ pprintf(p, "Your \"busy\" string was set to \" %s\"\n", pp->busy);
+ return VAR_OK;
+}
+
+/* this is really ugly */
+static int set_plan(int p, char *var, char *val)
+{
+ struct player *pp = &player_globals.parray[p];
+ int which;
+ int i;
+
+ if (val && !printablestring(val))
+ return VAR_BADVAL;
+ which = atoi(var); /* Must be an integer, no test needed */
+
+ if (which > MAX_PLAN)
+ return VAR_BADVAL;
+
+ if (which > pp->num_plan)
+ which = pp->num_plan + 1;
+
+ if (which == 0) { /* shove from top */
+ if (pp->num_plan >= MAX_PLAN) { /* free the bottom string */
+ if (pp->planLines[pp->num_plan - 1] != NULL)
+ free(pp->planLines[pp->num_plan - 1]);
+ }
+ if (pp->num_plan) {
+ for (i = (pp->num_plan >= MAX_PLAN) ? MAX_PLAN - 1 : pp->num_plan; i > 0; i--)
+ pp->planLines[i] = pp->planLines[i - 1];
+ }
+ if (pp->num_plan < MAX_PLAN)
+ pp->num_plan++;
+/* kludged the next line: "" was NULL, but crashed on pprintf. fb 2.24.96 */
+ pp->planLines[0] = ((val == NULL) ? "": strdup(val));
+ pprintf(p, "\nPlan variable %d changed to '%s'.\n", which+1, pp->planLines[which]);
+ pprintf(p, "All other variables moved down.\n");
+ return VAR_OK;
+ }
+ if (which > pp->num_plan) { /* new line at bottom */
+ if (pp->num_plan >= MAX_PLAN) { /* shove the old lines up */
+ if (pp->planLines[0] != NULL)
+ free(pp->planLines[0]);
+ for (i = 0; i < pp->num_plan; i++)
+ pp->planLines[i] = pp->planLines[i + 1];
+ } else {
+ pp->num_plan++;
+ }
+/* kludged the next line: "" was NULL, but crashed on pprintf. fb2.24.96 */
+ pp->planLines[which - 1] = ((val == NULL) ? "": strdup(val));
+ pprintf(p, "\nPlan variable %d changed to '%s'.\n", which, pp->planLines[which-1]);
+ return VAR_OK;
+ }
+ which--;
+ if (pp->planLines[which] != NULL) {
+ free(pp->planLines[which]);
+ }
+ if (val != NULL) {
+ pp->planLines[which] = strdup(val);
+ pprintf(p, "\nPlan variable %d changed to '%s'.\n", which+1, pp->planLines[which]);
+ } else {
+ pp->planLines[which] = NULL;
+ if (which == pp->num_plan - 1) { /* clear nulls from bottom */
+ while ((pp->num_plan > 0) && (pp->planLines[pp->num_plan - 1] == NULL)) {
+ pp->num_plan--;
+ pprintf(p, "\nPlan variable %d cleared.\n", which+1);
+ }
+ } else if (which == 0) { /* clear nulls from top */
+ while ((which < pp->num_plan) && (pp->planLines[which] == NULL)) {
+ which++;
+ }
+ if (which != pp->num_plan) {
+ for (i = which; i < pp->num_plan; i++)
+ pp->planLines[i - which] = pp->planLines[i];
+ }
+ pp->num_plan -= which;
+ }
+ }
+ return VAR_OK;
+}
+
+static int set_formula(int p, char *var, char *val)
+{
+ int which;
+ struct player *me = &player_globals.parray[p];
+
+#ifdef NO_FORMULAS
+ pprintf(p, "Sorry -- not available because of a bug\n");
+ return COM_OK;
+#else
+ if (isdigit(var[1]))
+ which = var[1] - '1';
+ else
+ which = MAX_FORMULA;
+
+ if (val != NULL) {
+ val = eatwhite(val);
+ if (val[0] == '\0')
+ val = NULL;
+ }
+ if (!SetValidFormula(p, which, val))
+ return VAR_BADVAL;
+
+ if (which < MAX_FORMULA) {
+ if (val != NULL) {
+ while (me->num_formula < which) {
+ me->formulaLines[me->num_formula] = NULL;
+ (me->num_formula)++;
+ }
+ if (me->num_formula <= which)
+ me->num_formula = which + 1;
+ pprintf(p, "Formula variable f%d set to %s.\n",
+ which + 1, me->formulaLines[which]);
+ return VAR_OK;
+ }
+ pprintf(p, "Formula variable f%d unset.\n", which + 1);
+ if (which + 1 >= me->num_formula) {
+ while (which >= 0 && me->formulaLines[which] == NULL)
+ which--;
+ me->num_formula = which + 1;
+ }
+ } else {
+ if (me->formula != NULL)
+ pprintf(p, "Formula set to %s.\n", me->formula);
+ else
+ pprintf(p, "Formula unset.\n");
+ }
+ return VAR_OK;
+#endif
+}
+
+static var_list variables[] = {
+ {"ads", set_ads},
+ {"availinfo", set_availinfo},
+ {"availmax", set_availmax},
+ {"availmin", set_availmin},
+ {"open", set_open},
+ {"tourney", set_tourney},
+ {"simopen", set_sopen},
+ {"rated", set_rated},
+ {"ropen", set_ropen},
+ {"cshout", set_cshout},
+ {"shout", set_shout},
+ {"kibitz", set_kibitz},
+ {"kiblevel", set_kiblevel},
+ {"tell", set_tell},
+ {"notifiedby", set_notifiedby},
+ {"pinform", set_pinform},
+ {"i_login", set_pinform},
+ {"ginform", set_ginform},
+ {"i_game", set_ginform},
+ {"automail", set_automail},
+ {"mailmess", set_mailmess},
+ {"bell", set_bell},
+ {"pgn", set_pgn},
+ {"private", set_private},
+ {"jprivate", set_jprivate},
+ {"highlight", set_highlight},
+ {"style", set_style},
+ {"flip", set_flip},
+ {"prompt", set_prompt},
+ {"promote", set_promote},
+ {"time", set_time},
+ {"inc", set_inc},
+ {"height", set_height},
+ {"width", set_width},
+ {"language", set_language},
+ {"busy", set_busy},
+ {"0", set_plan},
+ {"1", set_plan},
+ {"2", set_plan},
+ {"3", set_plan},
+ {"4", set_plan},
+ {"5", set_plan},
+ {"6", set_plan},
+ {"7", set_plan},
+ {"8", set_plan},
+ {"9", set_plan},
+ {"10", set_plan},
+ {"f1", set_formula},
+ {"f2", set_formula},
+ {"f3", set_formula},
+ {"f4", set_formula},
+ {"f5", set_formula},
+ {"f6", set_formula},
+ {"f7", set_formula},
+ {"f8", set_formula},
+ {"f9", set_formula},
+ {"formula", set_formula},
+ {"interface", set_interface},
+ {NULL, NULL}
+};
+
+static int set_find(char *var)
+{
+ int i = 0;
+ int gotIt = -1;
+ int len = strlen(var);
+
+ while (variables[i].name) {
+ if (!strncmp(variables[i].name, var, len)) {
+ if (len == strlen(variables[i].name)) {
+ return i;
+ } else if (gotIt >= 0) {
+ return -VAR_AMBIGUOUS;
+ }
+ gotIt = i;
+ }
+ i++;
+ }
+ if (gotIt >= 0) {
+ return gotIt;
+ }
+ return -VAR_NOSUCH;
+}
+
+int var_set(int p, char *var, char *val, int *wh)
+{
+ int which;
+
+ if (!var)
+ return VAR_NOSUCH;
+ if ((which = set_find(var)) < 0) {
+ return -which;
+ }
+ *wh = which;
+ return variables[which].var_func(p, (isdigit(*variables[which].name) ? var : variables[which].name), val);
+}
+
+int com_variables(int p, param_list param)
+{
+ int p1, connected;
+ int i;
+
+ if (param[0].type == TYPE_WORD) {
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+ } else {
+ p1 = p;
+ connected = 1;
+ }
+
+ pprintf(p, "Variable settings of %s:\n\n", player_globals.parray[p1].name);
+
+ pprintf(p, "time=%-3d private=%d shout=%d pin=%d style=%-3d\n",
+ player_globals.parray[p1].d_time, BoolCheckPFlag(p1, PFLAG_PRIVATE),
+ BoolCheckPFlag(p1, PFLAG_SHOUT), BoolCheckPFlag(p1, PFLAG_PIN),
+ player_globals.parray[p1].style + 1);
+ pprintf(p, "inc=%-3d jprivate=%d cshout=%d notifiedby=%d flip=%d\n",
+ player_globals.parray[p1].d_inc, BoolCheckPFlag(p1, PFLAG_JPRIVATE),
+ BoolCheckPFlag(p1, PFLAG_CSHOUT), BoolCheckPFlag(p1, PFLAG_NOTIFYBY),
+ BoolCheckPFlag(p1, PFLAG_FLIP));
+ pprintf(p, " kibitz=%d availinfo=%d highlight=%d\n",
+ BoolCheckPFlag(p1, PFLAG_KIBITZ), BoolCheckPFlag(p1, PFLAG_AVAIL),
+ player_globals.parray[p1].highlight);
+ pprintf(p, "rated=%d automail=%d kiblevel=%-4d availmin=%-4d bell=%d\n",
+ BoolCheckPFlag(p1, PFLAG_RATED), BoolCheckPFlag(p1, PFLAG_AUTOMAIL),
+ player_globals.parray[p1].kiblevel, player_globals.parray[p1].availmin,
+ BoolCheckPFlag(p1, PFLAG_BELL));
+ pprintf(p, "ropen=%d pgn=%d tell=%d availmax=%-4d width=%-3d\n",
+ BoolCheckPFlag(p1, PFLAG_ROPEN), BoolCheckPFlag(p1, PFLAG_PGN),
+ BoolCheckPFlag(p1, PFLAG_TELL), player_globals.parray[p1].availmax,
+ player_globals.parray[p1].d_width);
+ pprintf(p, "open=%d mailmess=%d gin=%d height=%-3d\n",
+ BoolCheckPFlag(p1, PFLAG_OPEN), BoolCheckPFlag(p1, PFLAG_MAILMESS),
+ BoolCheckPFlag(p1, PFLAG_GIN), player_globals.parray[p1].d_height);
+ pprintf(p, "simopen=%d tourney=%d Lang=%s",
+ BoolCheckPFlag(p1, PFLAG_SIMOPEN), BoolCheckPFlag(p1, PFLAG_TOURNEY),
+ Language(player_globals.parray[p1].language));
+
+ if (player_globals.parray[p1].prompt)
+ pprintf(p, " Prompt: %s\n", player_globals.parray[p1].prompt);
+ else
+ pprintf(p, "\n");
+
+ if (player_globals.parray[p1].partner >= 0)
+ pprintf(p, "\nBughouse partner: %s\n", player_globals.parray[player_globals.parray[p1].partner].name);
+
+ if (player_globals.parray[p1].num_formula) {
+ pprintf(p, "\n");
+ for (i = 0; i < player_globals.parray[p1].num_formula; i++) {
+ if (player_globals.parray[p1].formulaLines[i] != NULL)
+ pprintf(p, " f%d: %s\n", i + 1, player_globals.parray[p1].formulaLines[i]);
+ else
+ pprintf(p, " f%d:\n", i + 1);
+ }
+ }
+ if (player_globals.parray[p1].formula != NULL)
+ pprintf(p, "\nFormula: %s\n", player_globals.parray[p1].formula);
+ else
+ pprintf(p, "\n");
+
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+/* tournset (cause settourney is BAD for set)
+ * used by Tournament Director programs to set/unset the
+ * tourney variable of another registered player.
+ * fics usage: tournset playername int (int can be 0 or 1)
+ */
+int com_tournset(int p, param_list param)
+{
+ struct player *pp = &player_globals.parray[p];
+ int p1, v;
+
+ if (!in_list(p, L_TD, pp->name)) {
+ pprintf(p, "Only TD programs are allowed to use this command.\n");
+ return COM_OK;
+ }
+ if (((p1 = player_find_bylogin(param[0].val.word)) < 0)
+ || (!CheckPFlag(p1, PFLAG_REG))) {
+ return COM_OK;
+ }
+ v = BoolCheckPFlag(p1, PFLAG_TOURNEY);
+ if (param[1].val.integer == 0) { /* set it to 0 */
+ if (v == 1) {
+ SetPFlag(p1, PFLAG_TOURNEY, 0);
+ pprintf_prompt(p1, "\n%s has set your tourney variable to OFF.\n",
+ pp->name);
+ }
+ } else { /* set it to 1 */
+ if (v == 0) {
+ SetPFlag(p1, PFLAG_TOURNEY, 1);
+ pprintf_prompt(p1, "\n%s has set your tourney variable to ON.\n",
+ pp->name);
+ }
+ }
+ return COM_OK;
+}
+
+
--- /dev/null
+/*
+ Copyright (c) 1993 Richard V. Nash.
+ Copyright (c) 2000 Dan Papasian
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 2 of the License, 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.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#ifndef VARIABLE_H
+#define VARIABLE_H
+
+typedef struct var_list {
+ char *name;
+ int (*var_func)();
+} var_list;
+
+#define VAR_OK 0
+#define VAR_NOSUCH 1
+#define VAR_BADVAL 2
+#define VAR_AMBIGUOUS 3
+
+#define LANG_ENGLISH 0
+#define LANG_SPANISH 1
+#define LANG_FRENCH 2
+#define LANG_DANISH 3
+#define NUM_LANGS 4
+
+extern var_list variables[];
+
+#endif /* VARIABLE_H */
--- /dev/null
+
+#ifndef VERS_H
+#define VERS_H
+
+extern char SGS_VERS[];
+extern char VERS_NUM[];
+extern char COMP_DATE[];
+
+#endif /* VERS_H */
--- /dev/null
+/play2.pl/1.3/Sun Jul 18 08:46:32 2004//
+D
--- /dev/null
+lasker/testplay
--- /dev/null
+#!/usr/bin/perl
+#
+# Quick and nasty script to load a game record and play it
+# through via a FICS server.
+#
+# Anthony Wesley and Andrew Tridgell, July 2004
+#
+# Usage: play2.pl server client1/passwd1 client2/passwd2
+#
+# Reads game records on stdin.
+#
+
+use IO::Socket;
+
+my $server = shift @ARGV;
+my ($client1,$pass1) = split(/\//, shift @ARGV);
+my ($client2,$pass2) = split(/\//, shift @ARGV);
+
+print "Connecting to $server , port 5000\n";
+print "[$client1 / $pass1 ] , [$client2 / $pass2 ]\n";
+
+my $S1 = new IO::Socket::INET(
+ PeerAddr => $server,
+ PeerPort => 5000,
+ Proto => 'tcp',
+ ReuseAddr => 1
+ ) or die "Could not connect";
+
+my $S2 = new IO::Socket::INET(
+ PeerAddr => $server,
+ PeerPort => 5000,
+ Proto => 'tcp',
+ ReuseAddr => 1
+ ) or die "Could not connect";
+
+$S1->setsockopt(&Socket::IPPROTO_TCP, &Socket::TCP_NODELAY, 1) || die;
+$S2->setsockopt(&Socket::IPPROTO_TCP, &Socket::TCP_NODELAY, 1) || die;
+
+print "Connection opened. Logging in...\n";
+
+Login($S1,$client1,$pass1) or die "Could not login $client1";
+Login($S2,$client2,$pass2) or die "Could not login $client2";
+
+sleep(3);
+
+print "Logged in\n";
+
+# ensure we don't have any left over games
+$S1->print("resign $client2\n");
+
+print "Reading game record from stdin...\n";
+my $game = "";
+my $game_comment = "";
+my $game_num = 0;
+
+while(my $line = <STDIN>) {
+ chomp $line;
+ if ($line =~ /^\[/ || $line eq "") {
+ if ($game eq "") {
+ $game_comment .= "$line\n";
+ next;
+ }
+ $game = extract_moves($game);
+ $game_num++;
+ print "Starting game $game_num\n";
+ PlayGame($S1,$S2,$game);
+ $game = "";
+ $game_comment = "";
+ next;
+ }
+ $game .= $line . " ";
+}
+
+sub PlayGame($$$)
+{
+ my $s1 = shift;
+ my $s2 = shift;
+ my $game = shift;
+
+ Challenge($s1,$client1,$s2,$client2) or die "Could not setup game";
+
+ my $res = Play($s1, $s2, $game);
+ if ($res ne "OK") {
+ $s1->print("resign\n");
+
+ print "Writing bad game - $res\n";
+
+ local(*FILE);
+ open(FILE, ">>badgames.txt") || die "can't open badgames.txt";
+ print FILE "[$res]\n$game\n\n";
+ close(FILE);
+ }
+
+ WaitFor($s1, "$client1 vs. $client2");
+ WaitFor($s2, "$client1 vs. $client2");
+
+ WaitFor($s1, "No ratings adjustment done");
+ WaitFor($s2, "No ratings adjustment done");
+}
+
+
+sub Login($$$)
+{
+ my $s = shift;
+ my $name = shift;
+ my $pass = shift;
+
+ $s->print($name . "\n");
+ $s->print($pass . "\n");
+ $s->print("set style 12\n\n");
+
+ return 1;
+}
+
+sub extract_moves($)
+{
+ my $txt = shift;
+ my $moves = "";
+
+ my @lines = split(/[\n\r]+/, $txt);
+ foreach my $l (@lines) {
+ # Strip
+ $l =~ s/^\s+//; $l =~ s/\s+$//;
+
+ # Maybe metadata?
+ next if $l =~ /^\s+\[/;
+
+ # Maybe contains moves?
+ $moves .= $l . " ";
+ }
+
+ # Strip out the move numbers
+# $moves =~ s/\d+\.\s+//g;
+
+ return $moves;
+}
+
+sub Challenge($$$$)
+{
+ my $s1 = shift; # socket for client1
+ my $client1 = shift; # username for initiator
+ my $s2 = shift; # socket for receipient
+ my $client2 = shift; # name of receipient
+
+ $s1->print("match $client2 1 1 w u\n");
+
+ WaitFor($s1, "Issuing: $client1");
+ WaitFor($s2, "Challenge: $client1");
+ WaitFor($s2, "You can \"accept\"");
+ $s2->print("accept\n");
+ WaitFor($s2,"You accept the challenge of $client1");
+ WaitFor($s1,"$client2 accepts your challenge");
+ WaitFor($s1,"Creating: $client1");
+ WaitFor($s1,".$client1 vs. $client2. Creating");
+ WaitFor($s2,"Creating: $client1");
+ WaitFor($s2,".$client1 vs. $client2. Creating");
+
+ return 1;
+}
+
+sub Play($$$)
+{
+ my $s1 = shift;
+ my $s2 = shift;
+ my $game = shift;
+
+ my $who_to_move = "w";
+ my @moves = split(/\s+/, $game);
+
+ my $movenum = 1;
+ my $res = "OK";
+
+ CheckMove($s1,"none") || return "Initialisation failed for white";
+ CheckMove($s2,"none") || return "Initialisation failed for black";
+
+ foreach my $m (@moves) {
+ next if ($m =~ /^\d/);
+ last if ($m =~ /^\[/);
+ my $p1, $p2;
+
+ if ($who_to_move eq "w") {
+ $p1 = $s1;
+ $p2 = $s2;
+# print "White moves $movenum. $m\n";
+ } else {
+ $p1 = $s2;
+ $p2 = $s1;
+# print "Black moves $movenum ... $m\n";
+ }
+
+ SendMove($p1,$m);
+
+ $res = CheckMove($p1,$m);
+ if ($res ne "OK") {
+ return "Failed on move $movenum - $res";
+ }
+
+ $res = CheckMove($p2,$m);
+ if ($res ne "OK") {
+ return "Failed on move $movenum - $res";
+ }
+
+ # Change sides
+ if ($who_to_move eq "b") {
+ $movenum++;
+ $who_to_move = "w";
+ } else {
+ $who_to_move = "b";
+ }
+ }
+
+ # Resign
+ if ($who_to_move eq "w") {
+ Resign($s1);
+ } else {
+ Resign($s2);
+ }
+
+ return "OK";
+}
+
+sub SendMove($$)
+{
+ my $s = shift;
+ my $m = shift;
+
+ $s->print($m . "\n");
+
+ return 0;
+}
+
+sub CheckMove($$)
+{
+ my $s = shift;
+ my $m = shift;
+
+ # Readback to check
+ while ($l = $s->getline) {
+ chomp $l;
+# print "line3=\n[[[$l\n]]]\n";
+ if ($l =~ /^\s+fics%\s+$/) {
+ next;
+ }
+ if ($l =~ /^\s+$/) {
+ next;
+ }
+ if ($l =~ /Illegal Move/i) {
+ return "Server reports illegal move $m";
+ }
+ if ($l =~ /Ambiguous Move/i) {
+ return "Server reports ambiguous move $m";
+ }
+ my $rmove = ParseStyle12($l);
+ if ($rmove eq "") {
+ print "$l\n";
+ next;
+ }
+ if (!MoveEqual($rmove,$m)) {
+ return "wrong RecvMove $rmove should be $m";
+ }
+ return "OK";
+ }
+
+ return "eof from server";
+}
+
+sub ParseStyle12($)
+{
+ my $s = shift;
+ my $m = "";
+ if ($s =~ /\<12\>.*\(\d+\:\d\d\)\s(\S+)/m) {
+ $m = $1;
+# print "Move=$m\n";
+ }
+ return $m;
+}
+
+sub Resign($)
+{
+ my $s = shift;
+
+ $s->print("resign\n");
+}
+
+sub MoveEqual($$)
+{
+ my $m1 = shift;
+ my $m2 = shift;
+
+ # remove check and good move markers
+ if ($m1 =~ /^(.*)[+!]/) {
+ $m1 = $1;
+ }
+
+ if ($m2 =~ /^(.*)[+!]/) {
+ $m2 = $1;
+ }
+
+ if ($m1 eq $m2) {
+ return 1;
+ }
+
+ return 0;
+}
+
+sub WaitFor($$)
+{
+ my $s = shift;
+ my $str = shift;
+
+
+ while (my $l = $s->getline) {
+ chomp $l;
+ if ($l =~ /$str/) {
+# print "GOT: $str\n";
+ return;
+ }
+ if ($l =~ /^\s+fics%\s+$/) {
+ next;
+ }
+ if ($l =~ /^\s+$/) {
+ next;
+ }
+ print "$l\n";
+ }
+}
--- /dev/null
+/test1.exp/1.2/Sat Jun 29 00:18:43 2002//
+/setup.exp/1.1/Mon Jul 1 04:10:04 2002//
+D
--- /dev/null
+lasker/tests
--- /dev/null
+#!/usr/bin/expect -f
+# simple test setup script for lasker
+# Andrew Tridgell <lasker@tridgell.net>
+
+if {$argc < 3} {
+ send_user "Usage: setup.exp HOSTNAME USERNAME PASSWORD\n"
+ exit
+}
+
+set host [lrange $argv 0 0]
+set user [lrange $argv 1 1]
+set pass [lrange $argv 2 2]
+
+set timeout -1
+match_max 100000
+
+spawn telnet $host 5000
+expect "\rlogin: "
+send "admin\r"
+expect "Press return to enter the FICS"
+send "\r"
+expect "fics% "
+
+send "addplayer admin none The Admin\r"
+expect "Added: "
+expect "fics% "
+
+send "asetpass admin $pass\r"
+expect "has changed your password"
+expect "fics% "
+
+# login again
+spawn telnet $host 5000
+expect "\rlogin: "
+send "$user\r"
+expect "password: "
+send "$pass\r"
+expect "fics% "
+
+send "who\r"
+expect "$user"
+expect "players displayed"
+expect "indicates system administrator."
+expect "fics% "
+
+send "aconfig\r"
+expect "fics% "
+
+send "aconfig SERVER_LOCATION test location\r"
+expect "fics% "
+
+send "aconfig SERVER_HOSTNAME test\r"
+expect "fics% "
+
+send "aconfig HEAD_ADMIN_EMAIL nobody@samba.org\r"
+expect "fics% "
+
+send "aconfig\r"
+expect "fics% "
+
+send "quit\r"
+expect "Thank you"
--- /dev/null
+#!/usr/bin/expect -f
+# simple test script for lasker
+# Andrew Tridgell <lasker@tridgell.net>
+
+if {$argc < 3} {
+ send_user "Usage: test.exp HOSTNAME USERNAME PASSWORD\n"
+ exit
+}
+
+set host [lrange $argv 0 0]
+set user [lrange $argv 1 1]
+set pass [lrange $argv 2 2]
+
+set timeout -1
+match_max 100000
+spawn tseal $host 5000
+expect "\rlogin: "
+send "$user\r"
+expect "password: "
+send "$pass\r"
+expect "fics% "
+
+send "who\r"
+expect "$user"
+expect "players displayed"
+expect "indicates system administrator."
+expect "fics% "
+
+send "who a\r"
+expect "$user"
+expect "players displayed"
+expect "indicates system administrator."
+expect "fics% "
+
+send "who z\r"
+expect "Command: who"
+expect "See 'help who' for a complete description"
+expect "fics% "
+
+send "zzdf\r"
+expect "zzdf: Command not found."
+expect "fics% "
+
+send "help f\r"
+expect "'f' is a global alias for 'finger'"
+expect "fics% "
+
+send "help c\r"
+expect -- "-- Matches: "
+expect "help topics --"
+expect "clearmessages"
+expect "fics% "
+
+send -- "-notify tridge\r"
+send "+notify tridge\r"
+expect "added to your notify list."
+expect "fics% "
+
+send "+notify tridge\r"
+expect "is already on your notify list."
+expect "fics% "
+
+send "=notify\r"
+expect -- "-- notify list: 1 names --"
+expect "fics% "
+
+send "toggle notify tridge\r"
+expect "removed from your notify list."
+expect "fics% "
+
+send "set style 12\r"
+send "match $user\r"
+expect "<12> rnbqkbnr pppppppp -------- -------- -------- -------- PPPPPPPP RNBQKBNR"
+expect "fics% "
+
+send "e4\r"
+expect "<12> rnbqkbnr pppppppp -------- -------- ----P--- -------- PPPP-PPP RNBQKBNR"
+expect "fics% "
+
+send "e5\r"
+expect "<12> rnbqkbnr pppp-ppp -------- ----p--- ----P--- -------- PPPP-PPP RNBQKBNR"
+expect "fics% "
+
+send "unexamine\r"
+expect "You are no longer examining game"
+expect "fics% "
+
+
+send -- "quit\r"
+expect "Thank you for using a"
--- /dev/null
+/README/1.1/Wed Jun 12 02:44:07 2002//
+/timeseal_decoder-Linux-ELF-2.4/1.1/Wed Jun 12 01:06:02 2002/-kb/
+D
--- /dev/null
+lasker/timeseal
--- /dev/null
+Introduction
+------------
+
+This chess server supports the 'timeseal' protocol for keeping more
+accurate track of players time usage.
+
+Unlike previous chess servers that had to have the timeseal code built
+in in this server uses a small external timeseal_decoder process whose
+sole purpose is to decode the timeseal protocol. You can enable this
+process (and thus enable timeseal support) using the -T option to
+chessd.
+
+The reasons I designed it this way are:
+
+ - it keeps the timeseal protocol secret, and the protocol relies
+ on its secrecy to prevent cheating
+ - it allows me to use GPLd code in the chess server while not
+ distributing the timeseal decoder source code
+
+
+Using timeseal
+--------------
+
+To use timeseal in your chess server just pass the location of your
+timeseal_decoder binary to the -T option. For example:
+
+ bin/chessd -T bin/timeseal_decoder -p 5000
+
+If you also use the -R option to setup a secure chroot jail for your
+chess server then you must pass the -T option before the -R option.
+
+
+
+--------------------------------
+Andrew Tridgell
+tridge@chess.samba.org June 2002
+--------------------------------
--- /dev/null
+/index.html/1.14/Thu Jul 22 07:04:41 2004//
+D
--- /dev/null
+lasker/web
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<HTML>
+<HEAD>
+<TITLE>Lasker Chess Server</TITLE>
+</HEAD>
+<BODY BGCOLOR="#ffffff" TEXT="#000000" VLINK="#292555" LINK="#292555" ALINK="#cc0033">
+<h2>Lasker Chess Server</h2>
+
+This is an enhanced chess server based on the 'lasker' chess server
+from <a href="http://chessd.sourceforge.net/">http://chessd.sourceforge.net/</a>
+
+<p>
+For more details please see the <a href="/ftp/unpacked/lasker/README">README</a>
+
+<h2>Features</h2>
+<ul>
+<li> lots and lots of bugs fixed
+<li> timeseal support added (see
+<a href="/ftp/unpacked/lasker/timeseal/README">timeseal/README</a> for details)
+<li> server configuration via 'aconfig' command instead of config.h
+<li> added multi-part command parsing (commands separated by ';')
+<li> enhanced aliases
+<li> build/install process fixed
+<li> fixed help system
+<li> transparent server reload (upgrade without disturbing connections
+or games)
+<li> plus lots more …
+</ul>
+
+
+<h2>Download</h2>
+
+Tar balls of released version are available <a href="/ftp/lasker/">here</a>
+
+<h2>cvs</h2>
+
+I recommend you download the source using anonymous cvs. The following
+command should do it:
+
+<pre>
+ cvs -z5 -d :pserver:cvs@pserver.samba.org:/cvsroot co lasker
+</pre>
+
+Then to get updates do the following:
+
+<pre>
+ cd lasker
+ cvs -z5 update -dP
+</pre>
+
+<h2>Mailing list</h2>
+
+If you wish to discuss the development of Lasker then please join the
+<a
+href="http://lists.sourceforge.net/lists/listinfo/chessd-general">chessd-general</a>
+mailing list at <a href="http://chessd.sourceforge.net/">http://chessd.sourceforge.net/</a>
+
+<h2>Latest release</h2>
+
+The latest release is 2.2.3. This release adds:
+
+<ul>
+<li>new command "remote"
+<li>fixed several bugs in algebraic move parsing for ambiguous moves
+<li>fixed promotion using = notation
+<li>fixed time handling on first move
+<li>fixed handling of '$' commands
+<li>changed mam alias to use xtell
+<li>reduced CPU usage in server dramatically
+<li>fixed several crash bugs
+<li>added logging of admin commands
+</ul>
+
+<h2>News</h2>
+
+<ul>
+<li>June 12th 2002. First announcement of CVS version of enhanced lasker
+<li>June 13th 2002. Added ability to reload the server code (upgrade)
+without disturbing games or connections.
+<li>June 13th 2002. Released lasker-2.0.tar.gz
+<li>June 18th 2002. Released lasker-2.0.1.tar.gz
+<li>June 22nd 2002. Released lasker-2.1.0.tar.gz
+<li>June 23rd 2002. Released lasker-2.2.0.tar.gz
+<li>June 29th 2002. Released lasker-2.2.1.tar.gz
+<li>July 1st 2002. Released lasker-2.2.2.tar.gz
+<li>July 22nd 2004. Released lasker-2.2.3.tar.gz
+</ul>
+
+<hr>
+<tiny>
+<a href="http://samba.org/~tridge/">Andrew Tridgell</a><br>
+<a href="mailto:bugs@chess.samba.org">bugs@chess.samba.org</a>
+</tiny>
+
+</BODY>
+</HTML>