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 g2-g3, p is #p, o is g2

space g2 is P

0 P g2-g3 27 61 59 61 59 61 59 29

11011 111101 111011 111101 111011 111101 111011 11101

mv is c7-c6, p is #p, o is c7

space c7 is p

1 p c7-c6 27 61 59 61 59 61 59 29

11011 111101 111011 111101 111011 111101 111011 11101

mv is b1-c3, p is #p, o is b1

space b1 is b1

2 b1 b1-c3 27 61 59 61 59 61 59 29

11011 111101 111011 111101 111011 111101 111011 11101

5 one bits in var b1

11011 1 111011 111101 111011 111101 111011 11101

q end b1-c3 27 1 59 61 59 61 59 29

bb end b1-c3 27 1 59 61 59 61 59 29

bw end b1-c3 27 1 59 61 59 61 59 29

firstr is a1, and lastr is h1

r b1-c3 27 1 59 61 59 61 59 29

first 27 1 59 61 59 61 59 29

mv is g7-g6, p is #p, o is g7

space g7 is p

3 p g7-g6 27 1 59 61 59 61 59 29

11011 1 111011 111101 111011 111101 111011 11101

mv is d1-e3, p is #p, o is d1

space d1 is d1

4 d1 d1-e3 27 1 59 61 59 61 59 29

11011 1 111011 111101 111011 111101 111011 11101

5 one bits in var d1

11011 1 111011 1 111011 111101 111011 11101

q end d1-e3 27 1 59 1 59 61 59 29

bb end d1-e3 27 1 59 1 59 61 59 29

bw end d1-e3 27 1 59 1 59 61 59 29

firstr is a1, and lastr is h1

r d1-e3 27 1 59 1 59 61 59 29

first 27 1 59 1 59 61 59 29

11010 1 111010 1 111010 111100 111010 11100

q end d1-e3 26 1 58 1 58 60 58 28

bb end d1-e3 26 1 58 1 58 60 58 28

bw end d1-e3 26 1 58 1 58 60 58 28

firstr is a1, and lastr is h1

r d1-e3 26 1 58 1 58 60 58 28

first 26 1 58 1 58 60 58 28

mv is h8-c3, p is #p, o is h8

space h8 is h1

5 h1 h8-c3 26 1 58 1 58 60 58 28

11010 1 111010 1 111010 111100 111010 11100

3 one bits in var h1

11010 1 111010 1 111010 111100 111010 10100

q end h8-c3 26 1 58 1 58 60 58 20

bb end h8-c3 26 1 58 1 58 60 58 20

bw end h8-c3 26 1 58 1 58 60 58 20

firstr is a1, and lastr is g1

r h8-c3 26 1 58 1 58 60 26 20

first 26 1 58 1 58 60 26 20

11010 1 111010 1 111010 111100 11010 10100

q end h8-c3 26 1 58 1 58 60 26 20

bb end h8-c3 26 1 58 1 58 60 26 20

bw end h8-c3 26 1 58 1 58 60 26 20

firstr is a1, and lastr is g1

r h8-c3 26 1 58 1 58 60 26 20

first 26 1 58 1 58 60 26 20

mv is d2-c3, p is #p, o is d2

space d2 is P

6 P d2-c3 26 1 58 1 58 60 26 20

11010 1 111010 1 111010 111100 11010 10100

mv is e7-e6, p is #p, o is e7

space e7 is p

7 p e7-e6 26 1 58 1 58 60 26 20

11010 1 111010 1 111010 111100 11010 10100

mv is c1-d2, p is #p, o is c1

space c1 is c1

8 c1 c1-d2 26 1 58 1 58 60 26 20

11010 1 111010 1 111010 111100 11010 10100

4 one bits in var c1

11010 1 110010 1 111010 111100 11010 10100

q end c1-d2 26 1 50 1 58 60 26 20

bb end c1-d2 26 1 50 1 58 60 26 20

bw end c1-d2 26 1 50 1 58 60 26 20

firstr is a1, and lastr is g1

r c1-d2 26 1 50 1 58 60 26 20

first 26 1 50 1 58 60 26 20

mv is f7-f6, p is #p, o is f7

space f7 is p

9 p f7-f6 26 1 50 1 58 60 26 20

11010 1 110010 1 111010 111100 11010 10100

mv is e1-c1, p is #p, o is e1

space e1 is e1

10 e1 e1-c1 26 1 50 1 58 60 26 20

11010 1 110010 1 111010 111100 11010 10100

4 one bits in var e1

