Import zchess by Eric Schmidt
authorJason Self <j@jxself.org>
Wed, 21 Aug 2019 02:47:54 +0000 (19:47 -0700)
committerJason Self <j@jxself.org>
Wed, 21 Aug 2019 02:47:54 +0000 (19:47 -0700)
Release 4; Serial number 040124

From
http://www.ifarchive.org/if-archive/games/source/inform/zchess.zip

README [new file with mode: 0644]
gpl.txt [new file with mode: 0644]
zchess.inf [new file with mode: 0644]

diff --git a/README b/README
new file mode 100644 (file)
index 0000000..d277dfe
--- /dev/null
+++ b/README
@@ -0,0 +1,31 @@
+This repository contains a copy of zchess by Eric Schmidt.
+
+http://www.ifarchive.org/if-archive/games/source/inform/zchess.zip
+
+To compile this game you will also need version 6 of the Inform 
+compiler from https://jxself.org/git/?p=inform.git
+
+Once the compiler has been compiled and is ready for use return to 
+this directory and run:
+
+    inform zchess.inf
+
+You will then get the story file for this game that can be run using 
+any appropriate Z-Machine interpreter, such as Frotz. Your GNU/Linux 
+distro probably has that packaged already for easy installation.
+
+--
+Copyright (C) 2019 Jason Self <j@jxself.org>
+
+You may copy, redistribute and/or modify this 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 file 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 file. If not, see https://gnu.org/licenses/
\ No newline at end of file
diff --git a/gpl.txt b/gpl.txt
new file mode 100644 (file)
index 0000000..45645b4
--- /dev/null
+++ b/gpl.txt
@@ -0,0 +1,340 @@
+                   GNU GENERAL PUBLIC LICENSE\r
+                      Version 2, June 1991\r
+\r
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.\r
+                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ Everyone is permitted to copy and distribute verbatim copies\r
+ of this license document, but changing it is not allowed.\r
+\r
+                           Preamble\r
+\r
+  The licenses for most software are designed to take away your\r
+freedom to share and change it.  By contrast, the GNU General Public\r
+License is intended to guarantee your freedom to share and change free\r
+software--to make sure the software is free for all its users.  This\r
+General Public License applies to most of the Free Software\r
+Foundation's software and to any other program whose authors commit to\r
+using it.  (Some other Free Software Foundation software is covered by\r
+the GNU Library General Public License instead.)  You can apply it to\r
+your programs, too.\r
+\r
+  When we speak of free software, we are referring to freedom, not\r
+price.  Our General Public Licenses are designed to make sure that you\r
+have the freedom to distribute copies of free software (and charge for\r
+this service if you wish), that you receive source code or can get it\r
+if you want it, that you can change the software or use pieces of it\r
+in new free programs; and that you know you can do these things.\r
+\r
+  To protect your rights, we need to make restrictions that forbid\r
+anyone to deny you these rights or to ask you to surrender the rights.\r
+These restrictions translate to certain responsibilities for you if you\r
+distribute copies of the software, or if you modify it.\r
+\r
+  For example, if you distribute copies of such a program, whether\r
+gratis or for a fee, you must give the recipients all the rights that\r
+you have.  You must make sure that they, too, receive or can get the\r
+source code.  And you must show them these terms so they know their\r
+rights.\r
+\r
+  We protect your rights with two steps: (1) copyright the software, and\r
+(2) offer you this license which gives you legal permission to copy,\r
+distribute and/or modify the software.\r
+\r
+  Also, for each author's protection and ours, we want to make certain\r
+that everyone understands that there is no warranty for this free\r
+software.  If the software is modified by someone else and passed on, we\r
+want its recipients to know that what they have is not the original, so\r
+that any problems introduced by others will not reflect on the original\r
+authors' reputations.\r
+\r
+  Finally, any free program is threatened constantly by software\r
+patents.  We wish to avoid the danger that redistributors of a free\r
+program will individually obtain patent licenses, in effect making the\r
+program proprietary.  To prevent this, we have made it clear that any\r
+patent must be licensed for everyone's free use or not licensed at all.\r
+\r
+  The precise terms and conditions for copying, distribution and\r
+modification follow.\r
+\f\r
+                   GNU GENERAL PUBLIC LICENSE\r
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\r
+\r
+  0. This License applies to any program or other work which contains\r
+a notice placed by the copyright holder saying it may be distributed\r
+under the terms of this General Public License.  The "Program", below,\r
+refers to any such program or work, and a "work based on the Program"\r
+means either the Program or any derivative work under copyright law:\r
+that is to say, a work containing the Program or a portion of it,\r
+either verbatim or with modifications and/or translated into another\r
+language.  (Hereinafter, translation is included without limitation in\r
+the term "modification".)  Each licensee is addressed as "you".\r
+\r
+Activities other than copying, distribution and modification are not\r
+covered by this License; they are outside its scope.  The act of\r
+running the Program is not restricted, and the output from the Program\r
+is covered only if its contents constitute a work based on the\r
+Program (independent of having been made by running the Program).\r
+Whether that is true depends on what the Program does.\r
+\r
+  1. You may copy and distribute verbatim copies of the Program's\r
+source code as you receive it, in any medium, provided that you\r
+conspicuously and appropriately publish on each copy an appropriate\r
+copyright notice and disclaimer of warranty; keep intact all the\r
+notices that refer to this License and to the absence of any warranty;\r
+and give any other recipients of the Program a copy of this License\r
+along with the Program.\r
+\r
+You may charge a fee for the physical act of transferring a copy, and\r
+you may at your option offer warranty protection in exchange for a fee.\r
+\r
+  2. You may modify your copy or copies of the Program or any portion\r
+of it, thus forming a work based on the Program, and copy and\r
+distribute such modifications or work under the terms of Section 1\r
+above, provided that you also meet all of these conditions:\r
+\r
+    a) You must cause the modified files to carry prominent notices\r
+    stating that you changed the files and the date of any change.\r
+\r
+    b) You must cause any work that you distribute or publish, that in\r
+    whole or in part contains or is derived from the Program or any\r
+    part thereof, to be licensed as a whole at no charge to all third\r
+    parties under the terms of this License.\r
+\r
+    c) If the modified program normally reads commands interactively\r
+    when run, you must cause it, when started running for such\r
+    interactive use in the most ordinary way, to print or display an\r
+    announcement including an appropriate copyright notice and a\r
+    notice that there is no warranty (or else, saying that you provide\r
+    a warranty) and that users may redistribute the program under\r
+    these conditions, and telling the user how to view a copy of this\r
+    License.  (Exception: if the Program itself is interactive but\r
+    does not normally print such an announcement, your work based on\r
+    the Program is not required to print an announcement.)\r
+\f\r
+These requirements apply to the modified work as a whole.  If\r
+identifiable sections of that work are not derived from the Program,\r
+and can be reasonably considered independent and separate works in\r
+themselves, then this License, and its terms, do not apply to those\r
+sections when you distribute them as separate works.  But when you\r
+distribute the same sections as part of a whole which is a work based\r
+on the Program, the distribution of the whole must be on the terms of\r
+this License, whose permissions for other licensees extend to the\r
+entire whole, and thus to each and every part regardless of who wrote it.\r
+\r
+Thus, it is not the intent of this section to claim rights or contest\r
+your rights to work written entirely by you; rather, the intent is to\r
+exercise the right to control the distribution of derivative or\r
+collective works based on the Program.\r
+\r
+In addition, mere aggregation of another work not based on the Program\r
+with the Program (or with a work based on the Program) on a volume of\r
+a storage or distribution medium does not bring the other work under\r
+the scope of this License.\r
+\r
+  3. You may copy and distribute the Program (or a work based on it,\r
+under Section 2) in object code or executable form under the terms of\r
+Sections 1 and 2 above provided that you also do one of the following:\r
+\r
+    a) Accompany it with the complete corresponding machine-readable\r
+    source code, which must be distributed under the terms of Sections\r
+    1 and 2 above on a medium customarily used for software interchange; or,\r
+\r
+    b) Accompany it with a written offer, valid for at least three\r
+    years, to give any third party, for a charge no more than your\r
+    cost of physically performing source distribution, a complete\r
+    machine-readable copy of the corresponding source code, to be\r
+    distributed under the terms of Sections 1 and 2 above on a medium\r
+    customarily used for software interchange; or,\r
+\r
+    c) Accompany it with the information you received as to the offer\r
+    to distribute corresponding source code.  (This alternative is\r
+    allowed only for noncommercial distribution and only if you\r
+    received the program in object code or executable form with such\r
+    an offer, in accord with Subsection b above.)\r
+\r
+The source code for a work means the preferred form of the work for\r
+making modifications to it.  For an executable work, complete source\r
+code means all the source code for all modules it contains, plus any\r
+associated interface definition files, plus the scripts used to\r
+control compilation and installation of the executable.  However, as a\r
+special exception, the source code distributed need not include\r
+anything that is normally distributed (in either source or binary\r
+form) with the major components (compiler, kernel, and so on) of the\r
+operating system on which the executable runs, unless that component\r
+itself accompanies the executable.\r
+\r
+If distribution of executable or object code is made by offering\r
+access to copy from a designated place, then offering equivalent\r
+access to copy the source code from the same place counts as\r
+distribution of the source code, even though third parties are not\r
+compelled to copy the source along with the object code.\r
+\f\r
+  4. You may not copy, modify, sublicense, or distribute the Program\r
+except as expressly provided under this License.  Any attempt\r
+otherwise to copy, modify, sublicense or distribute the Program is\r
+void, and will automatically terminate your rights under this License.\r
+However, parties who have received copies, or rights, from you under\r
+this License will not have their licenses terminated so long as such\r
+parties remain in full compliance.\r
+\r
+  5. You are not required to accept this License, since you have not\r
+signed it.  However, nothing else grants you permission to modify or\r
+distribute the Program or its derivative works.  These actions are\r
+prohibited by law if you do not accept this License.  Therefore, by\r
+modifying or distributing the Program (or any work based on the\r
+Program), you indicate your acceptance of this License to do so, and\r
+all its terms and conditions for copying, distributing or modifying\r
+the Program or works based on it.\r
+\r
+  6. Each time you redistribute the Program (or any work based on the\r
+Program), the recipient automatically receives a license from the\r
+original licensor to copy, distribute or modify the Program subject to\r
+these terms and conditions.  You may not impose any further\r
+restrictions on the recipients' exercise of the rights granted herein.\r
+You are not responsible for enforcing compliance by third parties to\r
+this License.\r
+\r
+  7. If, as a consequence of a court judgment or allegation of patent\r
+infringement or for any other reason (not limited to patent issues),\r
+conditions are imposed on you (whether by court order, agreement or\r
+otherwise) that contradict the conditions of this License, they do not\r
+excuse you from the conditions of this License.  If you cannot\r
+distribute so as to satisfy simultaneously your obligations under this\r
+License and any other pertinent obligations, then as a consequence you\r
+may not distribute the Program at all.  For example, if a patent\r
+license would not permit royalty-free redistribution of the Program by\r
+all those who receive copies directly or indirectly through you, then\r
+the only way you could satisfy both it and this License would be to\r
+refrain entirely from distribution of the Program.\r
+\r
+If any portion of this section is held invalid or unenforceable under\r
+any particular circumstance, the balance of the section is intended to\r
+apply and the section as a whole is intended to apply in other\r
+circumstances.\r
+\r
+It is not the purpose of this section to induce you to infringe any\r
+patents or other property right claims or to contest validity of any\r
+such claims; this section has the sole purpose of protecting the\r
+integrity of the free software distribution system, which is\r
+implemented by public license practices.  Many people have made\r
+generous contributions to the wide range of software distributed\r
+through that system in reliance on consistent application of that\r
+system; it is up to the author/donor to decide if he or she is willing\r
+to distribute software through any other system and a licensee cannot\r
+impose that choice.\r
+\r
+This section is intended to make thoroughly clear what is believed to\r
+be a consequence of the rest of this License.\r
+\f\r
+  8. If the distribution and/or use of the Program is restricted in\r
+certain countries either by patents or by copyrighted interfaces, the\r
+original copyright holder who places the Program under this License\r
+may add an explicit geographical distribution limitation excluding\r
+those countries, so that distribution is permitted only in or among\r
+countries not thus excluded.  In such case, this License incorporates\r
+the limitation as if written in the body of this License.\r
+\r
+  9. The Free Software Foundation may publish revised and/or new versions\r
+of the General Public License from time to time.  Such new versions will\r
+be similar in spirit to the present version, but may differ in detail to\r
+address new problems or concerns.\r
+\r
+Each version is given a distinguishing version number.  If the Program\r
+specifies a version number of this License which applies to it and "any\r
+later version", you have the option of following the terms and conditions\r
+either of that version or of any later version published by the Free\r
+Software Foundation.  If the Program does not specify a version number of\r
+this License, you may choose any version ever published by the Free Software\r
+Foundation.\r
+\r
+  10. If you wish to incorporate parts of the Program into other free\r
+programs whose distribution conditions are different, write to the author\r
+to ask for permission.  For software which is copyrighted by the Free\r
+Software Foundation, write to the Free Software Foundation; we sometimes\r
+make exceptions for this.  Our decision will be guided by the two goals\r
+of preserving the free status of all derivatives of our free software and\r
+of promoting the sharing and reuse of software generally.\r
+\r
+                           NO WARRANTY\r
+\r
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\r
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\r
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\r
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\r
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\r
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\r
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\r
+REPAIR OR CORRECTION.\r
+\r
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\r
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\r
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\r
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\r
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\r
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\r
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\r
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\r
+POSSIBILITY OF SUCH DAMAGES.\r
+\r
+                    END OF TERMS AND CONDITIONS\r
+\f\r
+           How to Apply These Terms to Your New Programs\r
+\r
+  If you develop a new program, and you want it to be of the greatest\r
+possible use to the public, the best way to achieve this is to make it\r
+free software which everyone can redistribute and change under these terms.\r
+\r
+  To do so, attach the following notices to the program.  It is safest\r
+to attach them to the start of each source file to most effectively\r
+convey the exclusion of warranty; and each file should have at least\r
+the "copyright" line and a pointer to where the full notice is found.\r
+\r
+    <one line to give the program's name and a brief idea of what it does.>\r
+    Copyright (C) <year>  <name of author>\r
+\r
+    This program is free software; you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation; either version 2 of the License, or\r
+    (at your option) any later version.\r
+\r
+    This program is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+\r
+    You should have received a copy of the GNU General Public License\r
+    along with this program; if not, write to the Free Software\r
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+\r
+Also add information on how to contact you by electronic and paper mail.\r
+\r
+If the program is interactive, make it output a short notice like this\r
+when it starts in an interactive mode:\r
+\r
+    Gnomovision version 69, Copyright (C) year name of author\r
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\r
+    This is free software, and you are welcome to redistribute it\r
+    under certain conditions; type `show c' for details.\r
+\r
+The hypothetical commands `show w' and `show c' should show the appropriate\r
+parts of the General Public License.  Of course, the commands you use may\r
+be called something other than `show w' and `show c'; they could even be\r
+mouse-clicks or menu items--whatever suits your program.\r
+\r
+You should also get your employer (if you work as a programmer) or your\r
+school, if any, to sign a "copyright disclaimer" for the program, if\r
+necessary.  Here is a sample; alter the names:\r
+\r
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\r
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.\r
+\r
+  <signature of Ty Coon>, 1 April 1989\r
+  Ty Coon, President of Vice\r
+\r
+This General Public License does not permit incorporating your program into\r
+proprietary programs.  If your program is a subroutine library, you may\r
+consider it more useful to permit linking proprietary applications with the\r
+library.  If this is what you want to do, use the GNU Library General\r
+Public License instead of this License.\r
diff --git a/zchess.inf b/zchess.inf
new file mode 100644 (file)
index 0000000..0e7be5f
--- /dev/null
@@ -0,0 +1,872 @@
+! Z-Chess: two-player chess for the Z-machine\r
+! Copyright (C) 2002, 2003, 2004 Eric Schmidt\r
+\r
+! This program is free software; you can redistribute it and/or modify\r
+! it under the terms of the GNU General Public License as published by\r
+! the Free Software Foundation; either version 2 of the License, or\r
+! (at your option) any later version.\r
+\r
+! This program is distributed in the hope that it will be useful,\r
+! but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+! GNU General Public License for more details.\r
+! You should have received a copy of the GNU General Public License\r
+! along with this program; if not, write to the Free Software\r
+! Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+\r
+! The author may be contacted at <eschmidt@safeaccess.com>.\r
+\r
+Release 4;\r
+Serial "040124";\r
+\r
+! ---------------------------------------\r
+! Constants, Arrays, and Global Variables\r
+! ---------------------------------------\r
+\r
+Constant NULL = -1;\r
+\r
+! The screen size\r
+\r
+Global width; Global height;\r
+\r
+! The board position\r
+\r
+Global bleft; Global btop;\r
+\r
+! The board colors\r
+\r
+Global colorflag;\r
+Constant normal = 1;\r
+Constant black  = 2;\r
+Constant red    = 3;\r
+Constant cyan   = 8;\r
+Constant white  = 9;\r
+\r
+! Unicode\r
+\r
+Global unicode_support = false;\r
+\r
+! Code points for chess symbols\r
+\r
+Constant uni_wKing   = $2654;\r
+Constant uni_wQueen  = $2655;\r
+Constant uni_wRook   = $2656;\r
+Constant uni_wBishop = $2657;\r
+Constant uni_wKnight = $2658;\r
+Constant uni_wPawn   = $2659;\r
+Constant uni_bKing   = $265a;\r
+Constant uni_bQueen  = $265b;\r
+Constant uni_bRook   = $265c;\r
+Constant uni_bBishop = $265d;\r
+Constant uni_bKnight = $265e;\r
+Constant uni_bPawn   = $265f;\r
+\r
+! Reading from the keyboard\r
+\r
+Constant uKey     = $81;\r
+Constant dKey     = $82;\r
+Constant lKey     = $83;\r
+Constant rKey     = $84;\r
+Constant EnterKey = $0d;\r
+\r
+! The board caption system\r
+\r
+Global mrow;\r
+\r
+Constant whitemove =  0;\r
+Constant blackmove =  1;\r
+Constant promote   =  2;\r
+Constant illegal   =  3;\r
+Constant cillegal  =  4;\r
+Constant check     =  5;\r
+Constant checkmate =  6;\r
+Constant stalemate =  7;\r
+Constant lowpieces =  8;\r
+Constant saveyes   =  9;\r
+Constant loadyes   = 10;\r
+Constant saveno    = 11;\r
+Constant loadno    = 12;\r
+\r
+! Notice that all the messages the game displays are of even length.\r
+! This is deliberate. The window is likely to be of even width\r
+! and so only even-lengthed messages can be perfectly centered.\r
+\r
+Array mArray -->\r
+! message                    length\r
+  "White's turn to move"     20\r
+  "Black's turn to move"     20\r
+  "Type letter of piece"     20\r
+  "Illegal move"             12\r
+  "Illegal move - check"     20\r
+  "Check!"                   6\r
+  "Checkmate!"               10\r
+  "Stalemate!"               10\r
+  "Draw by too few pieces"   22\r
+  "Save succeeded"           14\r
+  "Load succeeded"           14\r
+  "Unable to save"           14\r
+  "Unable to load"           14;\r
+\r
+! Cursor location\r
+\r
+Global rank = 6; Global file = 0; ! This defaults to WQRP\r
+\r
+! Currently selected piece;\r
+\r
+Global mover = NULL;\r
+\r
+! The position\r
+\r
+Constant wPawn   = 1;\r
+Constant wKnight = 2;\r
+Constant wBishop = 3;\r
+Constant wRook   = 4;\r
+Constant wQueen  = 5;\r
+Constant wKing   = 6;\r
+\r
+Constant threshold = 7; ! If (a_piece < threshold), it is white.\r
+\r
+Constant bPawn   = 7;\r
+Constant bKnight = 8;\r
+Constant bBishop = 9;\r
+Constant bRook   = 10;\r
+Constant bQueen  = 11;\r
+Constant bKing   = 12;\r
+\r
+Array position ->\r
+  bRook   bKnight bBishop bQueen  bKing   bBishop bKnight bRook\r
+  bPawn   bPawn   bPawn   bPawn   bPawn   bPawn   bPawn   bPawn\r
+  nothing nothing nothing nothing nothing nothing nothing nothing\r
+  nothing nothing nothing nothing nothing nothing nothing nothing\r
+  nothing nothing nothing nothing nothing nothing nothing nothing\r
+  nothing nothing nothing nothing nothing nothing nothing nothing\r
+  wPawn   wPawn   wPawn   wPawn   wPawn   wPawn   wPawn   wPawn\r
+  wRook   wKnight wBishop wQueen  wKing   wBishop wKnight wRook;\r
+\r
+Array working_position -> 64;\r
+\r
+Global WhiteToMove = true;\r
+\r
+Constant e1 = 60;\r
+Constant e8 = 4;\r
+\r
+! For calculating check\r
+! We define "old" variables for backups\r
+\r
+Global wKingPos = e1; Global owKingPos;\r
+Global bKingPos = e8; Global obKingPos;\r
+\r
+! Castling\r
+\r
+Global just_castled;\r
+\r
+Global wking_moved;  Global owking_moved;\r
+Global bking_moved;  Global obking_moved;\r
+Global a1rook_moved; Global oa1rook_moved;\r
+Global h1rook_moved; Global oh1rook_moved;\r
+Global a8rook_moved; Global oa8rook_moved;\r
+Global h8rook_moved; Global oh8rook_moved;\r
+\r
+! The numbers of squares to do with castling\r
+! (It would be nice if Inform had octal numbers.)\r
+\r
+Constant a8 = 0;\r
+Constant a1 = 56;\r
+Constant h1 = 63;\r
+Constant h8 = 7;\r
+\r
+Constant f1 = 61;\r
+Constant g1 = 62;\r
+Constant d1 = 59;\r
+Constant c1 = 58;\r
+\r
+Constant f8 = 5;\r
+Constant g8 = 6;\r
+Constant d8 = 3;\r
+Constant c8 = 2;\r
+\r
+! En passant\r
+\r
+Global epPawn = NULL; Global oepPawn = NULL;\r
+\r
+! The current game status\r
+\r
+Global GameOver;\r
+\r
+! ------------\r
+! The Routines\r
+! ------------\r
+\r
+! The main routine: set game up and receive input\r
+\r
+[ Main input square piece i j;\r
+\r
+  ! Check for large enough screen\r
+\r
+  height = 0->$20;\r
+  width = 0->$21;\r
+  if (width < 22)  "Regretably, this interpreter has not provided a\r
+                    wide enough window for this program.";\r
+  if (height < 10) "Regretably, this interpreter has not provided a\r
+                    tall enough window for this program.";\r
+\r
+  ! Check for color. If the fixed-pitch font bit is set in the header, we got\r
+  ! here from a restart and shouldn't warn about the color.\r
+\r
+  if (0->1 & 1) colorflag = true;\r
+  else if (0-->$8 & $$10) font on;            ! Turn bit back off\r
+  else {\r
+    print "WARNING: This interpreter has not provided color.\r
+           The game may not perform optimally.^";\r
+    @read_char 1 -> input;\r
+  }\r
+\r
+  ! Locate board\r
+\r
+  bleft = (width - 16) / 2 + 1;\r
+  btop  = (height - 10) / 2 + 2;\r
+  if (height % 2) btop++;           ! Favor lower row\r
+  mrow  = btop + 8;\r
+\r
+  CheckUnicode();\r
+\r
+  CompleteRedraw();\r
+\r
+  ! Main gain loop\r
+\r
+  while (1) {\r
+    ! Set cursor position\r
+\r
+    i = btop + rank;\r
+    j = file * 2 + bleft;\r
+    @set_cursor i j;\r
+\r
+    ! Receive input\r
+\r
+    @read_char 1 -> input;\r
+    switch (input) {\r
+      'c', 'C':\r
+        @erase_window -1;\r
+        print "^^Release 1 - Initial release^^\r
+               Release 2\r
+               ^  * Added color support\r
+               ^  * Fixed two castling bugs^^\r
+               Release 3\r
+               ^  * Unicode support\r
+               ^  * Changed license to GPL^^\r
+               Release 4\r
+               ^  * Added ability to save and restore game";\r
+          @read_char 1 -> input;\r
+          CompleteRedraw();\r
+\r
+      'd', 'D':\r
+        @erase_window -1;\r
+        print "Use the arrow keys to move the cursor around.\r
+               Press space bar (or enter) to select a piece. \r
+               Move the cursor to the square you want to move the\r
+               piece, and press space bar (or enter) again to move.\r
+               To castle, move the king to its destination, and the\r
+               rook will automatically move to its. To deselect the \r
+               piece you've selected, press space bar when the cursor\r
+               is on the piece.^^\r
+               White pieces are indicated by the letter W and black pieces by\r
+               B. If supported by your system, the piece type will be shown as\r
+               a chess figurine. If not, a letter is used. This is the first\r
+               letter of the piece's name, except that a knight is represented\r
+               by N.^^\r
+               When a pawn promotion occurs, you must specify which type of\r
+               piece to promote it to. Do this by typing the letter of the\r
+               piece you want to promote it to.^^\r
+               At the main display, you can type D to view these directions,\r
+               I to view legal information, C to view major changes between\r
+               versions, Q to quit, N to start a new game, S to save a game,\r
+               or L to load a game from disk.^^\r
+               The author may be contacted at <eschmidt@@64safeaccess.com>.";\r
+        @read_char 1 -> input;\r
+        CompleteRedraw();\r
+\r
+      'i', 'I':\r
+        @erase_window -1;\r
+        print "Z-Chess: Chess for the Z-Machine^\r
+               Copyright (C) 2002, 2003, 2004 Eric Schmidt^^\r
+               This program is free software. It may be distributed\r
+               under the terms of the GNU General Public License\r
+               version 2, or (at your option) any later version.^^\r
+               This program is distributed in the hope that it will be\r
+               useful, but WITHOUT ANY WARRANTY; without even the implied\r
+               warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\r
+               See the GNU General Public License for more details. You should\r
+               have received a copy of the GNU General Public License along\r
+               with this program; if not, write to the Free Software\r
+               Foundation, Inc., 59 Temple Place, Suite 330, Boston,\r
+               MA 02111-1307 USA"; \r
+        @read_char 1 -> input;\r
+        CompleteRedraw();\r
+\r
+      'l', 'L':\r
+        @erase_window -1;\r
+        @restore -> i;\r
+        CompleteRedraw();\r
+        Message(loadno);          ! Load failed if we get here\r
+\r
+      'n', 'N':\r
+         font off;                ! Hack: We use the fixed-pitch font bit to\r
+         @restart;                ! signal that a restart is taking place\r
+\r
+      'q', 'Q':\r
+        @set_cursor height 1;\r
+        @erase_line 1;\r
+        quit;\r
+\r
+      'r', 'R':\r
+        @erase_window -1;\r
+        @restore -> i;\r
+        CompleteRedraw();\r
+        Message(loadno);         ! Cannot reach here if succeeded\r
+\r
+      's', 'S':\r
+        @erase_window -1;\r
+        @save -> i;\r
+        CompleteRedraw();  \r
+        switch (i) {\r
+          0: Message(saveno);\r
+          1: Message(saveyes);\r
+          2: Message(loadyes);\r
+        }\r
\r
+      uKey: if (rank > 0) { rank--; PrintCaption(); }\r
+      dKey: if (rank < 7) { rank++; PrintCaption(); }\r
+      lKey: if (file > 0) { file--; PrintCaption(); }\r
+      rKey: if (file < 7) { file++; PrintCaption(); }\r
+      EnterKey, ' ':\r
+        if (GameOver) break;\r
+        square = rank * 8 + file;\r
+        piece = position->square;\r
+        if (mover == NULL && piece\r
+          && WhiteToMove == (piece < threshold)) mover = square;\r
+        else if (mover == square) mover = NULL;\r
+        else if (mover ~= NULL) {\r
+          if (~~AttemptToMove(mover,square)) PrintCaption();\r
+          mover = NULL;\r
+        }\r
+        PrintPos();\r
+    }\r
+  }\r
+];\r
+\r
+[ CheckUnicode i;\r
+  ! Pre 1.0 terps won't allow @check_unicode\r
+  if (~~(0->$32)) return;\r
+\r
+  @split_window height;\r
+  @set_window 1;\r
+\r
+  ! Would there be support for one chess glyph but not the\r
+  ! others? Well, we might as well be on the safe side.\r
+  @"EXT:12S" uni_wKing   -> i; if (~~(i & 1)) return;\r
+  @"EXT:12S" uni_wQueen  -> i; if (~~(i & 1)) return;\r
+  @"EXT:12S" uni_wRook   -> i; if (~~(i & 1)) return;\r
+  @"EXT:12S" uni_wBishop -> i; if (~~(i & 1)) return;\r
+  @"EXT:12S" uni_wKnight -> i; if (~~(i & 1)) return;\r
+  @"EXT:12S" uni_wPawn   -> i; if (~~(i & 1)) return;\r
+  @"EXT:12S" uni_bKing   -> i; if (~~(i & 1)) return;\r
+  @"EXT:12S" uni_bQueen  -> i; if (~~(i & 1)) return;\r
+  @"EXT:12S" uni_bRook   -> i; if (~~(i & 1)) return;\r
+  @"EXT:12S" uni_bBishop -> i; if (~~(i & 1)) return;\r
+  @"EXT:12S" uni_bKnight -> i; if (~~(i & 1)) return;\r
+  @"EXT:12S" uni_bPawn   -> i; if (~~(i & 1)) return;\r
+\r
+  ! The interpreter has passed the sieve.\r
+  unicode_support = true;\r
+];\r
+\r
+[ CompleteRedraw;\r
+  @split_window height;\r
+  @set_window 1;\r
+  @erase_window -2;\r
+  style reverse;                                  \r
+  print "(D)irections"; spaces width - 18; print "(I)nfo";\r
+  style roman;\r
+\r
+  PrintPos();\r
+  PrintCaption();\r
+];\r
+\r
+! Routine to print the position\r
+\r
+[ PrintPos i;\r
+  @set_cursor btop bleft;\r
+\r
+  for (: i < 64: i++) {\r
+    \r
+    ! Set printing colors, considering color support\r
+\r
+    if (colorflag) {\r
+      if (i / 8 % 2 == i % 2) @push cyan; else @push red;\r
+      if (position->i < threshold) @push white; else @push black;\r
+      @set_colour sp sp;\r
+    }\r
+    else\r
+      if (i / 8 % 2 == i % 2) style roman; else style reverse;\r
\r
+    ! Print the piece symbol\r
+\r
+    ! Could look weird if system does not support color or both reverse and\r
+    ! bold type\r
+    if (i == mover) style bold;\r
+\r
+    if (~~position->i) print (char) ' ';\r
+    else if (position->i < threshold) print (char) 'W';\r
+    else print (char) 'B';\r
+\r
+    if (unicode_support) {\r
+      switch (position->i) {\r
+        nothing: print (char) ' ';\r
+        wPawn:   @"EXT:11" uni_wPawn;\r
+        wKnight: @"EXT:11" uni_wKnight;\r
+        wBishop: @"EXT:11" uni_wBishop;\r
+        wRook:   @"EXT:11" uni_wRook;\r
+        wQueen:  @"EXT:11" uni_wQueen;\r
+        wKing:   @"EXT:11" uni_wKing;\r
+        bPawn:   @"EXT:11" uni_bPawn;\r
+        bKnight: @"EXT:11" uni_bKnight;\r
+        bBishop: @"EXT:11" uni_bBishop;\r
+        bRook:   @"EXT:11" uni_bRook;\r
+        bQueen:  @"EXT:11" uni_bQueen;\r
+        bKing:   @"EXT:11" uni_bKing;\r
+      }\r
+    } else {\r
+      switch (position->i) {\r
+        nothing: print (char) ' ';\r
+        wPawn, bPawn:     print (char) 'P';\r
+        wKnight, bKnight: print (char) 'N';\r
+        wBishop, bBishop: print (char) 'B';\r
+        wRook, bRook:     print (char) 'R';\r
+        wQueen, bQueen:   print (char) 'Q';\r
+        wKing, bKing:     print (char) 'K';\r
+      }\r
+    if (i == mover) style roman;\r
+    }\r
+\r
+    ! If at the end of a row, move to the next line\r
+\r
+    if (i % 8 == 7) {\r
+      style roman;\r
+      @set_colour normal normal;\r
+      if (i < 63) {\r
+        new_line;\r
+        spaces bleft - 1;\r
+      }\r
+    }\r
+  }\r
+];\r
+\r
+! The board caption\r
+\r
+[ PrintCaption;\r
+    if (GameOver) Message(GameOver);\r
+    else {\r
+      if (WhiteToMove) Message(whitemove);\r
+      else Message(blackmove);\r
+    }\r
+];\r
+\r
+! AttemptToMove evaluates the move and makes it if legal\r
+! It returns true if it prints a message, false if not\r
+\r
+[ AttemptToMove start end;\r
+\r
+  ! First, the basic test\r
+\r
+  if (~~MovePrimitive(start, end, position)) {\r
+    Message(illegal); return;\r
+  }\r
+    \r
+  ! Make the move\r
+\r
+  TransferPos(position, working_position);\r
+  DoMove(start, end, working_position);\r
+\r
+  ! If the move is illegal due to check, restore the old game status\r
+\r
+  if (InCheck(working_position)) {\r
+    TransferVarsToNew();\r
+    Message(cillegal);\r
+    return;\r
+  }\r
+\r
+  ! Do promotion if needed\r
+\r
+  if ((end <= h8 || end >= a1) && working_position->end == wPawn or bPawn)\r
+    Promotion(end);\r
+\r
+  ! Update the board\r
+\r
+  TransferPos(working_position, position);\r
+  TransferVarsToOld();\r
+  WhiteToMove = ~~WhiteToMove;\r
+\r
+  ! Finally, evaulate for a draw, win, or check\r
+\r
+  if (HasntLegal()) rfalse;\r
+  if (InCheck(position)) return Message(check);\r
+  rfalse;\r
+];\r
+\r
+! Moving data around\r
+\r
+[ TransferPos p_array1 p_array2 i;\r
+  for (: i < 64: i++) p_array2->i = p_array1->i;\r
+];\r
+\r
+[ TransferVarsToNew;\r
+  wKingPos     = owKingPos;\r
+  bKingPos     = obKingPos;\r
+  wking_moved  = owking_moved;\r
+  bking_moved  = obking_moved;\r
+  a1rook_moved = oa1rook_moved;\r
+  h1rook_moved = oh1rook_moved;\r
+  a8rook_moved = oa8rook_moved;\r
+  h8rook_moved = oh8rook_moved;\r
+  epPawn       = oepPawn;\r
+];\r
+\r
+[ TransferVarsToOld;\r
+  owKingPos     = wKingPos;\r
+  obKingPos     = bKingPos;\r
+  owking_moved  = wking_moved;\r
+  obking_moved  = bking_moved;\r
+  oa1rook_moved = a1rook_moved;\r
+  oh1rook_moved = h1rook_moved;\r
+  oa8rook_moved = a8rook_moved;\r
+  oh8rook_moved = h8rook_moved;\r
+  oepPawn       = epPawn;\r
+];\r
+\r
+! MovePrimitive tests if a move is legal, but doesn't\r
+! consider check. Returns true if the move seems legal,\r
+! false if it seems illegal.\r
+\r
+[ MovePrimitive start end p_array side otherside\r
+                srank sfile erank efile a b c d;\r
+\r
+  ! Find the sides of the pieces on the starting\r
+  ! and ending squares\r
+\r
+  side = p_array->start < threshold;\r
+  if (p_array->end == nothing) otherside = NULL;\r
+    else otherside = (p_array->end < threshold);\r
+\r
+  ! If they are the same, stop now\r
+\r
+  if (side == otherside) rfalse;\r
+\r
+  ! Locate the pieces on the board\r
+\r
+  srank = start / 8;\r
+  sfile = start % 8;\r
+  erank = end / 8;\r
+  efile = end % 8;\r
+\r
+  ! Now, the actual evaluation\r
+\r
+  switch (p_array->start) {\r
+    wPawn, bPawn:\r
+      \r
+      ! For pawns, the rules are different for each side\r
+      ! so test and set key numbers appropriately.\r
+      \r
+      if (side) {\r
+        a = 1; b = 6; c = 4; d = 8;\r
+      }\r
+      else {\r
+        a = -1; b = 1; c = 3; d = -8;\r
+      }\r
+      \r
+      if (srank - erank == a) {\r
+      \r
+        ! Standard move?\r
+      \r
+        if (sfile == efile && otherside == NULL) rtrue;\r
+       \r
+        ! Capture?\r
\r
+        if (sfile - efile == -1 or 1 &&\r
+           (otherside ~= NULL || eppawn == end+d)) rtrue;\r
+      }\r
+      \r
+      ! Two square move?\r
+\r
+      if (srank == b && erank == c && sfile == efile && (~~p_array->(start-d))\r
+          && otherside == NULL) rtrue;\r
+    \r
+    ! The knights, bishops, rooks, queens, and kings\r
+\r
+    wKnight, bKnight:\r
+      if ((srank - erank == 1 or -1 && sfile - efile == 2 or -2) ||\r
+          (srank - erank == 2 or -2 && sfile - efile == 1 or -1)) rtrue;\r
+    wBishop, bBishop:\r
+      return DiagonalMove(srank, sfile, erank, efile, p_array);\r
+    wRook, bRook:\r
+      return StraightMove(srank, sfile, erank, efile, p_array);\r
+    wQueen, bQueen:\r
+      return DiagonalMove(srank, sfile, erank, efile, p_array)\r
+          || StraightMove(srank, sfile, erank, efile, p_array);\r
+    wKing, bKing:\r
+     if (srank - erank < 2 && erank - srank < 2\r
+      && sfile - efile < 2 && efile - sfile < 2) rtrue;\r
+  }\r
+\r
+  ! Castling?\r
+\r
+  if (p_array->start == wKing && ~~wking_moved) {\r
+      if (end == g1 && ~~h1rook_moved)\r
+        return StraightMove(7, 4, 7, 7, p_array);\r
+      if (end == c1 && ~~a1rook_moved)\r
+        return StraightMove(7, 4, 7, 0, p_array);\r
+  }\r
+  if (p_array->start == bKing && ~~bking_moved) {\r
+      if (end == g8 && ~~h8rook_moved)\r
+        return StraightMove(0, 4, 0, 7, p_array);\r
+      if (end == c8 && ~~a8rook_moved)\r
+        return StraightMove(0, 4, 0, 0, p_array);\r
+  }\r
+  rfalse;\r
+];\r
+\r
+! DiagonalMove tests if a diagonal move is valid.\r
+! That is, that the squares are diagonal from each other\r
+! and nothing is in the way. Returns true if valid, false if not.\r
+\r
+[ DiagonalMove srank sfile erank efile p_array i j;\r
+\r
+  ! Make sure squares are diagonal from each other\r
+\r
+  if (srank - erank ~= sfile - efile or efile - sfile) rfalse;\r
+\r
+  ! Before testing for obstacles, find the direction of the move\r
+\r
+  if (srank < erank) i = 1; else i = -1;\r
+  if (sfile < efile) j = 1; else j = -1;\r
+\r
+  ! Now test for obstacles\r
+\r
+  for (::) {\r
+    srank = srank + i; sfile = sfile + j;\r
+    if (srank == erank) break;\r
+    if (p_array->(srank * 8 + sfile)) rfalse;\r
+  }\r
+];\r
+\r
+! StraightMove is similar to DiagonalMove\r
+\r
+[ StraightMove srank sfile erank efile p_array i;\r
+  if (srank ~= erank && sfile ~= efile) rfalse;\r
+  if (srank == erank) {\r
+    if (sfile < efile) i = 1; else i = -1;\r
+    for (::) {\r
+      sfile = sfile + i;\r
+      if (sfile == efile) break;\r
+      if (p_array->(srank * 8 + sfile)) rfalse;\r
+    }\r
+  }\r
+  else {\r
+    if (srank < erank) i = 1; else i = -1;\r
+    for (::) {\r
+      srank = srank + i;\r
+      if (srank == erank) break;\r
+      if (p_array->(srank * 8 + sfile)) rfalse;\r
+    }\r
+  }\r
+];\r
+\r
+! DoMove actually performs the move, taking special note of\r
+! castling and en passant.\r
+\r
+[ DoMove start end p_array;\r
+\r
+  ! If en passant, remove the pawn being taken\r
+\r
+  if (p_array->end == nothing && (start - end) % 8 &&\r
+       p_array->start == wPawn or bPawn)\r
+          p_array->(epPawn) = nothing;\r
+  \r
+  ! If a pawn is being moved 2 squares, store it in epPawn\r
+  ! If not, we clear it\r
+\r
+  epPawn = NULL;\r
+  \r
+  if (p_array->start == wPawn or bPawn && start - end == 16 or -16)\r
+    epPawn = end;\r
+  \r
+  ! Set movement variables if necessary\r
+\r
+       if (start == a1) a1rook_moved = true;\r
+  else if (start == h1) h1rook_moved = true;\r
+  else if (start == a8) a8rook_moved = true;\r
+  else if (start == h8) h8rook_moved = true;\r
+  else if (start == e1) wKing_moved  = true;\r
+  else if (start == e8) bKing_moved  = true;\r
+\r
+  ! The move\r
+\r
+  p_array->end = p_array->start;\r
+  p_array->start = nothing;\r
+  \r
+  ! Set variable if a king moved\r
+\r
+  if (p_array->end == wKing) wKingPos = end;\r
+  else if (p_array->end == bKing) bKingPos = end;\r
+\r
+  ! If castling, move the rooks also, and set just_castled\r
+\r
+  just_castled = false;\r
+  if (p_array->end == wKing && start == e1) {\r
+     if      (end == g1) {DoMove(h1, f1, p_array); just_castled = true;}\r
+     else if (end == c1) {DoMove(a1, d1, p_array); just_castled = true;}\r
+  }\r
+  else if (p_array->end == bKing && start == e8) {\r
+    if      (end == g8) {DoMove(h8, f8, p_array); just_castled = true;}\r
+    else if (end == c8) {DoMove(a8, d8, p_array); just_castled = true;}\r
+  }\r
+];\r
+     \r
+! Promotion finds from the player the piece to promote to and executes\r
+! the promotion.\r
+\r
+[ Promotion pawn input a i;\r
+  if (working_position->pawn == bPawn) a = 6;\r
+  message(promote);\r
+  i = (width - 20) / 2 + 21;\r
+  @set_cursor mrow i;\r
+\r
+  while (1) {\r
+    @read_char 1 -> input;\r
+    switch (input) {\r
+      'q', 'Q': working_position->pawn = wQueen  + a; return;\r
+      'n', 'N': working_position->pawn = wKnight + a; return;\r
+      'b', 'B': working_position->pawn = wBishop + a; return;\r
+      'r', 'R': working_position->pawn = wRook   + a; return;\r
+    }\r
+  }\r
+];\r
+\r
+! InCheck tests if the current side to move is in check.\r
+! Returns true if in check, false if not.\r
+\r
+[ InCheck p_array king kstart kmiddle i s_ep;  \r
+\r
+  ! First, find the king\r
+\r
+  if (WhiteToMove) king = wKingPos; else king = bKingPos;\r
+\r
+  ! If castling, check the starting and middle squares too.\r
+\r
+  if (just_castled) {\r
+    if      (king == g1) { kstart = e1;  kmiddle = f1; }\r
+    else if (king == c1) { kstart = e1;  kmiddle = d1; }\r
+    else if (king == g8) { kstart = e8;  kmiddle = f8; }\r
+    else if (king == c8) { kstart = e8;  kmiddle = d8; }\r
+  }\r
+\r
+  if (kstart) {\r
+    s_ep = epPawn;              ! DoMove wrecks epPawn. Save a backup.\r
+    DoMove(king, kstart, p_array);\r
+    if (InCheck(p_array)) i = true;\r
+    DoMove(kstart, kmiddle, p_array);\r
+    if (InCheck(p_array)) i = true;\r
+    DoMove(kmiddle, king, p_array);\r
+    if (WhiteToMove) p_array->kmiddle = wRook;\r
+    else p_array->kmiddle = bRook;\r
+    epPawn = s_ep;\r
+    if (i) rtrue;\r
+  }\r
+\r
+  ! Now, find all enemy pieces, and use MovePrimitive\r
+  ! to see if they can take the king\r
+\r
+  if (WhiteToMove)\r
+    for (: i < 64: i++) {\r
+      if (p_array->i < threshold) continue;\r
+      if (MovePrimitive(i, king, p_array)) rtrue;\r
+    }\r
+  else\r
+    for (: i < 64: i++) {\r
+      if (p_array->i == nothing) continue;\r
+      if (p_array->i < threshold\r
+          && MovePrimitive(i, king, p_array)) rtrue;\r
+  }\r
+  rfalse;\r
+];\r
+\r
+! HasntLegal tests if the game is over due to checkmate, stalemate,\r
+! or insufficiant material to mate, and sets gameover accordingly.\r
+\r
+[ HasntLegal i j k knight lbishop dbishop;\r
+\r
+  ! Try to find a legal move for side to move with MovePrimitive, DoMove, and InCheck.\r
+\r
+  if (WhiteToMove)\r
+    for (: i < 64: i++) {\r
+      if (position->i == nothing ||\r
+          position->i >= threshold) continue;\r
+      for (j = 0: j < 64: j++) {\r
+        if (MovePrimitive(i, j, position) && DoMove(i, j, position)\r
+            && (~~InCheck(position))) k = true;\r
+        TransferPos(working_position, position);\r
+        TransferVarsToNew();\r
+        if (k) jump out;\r
+      }\r
+    }\r
+  else\r
+    for (: i < 64: i++) {\r
+      if (position->i < threshold) continue;\r
+      for (j = 0: j < 64: j++) {\r
+        if (MovePrimitive(i, j, position) && DoMove(i, j, position)\r
+            && (~~InCheck(position))) k = true;\r
+        TransferPos(working_position, position);\r
+        TransferVarsToNew();\r
+        if (k) jump out;\r
+      }\r
+    }\r
+\r
+  .out;\r
+\r
+  ! If i is 64, the entire loop found no legal move\r
+\r
+  if (i == 64) {\r
+    if (InCheck(position)) gameover = checkmate;\r
+      else gameover = stalemate;\r
+    rtrue;\r
+  }\r
+\r
+  ! The final task is to check for low pieces. Anything other than\r
+  ! a minor piece or king means no draw. Two minor pieces\r
+  ! mean no draw, unless they are two bishops found on the same\r
+  ! color square. The same is true of any number of bishops\r
+  ! of the same color square.\r
+\r
+  for (i = 0: i < 64: i++)\r
+    switch (position->i) {\r
+      wPawn, bPawn, wRook, bRook, wQueen, bQueen: rfalse;\r
+      wKnight, bKnight:\r
+        if (knight || lbishop || dbishop) rfalse;\r
+        knight = true;\r
+      wBishop, bBishop:\r
+        if (i / 8 % 2 == i % 2) lbishop = true;\r
+        else dbishop = true;\r
+        if (knight || (lbishop && dbishop)) rfalse;\r
+    }\r
+  gameover = lowpieces;\r
+]; \r
+\r
+! A routine to center all the messages neatly under the board\r
+\r
+[ Message num start;\r
+  num = num * 2;\r
+  start = (width - mArray-->(num+1)) / 2;\r
+  @set_cursor mrow 1;\r
+  spaces start;\r
+  print (string) mArray-->num;\r
+  spaces start;\r
+];\r