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

You may not move a e from g8 to g6

Use your browser's BACK button to go back to the previous page, then reload if necessary.

For general reference, here is the complete list of moves:

1. P b2-b4 
1... p e7-e5 
2. P c2-c4 
2... wa g8-g6 
3. WR g1-g3 
3... fa f8-f6 
4. P d2-d3 
4... k e8-g8 
5. P e2-e4 
5... ca d8-c6 
6. HD c1-c3

If this is your settings file, you may edit it at https://www.chessvariants.com/play/pbm/play.php?game=Chess+with+Different+Armies&settings=Rookies-Colorbound&submit=Edit

Here is a code listing:

   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 cwda
   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 A E F C I M D G L W J H
  23     set legal fn moved origin dest
  24     if match moved R A I L
  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 a e f c i m d g l w j h
  52     set legal fn toupper moved origin dest
  53     if equal moved r a i l
  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 0
  65 MOVE: P b2-b4
  66 postauto1
  67 moveindex 1
  68 MOVE: p e7-e5
  69 postauto2
  70 moveindex 2
  71 MOVE: P c2-c4
  72 postauto1
  73 moveindex 3
  74 MOVE: wa g8-g6
  75 postauto2
  76 moveindex 4
  77 MOVE: WR g1-g3
  78 postauto1
  79 moveindex 5
  80 MOVE: fa f8-f6
  81 postauto2
  82 moveindex 6
  83 MOVE: P d2-d3
  84 postauto1
  85 moveindex 7
  86 MOVE: k e8-g8
  87 postauto2
  88 moveindex 8
  89 MOVE: P e2-e4
  90 postauto1
  91 moveindex 9
  92 MOVE: ca d8-c6
  93 postauto2
  94 moveindex 10
  95 MOVE: HD c1-c3
  96 postauto1
  97 set checks sub checks #k
  98 if var checks
  99   if sub checkmated #k #checks
 100     say Checkmate! White has won!
 101     won
 102   else
 103     say Check!
 104   endif
 105 elseif sub stalemated #k
 106   say Stalemate! The game is drawn.
 107   drawn
 108 endif
 109 end
 110 
 111 lib cwda
 112 include chess
 113 alias BD A WA E FA F CA C CR I FN M CN D CO G SR L WR W HD J CH H bd a wa e fa f ca c cr i fn m cn d co g sr l wr w hd j ch h
 114 def AF checkleap #0 #1 2 2
 115 def DB checkleap #0 #1 2 0
 116 def FZ checkleap #0 #1 1 1
 117 def WZ checkleap #0 #1 1 0
 118 def A fn B #0 #1 or fn DB #0 #1
 119 def E fn WZ #0 #1 or fn AF #0 #1
 120 def F fn FZ #0 #1 or fn AF #0 #1 or fn DB #0 #1
 121 def C fn B #0 #1 or fn N #0 #1
 122 def a fn b #0 #1 or fn DB #0 #1
 123 def e fn WZ #0 #1 or fn AF #0 #1
 124 def f fn FZ #0 #1 or fn AF #0 #1 or fn DB #0 #1
 125 def c fn b #0 #1 or fn n #0 #1
 126 def AL merge rays #0 1 1 leaps #0 2 0
 127 def EL merge leaps #0 1 0 leaps #0 2 2
 128 def FL merge leaps #0 1 1 merge leaps #0 2 2 leaps #0 2 0
 129 def CL merge rays #0 1 1 leaps #0 1 2
 130 def aL merge rays #0 1 1 leaps #0 2 0
 131 def eL merge leaps #0 1 0 leaps #0 2 2
 132 def fL merge leaps #0 1 1 merge leaps #0 2 2 leaps #0 2 0
 133 def cL merge rays #0 1 1 leaps #0 1 2
 134 def I checkaride #0 #1 1 0 or checkaride #0 #1 -1 0 or checkaride #0 #1 0 1 or checkaleap #0 #1 -1 -1 or checkaleap #0 #1 1 -1 or checkaleap #0 #1 0 -1
 135 def M checkaleap #0 #1 1 2 or checkaleap #0 #1 -1 2 or checkaleap #0 #1 1 -2 or checkaleap #0 #1 -1 -2 or fn FZ #0 #1
 136 def D checkaleap #0 #1 1 2 or checkaleap #0 #1 -1 2 or checkaleap #0 #1 2 1 or checkaleap #0 #1 -2 1 or checkaleap #0 #1 -1 -1 or checkaleap #0 #1 1 -1 or checkaleap #0 #1 -1 0 or checkaleap #0 #1 1 0 or checkaleap #0 #1 0 -1
 137 def G checkaride #0 #1 1 0 or checkaride #0 #1 -1 0 or checkaride #0 #1 0 1 or checkaleap #0 #1 1 2 or checkaleap #0 #1 -1 2 or checkaleap #0 #1 2 1 or checkaleap #0 #1 -2 1 or fn FZ #0 #1 or fn WZ #0 #1
 138 def i checkaride #0 #1 1 0 or checkaride #0 #1 -1 0 or checkaride #0 #1 0 -1 or checkaleap #0 #1 -1 1 or checkaleap #0 #1 1 1 or checkaleap #0 #1 0 1
 139 def m checkaleap #0 #1 1 2 or checkaleap #0 #1 -1 2 or checkaleap #0 #1 1 -2 or checkaleap #0 #1 -1 -2 or fn FZ #0 #1
 140 def d checkaleap #0 #1 1 -2 or checkaleap #0 #1 -1 -2 or checkaleap #0 #1 2 -1 or checkaleap #0 #1 -2 -1 or checkaleap #0 #1 -1 1 or checkaleap #0 #1 1 1 or checkaleap #0 #1 -1 0 or checkaleap #0 #1 1 0 or checkaleap #0 #1 0 1
 141 def g checkaride #0 #1 1 0 or checkaride #0 #1 -1 0 or checkaride #0 #1 0 -1 or checkaleap #0 #1 1 -2 or checkaleap #0 #1 -1 -2 or checkaleap #0 #1 2 -1 or checkaleap #0 #1 -2 -1 or fn FZ #0 #1 or fn WZ #0 #1
 142 def IL merge rays #0 1 0 array where #0 -1 -1 where #0 1 -1
 143 def iL merge rays #0 1 0 array where #0 -1 1 where #0 1 1
 144 def ML merge leaps #0 1 1 array where #0 1 2 where #0 -1 2 where #0 1 -2 where #0 -1 -2
 145 def mL merge leaps #0 1 1 array where #0 1 2 where #0 -1 2 where #0 1 -2 where #0 -1 -2
 146 def DL array where #0 1 2 where #0 -1 2 where #0 2 1 where #0 -2 1 where #0 -1 0 where #0 1 0 where #0 0 -1 where #0 -1 -1 where #0 1 -1
 147 def dL array where #0 1 -2 where #0 -1 -2 where #0 2 -1 where #0 -2 -1 where #0 -1 0 where #0 1 0 where #0 0 1 where #0 -1 1 where #0 1 1
 148 def GL merge merge leaps #0 1 1 rays #0 1 0 array where #0 1 2 where #0 -1 2 where #0 2 1 where #0 -2 1
 149 def gL merge merge leaps #0 1 1 rays #0 1 0 array where #0 1 -2 where #0 -1 -2 where #0 2 -1 where #0 -2 -1
 150 def L fn R #0 #1 and <= distance #0 #1 4
 151 def W fn DB #0 #1 or fn WZ #0 #1
 152 def J fn DB #0 #1 or fn FZ #0 #1 or checkleap #0 #1 0 3
 153 def H fn N #0 #1 or fn R #0 #1
 154 def l fn r #0 #1 and <= distance #0 #1 4
 155 def w fn DB #0 #1 or fn WZ #0 #1
 156 def j fn DB #0 #1 or fn FZ #0 #1 or checkleap #0 #1 0 3
 157 def h fn n #0 #1 or fn r #0 #1
 158 def LL merge merge leaps #0 1 0 leaps #0 2 0 merge leaps #0 3 0 leaps #0 4 0
 159 def WL merge leaps #0 1 0 leaps #0 2 0
 160 def JL merge leaps #0 3 0 merge leaps #0 1 1 leaps #0 2 0
 161 def HL merge rays #0 1 0 leaps #0 1 2
 162 def lL merge merge leaps #0 1 0 leaps #0 2 0 merge leaps #0 3 0 leaps #0 4 0
 163 def wL merge leaps #0 1 0 leaps #0 2 0
 164 def jL merge leaps #0 3 0 merge leaps #0 1 1 leaps #0 2 0
 165 def hL merge rays #0 1 0 leaps #0 1 2
 166 def DABBABAH check what #0 0 -2 check what #0 -2 0 check what #0 0 2 check what #0 2 0 target #1
 167 def ALFIL check what #0 -2 -2 check what #0 -2 2 check what #0 2 -2 check what #0 2 2 target #1
 168 def LONGKNIGHT check what #0 1 2 check what #0 -1 2 check what #0 1 -2 check what #0 -1 -2 target #1
 169 def FOREKNIGHT check what #0 1 2 check what #0 -1 2 check what #0 2 1 check what #0 -2 1 target #1
 170 def BACKKNIGHT check what #0 1 -2 check what #0 -1 -2 check what #0 2 -1 check what #0 -2 -1 target #1
 171 def FOREKING check what #0 -1 1 check what #0 0 1 check what #0 1 1 target #1
 172 def BACKKING check what #0 -1 -1 check what #0 0 -1 check what #0 1 -1 target #1
 173 def SIDEKING check what #0 1 0 check what #0 -1 0 target #1
 174 def FOREROOK match insight #0 0 1 #1
 175 def BACKROOK match insight #0 0 -1 #1
 176 def SIDEROOK check insight #0 1 0 check insight #0 -1 0 target #1
 177 def SHORTROOK check inrange #0 0 -1 4 check inrange #0 -1 0 4 check inrange #0 0 1 4 check inrange #0 1 0 4 target #1
 178 def O3 check what #0 0 -3 check what #0 -3 0 check what #0 0 3 check what #0 3 0 target #1
 179 def WAZIR check what #0 0 -1 check what #0 -1 0 check what #0 0 1 check what #0 1 0 target #1
 180 def FERZ check what #0 -1 -1 check what #0 -1 1 check what #0 1 -1 check what #0 1 1 target #1
 181 def ATTACKEDBYW fn WPAWN #0 or fn O3 #0 J or fn SIDEKING #0 D or fn LONGKNIGHT #0 M or fn SHORTROOK #0 L or fn FOREKING #0 (I D) or fn ALFIL #0 (E F) or fn DABBABAH #0 (A F W J) or fn WAZIR #0 (E W K G) or fn FERZ #0 (F J K G M) or fn FOREROOK #0 (H Q R) or fn BACKROOK #0 (I G H Q R) or fn SIDEROOK #0 (I G H Q R) or fn FOREKNIGHT #0 (C H N) or fn BACKKNIGHT #0 (D G C H N) or fn BISHOP #0 (A C B Q)
 182 def ATTACKEDBYB fn BPAWN #0 or fn O3 #0 j or fn SIDEKING #0 d or fn LONGKNIGHT #0 m or fn SHORTROOK #0 l or fn BACKKING #0 (i d) or fn ALFIL #0 (e f) or fn DABBABAH #0 (a f w j) or fn WAZIR #0 (e w k g) or fn FERZ #0 (f j k g m) or fn BACKROOK #0 (h q r) or fn FOREROOK #0 (i g h q r) or fn SIDEROOK #0 (i g h q r) or fn BACKKNIGHT #0 (c h n) or fn FOREKNIGHT #0 (d g c h n) or fn BISHOP #0 (a c b q)
 183 sub checkedthru king loc
 184   my dir c
 185   set c revealed #king #loc
 186   if samecase space #king space #c or not #c
 187     return false
 188   endif
 189   set dir direction #king #loc
 190   switch #dir
 191     case n
 192     if match space #c R r Q q i g H h
 193       return #c
 194     endif
 195     if <= distance #king #loc 4 and match space #c L l
 196       return #c
 197     endif
 198     return false
 199     case s
 200     if match space #c R r Q q I G H h
 201       return #c
 202     endif
 203     if <= distance #king #loc 4 and match space #c L l
 204       return #c
 205     endif
 206     return false
 207     case e w
 208     if match space #c R r Q q I i G g H h
 209       return #c
 210     endif
 211     if <= distance #king #loc 4 and match space #c L l
 212       return #c
 213     endif
 214     return false
 215     case nw sw ne se
 216     if match space #c B b Q q A a C c
 217       return #c
 218     endif
 219     return false
 220     default
 221     return false
 222   endswitch
 223 endsub
 224 set cdist 2
 225 set CDIST 2
 226 sub K from to
 227   set legal fn K #from #to
 228   if match #to where #from 2 0 where #from neg #CDIST 0
 229     set legal sub castle
 230   endif
 231   set K #to
 232   unsetflag #from
 233 endsub
 234 sub k from to
 235   set legal fn K #from #to
 236   if match #to where #from 2 0 where #from neg #cdist 0
 237     set legal sub castle
 238   endif
 239   set k #to
 240   unsetflag #from
 241 endsub
 242 set x 0
 243 switch space d1
 244   case C
 245   set x 1
 246   break
 247   case G
 248   set x 2
 249   break
 250   case H
 251   set x 3
 252   break
 253   default
 254   break
 255 endswitch
 256 switch space d8
 257   case c
 258   set x plus #x 4
 259   break
 260   case g
 261   set x plus #x 8
 262   break
 263   case h
 264   set x plus #x 12
 265   break
 266   default
 267   break
 268 endswitch
 269 if == #x 0
 270   if flag neversame
 271     set x rand 1 12
 272     if > #x 4
 273       inc x
 274     endif
 275     if > #x 9
 276       inc x
 277     endif
 278   else
 279     set x rand 1 15
 280   endif
 281 endif
 282 set wx mod #x 4
 283 set bx / - #x #wx 4
 284 switch #wx
 285   case 0
 286   add R a1
 287   add N b1
 288   add B c1
 289   add Q d1
 290   add B f1
 291   add N g1
 292   add R h1
 293   pushall wprom R N B Q
 294   pushall bprom r n b q
 295   break
 296   case 1
 297   add A a1
 298   add E b1
 299   add F c1
 300   add C d1
 301   add F f1
 302   add E g1
 303   add A h1
 304   pushall wprom A E F C
 305   pushall bprom a e f c
 306   set CDIST 3
 307   set wcastle b1 g1
 308   break
 309   case 2
 310   add I a1
 311   add M b1
 312   add D c1
 313   add G d1
 314   add D f1
 315   add M g1
 316   add I h1
 317   pushall wprom I M D G
 318   pushall bprom i m d g
 319   break
 320   case 3
 321   add L a1
 322   add W b1
 323   add J c1
 324   add H d1
 325   add J f1
 326   add W g1
 327   add L h1
 328   pushall wprom L W J H
 329   pushall bprom l w j h
 330   break
 331   default
 332   break
 333 endswitch
 334 switch #bx
 335   case 0
 336   add r a8
 337   add n b8
 338   add b c8
 339   add q d8
 340   add b f8
 341   add n g8
 342   add r h8
 343   if != #wx 0
 344     pushall wprom R N B Q
 345     pushall bprom r n b q
 346   endif
 347   break
 348   case 1
 349   add a a8
 350   add e b8
 351   add f c8
 352   add c d8
 353   add f f8
 354   add e g8
 355   add a h8
 356   if != #wx 1
 357     pushall wprom A E F C
 358     pushall bprom a e f c
 359   endif
 360   set cdist 3
 361   set bcastle b8 g8
 362   break
 363   case 2
 364   add i a8
 365   add m b8
 366   add d c8
 367   add g d8
 368   add d f8
 369   add m g8
 370   add i h8
 371   if != #wx 2
 372     pushall wprom I M D G
 373     pushall bprom i m d g
 374   endif
 375   break
 376   case 3
 377   add l a8
 378   add w b8
 379   add j c8
 380   add h d8
 381   add j f8
 382   add w g8
 383   add l h8
 384   if != #wx 3
 385     pushall wprom L W J H
 386     pushall bprom l w j h
 387   endif
 388   break
 389   default
 390   break
 391 endswitch
 392 setglobal piecekeys merge var wprom var bprom
 393 endlib
 394 lib chess
 395 set wpr 2
 396 set bpr 7
 397 set fps 2
 398 set pzs 1
 399 set wcastle c1 g1
 400 set bcastle c8 g8
 401 do
 402   local x
 403   for x piecekeys
 404     if match #x P K p k
 405       continue
 406     elseif isupper #x
 407       push wprom #x
 408     elseif islower #x
 409       push bprom #x
 410     endif
 411   next
 412 loop never
 413 setsystem maxmove 2
 414 ban commands allmoves
 415 allow moves 1 captures 1 promotions 2
 416 def N checkleap #0 #1 1 2
 417 def B checkride #0 #1 1 1
 418 def R checkride #0 #1 1 0
 419 def Q fn B #0 #1 or fn R #0 #1
 420 def K checkleap #0 #1 1 1 or checkleap #0 #1 1 0
 421 def M fn N #0 #1 or fn R #0 #1
 422 def A fn N #0 #1 or fn B #0 #1
 423 def n checkleap #0 #1 1 2
 424 def b checkride #0 #1 1 1
 425 def r checkride #0 #1 1 0
 426 def q fn b #0 #1 or fn r #0 #1
 427 def k checkleap #0 #1 1 1 or checkleap #0 #1 1 0
 428 def m fn n #0 #1 or fn r #0 #1
 429 def a fn n #0 #1 or fn b #0 #1
 430 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
 431 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
 432 sub capturep p
 433   empty #p
 434   return true
 435 endsub
 436 sub checks king
 437   if not dest
 438     return false
 439   endif
 440   my checks c
 441   set checks ()
 442   if fn space dest dest #king
 443     setelem checks dest space dest
 444   endif
 445   set c sub checkedthru #king origin
 446   if #c
 447     setelem checks #c space #c
 448   elseif #epc
 449     set c sub checkedthru #king #epc
 450     if #c
 451       setelem checks #c space #c
 452     endif
 453   endif
 454   return var checks
 455 endsub
 456 sub checkmated king checks
 457   local from piece to key legalmove piece nopawn
 458   store
 459   if isupper space #king
 460     def friends onlyupper
 461     def friend isupper #0
 462     set attacked ATTACKEDBYB
 463   else
 464     def friends onlylower
 465     def friend islower #0
 466     set attacked ATTACKEDBYW
 467   endif
 468   set kingmoves fn KL #king
 469   for to #kingmoves
 470     if not fn friend space #to and onboard #to
 471       move #king #to
 472       set incheck fn var attacked #to
 473       restore
 474       if not #incheck
 475         setlegal #king #to
 476       endif
 477     endif
 478   next
 479   if == count var checks 1
 480     for (key enemy) var checks
 481       set possible path #king #key
 482       push possible #key
 483       if == #key #ep
 484         push possible cond isupper space #ep where #ep 0 -1 where #ep 0 1
 485       endif
 486       for (from piece) fn friends
 487         if == #from #king
 488           continue
 489         endif
 490         for to #possible
 491           if fn #piece #from #to
 492             move #from #to
 493             set incheck fn var attacked #king
 494             if not #incheck
 495               setlegal #from #to
 496             endif
 497           endif
 498           restore
 499         next
 500       next
 501     next
 502   endif
 503   return cond count system legalmoves false true and checks
 504 endsub
 505 def PL array where #0 0 2 where #0 0 1 where #0 -1 1 where #0 1 1
 506 def pL array where #0 0 -2 where #0 0 -1 where #0 -1 -1 where #0 1 -1
 507 def NL leaps #0 1 2
 508 def BL rays #0 1 1
 509 def RL rays #0 1 0
 510 def VL rays #0 1 1
 511 def CL rays #0 1 0
 512 def QL merge rays #0 1 0 rays #0 1 1
 513 def KL merge leaps #0 1 0 leaps #0 1 1
 514 def AL merge leaps #0 1 2 rays #0 1 1
 515 def ML merge rays #0 1 0 leaps #0 1 2
 516 def nL leaps #0 1 2
 517 def bL rays #0 1 1
 518 def rL rays #0 1 0
 519 def vL rays #0 1 1
 520 def cL rays #0 1 0
 521 def qL merge rays #0 1 0 rays #0 1 1
 522 def kL merge leaps #0 1 0 leaps #0 1 1
 523 def aL merge leaps #0 1 2 rays #0 1 1
 524 def mL merge rays #0 1 0 leaps #0 1 2
 525 sub castlepos from to
 526   local c RPOS RDEST xdir safe
 527   verify flag #from
 528   verify empty #to
 529   if isupper space #king
 530     def friend isupper #0
 531     def friends onlyupper
 532     set attacked ATTACKEDBYB
 533   else
 534     def friend islower #0
 535     def friends onlylower
 536     set attacked ATTACKEDBYW
 537   endif
 538   set xdir sign minus file #to file #from
 539   verify checkaride #from #to #xdir 0
 540   verify not fn var attacked #from
 541   set c #to
 542   do
 543     set c where #c #xdir 0
 544     if flag #c
 545       break
 546     endif
 547     verify onboard #c
 548     verify empty #c
 549   loop
 550   verify flag #c
 551   set RPOS #c
 552   store
 553   for c path #from #to
 554     move #from #c
 555     set safe not fn var attacked #c
 556     restore
 557     verify #safe
 558   next
 559   move #from #to
 560   set RDEST where #to neg #xdir 0
 561   move #RPOS #RDEST
 562   return true
 563 endsub
 564 sub stalemated king
 565   local legalmove temp from piece to attacked ra
 566   if isupper space #king
 567     def friend isupper #0
 568     def friends onlyupper
 569     set attacked ATTACKEDBYB
 570     set cspaces var wcastle
 571   else
 572     def friend islower #0
 573     def friends onlylower
 574     set attacked ATTACKEDBYW
 575     set cspaces var bcastle
 576   endif
 577   store
 578   set kingmoves fn KL #king
 579   for to #kingmoves
 580     if not fn friend space #to and onboard #to
 581       move #king #to
 582       set incheck fn var attacked #to
 583       restore
 584       if not #incheck
 585         setlegal #king #to
 586       endif
 587     endif
 588   next
 589   for to var cspaces
 590     if sub castlepos #king #to
 591       set incheck fn var attacked #to
 592       restore
 593       if not #incheck
 594         setlegal #king #to
 595       endif
 596     endif
 597   next
 598   restore
 599   for (from piece) fn friends
 600     if == #from #king
 601       continue
 602     endif
 603     for to fn join #piece L #from
 604       if fn #piece #from #to and not fn friend space #to and onboard #to
 605         move #from #to
 606         set incheck fn var attacked #king
 607         if not #incheck
 608           setlegal #from #to
 609         endif
 610       endif
 611       restore
 612     next
 613   next
 614   return cond count system legalmoves false true
 615 endsub
 616 def WPAWN match P what #0 1 -1 what #0 -1 -1
 617 def BPAWN match p what #0 1 1 what #0 -1 1
 618 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
 619 def WAZIR check what #0 0 -1 check what #0 -1 0 check what #0 0 1 check what #0 1 0 target #1
 620 def FERZ check what #0 -1 -1 check what #0 -1 1 check what #0 1 -1 check what #0 1 1 target #1
 621 def KING fn WAZIR #0 #1 or fn FERZ #0 #1
 622 def ROOK check insight #0 0 -1 check insight #0 -1 0 check insight #0 0 1 check insight #0 1 0 target #1
 623 def BISHOP check insight #0 -1 -1 check insight #0 -1 1 check insight #0 1 -1 check insight #0 1 1 target #1
 624 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)
 625 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)
 626 sub P from to
 627   local ydir
 628   if == file #from file #to and not capture
 629     set legal checkaleap #from #to 0 1
 630     if var legal
 631       set ep false
 632     else
 633       set legal checkaride #from #to 0 1 and <= distance #from #to #fps and or == rankname #from #wpr < #wpr 0
 634       set ep #to
 635     endif
 636     set epc false
 637   elseif capture or #ep
 638     set legal checkaleap #from #to -1 1 or checkaleap #from #to 1 1
 639     set epc false
 640     if not capture and var legal
 641       set legal > rank #to rank #ep and < rankname #to #bpr and == file #to file #ep
 642       if var legal
 643         capture #ep
 644         set epc #ep
 645       endif
 646     endif
 647     set ep false
 648   endif
 649   if != space #to moved and onboard where #to 0 #pzs
 650     die "You may not promote a Pawn until it reaches the promotion zone."
 651   endif
 652   if not onboard where #to 0 1
 653     if == P space #to
 654       askpromote #wprom
 655     elseif not match space #to var wprom
 656       set np space #to
 657       die "You may not promote your Pawn to a" #np
 658     endif
 659   endif
 660 endsub
 661 sub p from to
 662   if == file #from file #to and not capture
 663     set legal checkaleap #from #to 0 -1
 664     if var legal
 665       set ep false
 666     else
 667       set legal checkaride #from #to 0 -1 and <= distance #from #to #fps and or == rankname #from #bpr > #bpr lastrank
 668       set ep #to
 669     endif
 670     set epc false
 671   elseif capture or #ep
 672     set legal checkaleap #from #to -1 -1 or checkaleap #from #to 1 -1
 673     set epc false
 674     if not capture and var legal
 675       set legal < rank #to rank #ep and > rankname #to #wpr and == file #to file #ep
 676       if var legal
 677         capture #ep
 678         set epc #ep
 679       endif
 680     endif
 681     set ep false
 682   endif
 683   if != space #to moved and onboard where #to 0 neg #pzs
 684     die You may not promote a Pawn until it reaches the promotion zone.
 685   endif
 686   if not onboard where #to 0 -1
 687     if == p space #to
 688       askpromote #bprom
 689     elseif not match space #to var bprom
 690       set np space #to
 691       die You may not promote your Pawn to a #np
 692     endif
 693   endif
 694 endsub
 695 sub K from to
 696   if match #to var wcastle and flag #from
 697     set legal sub castle
 698   else
 699     set legal fn K #from #to
 700   endif
 701   set K #to
 702   unsetflag e1
 703 endsub
 704 sub k from to
 705   if match #to var bcastle and flag #from
 706     set legal sub castle
 707   else
 708     set legal fn k #from #to
 709   endif
 710   set k #to
 711   unsetflag e8
 712 endsub
 713 sub castle
 714   local ATTACKED c RPOS RDEST xdir
 715   if not flag #from
 716     die A King may not castle after it moves.
 717   endif
 718   if capture
 719     die A King may not castle to an occupied space.
 720   endif
 721   set xdir sign minus file #to file #from
 722   if not checkaride #from #to #xdir 0
 723     die A King may not castle across any occupied space.
 724   endif
 725   set c #to
 726   do
 727     set c where #c #xdir 0
 728     if flag #c
 729       break
 730     elseif not onboard #c
 731       die No piece was found to castle with.
 732     elseif not empty #c
 733       die The King cannot castle with the piece at #c
 734     endif
 735   loop
 736   set RPOS #c
 737   set ATTACKED ATTACKEDBYW unless isupper moved ATTACKEDBYB
 738   if fn var ATTACKED #from
 739     die A King may not castle out of check.
 740   endif
 741   for c path #from #to
 742     if fn var ATTACKED #c
 743       die A King may not castle through check.
 744     endif
 745   next
 746   if == count var subargs 0
 747     set RDEST where #to neg #xdir 0
 748   else
 749     set RDEST elem 0 subarg
 750   endif
 751   unsetflag #RPOS
 752   move #RPOS #RDEST
 753   return true
 754 endsub
 755 sub checkedthru king loc
 756   my dir c
 757   set c revealed #king #loc
 758   verify fn space #c #c #king and not samecase space #king space #c and onboard #c and #c
 759   return #c
 760 endsub
 761 def fn checkedfrom fn space #1 #0 and xor isupper space #0 isupper space #1 and not empty #1
 762 sub P1 from to
 763   if == file #from file #to
 764     return not capture
 765   elseif capture
 766     return true
 767   elseif == file #to file #ep and == rank #from rank #ep and #ep
 768     capture #ep
 769     return true
 770   endif
 771   return false
 772 endsub
 773 sub PP from to
 774   if checkatwostep #from #to 0 1 0 1 or checkaleap #from #to 0 1
 775     return empty #to
 776   elseif not checkaleap #from #to 1 1 and not checkaleap #from #to -1 1
 777     return false
 778   elseif not empty #to
 779     return true
 780   elseif == file #to file #ep and == rank #from rank #ep and #ep
 781     capture #ep
 782     return true
 783   endif
 784   return false
 785 endsub
 786 sub pp from to
 787   if checkatwostep #from #to 0 -1 0 -1 or checkaleap #from #to 0 -1
 788     return empty #to
 789   elseif not checkaleap #from #to 1 -1 and not checkaleap #from #to -1 -1
 790     return false
 791   elseif not empty #to
 792     return true
 793   elseif == file #to file #ep and == rank #from rank #ep and #ep
 794     capture #ep
 795     return true
 796   endif
 797   return false
 798 endsub
 799 endlib