rook ride

King castling by moving 2+ spaces

Assuming not actually a castling move.

11010 1 110010 1 11000 111100 11010 10100

q end e1-c1 26 1 50 1 24 60 26 20

bb end e1-c1 26 1 50 1 24 60 26 20

bw end e1-c1 26 1 50 1 24 60 26 20

firstr is a1, and lastr is g1

r e1-c1 26 1 50 1 24 60 26 20

first 26 1 50 1 24 60 26 20

mv is d8-f7, p is #p, o is d8

space d8 is d1

11 d1 d8-f7 26 1 50 1 24 60 26 20

11010 1 110010 1 11000 111100 11010 10100

1 one bits in var d1

11010 1 110010 1 11000 111100 11010 10100

q end d8-f7 26 1 50 1 24 60 26 20

bb end d8-f7 26 1 50 1 24 60 26 20

bw end d8-f7 26 1 50 1 24 60 26 20

firstr is a1, and lastr is g1

r d8-f7 26 1 50 1 24 60 26 20

first 26 1 50 1 24 60 26 20

mv is e3-c4, p is #p, o is e3

space e3 is d1

12 d1 e3-c4 26 1 50 1 24 60 26 20

11010 1 110010 1 11000 111100 11010 10100

1 one bits in var d1

11010 1 110010 1 11000 111100 11010 10100

q end e3-c4 26 1 50 1 24 60 26 20

bb end e3-c4 26 1 50 1 24 60 26 20

bw end e3-c4 26 1 50 1 24 60 26 20

firstr is a1, and lastr is g1

r e3-c4 26 1 50 1 24 60 26 20

first 26 1 50 1 24 60 26 20

mv is f7-e5, p is #p, o is f7

space f7 is d1

13 d1 f7-e5 26 1 50 1 24 60 26 20

11010 1 110010 1 11000 111100 11010 10100

1 one bits in var d1

11010 1 110010 1 11000 111100 11010 10100

q end f7-e5 26 1 50 1 24 60 26 20

bb end f7-e5 26 1 50 1 24 60 26 20

bw end f7-e5 26 1 50 1 24 60 26 20

firstr is a1, and lastr is g1

r f7-e5 26 1 50 1 24 60 26 20

first 26 1 50 1 24 60 26 20

mv is c4-e5, p is #p, o is c4

space c4 is d1

14 d1 c4-e5 26 1 50 1 24 60 26 20

11010 1 110010 1 11000 111100 11010 10100

1 one bits in var d1

11010 1 110010 1 11000 111100 11010 10100

q end c4-e5 26 1 50 1 24 60 26 20

bb end c4-e5 26 1 50 1 24 60 26 20

bw end c4-e5 26 1 50 1 24 60 26 20

firstr is a1, and lastr is g1

r c4-e5 26 1 50 1 24 60 26 20

first 26 1 50 1 24 60 26 20

mv is f6-e5, p is #p, o is f6

space f6 is p

15 p f6-e5 26 1 50 1 24 60 26 20

11010 1 110010 1 11000 111100 11010 10100

mv is f2-f4, p is #p, o is f2

space f2 is P

16 P f2-f4 26 1 50 1 24 60 26 20

11010 1 110010 1 11000 111100 11010 10100

mv is e5-f4, p is #p, o is e5

space e5 is p

17 p e5-f4 26 1 50 1 24 60 26 20

11010 1 110010 1 11000 111100 11010 10100

mv is f1-f4, p is #p, o is f1

space f1 is f1

18 f1 f1-f4 26 1 50 1 24 60 26 20

11010 1 110010 1 11000 111100 11010 10100

4 one bits in var f1

rook ride

f1 currently set to 60

f1 now set to 24

11010 1 110010 1 11000 11000 11010 10100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end f1-f4 8 1 32 1 24 24 26 20

bb end f1-f4 8 1 32 1 24 24 2 20

bw end f1-f4 8 1 32 1 24 24 2 4

firstr is a1, and lastr is f1

One Rook found

b1 1

c1 32

r f1-f4 8 1 32 1 24 24 2 4

first 8 1 32 1 24 24 2 4

1000 1 100000 1 11000 11000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end f1-f4 8 1 32 1 24 24 2 4

bb end f1-f4 8 1 32 1 24 24 2 4

bw end f1-f4 8 1 32 1 24 24 2 4

firstr is a1, and lastr is f1

One Rook found

b1 1

c1 32

r f1-f4 8 1 32 1 24 24 2 4

