include chess; // Restricting user input setsystem maxmove 4; ban commands; allow moves 1 captures 1 promotions 2 moves 2 moves 3 promotions 3 promotions 4; // These two subroutines are for actual Pawn moves. They are unsuitable for evaluating // possible Pawn moves, because they exit the whole program with an error message on // finding an illegal move, and they concern themselves with promotion, which does not // affect the legality of a possible move. Unlike the default functions in chess.txt, // these allow double moves only the second move and captures only on the first. sub P from to; local ydir; if == file #from file #to and not capture: set legal checkaleap #from #to 0 1; if var legal: set ep false; else; set legal checkatwostep #from #to 0 1 0 1 and == rankname #from 2 and not #firstpart; set ep #to; endif; set epc false; elseif and #firstpart or capture #ep: set legal checkaleap #from #to -1 1 or checkaleap #from #to 1 1; set epc false; if not capture and var legal: set legal == #ep where #to 0 -1; if var legal: capture #ep; set epc #ep; endif; endif; set ep false; endif; if != space #to moved and onboard where #to 0 1: die "You may not promote a Pawn that can still move forward."; endif; if not onboard where #to 0 1: if == P space #to: die "You must promote a Pawn when it can no longer move forward."; elseif not match space #to var wprom: set np space #to; die "You may not promote your Pawn to a" #np; endif; endif; endsub; sub p from to; if == file #from file #to and not capture: set legal checkaleap #from #to 0 -1; if var legal: set ep false; else: set legal checkatwostep #from #to 0 -1 0 -1 and == rankname #from 7 and not #firstpart; set ep #to; endif; set epc false; elseif and #firstpart or capture #ep: set legal checkaleap #from #to -1 -1 or checkaleap #from #to 1 -1; set epc false; if not capture and var legal: set legal == #ep where #to 0 1; if var legal: capture #ep; set epc #ep; endif; endif; set ep false; endif; if != space #to moved and onboard where #to 0 -1: die You may not promote a Pawn that can still move forward.; endif; if not onboard where #to 0 1: if == p space #to: die You must promote a Pawn when it can no longer move forward.; elseif not match space #to var bprom: set np space #to; die You may not promote your Pawn to a #np; endif; endif; endsub; // The following subroutine creates an associative array of all checking pieces. // It presumes that functions have been created for checking the movement of each piece, // and that each function bears the capitalized piece label as its name. // For efficiency's sake, there are separate subroutines for white and black. // Finds checks against a player's King. Used only after a player moves. // Assumes prior legal play and checks only for a check from the last two pieces // moved by the opponent and for revealed checks. sub checks king; if not dest: return false; endif; my checks c; set checks (); if fn space #dest1 #dest1 #king and #dest1: setelem checks #dest1 space dest; endif; set c sub checkedthru #king #o1; if #c: setelem checks #c space #c; endif; if fn space #dest2 #dest2 #king and #dest2: setelem checks #dest2 space #dest2; endif; set c sub checkedthru #king #o2; if #c: setelem checks #c space #c; endif; if #epc: set c sub checkedthru #king #epc; if #c: setelem checks #c space #c; endif; endif; return var checks; endsub;