Since no firstrank constant has been stored for this game, one will be calculated by analyzing the moves in the game. This will work only if the game lasted long enough to put enough pieces into play.
mv is P e2-e4, p is P, o is e2
space e2 is P
0 P P e2-e4 27 61 59 61 59 61 59 29
11011 111101 111011 111101 111011 111101 111011 11101
mv is p e7-e5, p is p, o is e7
space e7 is p
1 p p e7-e5 27 61 59 61 59 61 59 29
11011 111101 111011 111101 111011 111101 111011 11101
mv is N f1-e3, p is N, o is f1
space f1 is f1
2 f1 N f1-e3 27 61 59 61 59 61 59 29
11011 111101 111011 111101 111011 111101 111011 11101
5 one bits in var f1
11011 111101 111011 111101 111011 1 111011 11101
q end N f1-e3 27 61 59 61 59 1 59 29
bb end N f1-e3 27 61 59 61 59 1 59 29
bw end N f1-e3 27 61 59 61 59 1 59 29
firstr is a1, and lastr is h1
r N f1-e3 27 61 59 61 59 1 59 29
first 27 61 59 61 59 1 59 29
mv is p d7-d6, p is p, o is d7
space d7 is p
3 p p d7-d6 27 61 59 61 59 1 59 29
11011 111101 111011 111101 111011 1 111011 11101
mv is P c2-c3, p is P, o is c2
space c2 is P
4 P P c2-c3 27 61 59 61 59 1 59 29
11011 111101 111011 111101 111011 1 111011 11101
mv is n a8-b6, p is n, o is a8
space a8 is a1
5 a1 n a8-b6 27 61 59 61 59 1 59 29
11011 111101 111011 111101 111011 1 111011 11101
4 one bits in var a1
1 111101 111011 111101 111011 1 111011 11101
q end n a8-b6 1 61 59 61 59 1 59 29
bb end n a8-b6 1 61 59 61 59 1 59 29
bw end n a8-b6 1 61 59 61 59 1 59 29
firstr is b1, and lastr is h1
r n a8-b6 1 29 59 61 59 1 59 29
first 1 29 59 61 59 1 59 29
1 11100 111010 111100 111010 1 111010 11100
q end n a8-b6 1 28 58 60 58 1 58 28
bb end n a8-b6 1 28 58 60 58 1 58 28
bw end n a8-b6 1 28 58 60 58 1 58 28
firstr is b1, and lastr is h1
r n a8-b6 1 28 58 60 58 1 58 28
first 1 28 58 60 58 1 58 28
mv is P d2-d4, p is P, o is d2
space d2 is P
6 P P d2-d4 1 28 58 60 58 1 58 28
1 11100 111010 111100 111010 1 111010 11100
mv is p e5-d4, p is p, o is e5
space e5 is p
7 p p e5-d4 1 28 58 60 58 1 58 28
1 11100 111010 111100 111010 1 111010 11100
mv is resign, p is #p, o is resign
Continue because resign is resign
Continue because mv is empty
This game may have been too short to properly calculate the original position, and the calculated pattern of N????N?? is inconsistent with randomly generated value of NNRBKRBQ. If you think this game does have enough data to calculate the original position, please report it to Fergus Duniho.
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 e2-e4 1... p e7-e5 2. N f1-e3 2... p d7-d6 3. P c2-c3 3... n a8-b6 4. P d2-d4 4... p e5-d4 5. resignIf this is your settings file, you may edit it at https://www.chessvariants.com/play/pbm/play.php?game=Fischer+Random+Chess&settings=Abstract&submit=Edit
Here is a code listing:
0 empty a1 b1 c1 d1 e1 f1 g1 h1 a8 b8 c8 d8 e8 f8 h8 1 include fischer 2 if isconst firstrank 3 for i range 0 7 4 set c join chr + 97 var i 1 5 set p substr const firstrank var i 1 6 add #p #c 7 next 8 elseif == status "Ongoing" 9 drop B any a1 c1 e1 g1 10 drop B any b1 d1 f1 h1 11 drop Q any a1 b1 c1 d1 e1 f1 g1 h1 12 drop N any a1 b1 c1 d1 e1 f1 g1 h1 13 drop N any a1 b1 c1 d1 e1 f1 g1 h1 14 drop R first a1 b1 c1 d1 e1 f1 15 drop K first b1 c1 d1 e1 f1 g1 16 drop R last c1 d1 e1 f1 g1 h1 17 set fr null 18 for i range a h 19 set fr join var fr space join var i 1 20 next 21 setconst firstrank var fr 22 else 23 echo "Since no firstrank constant has been stored for this game, one will be calculated by analyzing the moves in the game. This will work only if the game lasted long enough to put enough pieces into play." 24 gosub calc_original_position 25 endif 26 copy a1 a8 27 copy b1 b8 28 copy c1 c8 29 copy d1 d8 30 copy e1 e8 31 copy f1 f8 32 copy g1 g8 33 copy h1 h8 34 flip a8 b8 c8 d8 e8 f8 g8 h8 35 set AR findpiece R first a1 b1 c1 d1 e1 f1 36 set HR findpiece R first h1 g1 f1 e1 d1 c1 37 set K findpiece K first b1 c1 d1 e1 f1 g1 38 set ar findpiece r first a8 b8 c8 d8 e8 f8 39 set hr findpiece r first h8 g8 f8 e8 d8 c8 40 set k findpiece k first b8 c8 d8 e8 f8 g8 41 setflag #AR #HR #K #ar #hr #k 42 set k findpiece k spaces 43 set K findpiece K spaces 44 set ep false 45 set koo g8 46 set roo f8 47 set kooo c8 48 set rooo d8 49 set KOO g1 50 set ROO f1 51 set KOOO c1 52 set ROOO d1 53 setsystem "dest" null 54 sub postauto1 55 if not equal moved P 56 set ep false 57 if unequal space dest moved 58 die You may not change the type of this piece. 59 endif 60 endif 61 set legal false 62 if match moved P K R 63 gosub moved origin dest 64 if equal moved K 65 set K dest 66 endif 67 elseif match moved Q B N 68 set legal fn moved origin dest 69 endif 70 if not var legal 71 die You may not move a moved from origin to dest 72 endif 73 if isupper $old and != $old K and != $moved R 74 die You may not capture your own pieces. 75 endif 76 if fn ATTACKEDBYB #K 77 die You may not move into check. 78 endif 79 endsub 80 sub postauto2 81 if not equal moved p 82 set ep false 83 if unequal space dest moved 84 die You may not change the type of this piece. 85 endif 86 endif 87 set legal false 88 if match moved p k r 89 gosub moved origin dest 90 if equal moved k 91 set k dest 92 endif 93 elseif match moved q b n 94 set legal fn toupper moved origin dest 95 endif 96 if not var legal 97 die You may not move a moved from origin to dest 98 endif 99 if islower old and != $old k and != $moved r 100 die You may not capture your own pieces. 101 endif 102 if fn ATTACKEDBYW #k 103 die You may not move into check. 104 endif 105 endsub 106 moveindex 0 107 MOVE: P e2-e4 108 postauto1 109 moveindex 1 110 MOVE: p e7-e5 111 postauto2 112 moveindex 2 113 MOVE: N f1-e3 114 postauto1 115 moveindex 3 116 MOVE: p d7-d6 117 postauto2 118 moveindex 4 119 MOVE: P c2-c3 120 postauto1 121 moveindex 5 122 MOVE: n a8-b6 123 postauto2 124 moveindex 6 125 MOVE: P d2-d4 126 postauto1 127 moveindex 7 128 MOVE: p e5-d4 129 postauto2 130 moveindex 8 131 MOVE: resign 132 postauto1 133 set checks sub checks #k 134 if var checks 135 if sub checkmated #k #checks 136 say Checkmate! White has won! 137 won 138 else 139 say Check! 140 endif 141 elseif sub stalemated #k 142 say Stalemate! The game is drawn. 143 drawn 144 endif 145 end 146 147 lib fischer 148 include chess 149 set wprom (Q R B N) 150 set bprom (q r b n) 151 sub K from to 152 set legal fn K #from #to 153 if not var legal or == old R 154 if == #to #KOOO 155 castle #K #KOOO #AR #ROOO 156 elseif == #to #KOO 157 castle #K #KOO #HR #ROO 158 endif 159 endif 160 set K #to 161 unsetflag #from 162 endsub 163 sub k from to 164 set legal fn K #from #to 165 if not var legal or == old r 166 if == #to #kooo 167 castle #k #kooo #ar #rooo 168 elseif == #to #koo 169 castle #k #koo #hr #roo 170 endif 171 endif 172 set k #to 173 unsetflag #from 174 endsub 175 sub R from to 176 set legal fn R #from #to 177 if not var legal or == old K 178 echo "Castling with Rook!" #from #to #AR #ROOO #HR #ROO 179 if == #from #AR and == #to #ROOO 180 castle #K #KOOO #from #ROOO 181 set K #KOOO 182 elseif == #from #HR and == #to #ROO 183 castle #K #KOO #from #ROO 184 set K #KOO 185 endif 186 endif 187 unsetflag #from 188 endsub 189 sub r from to 190 set legal fn R #from #to 191 if not var legal or == old k 192 if == #from #ar and == #to #rooo 193 castle #k #kooo #from #rooo 194 set k #kooo 195 elseif == #from #hr and == #to #roo 196 castle #k #koo #from #roo 197 set k #koo 198 endif 199 endif 200 unsetflag #from 201 endsub 202 sub castle 203 local ATTACKED c KP RP KF KT RF RT RN 204 if < count #subargs 4 205 die The castle suboutine requires at least four arguments. 206 endif 207 set KF #subargs.0 208 set KT #subargs.1 209 set RF #subargs.2 210 set RT #subargs.3 211 if > count #subargs 4 212 set RN #subargs.4 213 else 214 set RN Rook 215 endif 216 if not flag #KF 217 die A King may not castle after it moves. 218 endif 219 if not flag #RF 220 die A #RN may not castle after it moves. 221 endif 222 if empty #KF and empty #RF 223 die Please castle by moving only one piece. 224 elseif empty #KF 225 if != #RF #KT 226 if capture 227 die The King may not castle to an occupied space. 228 endif 229 set RP space #RF 230 else 231 set RP old 232 setglobal lastcaptured nil 233 endif 234 set KP space #KT 235 empty #KT 236 empty #RF 237 elseif empty #RF 238 if != #KF #RT 239 if capture 240 die The #RN may not castle to an occupied space. 241 endif 242 set KP space #KF 243 else 244 set KP old 245 setglobal lastcaptured nil 246 endif 247 set RP space #RT 248 empty #KF 249 empty #RT 250 elseif capture 251 die You're not allowed to castle with a null move. 252 else 253 set RP space #RF 254 set KP space #KF 255 empty #KF 256 empty #RF 257 endif 258 unsetflag #KF 259 unsetflag #RF 260 if not checkride #KF #KT 1 0 and != #KF #KT 261 die The King may not castle across an obstructed path. 262 endif 263 if not checkride #RF #RT 1 0 and != #RF #RT 264 die The #RN may not castle across an obstructed path. 265 endif 266 add #RP #RF 267 set ATTACKED ATTACKEDBYW unless isupper moved ATTACKEDBYB 268 if fn #ATTACKED #KT 269 die A King may not castle out of check. 270 endif 271 for c path #KF #KT 272 if fn var ATTACKED #c 273 die A King may not castle through check. 274 endif 275 next 276 move #RF #RT 277 add #KP #KT 278 set legal true 279 endsub 280 sub castlepos KF KT RF RT 281 local ATTACKED c safe 282 verify flag #KF 283 verify flag #RF 284 verify empty #KT or match #KT #KF #RF 285 verify empty #RT or match #RT #KF #RF 286 verify checkride #KF #RF 1 0 287 verify checkride #KF #KT 1 0 or checkride #RF #KT 1 0 288 verify allequal rank #KF rank #KT rank #RF rank #RT 289 if isupper space #king 290 def friend isupper #0 291 def friends onlyupper 292 set attacked ATTACKEDBYB 293 else 294 def friend islower #0 295 def friends onlylower 296 set attacked ATTACKEDBYW 297 endif 298 verify not fn var attacked #KF 299 verify not fn var attacked #KT 300 foreach c path #KF #KT 301 verify not fn var attacked #c 302 next 303 store 304 if != #KT #RF 305 move #KF #KT 306 move #RF #RT 307 else 308 move #RF #RT 309 move #KF #KT 310 endif 311 set safe not fn var attacked #KT 312 restore 313 return #safe 314 endsub 315 sub stalemated king 316 local legalmove temp from piece to attacked ra 317 if isupper space #king 318 def friend isupper #0 319 def friends onlyupper 320 set attacked ATTACKEDBYB 321 else 322 def friend islower #0 323 def friends onlylower 324 set attacked ATTACKEDBYW 325 endif 326 store 327 set kingmoves fn KL #king 328 for to #kingmoves 329 if not fn friend space #to and onboard #to 330 move #king #to 331 set incheck fn var attacked #to 332 restore 333 if not #incheck 334 setlegal #king #to 335 endif 336 endif 337 next 338 if isupper space #king 339 if sub castlepos #king #KOOO #AR #ROOO 340 if > distance #king #KOOO 1 or == #KOOO #AR 341 setlegal #king #KOOO 342 else 343 setlegal #AR #ROOO 344 endif 345 endif 346 if sub castlepos #king #KOO #HR #ROO 347 if > distance #king #KOO 1 or == #KOO #HR 348 setlegal #king #KOO 349 else 350 setlegal #HR #ROO 351 endif 352 endif 353 else 354 if sub castlepos #king #kooo #ar #rooo 355 if > distance #king #kooo 1 or == #kooo #ar 356 setlegal #king #kooo 357 else 358 setlegal #ar #rooo 359 endif 360 endif 361 if sub castlepos #king #koo #hr #roo 362 if > distance #king #koo 1 or == #koo #hr 363 setlegal #king #koo 364 else 365 setlegal #hr #roo 366 endif 367 endif 368 endif 369 restore 370 for (from piece) fn friends 371 if == #from #king 372 continue 373 endif 374 for to fn join #piece L #from 375 if fn #piece #from #to and not fn friend space #to and onboard #to 376 move #from #to 377 set incheck fn var attacked #king 378 if not #incheck 379 setlegal #from #to 380 endif 381 endif 382 restore 383 next 384 next 385 return cond count system legalmoves false true 386 endsub 387 sub calc_original_position 388 store 389 local a1 b1 c1 d1 e1 f1 g1 h1 n bb w b r q k K Q R B N ra firstr lastr last 390 add a1 a1 391 add b1 b1 392 add c1 c1 393 add d1 d1 394 add e1 e1 395 add f1 f1 396 add g1 g1 397 add h1 h1 398 add a1 a8 399 add b1 b8 400 add c1 c8 401 add d1 d8 402 add e1 e8 403 add f1 f8 404 add g1 g8 405 add h1 h8 406 set many n 1 bb 2 bw 4 b 6 r 8 q 16 k 32 407 set a1 orsum #r #n #bb #q 408 set b1 orsum #r #n #bw #q #k 409 set c1 orsum #r #n #bb #q #k 410 set d1 orsum #r #n #bw #q #k 411 set e1 orsum #r #n #bb #q #k 412 set f1 orsum #r #n #bw #q #k 413 set g1 orsum #r #n #bb #q #k 414 set h1 orsum #r #n #bw #q 415 set many K 1 Q 1 R 2 B 2 N 2 416 set rank1 array a1 b1 c1 d1 e1 f1 g1 h1 417 setflag a1 b1 c1 d1 e1 f1 g1 h1 a8 b8 c8 d8 e8 f8 g8 h8 418 foreach i range 0 $maxmoves 419 set normal true 420 set mv move #i 421 if not var mv 422 echo "Continue because mv is empty" 423 continue 424 endif 425 set mv str_replace " - " chr 45 var mv 426 set pm explode " " var mv 427 set p elem 0 pm 428 set m elem 1 pm 429 if != var m null 430 set od explode hyphen var m 431 else 432 set od explode hyphen var mv 433 unset p 434 endif 435 set o elem 0 od 436 set d elem 1 od 437 echo "mv is {#mv}, p is {#p}, o is {#o}" 438 if == #mv #o 439 echo "Continue because {#mv} is {#o}" 440 continue 441 endif 442 set pp space #o 443 echo "space {#o} is {#pp}" 444 echo #i #pp #mv #a1 #b1 #c1 #d1 #e1 #f1 #g1 #h1 445 set b2 list base 2 #a1 base 2 #b1 base 2 #c1 base 2 #d1 base 2 #e1 base 2 #f1 base 2 #g1 base 2 #h1 446 echo #b2 447 if match #pp p P 448 if checkleap #o #d 1 1 and empty #d 449 set ep join filename #d rankname #o 450 if == space #ep flipcase space #0 451 empty #ep 452 endif 453 endif 454 move #o #d 455 continue 456 elseif match #pp n N b B r R q Q 457 move #o #d 458 continue 459 endif 460 set bp onebits var #pp 461 echo "{#bp} one bits in var {#pp}" 462 if > #bp 1 and match var p k q r b n p K Q R B N P and != var p null 463 set lc tolower var p 464 set #pp bitand ##pp ##lc 465 elseif == ##pp "@" 466 echo "Warning: There is no piece on {#o}" 467 elseif > #bp 1 468 if checkleap #o #d 1 2 469 set #pp bitand ##pp #n 470 elseif checkleap #o #d 1 0 471 set os orsum #r #q #k 472 set #pp bitand ##pp orsum #r #q #k 473 elseif checkleap #o #d 1 1 474 set #pp bitand ##pp orsum #b #q #k 475 elseif checkride #o #d 1 1 476 set #pp bitand ##pp orsum #b #q 477 elseif checkride #o #d 1 0 478 echo "rook ride" 479 if == rank #o rank #d and match rankname #d 1 8 480 if match #d c1 g1 c8 g8 and flag #o 481 if not empty #d 482 echo "King castles by moving to Rook's space." 483 set #pp bitand ##pp #k 484 set ro #d 485 set rp space #ro 486 set #rp #r 487 echo "rp: {#rp}, val: {##rp}" 488 if == #d c1 489 set rd d1 490 elseif == #d c8 491 set rd d8 492 elseif == #d g1 493 set rd f1 494 else 495 set rd f8 496 endif 497 move #o temp 498 move #d #rd 499 move temp #d 500 foreach f flags 501 if == rank f rank #o 502 unsetflag #f 503 endif 504 next 505 set normal false 506 elseif empty #d and bitand ##pp #k 507 echo "King castling by moving 2+ spaces" 508 if == #d c1 509 if empty b1 510 set ro a1 511 else 512 set ro b1 513 endif 514 set rd d1 515 elseif == #d g1 516 set ro h1 517 set rd f1 518 elseif == #d c8 519 if empty b8 520 set ro a8 521 else 522 set ro b8 523 endif 524 set rd d8 525 elseif == #d g8 526 set ro h8 527 set rd f8 528 endif 529 set rp space #ro 530 if not bitand #ko #r or not bitand #a1 #r or match file #ro a h bitand ##rp #r and not bitand ##pp #q and flag #ro 531 move #o #d 532 move #ro #rd 533 set #pp #k 534 set #rp #r 535 foreach f flags 536 if == rank f rank #o 537 unsetflag #f 538 endif 539 next 540 set normal false 541 else 542 echo "Assuming not actually a castling move." 543 set #pp bitand ##pp orsum #r #q 544 endif 545 else 546 echo "Rook or Queen move" 547 set #pp bitand ##pp orsum #r #q 548 endif 549 elseif not empty #d and match #d f1 d1 f8 d8 and flag #o 550 echo "Rook castles by moving to King's space." 551 set #pp bitand ##pp #r 552 set ko #d 553 echo "ko set to {#ko}" 554 set kp space #ko 555 set #kp #k 556 echo "{#kp} set to {##kp}" 557 if == #d f1 558 set kd g1 559 elseif == #d d1 560 set kd c1 561 elseif == #d f8 562 set kd g8 563 elseif == #d d8 564 set kd c8 565 endif 566 if == #kd #o 567 swap #kd #o 568 else 569 move #o #d 570 move #ko #kd 571 endif 572 foreach f flags 573 if == rank f rank #o 574 unsetflag #f 575 endif 576 next 577 set normal false 578 else 579 echo "Rook or Queen move" 580 set #pp bitand ##pp orsum #r #q 581 endif 582 else 583 echo "{#pp} currently set to {##pp}" 584 set #pp bitand ##pp bitor #r #q 585 echo "{#pp} now set to {##pp}" 586 endif 587 elseif checkhop #o #d 1 0 and match rankname #o 1 8 and flag #o 588 echo "rook hopping king to castle" 589 if and match #d f1 d1 f8 d8 590 set #pp bitand ##pp #r 591 set ko screen 592 set kp var space #ko 593 set #kp #k 594 if == #d f1 595 set kd g1 596 elseif == #d d1 597 set kd c1 598 elseif == #d f8 599 set kd g8 600 elseif == #d d8 601 set kd c8 602 endif 603 if == #kd #o and == #d #ko 604 swap #kd #o 605 elseif == #d #ko 606 move #o temp 607 move #ko #kd 608 move temp #d 609 else 610 move #o #d 611 move #ko #kd 612 endif 613 foreach f flags 614 if == rank f rank #o 615 unsetflag #f 616 endif 617 next 618 set normal false 619 elseif match #d c1 g1 c8 g8 and flag #o 620 echo "King castling by hopping over Rook" 621 set #pp bitand ##pp #k 622 set ro screen 623 set rp var space #ro 624 set #rp #r 625 if == #d c1 626 set rd d1 627 elseif == #d c8 628 set rd d8 629 elseif == #d g1 630 set rd f1 631 else 632 set rd f8 633 endif 634 move #o #d 635 move #ro #rd 636 foreach f flags 637 if == rank f rank #o 638 unsetflag #f 639 endif 640 next 641 set normal false 642 endif 643 endif 644 if == ##pp 0 645 echo "ERROR: Potential piece value set to zero" 646 endif 647 endif 648 do 649 set b2 list base 2 #a1 base 2 #b1 base 2 #c1 base 2 #d1 base 2 #e1 base 2 #f1 base 2 #g1 base 2 #h1 650 echo #b2 651 set changed false 652 set ra aggregate lambda (cond bitand var #0 #k #0 false) #rank1 653 if == count #ra 1 654 set kp #ra.0 655 if != ##kp #k 656 set #kp #k 657 set changed true 658 endif 659 set ra aggregate lambda (cond == var #0 #k #0 false) #rank1 660 set kp #ra.0 661 echo #kp 662 set leftside aggregate lambda (cond < #0 #kp #0 false) #rank1 663 printr #leftside 664 set ra aggregate lambda (cond bitand var #0 #r #0 false) #leftside 665 if == count #ra 1 666 foreach sp #ra 667 if != ##sp #r 668 set #sp #r 669 set changed true 670 endif 671 next 672 else 673 set ra aggregate lambda (cond == var #0 #r #0 false) #leftside 674 if == count #ra 1 675 foreach sp #leftside 676 if != ##sp #r 677 set #sp bitand ##sp bitxor 63 #r 678 set changed true 679 endif 680 next 681 endif 682 endif 683 set rightside aggregate lambda (cond > #0 #kp #0 false) #rank1 684 set ra aggregate lambda (cond bitand var #0 #r #0 false) #rightside 685 if == count #ra 1 686 foreach sp #ra 687 if != ##sp #r 688 set #sp #r 689 set changed true 690 endif 691 next 692 else 693 set ra aggregate lambda (cond == var #0 #r #0 false) #rightside 694 if == count #ra 1 695 foreach sp #rightside 696 if != ##sp #r 697 set #sp bitand ##sp bitxor 63 #r 698 set changed true 699 endif 700 next 701 endif 702 endif 703 else 704 set ra aggregate lambda (cond != var #0 #k #0 false) #rank1 705 if == count #ra 7 706 foreach sp #ra 707 if bitand ##sp #k 708 set #sp bitand ##sp bitxor 63 #k 709 set changed true 710 endif 711 next 712 endif 713 endif 714 set ra aggregate lambda (cond bitand var #0 #q #0 false) #rank1 715 if == count #ra 1 716 foreach sp #ra 717 if != ##sp #q 718 set #sp #q 719 set changed true 720 endif 721 next 722 else 723 set ra aggregate lambda (cond != var #0 #q #0 false) #rank1 724 if == count #ra 7 725 echo queen before #mv #a1 #b1 #c1 #d1 #e1 #f1 #g1 #h1 726 foreach sp #ra 727 if bitand ##sp #q 728 set #sp bitand ##sp bitxor 63 #q 729 set changed true 730 endif 731 next 732 echo queen after #mv #a1 #b1 #c1 #d1 #e1 #f1 #g1 #h1 733 endif 734 endif 735 echo q end #mv #a1 #b1 #c1 #d1 #e1 #f1 #g1 #h1 736 set ra aggregate lambda (cond bitand var #0 #bb #0 false) #rank1 737 if == count #ra 1 738 foreach sp #ra 739 if != ##sp #bb 740 set #sp #bb 741 set changed true 742 endif 743 next 744 else 745 set ra aggregate lambda (cond != var #0 #bb #0 false) #rank1 746 if == count #ra 7 747 foreach sp #ra 748 if bitand ##sp #bb 749 set #sp bitand ##sp bitxor 63 #bb 750 set changed true 751 endif 752 next 753 endif 754 endif 755 echo bb end #mv #a1 #b1 #c1 #d1 #e1 #f1 #g1 #h1 756 set ra aggregate lambda (cond bitand var #0 #bw #0 false) #rank1 757 if == count #ra 1 758 foreach sp #ra 759 if != ##sp #bw 760 set #sp #bw 761 set changed true 762 endif 763 next 764 else 765 set ra aggregate lambda (cond != var #0 #bw #0 false) #rank1 766 if == count #ra 7 767 foreach sp #ra 768 if bitand ##sp #bw 769 set #sp bitand ##sp bitxor 63 #bw 770 set changed true 771 endif 772 next 773 endif 774 endif 775 echo bw end #mv #a1 #b1 #c1 #d1 #e1 #f1 #g1 #h1 776 set ra aggregate lambda (cond bitand var #0 #r #0 false) #rank1 777 if == count #ra 2 778 foreach sp #ra 779 if != ##sp #r 780 set #sp #r 781 set changed true 782 endif 783 next 784 set betweenrooks aggregate lambda (cond and < #ra.0 #0 > #ra.1 #0 #0 false) #rank1 785 set ra2 aggregate lambda (cond bitand var #0 #k #0 false) #betweenrooks 786 if == count #ra2 1 787 foreach sp #ra2 788 if != ##sp #k 789 set #sp #k 790 set changed true 791 endif 792 next 793 else 794 set ra2 aggregate lambda (cond == var #0 #r #0 false) #rank1 795 foreach sp #rank1 796 echo #ra2.0 #ra2.1 797 if < #sp #ra2.0 or > #sp #ra2.1 and bitand ##sp #k 798 set #sp bitand ##sp bitxor 63 #k 799 set changed true 800 endif 801 next 802 endif 803 else 804 set firstr #ra.0 805 set last - count #ra 1 806 set lastr #ra.{#last} 807 echo "firstr is {#firstr}, and lastr is {#lastr}" 808 set rooks 0 809 foreach sp #rank1 810 if match #sp #firstr #lastr 811 inc rooks 812 if bitand ##sp #k 813 set #sp bitand ##sp bitxor 63 #k 814 set changed true 815 endif 816 elseif != #rooks 1 817 if bitand ##sp #k 818 set #sp bitand ##sp bitxor 63 #k 819 set changed true 820 endif 821 endif 822 next 823 if == count #ra 3 824 set leftking anytrue lambda (bitand var #0 #k and > #0 #ra.0 and < #0 #ra.1) #rank1 825 set rghtking anytrue lambda (bitand var #0 #k and > #0 #ra.1 and < #0 #ra.2) #rank1 826 if not #leftking 827 set #ra.2 #r 828 elseif not #rghtking 829 set #ra.0 #r 830 endif 831 endif 832 set ra aggregate lambda (cond != var #0 #r #0 false) #rank1 833 if == count #ra 6 834 echo "Two rooks found." 835 foreach sp #ra 836 if bitand ##sp #r 837 set #sp bitand ##sp bitxor 63 #r 838 set changed true 839 endif 840 next 841 elseif == count #ra 7 842 echo "One Rook found" 843 set ra aggregate lambda (cond == var #0 #r #0 false) #rank1 844 set next where #ra.0 1 0 845 do while onboard #next 846 echo #next ##next 847 if bitand ##next #r 848 set #next bitand ##next bitxor 63 #r 849 set changed true 850 endif 851 if bitand ##next #k 852 break 853 endif 854 set next where #next 1 0 855 loop 856 set prev where #ra.0 -1 0 857 do while onboard #prev 858 if bitand ##prev #r 859 set #prev bitand ##prev bitxor 63 #r 860 set changed true 861 endif 862 if bitand ##prev #k 863 break 864 endif 865 set prev where #prev -1 0 866 loop 867 endif 868 echo r #mv #a1 #b1 #c1 #d1 #e1 #f1 #g1 #h1 869 endif 870 echo first #a1 #b1 #c1 #d1 #e1 #f1 #g1 #h1 871 set ra aggregate lambda (cond bitand var #0 #2 #0 false) #rank1 872 if == count #ra 2 873 foreach sp #ra 874 if != ##sp #n 875 set #sp #n 876 set changed true 877 endif 878 next 879 else 880 set ra aggregate lambda (cond != var #0 #n #0 false) #rank1 881 if == count #ra 6 882 foreach sp #ra 883 if bitand ##sp #n 884 set #sp bitand ##sp bitxor 63 #n 885 set changed true 886 endif 887 next 888 endif 889 endif 890 loop while #changed 891 if var normal 892 move #o #d 893 unsetflag #o #d 894 endif 895 next 896 set fr "" 897 foreach c (a1 b1 c1 d1 e1 f1 g1 h1) 898 if == ##c #n 899 set fr join #fr "N" 900 elseif match ##c #bb #bw 901 set fr join #fr "B" 902 elseif == ##c #r 903 set fr join #fr "R" 904 elseif == ##c #q 905 set fr join #fr "Q" 906 elseif == ##c #k 907 set fr join #fr "K" 908 else 909 set fr join #fr "@" 910 endif 911 next 912 if !== false strstr #fr "@" 913 set pat str_replace "@" "?" #fr 914 empty a1 b1 c1 d1 e1 f1 g1 h1 a8 b8 c8 d8 e8 f8 h8 915 drop B any a1 c1 e1 g1 916 drop B any b1 d1 f1 h1 917 drop Q any a1 b1 c1 d1 e1 f1 g1 h1 918 drop N any a1 b1 c1 d1 e1 f1 g1 h1 919 drop N any a1 b1 c1 d1 e1 f1 g1 h1 920 drop R first a1 b1 c1 d1 e1 f1 921 drop K first b1 c1 d1 e1 f1 g1 922 drop R last c1 d1 e1 f1 g1 h1 923 set fr null 924 for i range a h 925 set fr join var fr space join var i 1 926 next 927 if not fnmatch var pat var fr 928 die "This game may have been too short to properly calculate the original position, and the calculated pattern of {#pat} is inconsistent with randomly generated value of {#fr}. If you think this game does have enough data to calculate the original position, please report it to Fergus Duniho." 929 endif 930 endif 931 restore 932 setconst firstrank #fr 933 for i range 0 7 934 set c join chr + 97 var i 1 935 set p substr const firstrank var i 1 936 add #p #c 937 next 938 echo "firstrank is" @firstrank 939 endsub 940 endlib 941 lib chess 942 set wpr 2 943 set bpr 7 944 set fps 2 945 set pzs 1 946 set wcastle c1 g1 947 set bcastle c8 g8 948 do 949 local x 950 for x piecekeys 951 if match #x P K p k 952 continue 953 elseif isupper #x 954 push wprom #x 955 elseif islower #x 956 push bprom #x 957 endif 958 next 959 loop never 960 setsystem maxmove 2 961 ban commands allmoves 962 allow moves 1 captures 1 promotions 2 963 def N checkleap #0 #1 1 2 964 def B checkride #0 #1 1 1 965 def R checkride #0 #1 1 0 966 def Q fn B #0 #1 or fn R #0 #1 967 def K checkleap #0 #1 1 1 or checkleap #0 #1 1 0 968 def M fn N #0 #1 or fn R #0 #1 969 def A fn N #0 #1 or fn B #0 #1 970 def n checkleap #0 #1 1 2 971 def b checkride #0 #1 1 1 972 def r checkride #0 #1 1 0 973 def q fn b #0 #1 or fn r #0 #1 974 def k checkleap #0 #1 1 1 or checkleap #0 #1 1 0 975 def m fn n #0 #1 or fn r #0 #1 976 def a fn n #0 #1 or fn b #0 #1 977 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 978 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 979 sub capturep p 980 empty #p 981 return true 982 endsub 983 sub checks king 984 if not dest 985 return false 986 endif 987 my checks c 988 set checks () 989 if fn space dest dest #king 990 setelem checks dest space dest 991 endif 992 set c sub checkedthru #king origin 993 if #c 994 setelem checks #c space #c 995 elseif #epc 996 set c sub checkedthru #king #epc 997 if #c 998 setelem checks #c space #c 999 endif 1000 endif 1001 return var checks 1002 endsub 1003 sub checkmated king checks 1004 local from piece to key legalmove piece nopawn 1005 store 1006 if isupper space #king 1007 def friends onlyupper 1008 def friend isupper #0 1009 set attacked ATTACKEDBYB 1010 else 1011 def friends onlylower 1012 def friend islower #0 1013 set attacked ATTACKEDBYW 1014 endif 1015 set kingmoves fn KL #king 1016 for to #kingmoves 1017 if not fn friend space #to and onboard #to 1018 move #king #to 1019 set incheck fn var attacked #to 1020 restore 1021 if not #incheck 1022 setlegal #king #to 1023 endif 1024 endif 1025 next 1026 if == count var checks 1 1027 for (key enemy) var checks 1028 set possible path #king #key 1029 push possible #key 1030 if == #key #ep 1031 push possible cond isupper space #ep where #ep 0 -1 where #ep 0 1 1032 endif 1033 for (from piece) fn friends 1034 if == #from #king 1035 continue 1036 endif 1037 for to #possible 1038 if fn #piece #from #to 1039 move #from #to 1040 set incheck fn var attacked #king 1041 if not #incheck 1042 setlegal #from #to 1043 endif 1044 endif 1045 restore 1046 next 1047 next 1048 next 1049 endif 1050 return cond count system legalmoves false true and checks 1051 endsub 1052 def PL array where #0 0 2 where #0 0 1 where #0 -1 1 where #0 1 1 1053 def pL array where #0 0 -2 where #0 0 -1 where #0 -1 -1 where #0 1 -1 1054 def NL leaps #0 1 2 1055 def BL rays #0 1 1 1056 def RL rays #0 1 0 1057 def VL rays #0 1 1 1058 def CL rays #0 1 0 1059 def QL merge rays #0 1 0 rays #0 1 1 1060 def KL merge leaps #0 1 0 leaps #0 1 1 1061 def AL merge leaps #0 1 2 rays #0 1 1 1062 def ML merge rays #0 1 0 leaps #0 1 2 1063 def nL leaps #0 1 2 1064 def bL rays #0 1 1 1065 def rL rays #0 1 0 1066 def vL rays #0 1 1 1067 def cL rays #0 1 0 1068 def qL merge rays #0 1 0 rays #0 1 1 1069 def kL merge leaps #0 1 0 leaps #0 1 1 1070 def aL merge leaps #0 1 2 rays #0 1 1 1071 def mL merge rays #0 1 0 leaps #0 1 2 1072 sub castlepos from to 1073 local c RPOS RDEST xdir safe 1074 verify flag #from 1075 verify empty #to 1076 if isupper space #king 1077 def friend isupper #0 1078 def friends onlyupper 1079 set attacked ATTACKEDBYB 1080 else 1081 def friend islower #0 1082 def friends onlylower 1083 set attacked ATTACKEDBYW 1084 endif 1085 set xdir sign minus file #to file #from 1086 verify checkaride #from #to #xdir 0 1087 verify not fn var attacked #from 1088 set c #to 1089 do 1090 set c where #c #xdir 0 1091 if flag #c 1092 break 1093 endif 1094 verify onboard #c 1095 verify empty #c 1096 loop 1097 verify flag #c 1098 set RPOS #c 1099 store 1100 for c path #from #to 1101 move #from #c 1102 set safe not fn var attacked #c 1103 restore 1104 verify #safe 1105 next 1106 move #from #to 1107 set RDEST where #to neg #xdir 0 1108 move #RPOS #RDEST 1109 return true 1110 endsub 1111 sub stalemated king 1112 local legalmove temp from piece to attacked ra 1113 if isupper space #king 1114 def friend isupper #0 1115 def friends onlyupper 1116 set attacked ATTACKEDBYB 1117 set cspaces var wcastle 1118 else 1119 def friend islower #0 1120 def friends onlylower 1121 set attacked ATTACKEDBYW 1122 set cspaces var bcastle 1123 endif 1124 store 1125 set kingmoves fn KL #king 1126 for to #kingmoves 1127 if not fn friend space #to and onboard #to 1128 move #king #to 1129 set incheck fn var attacked #to 1130 restore 1131 if not #incheck 1132 setlegal #king #to 1133 endif 1134 endif 1135 next 1136 for to var cspaces 1137 if sub castlepos #king #to 1138 set incheck fn var attacked #to 1139 restore 1140 if not #incheck 1141 setlegal #king #to 1142 endif 1143 endif 1144 next 1145 restore 1146 for (from piece) fn friends 1147 if == #from #king 1148 continue 1149 endif 1150 for to fn join #piece L #from 1151 if fn #piece #from #to and not fn friend space #to and onboard #to 1152 move #from #to 1153 set incheck fn var attacked #king 1154 if not #incheck 1155 setlegal #from #to 1156 endif 1157 endif 1158 restore 1159 next 1160 next 1161 return cond count system legalmoves false true 1162 endsub 1163 def WPAWN match P what #0 1 -1 what #0 -1 -1 1164 def BPAWN match p what #0 1 1 what #0 -1 1 1165 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 1166 def WAZIR check what #0 0 -1 check what #0 -1 0 check what #0 0 1 check what #0 1 0 target #1 1167 def FERZ check what #0 -1 -1 check what #0 -1 1 check what #0 1 -1 check what #0 1 1 target #1 1168 def KING fn WAZIR #0 #1 or fn FERZ #0 #1 1169 def ROOK check insight #0 0 -1 check insight #0 -1 0 check insight #0 0 1 check insight #0 1 0 target #1 1170 def BISHOP check insight #0 -1 -1 check insight #0 -1 1 check insight #0 1 -1 check insight #0 1 1 target #1 1171 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) 1172 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) 1173 sub P from to 1174 local ydir 1175 if == file #from file #to and not capture 1176 set legal checkaleap #from #to 0 1 1177 if var legal 1178 set ep false 1179 else 1180 set legal checkaride #from #to 0 1 and <= distance #from #to #fps and or == rankname #from #wpr < #wpr 0 1181 set ep #to 1182 endif 1183 set epc false 1184 elseif capture or #ep 1185 set legal checkaleap #from #to -1 1 or checkaleap #from #to 1 1 1186 set epc false 1187 if not capture and var legal 1188 set legal > rank #to rank #ep and < rankname #to #bpr and == file #to file #ep 1189 if var legal 1190 capture #ep 1191 set epc #ep 1192 endif 1193 endif 1194 set ep false 1195 endif 1196 if != space #to moved and onboard where #to 0 #pzs 1197 die "You may not promote a Pawn until it reaches the promotion zone." 1198 endif 1199 if not onboard where #to 0 1 1200 if == P space #to 1201 askpromote #wprom 1202 elseif not match space #to var wprom 1203 set np space #to 1204 die "You may not promote your Pawn to a" #np 1205 endif 1206 endif 1207 endsub 1208 sub p from to 1209 if == file #from file #to and not capture 1210 set legal checkaleap #from #to 0 -1 1211 if var legal 1212 set ep false 1213 else 1214 set legal checkaride #from #to 0 -1 and <= distance #from #to #fps and or == rankname #from #bpr > #bpr lastrank 1215 set ep #to 1216 endif 1217 set epc false 1218 elseif capture or #ep 1219 set legal checkaleap #from #to -1 -1 or checkaleap #from #to 1 -1 1220 set epc false 1221 if not capture and var legal 1222 set legal < rank #to rank #ep and > rankname #to #wpr and == file #to file #ep 1223 if var legal 1224 capture #ep 1225 set epc #ep 1226 endif 1227 endif 1228 set ep false 1229 endif 1230 if != space #to moved and onboard where #to 0 neg #pzs 1231 die You may not promote a Pawn until it reaches the promotion zone. 1232 endif 1233 if not onboard where #to 0 -1 1234 if == p space #to 1235 askpromote #bprom 1236 elseif not match space #to var bprom 1237 set np space #to 1238 die You may not promote your Pawn to a #np 1239 endif 1240 endif 1241 endsub 1242 sub K from to 1243 if match #to var wcastle and flag #from 1244 set legal sub castle 1245 else 1246 set legal fn K #from #to 1247 endif 1248 set K #to 1249 unsetflag e1 1250 endsub 1251 sub k from to 1252 if match #to var bcastle and flag #from 1253 set legal sub castle 1254 else 1255 set legal fn k #from #to 1256 endif 1257 set k #to 1258 unsetflag e8 1259 endsub 1260 sub castle 1261 local ATTACKED c RPOS RDEST xdir 1262 if not flag #from 1263 die A King may not castle after it moves. 1264 endif 1265 if capture 1266 die A King may not castle to an occupied space. 1267 endif 1268 set xdir sign minus file #to file #from 1269 if not checkaride #from #to #xdir 0 1270 die A King may not castle across any occupied space. 1271 endif 1272 set c #to 1273 do 1274 set c where #c #xdir 0 1275 if flag #c 1276 break 1277 elseif not onboard #c 1278 die No piece was found to castle with. 1279 elseif not empty #c 1280 die The King cannot castle with the piece at #c 1281 endif 1282 loop 1283 set RPOS #c 1284 set ATTACKED ATTACKEDBYW unless isupper moved ATTACKEDBYB 1285 if fn var ATTACKED #from 1286 die A King may not castle out of check. 1287 endif 1288 for c path #from #to 1289 if fn var ATTACKED #c 1290 die A King may not castle through check. 1291 endif 1292 next 1293 if == count var subargs 0 1294 set RDEST where #to neg #xdir 0 1295 else 1296 set RDEST elem 0 subarg 1297 endif 1298 unsetflag #RPOS 1299 move #RPOS #RDEST 1300 return true 1301 endsub 1302 sub checkedthru king loc 1303 my dir c 1304 set c revealed #king #loc 1305 verify fn space #c #c #king and not samecase space #king space #c and onboard #c and #c 1306 return #c 1307 endsub 1308 def fn checkedfrom fn space #1 #0 and xor isupper space #0 isupper space #1 and not empty #1 1309 sub P1 from to 1310 if == file #from file #to 1311 return not capture 1312 elseif capture 1313 return true 1314 elseif == file #to file #ep and == rank #from rank #ep and #ep 1315 capture #ep 1316 return true 1317 endif 1318 return false 1319 endsub 1320 sub PP from to 1321 if checkatwostep #from #to 0 1 0 1 or checkaleap #from #to 0 1 1322 return empty #to 1323 elseif not checkaleap #from #to 1 1 and not checkaleap #from #to -1 1 1324 return false 1325 elseif not empty #to 1326 return true 1327 elseif == file #to file #ep and == rank #from rank #ep and #ep 1328 capture #ep 1329 return true 1330 endif 1331 return false 1332 endsub 1333 sub pp from to 1334 if checkatwostep #from #to 0 -1 0 -1 or checkaleap #from #to 0 -1 1335 return empty #to 1336 elseif not checkaleap #from #to 1 -1 and not checkaleap #from #to -1 -1 1337 return false 1338 elseif not empty #to 1339 return true 1340 elseif == file #to file #ep and == rank #from rank #ep and #ep 1341 capture #ep 1342 return true 1343 endif 1344 return false 1345 endsub 1346 endlib