first 8 1 32 1 24 24 2 4

mv is f8-f4, p is #p, o is f8

space f8 is f1

19 f1 f8-f4 8 1 32 1 24 24 2 4

1000 1 100000 1 11000 11000 10 100

2 one bits in var f1

rook ride

f1 currently set to 24

f1 now set to 24

1000 1 100000 1 11000 11000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end f8-f4 8 1 32 1 24 24 2 4

bb end f8-f4 8 1 32 1 24 24 2 4

bw end f8-f4 8 1 32 1 24 24 2 4

firstr is a1, and lastr is f1

One Rook found

b1 1

c1 32

r f8-f4 8 1 32 1 24 24 2 4

first 8 1 32 1 24 24 2 4

mv is d2-f4, p is #p, o is d2

space d2 is c1

20 c1 d2-f4 8 1 32 1 24 24 2 4

1000 1 100000 1 11000 11000 10 100

1 one bits in var c1

1000 1 100000 1 11000 11000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end d2-f4 8 1 32 1 24 24 2 4

bb end d2-f4 8 1 32 1 24 24 2 4

bw end d2-f4 8 1 32 1 24 24 2 4

firstr is a1, and lastr is f1

One Rook found

b1 1

c1 32

r d2-f4 8 1 32 1 24 24 2 4

first 8 1 32 1 24 24 2 4

mv is b8-a6, p is #p, o is b8

space b8 is b1

21 b1 b8-a6 8 1 32 1 24 24 2 4

1000 1 100000 1 11000 11000 10 100

1 one bits in var b1

1000 1 100000 1 11000 11000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end b8-a6 8 1 32 1 24 24 2 4

bb end b8-a6 8 1 32 1 24 24 2 4

bw end b8-a6 8 1 32 1 24 24 2 4

firstr is a1, and lastr is f1

One Rook found

b1 1

c1 32

r b8-a6 8 1 32 1 24 24 2 4

first 8 1 32 1 24 24 2 4

mv is d1-f1, p is #p, o is d1

space d1 is @

22 @ d1-f1 8 1 32 1 24 24 2 4

1000 1 100000 1 11000 11000 10 100

0 one bits in var @

1000 1 100000 1 11000 11000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end d1-f1 8 1 32 1 24 24 2 4

bb end d1-f1 8 1 32 1 24 24 2 4

bw end d1-f1 8 1 32 1 24 24 2 4

firstr is a1, and lastr is f1

One Rook found

b1 1

c1 32

r d1-f1 8 1 32 1 24 24 2 4

first 8 1 32 1 24 24 2 4

mv is e8-e7, p is #p, o is e8

space e8 is e1

23 e1 e8-e7 8 1 32 1 24 24 2 4

1000 1 100000 1 11000 11000 10 100

2 one bits in var e1

1000 1 100000 1 11000 11000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end e8-e7 8 1 32 1 24 24 2 4

bb end e8-e7 8 1 32 1 24 24 2 4

bw end e8-e7 8 1 32 1 24 24 2 4

firstr is a1, and lastr is f1

One Rook found

b1 1

c1 32

r e8-e7 8 1 32 1 24 24 2 4

first 8 1 32 1 24 24 2 4

mv is f4-f6, p is #p, o is f4

space f4 is c1

24 c1 f4-f6 8 1 32 1 24 24 2 4

1000 1 100000 1 11000 11000 10 100

1 one bits in var c1

1000 1 100000 1 11000 11000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end f4-f6 8 1 32 1 24 24 2 4

bb end f4-f6 8 1 32 1 24 24 2 4

bw end f4-f6 8 1 32 1 24 24 2 4

firstr is a1, and lastr is f1

One Rook found

b1 1

c1 32

r f4-f6 8 1 32 1 24 24 2 4

first 8 1 32 1 24 24 2 4

mv is e7-d6, p is #p, o is e7

space e7 is e1

25 e1 e7-d6 8 1 32 1 24 24 2 4

1000 1 100000 1 11000 11000 10 100

2 one bits in var e1

1000 1 100000 1 10000 11000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end e7-d6 8 1 32 1 16 8 2 4

bb end e7-d6 8 1 32 1 16 8 2 4

bw end e7-d6 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end e7-d6 8 1 32 1 16 8 2 4

bb end e7-d6 8 1 32 1 16 8 2 4

bw end e7-d6 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is f1-d1, p is #p, o is f1

space f1 is @

26 @ f1-d1 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

0 one bits in var @

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end f1-d1 8 1 32 1 16 8 2 4

