This preset now uses the new code for identifying check, checkmate, and stalemate. Let me know of any problems with it.

1

BANNED INPUT: b2-b4; b1-c3; a1-b1;c1-b2; d1-c1; e1-d1 on turn 1:

MOVE: b1-c3 and other moves from one space to another are banned here.

Go back and try again.

What is otherwise valid user input in Game Courier can be banned in a GAME Code program for the sake of better enforcing the rules. See "Restricting User Input" in the Game Courier Developer's Guide for details on how this is done.

If you believe that your input should not have been banned, contact Fergus Duniho or whoever programmed the rules for this game.

Edit Settings File
   0 echo This preset now uses the new code for identifying check, checkmate, and stalemate. Let me know of any problems with it.
   1 setflag a1 a8 h1 h8 e1 e8
   2 set k e8
   3 set K e1
   4 set ep false
   5 include chess
   6 sub postauto1
   7   if isupper old
   8     die You may not capture your own pieces.
   9   endif
  10   if not equal moved P
  11     set ep false
  12     if unequal space dest moved
  13       die You may not change the type of this piece.
  14     endif
  15   endif
  16   set legal false
  17   if match moved P K
  18     gosub moved origin dest
  19     if equal moved K
  20       set K dest
  21     endif
  22   elseif match moved Q R B N
  23     set legal fn moved origin dest
  24     if equal moved R
  25       unsetflag origin
  26     endif
  27   endif
  28   if not var legal
  29     die You may not move a moved from origin to dest
  30   endif
  31   if fn ATTACKEDBYB #K
  32     die You may not move into check.
  33   endif
  34 endsub
  35 sub postauto2
  36   if islower old
  37     die You may not capture your own pieces.
  38   endif
  39   if not equal moved p
  40     set ep false
  41     if unequal space dest moved
  42       die You may not change the type of this piece.
  43     endif
  44   endif
  45   set legal false
  46   if match moved p k
  47     gosub moved origin dest
  48     if equal moved k
  49       set k dest
  50     endif
  51   elseif match moved q r b n
  52     set legal fn toupper moved origin dest
  53     if equal moved r
  54       unsetflag origin
  55     endif
  56   endif
  57   if not var legal
  58     die You may not move a moved from origin to dest
  59   endif
  60   if fn ATTACKEDBYW #k
  61     die You may not move into check.
  62   endif
  63 endsub
  64 moveindex 1
  65 MOVE: b2-b4
  66 MOVE:  b1-c3
  67 MOVE:  a1-b1
  68 MOVE: c1-b2
  69 MOVE:  d1-c1
  70 MOVE:  e1-d1
  71 postauto1
  72 moveindex 2
  73 MOVE: d7-d5
  74 MOVE:  e7-e5
  75 MOVE:  f7-f5
  76 MOVE:  g8-f6
  77 MOVE:  b8-c6
  78 MOVE:  f8-d6
  79 MOVE:  c8-e6
  80 MOVE:  e8-g8
  81 MOVE:  h8-f8
  82 MOVE:  d8-e7
  83 MOVE:  a8-d8
  84 postauto2
  85 moveindex 3
  86 MOVE: b4-b5
  87 MOVE: a2-a3
  88 MOVE: e2-e3
  89 MOVE:  h2-h3
  90 MOVE:  g2-g3
  91 postauto1
  92 moveindex 4
  93 MOVE: c6-a5
  94 MOVE:  e5-e4
  95 MOVE:  d6-e5
  96 MOVE:  d8-d7
  97 MOVE:  f8-d8
  98 MOVE:  f6-e8
  99 MOVE:  e7-f6
 100 MOVE:  c7-c6
 101 MOVE:  e6-f7
 102 postauto2
 103 moveindex 5
 104 MOVE: a3-a4
 105 postauto1
 106 moveindex 6
 107 MOVE: c6-c5
 108 MOVE:  d5-d4
 109 MOVE:  b7-b6
 110 MOVE:  e8-d6
 111 MOVE:  f7-c4
 112 postauto2
 113 moveindex 7
 114 MOVE: f1-c4
 115 MOVE:  h1-h2
 116 postauto1
 117 moveindex 8
 118 MOVE: d4-c3
 119 MOVE:  a5-c4
 120 postauto2
 121 moveindex 9
 122 MOVE: d1-e1
 123 MOVE:  h3-h4
 124 MOVE:  d2-c3
 125 MOVE:  b2-a1
 126 postauto1
 127 moveindex 10
 128 MOVE: e5-c3
 129 MOVE:  c4-b2
 130 MOVE:  d6-c4
 131 MOVE:  d7-d1
 132 MOVE:  d8-d2
 133 MOVE:  f6-d6
 134 postauto2
 135 moveindex 11
 136 MOVE: c1-d2
 137 MOVE:  b1-d1
 138 MOVE: a1-b2
 139 MOVE:  g1-e2
 140 MOVE:  h4-h5
 141 MOVE: h2-h4
 142 postauto1
 143 moveindex 12
 144 MOVE: c3-d2
 145 postauto2
 146 moveindex 13
 147 MOVE: e1-f1
 148 MOVE: h4-f4
 149 MOVE:  b2-a1
 150 postauto1
 151 moveindex 14
 152 MOVE: d2-b4
 153 MOVE:  d6-d1
 154 MOVE:  c4-d2
 155 MOVE:  g7-g6
 156 postauto2
 157 set checks sub checks #K
 158 if var checks
 159   if sub checkmated #K #checks
 160     say Checkmate! Black has won!
 161     won
 162   else
 163     say Check!
 164   endif
 165 elseif sub stalemated #K
 166   say Stalemate! The game is drawn.
 167   drawn
 168 endif
 169 end
 170 
 171 lib chess
 172 set wpr 2
 173 set bpr 7
 174 set fps 2
 175 set pzs 1
 176 set wcastle c1 g1
 177 set bcastle c8 g8
 178 do
 179   local x
 180   for x piecekeys
 181     if match #x P K p k
 182       continue
 183     elseif isupper #x
 184       push wprom #x
 185     elseif islower #x
 186       push bprom #x
 187     endif
 188   next
 189 loop never
 190 setsystem maxmove 2
 191 ban commands allmoves
 192 allow moves 1 captures 1 promotions 2
 193 def N checkleap #0 #1 1 2
 194 def B checkride #0 #1 1 1
 195 def R checkride #0 #1 1 0
 196 def Q fn B #0 #1 or fn R #0 #1
 197 def K checkleap #0 #1 1 1 or checkleap #0 #1 1 0
 198 def M fn N #0 #1 or fn R #0 #1
 199 def A fn N #0 #1 or fn B #0 #1
 200 def n checkleap #0 #1 1 2
 201 def b checkride #0 #1 1 1
 202 def r checkride #0 #1 1 0
 203 def q fn b #0 #1 or fn r #0 #1
 204 def k checkleap #0 #1 1 1 or checkleap #0 #1 1 0
 205 def m fn n #0 #1 or fn r #0 #1
 206 def a fn n #0 #1 or fn b #0 #1
 207 def P
