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 into check.

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. N b1 - c3 
1... d7-d5 
2. d2-d4 
2... e7-e6 
3. N g1-f3 
3... g8-f6 
4. N f3 - e5 
4... f6-e4 
5. N c3 - e4 
5... d5-e4 
6. B c1 - f4 
6... d8-d6 
7. Q d1 - d2 
7... b8-c6 
8. e2-e3 
8... f7-f6 
9. N e5 - c4 
9... d6-d5 
10. b2-b3 
10... b7-b5 
11. N c4 - a3 
11... f8-a3 
12. c2 - c4 
12... b5-c4 
13. B f1 - c4 
13... d5-a5 
14. K e1 - d1 
14... e8-d8 
15. Q d2-c2 
15... g7-g5 
16. Q c2 - e4 
16... a5-c3 
17. R a1 - b1 
17... g5-f4 
18. Q e4 - c6 
18... a8-b8 
19. R h1 - e1 
19... b8-b6 
20. Q c6-a4 
20... a3-b2 
21. R b1-b2 
21... c3-b2 
22. e3-f4 
22... b2-d4 
23. K d1-c2 
23... b6-d6 
24. R e1-e2 
24... d4-d1 
25. K c2-c3 
25... d1-c1 
26. K c3-b4 
26... d6-b6 
27. K b4-c5 
27... c1-f4 
28. B c4-e6 
28... f4-d6 
29. K c5-c4 
29... c8-e6 
30. K c4-c3 
30... d6-c6 
31. K c3-b2 
31... c6-a4 
32. resign

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