bb end f1-d1 8 1 32 1 16 8 2 4

bw end f1-d1 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is d6-c7, p is #p, o is d6

space d6 is e1

27 e1 d6-c7 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var e1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end d6-c7 8 1 32 1 16 8 2 4

bb end d6-c7 8 1 32 1 16 8 2 4

bw end d6-c7 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is g1-e3, p is #p, o is g1

space g1 is g1

28 g1 g1-e3 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var g1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end g1-e3 8 1 32 1 16 8 2 4

bb end g1-e3 8 1 32 1 16 8 2 4

bw end g1-e3 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is c8-e8, p is #p, o is c8

space c8 is c1

29 c1 c8-e8 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var c1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end c8-e8 8 1 32 1 16 8 2 4

bb end c8-e8 8 1 32 1 16 8 2 4

bw end c8-e8 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is e3-f4, p is #p, o is e3

space e3 is g1

30 g1 e3-f4 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var g1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end e3-f4 8 1 32 1 16 8 2 4

bb end e3-f4 8 1 32 1 16 8 2 4

bw end e3-f4 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is c7-b6, p is #p, o is c7

space c7 is e1

31 e1 c7-b6 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var e1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end c7-b6 8 1 32 1 16 8 2 4

bb end c7-b6 8 1 32 1 16 8 2 4

bw end c7-b6 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is f6-d4, p is #p, o is f6

space f6 is c1

32 c1 f6-d4 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var c1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end f6-d4 8 1 32 1 16 8 2 4

bb end f6-d4 8 1 32 1 16 8 2 4

bw end f6-d4 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is a6-c5, p is #p, o is a6

space a6 is b1

33 b1 a6-c5 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var b1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end a6-c5 8 1 32 1 16 8 2 4

bb end a6-c5 8 1 32 1 16 8 2 4

bw end a6-c5 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is f4-d6, p is #p, o is f4

space f4 is g1

34 g1 f4-d6 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var g1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end f4-d6 8 1 32 1 16 8 2 4

bb end f4-d6 8 1 32 1 16 8 2 4

bw end f4-d6 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is e8-d8, p is #p, o is e8

space e8 is c1

35 c1 e8-d8 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var c1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end e8-d8 8 1 32 1 16 8 2 4

bb end e8-d8 8 1 32 1 16 8 2 4

bw end e8-d8 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is d4-c5, p is #p, o is d4

space d4 is c1

36 c1 d4-c5 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var c1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end d4-c5 8 1 32 1 16 8 2 4

bb end d4-c5 8 1 32 1 16 8 2 4

bw end d4-c5 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is b6-a6, p is #p, o is b6

space b6 is e1

37 e1 b6-a6 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var e1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end b6-a6 8 1 32 1 16 8 2 4

bb end b6-a6 8 1 32 1 16 8 2 4

bw end b6-a6 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is d1-d4, p is #p, o is d1

space d1 is @

38 @ d1-d4 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

0 one bits in var @

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end d1-d4 8 1 32 1 16 8 2 4

bb end d1-d4 8 1 32 1 16 8 2 4

bw end d1-d4 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is b7-b5, p is #p, o is b7

space b7 is p

39 p b7-b5 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

mv is a2-a4, p is #p, o is a2

space a2 is P

40 P a2-a4 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

mv is e6-e5, p is #p, o is e6

space e6 is p

41 p e6-e5 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

mv is a4-b5, p is #p, o is a4

space a4 is P

42 P a4-b5 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

mv is c6-b5, p is #p, o is c6

space c6 is p

43 p c6-b5 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

mv is d4-b4, p is #p, o is d4

space d4 is @

44 @ d4-b4 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

0 one bits in var @

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end d4-b4 8 1 32 1 16 8 2 4

bb end d4-b4 8 1 32 1 16 8 2 4

bw end d4-b4 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is a8-b8, p is #p, o is a8

space a8 is a1

45 a1 a8-b8 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var a1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end a8-b8 8 1 32 1 16 8 2 4

bb end a8-b8 8 1 32 1 16 8 2 4

bw end a8-b8 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is d6-b8, p is #p, o is d6

space d6 is g1

46 g1 d6-b8 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var g1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end d6-b8 8 1 32 1 16 8 2 4

bb end d6-b8 8 1 32 1 16 8 2 4

bw end d6-b8 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is d8-b8, p is #p, o is d8

space d8 is c1

47 c1 d8-b8 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var c1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end d8-b8 8 1 32 1 16 8 2 4