remove var ep
and checkleap #0 #1 1 1
and == var ep join filename #1 rankname #0
or and checkride #0 #1 0 1 == rankname #0 var wpr
or checkleap #0 #1 0 1
and empty #1
or and islower space #1 checkleap #0 #1 1 1
and <= distance #0 #1 var fps
and > rank #1 rank #0
 208 def p
remove var ep
and checkleap #0 #1 1 1
and == var ep join filename #1 rankname #0
or and checkride #0 #1 0 1 == rankname #0 var bpr
or checkleap #0 #1 0 1
and empty #1
or and isupper space #1 checkleap #0 #1 1 1
and <= distance #0 #1 var fps
and < rank #1 rank #0
 209 sub capturep p
 210   empty #p
 211   return true
 212 endsub
 213 sub checks king
 214   if not dest
 215     return false
 216   endif
 217   my checks c
 218   set checks ()
 219   if fn space dest dest #king
 220     setelem checks dest space dest
 221   endif
 222   set c sub checkedthru #king origin
 223   if #c
 224     setelem checks #c space #c
 225   elseif #epc
 226     set c sub checkedthru #king #epc
 227     if #c
 228       setelem checks #c space #c
 229     endif
 230   endif
 231   return var checks
 232 endsub
 233 sub checkmated king checks
 234   local from piece to key legalmove piece nopawn
 235   store
 236   if isupper space #king
 237     def friends onlyupper
 238     def friend isupper #0
 239     set attacked ATTACKEDBYB
 240   else
 241     def friends onlylower
 242     def friend islower #0
 243     set attacked ATTACKEDBYW
 244   endif
 245   set kingmoves fn KL #king
 246   for to #kingmoves
 247     if not fn friend space #to and onboard #to
 248       move #king #to
 249       set incheck fn var attacked #to
 250       restore
 251       if not #incheck
 252         setlegal #king #to
 253       endif
 254     endif
 255   next
 256   if == count var checks 1
 257     for (key enemy) var checks
 258       set possible path #king #key
 259       push possible #key
 260       if == #key #ep
 261         push possible cond isupper space #ep where #ep 0 -1 where #ep 0 1
 262       endif
 263       for (from piece) fn friends
 264         if == #from #king
 265           continue
 266         endif
 267         for to #possible
 268           if fn #piece #from #to
 269             move #from #to
 270             set incheck fn var attacked #king
 271             if not #incheck
 272               setlegal #from #to
 273             endif
 274           endif
 275           restore
 276         next
 277       next
 278     next
 279   endif
 280   return cond count system legalmoves false true and checks
 281 endsub
 282 def PL array where #0 0 2 where #0 0 1 where #0 -1 1 where #0 1 1
 283 def pL array where #0 0 -2 where #0 0 -1 where #0 -1 -1 where #0 1 -1
 284 def NL leaps #0 1 2
 285 def BL rays #0 1 1
 286 def RL rays #0 1 0
 287 def VL rays #0 1 1
 288 def CL rays #0 1 0
 289 def QL merge rays #0 1 0 rays #0 1 1
 290 def KL merge leaps #0 1 0 leaps #0 1 1
 291 def AL merge leaps #0 1 2 rays #0 1 1
 292 def ML merge rays #0 1 0 leaps #0 1 2
 293 def nL leaps #0 1 2
 294 def bL rays #0 1 1
 295 def rL rays #0 1 0
 296 def vL rays #0 1 1
 297 def cL rays #0 1 0
 298 def qL merge rays #0 1 0 rays #0 1 1
 299 def kL merge leaps #0 1 0 leaps #0 1 1
 300 def aL merge leaps #0 1 2 rays #0 1 1
 301 def mL merge rays #0 1 0 leaps #0 1 2
 302 sub castlepos from to
 303   local c RPOS RDEST xdir safe
 304   verify flag #from
 305   verify empty #to
 306   if isupper space #king
 307     def friend isupper #0
 308     def friends onlyupper
 309     set attacked ATTACKEDBYB
 310   else
 311     def friend islower #0
 312     def friends onlylower
 313     set attacked ATTACKEDBYW
 314   endif
 315   set xdir sign minus file #to file #from
 316   verify checkaride #from #to #xdir 0
 317   verify not fn var attacked #from
 318   set c #to
 319   do
 320     set c where #c #xdir 0
 321     if flag #c
 322       break
 323     endif
 324     verify onboard #c
 325     verify empty #c
 326   loop
 327   verify flag #c
 328   set RPOS #c
 329   store
 330   for c path #from #to
 331     move #from #c
 332     set safe not fn var attacked #c
 333     restore
 334     verify #safe
 335   next
 336   move #from #to
 337   set RDEST where #to neg #xdir 0
 338   move #RPOS #RDEST
 339   return true
 340 endsub
 341 sub stalemated king
 342   local legalmove temp from piece to attacked ra
 343   if isupper space #king
 344     def friend isupper #0
 345     def friends onlyupper
 346     set attacked ATTACKEDBYB
 347     set cspaces var wcastle
 348   else
 349     def friend islower #0
 350     def friends onlylower
 351     set attacked ATTACKEDBYW
 352     set cspaces var bcastle
 353   endif
 354   store
 355   set kingmoves fn KL #king
 356   for to #kingmoves
 357     if not fn friend space #to and onboard #to
 358       move #king #to
 359       set incheck fn var attacked #to
 360       restore
 361       if not #incheck
 362         setlegal #king #to
 363       endif
 364     endif
 365   next
 366   for to var cspaces
 367     if sub castlepos #king #to
 368       set incheck fn var attacked #to
 369       restore
 370       if not #incheck
 371         setlegal #king #to
 372       endif
 373     endif
 374   next
 375   restore
 376   for (from piece) fn friends
 377     if == #from #king
 378       continue
 379     endif
 380     for to fn join #piece L #from
 381       if fn #piece #from #to and not fn friend space #to and onboard #to
 382         move #from #to
 383         set incheck fn var attacked #king
 384         if not #incheck
 385           setlegal #from #to
 386         endif
 387       endif
 388       restore
 389     next
 390   next
 391   return cond count system legalmoves false true
 392 endsub
 393 def WPAWN match P what #0 1 -1 what #0 -1 -1
 394 def BPAWN match p what #0 1 1 what #0 -1 1
 395 def KNIGHT check what #0 1 2 check what #0 -1 2 check what #0 1 -2 check what #0 -1 -2 check what #0 2 1 check what #0 -2 1 check what #0 2 -1 check what #0 -2 -1 target #1
 396 def WAZIR check what #0 0 -1 check what #0 -1 0 check what #0 0 1 check what #0 1 0 target #1
 397 def FERZ check what #0 -1 -1 check what #0 -1 1 check what #0 1 -1 check what #0 1 1 target #1
 398 def KING fn WAZIR #0 #1 or fn FERZ #0 #1
 399 def ROOK check insight #0 0 -1 check insight #0 -1 0 check insight #0 0 1 check insight #0 1 0 target #1
 400 def BISHOP check insight #0 -1 -1 check insight #0 -1 1 check insight #0 1 -1 check insight #0 1 1 target #1
 401 def ATTACKEDBYB fn KING #0 k or fn BPAWN #0 or fn KNIGHT #0 (n a m) or fn ROOK #0 (r q m) or fn BISHOP #0 (b q a)
 402 def ATTACKEDBYW fn KING #0 K or fn WPAWN #0 or fn KNIGHT #0 (N A M) or fn ROOK #0 (R Q M) or fn BISHOP #0 (B Q A)
 403 sub P from to
 404   local ydir
 405   if == file #from file #to and not capture
 406     set legal checkaleap #from #to 0 1
 407     if var legal
 408       set ep false
 409     else
 410       set legal checkaride #from #to 0 1 and <= distance #from #to #fps and or == rankname #from #wpr < #wpr 0
 411       set ep #to
 412     endif
 413     set epc false
 414   elseif capture or #ep
 415     set legal checkaleap #from #to -1 1 or checkaleap #from #to 1 1
 416     set epc false
 417     if not capture and var legal
 418       set legal > rank #to rank #ep and < rankname #to #bpr and == file #to file #ep
 419       if var legal
 420         capture #ep
 421         set epc #ep
 422       endif
 423     endif
 424     set ep false
 425   endif
 426   if != space #to moved and onboard where #to 0 #pzs
 427     die "You may not promote a Pawn until it reaches the promotion zone."
 428   endif
 429   if not onboard where #to 0 1
 430     if == P space #to
 431       askpromote #wprom
 432     elseif not match space #to var wprom
 433       set np space #to
 434       die "You may not promote your Pawn to a" #np
 435     endif
 436   endif
 437 endsub
 438 sub p from to
 439   if == file #from file #to and not capture
 440     set legal checkaleap #from #to 0 -1
 441     if var legal
 442       set ep false
 443     else
 444       set legal checkaride #from #to 0 -1 and <= distance #from #to #fps and or == rankname #from #bpr > #bpr lastrank
 445       set ep #to
 446     endif
 447     set epc false
 448   elseif capture or #ep
 449     set legal checkaleap #from #to -1 -1 or checkaleap #from #to 1 -1
 450     set epc false
 451     if not capture and var legal
 452       set legal < rank #to rank #ep and > rankname #to #wpr and == file #to file #ep
 453       if var legal
 454         capture #ep
 455         set epc #ep
 456       endif
 457     endif
 458     set ep false
 459   endif
 460   if != space #to moved and onboard where #to 0 neg #pzs
 461     die You may not promote a Pawn until it reaches the promotion zone.
 462   endif
 463   if not onboard where #to 0 -1
 464     if == p space #to
 465       askpromote #bprom
 466     elseif not match space #to var bprom
 467       set np space #to
 468       die You may not promote your Pawn to a #np
 469     endif
 470   endif
 471 endsub
 472 sub K from to
 473   if match #to var wcastle and flag #from
 474     set legal sub castle
 475   else
 476     set legal fn K #from #to
 477   endif
 478   set K #to
 479   unsetflag e1
 480 endsub
 481 sub k from to
 482   if match #to var bcastle and flag #from
 483     set legal sub castle
 484   else
 485     set legal fn k #from #to
 486   endif
 487   set k #to
 488   unsetflag e8
 489 endsub
 490 sub castle
 491   local ATTACKED c RPOS RDEST xdir
 492   if not flag #from
 493     die A King may not castle after it moves.
 494   endif
 495   if capture
 496     die A King may not castle to an occupied space.
 497   endif
 498   set xdir sign minus file #to file #from
 499   if not checkaride #from #to #xdir 0
 500     die A King may not castle across any occupied space.
 501   endif
 502   set c #to
 503   do
 504     set c where #c #xdir 0
 505     if flag #c
 506       break
 507     elseif not onboard #c
 508       die No piece was found to castle with.
 509     elseif not empty #c
 510       die The King cannot castle with the piece at #c
 511     endif
 512   loop
 513   set RPOS #c
 514   set ATTACKED ATTACKEDBYW unless isupper moved ATTACKEDBYB
 515   if fn var ATTACKED #from
 516     die A King may not castle out of check.
 517   endif
 518   for c path #from #to
 519     if fn var ATTACKED #c
 520       die A King may not castle through check.
 521     endif
 522   next
 523   if == count var subargs 0
 524     set RDEST where #to neg #xdir 0
 525   else
 526     set RDEST elem 0 subarg
 527   endif
 528   unsetflag #RPOS
 529   move #RPOS #RDEST
 530   return true
 531 endsub
 532 sub checkedthru king loc
 533   my dir c
 534   set c revealed #king #loc
 535   verify fn space #c #c #king and not samecase space #king space #c and onboard #c and #c
 536   return #c
 537 endsub
 538 def fn checkedfrom fn space #1 #0 and xor isupper space #0 isupper space #1 and not empty #1
 539 sub P1 from to
 540   if == file #from file #to
 541     return not capture
 542   elseif capture
 543     return true
 544   elseif == file #to file #ep and == rank #from rank #ep and #ep
 545     capture #ep
 546     return true
 547   endif
 548   return false
 549 endsub
 550 sub PP from to
 551   if checkatwostep #from #to 0 1 0 1 or checkaleap #from #to 0 1
 552     return empty #to
 553   elseif not checkaleap #from #to 1 1 and not checkaleap #from #to -1 1
 554     return false
 555   elseif not empty #to
 556     return true
 557   elseif == file #to file #ep and == rank #from rank #ep and #ep
 558     capture #ep
 559     return true
 560   endif
 561   return false
 562 endsub
 563 sub pp from to
 564   if checkatwostep #from #to 0 -1 0 -1 or checkaleap #from #to 0 -1
 565     return empty #to
 566   elseif not checkaleap #from #to 1 -1 and not checkaleap #from #to -1 -1
 567     return false
 568   elseif not empty #to
 569     return true
 570   elseif == file #to file #ep and == rank #from rank #ep and #ep
 571     capture #ep
 572     return true
 573   endif
 574   return false
 575 endsub
 576 endlib