bb end d8-b8 8 1 32 1 16 8 2 4

bw end d8-b8 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is h1-e4, p is #p, o is h1

space h1 is h1

48 h1 h1-e4 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var h1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end h1-e4 8 1 32 1 16 8 2 4

bb end h1-e4 8 1 32 1 16 8 2 4

bw end h1-e4 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is g8-c4, p is #p, o is g8

space g8 is g1

49 g1 g8-c4 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var g1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end g8-c4 8 1 32 1 16 8 2 4

bb end g8-c4 8 1 32 1 16 8 2 4

bw end g8-c4 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is e4-d3, p is #p, o is e4

space e4 is h1

50 h1 e4-d3 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var h1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end e4-d3 8 1 32 1 16 8 2 4

bb end e4-d3 8 1 32 1 16 8 2 4

bw end e4-d3 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is d7-d6, p is #p, o is d7

space d7 is p

51 p d7-d6 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

mv is c5-e3, p is #p, o is c5

space c5 is c1

52 c1 c5-e3 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var c1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end c5-e3 8 1 32 1 16 8 2 4

bb end c5-e3 8 1 32 1 16 8 2 4

bw end c5-e3 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is d6-d5, p is #p, o is d6

space d6 is p

53 p d6-d5 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

mv is b2-b3, p is #p, o is b2

space b2 is P

54 P b2-b3 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

mv is c4-d3, p is #p, o is c4

space c4 is g1

55 g1 c4-d3 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var g1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end c4-d3 8 1 32 1 16 8 2 4

bb end c4-d3 8 1 32 1 16 8 2 4

bw end c4-d3 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is c2-d3, p is #p, o is c2

space c2 is P

56 P c2-d3 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

mv is d5-d4, p is #p, o is d5

space d5 is p

57 p d5-d4 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

mv is c3-d4, p is #p, o is c3

space c3 is P

58 P c3-d4 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

mv is b8-c7, p is #p, o is b8

space b8 is c1

59 c1 b8-c7 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var c1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end b8-c7 8 1 32 1 16 8 2 4

bb end b8-c7 8 1 32 1 16 8 2 4

bw end b8-c7 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is c1-b2, p is #p, o is c1

space c1 is e1

60 e1 c1-b2 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var e1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end c1-b2 8 1 32 1 16 8 2 4

bb end c1-b2 8 1 32 1 16 8 2 4

bw end c1-b2 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is a6-a5, p is #p, o is a6

space a6 is e1

61 e1 a6-a5 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var e1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end a6-a5 8 1 32 1 16 8 2 4

bb end a6-a5 8 1 32 1 16 8 2 4

bw end a6-a5 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is e3-d2, p is #p, o is e3

space e3 is c1

62 c1 e3-d2 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var c1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end e3-d2 8 1 32 1 16 8 2 4

bb end e3-d2 8 1 32 1 16 8 2 4

bw end e3-d2 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is a5-b6, p is #p, o is a5

space a5 is e1

63 e1 a5-b6 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var e1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end a5-b6 8 1 32 1 16 8 2 4

bb end a5-b6 8 1 32 1 16 8 2 4

bw end a5-b6 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is d4-e5, p is #p, o is d4

space d4 is P

64 P d4-e5 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

mv is c7-e5, p is #p, o is c7

space c7 is c1

65 c1 c7-e5 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var c1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end c7-e5 8 1 32 1 16 8 2 4

bb end c7-e5 8 1 32 1 16 8 2 4

bw end c7-e5 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is b2-a2, p is #p, o is b2

space b2 is e1

66 e1 b2-a2 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var e1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end b2-a2 8 1 32 1 16 8 2 4

bb end b2-a2 8 1 32 1 16 8 2 4

bw end b2-a2 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is a7-a5, p is #p, o is a7

space a7 is p

67 p a7-a5 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

mv is b4-e4, p is #p, o is b4

space b4 is @

68 @ b4-e4 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

0 one bits in var @

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end b4-e4 8 1 32 1 16 8 2 4

bb end b4-e4 8 1 32 1 16 8 2 4

bw end b4-e4 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is e5-d5, p is #p, o is e5

space e5 is c1

69 c1 e5-d5 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var c1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end e5-d5 8 1 32 1 16 8 2 4

bb end e5-d5 8 1 32 1 16 8 2 4

bw end e5-d5 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is d2-e3, p is #p, o is d2

space d2 is c1

70 c1 d2-e3 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var c1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end d2-e3 8 1 32 1 16 8 2 4

bb end d2-e3 8 1 32 1 16 8 2 4

bw end d2-e3 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is d5-c5, p is #p, o is d5

space d5 is c1

71 c1 d5-c5 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var c1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end d5-c5 8 1 32 1 16 8 2 4

bb end d5-c5 8 1 32 1 16 8 2 4

bw end d5-c5 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is e4-e6, p is #p, o is e4

space e4 is @

72 @ e4-e6 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

0 one bits in var @

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end e4-e6 8 1 32 1 16 8 2 4

bb end e4-e6 8 1 32 1 16 8 2 4

bw end e4-e6 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is b6-b7, p is #p, o is b6

space b6 is e1

73 e1 b6-b7 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var e1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end b6-b7 8 1 32 1 16 8 2 4

bb end b6-b7 8 1 32 1 16 8 2 4

bw end b6-b7 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is e3-c5, p is #p, o is e3

space e3 is c1

74 c1 e3-c5 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var c1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end e3-c5 8 1 32 1 16 8 2 4

bb end e3-c5 8 1 32 1 16 8 2 4

bw end e3-c5 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is a5-a4, p is #p, o is a5

space a5 is p

75 p a5-a4 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

mv is c5-c6, p is #p, o is c5

space c5 is c1

76 c1 c5-c6 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var c1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end c5-c6 8 1 32 1 16 8 2 4

bb end c5-c6 8 1 32 1 16 8 2 4

bw end c5-c6 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is b7-a7, p is #p, o is b7

space b7 is e1

77 e1 b7-a7 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var e1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end b7-a7 8 1 32 1 16 8 2 4

bb end b7-a7 8 1 32 1 16 8 2 4

bw end b7-a7 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is c6-c7, p is #p, o is c6

space c6 is c1

78 c1 c6-c7 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var c1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end c6-c7 8 1 32 1 16 8 2 4

bb end c6-c7 8 1 32 1 16 8 2 4

bw end c6-c7 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is a7-a8, p is #p, o is a7

space a7 is e1

79 e1 a7-a8 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var e1

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end a7-a8 8 1 32 1 16 8 2 4

bb end a7-a8 8 1 32 1 16 8 2 4

bw end a7-a8 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

mv is e6-e8, p is #p, o is e6

space e6 is @

80 @ e6-e8 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

0 one bits in var @

1000 1 100000 1 10000 1000 10 100

c1

Array
(
    [0] => a1
    [1] => b1
)

q end e6-e8 8 1 32 1 16 8 2 4

bb end e6-e8 8 1 32 1 16 8 2 4

bw end e6-e8 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

Continue because mv is empty

firstrank is RNKNQRBB

You may not move a K from d2 to f4

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. g2-g3 
1... c7-c6 
2. b1-c3 
2... g7-g6 
3. d1-e3 
3... h8-c3 
4. d2-c3 
4... e7-e6 
5. c1-d2 
5... f7-f6 
6. e1-c1 
6... d8-f7 
7. e3-c4 
7... f7-e5 
8. c4-e5 
8... f6-e5 
9. f2-f4 
9... e5-f4 
10. f1-f4 
10... f8-f4 
11. d2-f4 
11... b8-a6 
12. d1-f1 
12... e8-e7 
13. f4-f6 
13... e7-d6 
14. f1-d1 
14... d6-c7 
15. g1-e3 
15... c8-e8 
16. e3-f4 
16... c7-b6 
17. f6-d4 
17... a6-c5 
18. f4-d6 
18... e8-d8 
19. d4-c5 
19... b6-a6 
20. d1-d4 
20... b7-b5 
21. a2-a4 
21... e6-e5 
22. a4-b5 
22... c6-b5 
23. d4-b4 
23... a8-b8 
24. d6-b8 
24... d8-b8 
25. h1-e4 
25... g8-c4 
26. e4-d3 
26... d7-d6 
27. c5-e3 
27... d6-d5 
28. b2-b3 
28... c4-d3 
29. c2-d3 
29... d5-d4 
30. c3-d4 
30... b8-c7 
31. c1-b2 
31... a6-a5 
32. e3-d2 
32... a5-b6 
33. d4-e5 
33... c7-e5 
34. b2-a2 
34... a7-a5 
35. b4-e4 
35... e5-d5 
36. d2-e3 
36... d5-c5 
37. e4-e6 
37... b6-b7 
38. e3-c5 
38... a5-a4 
39. c5-c6 
39... b7-a7 
40. c6-c7 
40... a7-a8 
41. e6-e8

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