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 c2-c3, p is #p, o is c2

space c2 is P

0 P c2-c3 27 61 59 61 59 61 59 29

11011 111101 111011 111101 111011 111101 111011 11101

mv is h7-h6, p is #p, o is h7

space h7 is p

1 p h7-h6 27 61 59 61 59 61 59 29

11011 111101 111011 111101 111011 111101 111011 11101

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

space e2 is P

2 P e2-e4 27 61 59 61 59 61 59 29

11011 111101 111011 111101 111011 111101 111011 11101

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

space g8 is g1

3 g1 g8-h7 27 61 59 61 59 61 59 29

11011 111101 111011 111101 111011 111101 111011 11101

5 one bits in var g1

11011 111101 111011 111101 111011 111101 110010 11101

q end g8-h7 27 61 59 61 59 61 50 29

bb end g8-h7 27 61 59 61 59 61 50 29

bw end g8-h7 27 61 59 61 59 61 50 29

firstr is a1, and lastr is h1

r g8-h7 27 61 59 61 59 61 50 29

first 27 61 59 61 59 61 50 29

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

space f2 is P

4 P f2-f3 27 61 59 61 59 61 50 29

11011 111101 111011 111101 111011 111101 110010 11101

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

space g7 is p

5 p g7-g5 27 61 59 61 59 61 50 29

11011 111101 111011 111101 111011 111101 110010 11101

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

space g1 is g1

6 g1 g1-f2 27 61 59 61 59 61 50 29

11011 111101 111011 111101 111011 111101 110010 11101

3 one bits in var g1

11011 111101 111011 111101 111011 111101 110010 11101

q end g1-f2 27 61 59 61 59 61 50 29

bb end g1-f2 27 61 59 61 59 61 50 29

bw end g1-f2 27 61 59 61 59 61 50 29

firstr is a1, and lastr is h1

r g1-f2 27 61 59 61 59 61 50 29

first 27 61 59 61 59 61 50 29

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

space b8 is b1

7 b1 b8-c6 27 61 59 61 59 61 50 29

11011 111101 111011 111101 111011 111101 110010 11101

5 one bits in var b1

11011 1 111011 111101 111011 111101 110010 11101

q end b8-c6 27 1 59 61 59 61 50 29

bb end b8-c6 27 1 59 61 59 61 50 29

bw end b8-c6 27 1 59 61 59 61 50 29

firstr is a1, and lastr is h1

r b8-c6 27 1 59 61 59 61 50 29

first 27 1 59 61 59 61 50 29

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

space b2 is P

8 P b2-b3 27 1 59 61 59 61 50 29

11011 1 111011 111101 111011 111101 110010 11101

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

space d7 is p

9 p d7-d6 27 1 59 61 59 61 50 29

11011 1 111011 111101 111011 111101 110010 11101

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

space d2 is P

10 P d2-d4 27 1 59 61 59 61 50 29

11011 1 111011 111101 111011 111101 110010 11101

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

space f7 is p

11 p f7-f5 27 1 59 61 59 61 50 29

11011 1 111011 111101 111011 111101 110010 11101

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

space b1 is b1

12 b1 b1-d2 27 1 59 61 59 61 50 29

11011 1 111011 111101 111011 111101 110010 11101

1 one bits in var b1

11011 1 111011 111101 111011 111101 110010 11101

q end b1-d2 27 1 59 61 59 61 50 29

bb end b1-d2 27 1 59 61 59 61 50 29

bw end b1-d2 27 1 59 61 59 61 50 29

firstr is a1, and lastr is h1

r b1-d2 27 1 59 61 59 61 50 29

first 27 1 59 61 59 61 50 29

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

space c8 is c1

13 c1 c8-d7 27 1 59 61 59 61 50 29

11011 1 111011 111101 111011 111101 110010 11101

5 one bits in var c1

11011 1 110010 111101 111011 111101 110010 11101

q end c8-d7 27 1 50 61 59 61 50 29

bb end c8-d7 27 1 50 61 59 61 50 29

bw end c8-d7 27 1 50 61 59 61 50 29

firstr is a1, and lastr is h1

r c8-d7 27 1 50 61 59 61 50 29

first 27 1 50 61 59 61 50 29

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

space d1 is d1

14 d1 d1-e3 27 1 50 61 59 61 50 29

11011 1 110010 111101 111011 111101 110010 11101

5 one bits in var d1

11011 1 110010 1 111011 111101 110010 11101

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

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

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

firstr is a1, and lastr is h1

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

first 27 1 50 1 59 61 50 29

11010 1 110010 1 111010 111100 110010 11100

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

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

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

firstr is a1, and lastr is h1

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

first 26 1 50 1 58 60 50 28

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

space f5 is p

15 p f5-e4 26 1 50 1 58 60 50 28

11010 1 110010 1 111010 111100 110010 11100

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

space d4 is P

16 P d4-d5 26 1 50 1 58 60 50 28

11010 1 110010 1 111010 111100 110010 11100

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

space c6 is b1

17 b1 c6-e5 26 1 50 1 58 60 50 28

11010 1 110010 1 111010 111100 110010 11100

1 one bits in var b1

11010 1 110010 1 111010 111100 110010 11100

q end c6-e5 26 1 50 1 58 60 50 28

bb end c6-e5 26 1 50 1 58 60 50 28

bw end c6-e5 26 1 50 1 58 60 50 28

firstr is a1, and lastr is h1

r c6-e5 26 1 50 1 58 60 50 28

first 26 1 50 1 58 60 50 28

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

space f3 is P

18 P f3-e4 26 1 50 1 58 60 50 28

11010 1 110010 1 111010 111100 110010 11100

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

space e7 is p

19 p e7-e6 26 1 50 1 58 60 50 28

11010 1 110010 1 111010 111100 110010 11100

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

space d5 is P

20 P d5-e6 26 1 50 1 58 60 50 28

11010 1 110010 1 111010 111100 110010 11100

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

space d8 is d1

21 d1 d8-e6 26 1 50 1 58 60 50 28

11010 1 110010 1 111010 111100 110010 11100

1 one bits in var d1

11010 1 110010 1 111010 111100 110010 11100

q end d8-e6 26 1 50 1 58 60 50 28

bb end d8-e6 26 1 50 1 58 60 50 28

bw end d8-e6 26 1 50 1 58 60 50 28

firstr is a1, and lastr is h1

r d8-e6 26 1 50 1 58 60 50 28

first 26 1 50 1 58 60 50 28

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

space f2 is g1

22 g1 f2-g3 26 1 50 1 58 60 50 28

11010 1 110010 1 111010 111100 110010 11100

3 one bits in var g1

11010 1 110010 1 111010 111100 110010 11100

q end f2-g3 26 1 50 1 58 60 50 28

bb end f2-g3 26 1 50 1 58 60 50 28

bw end f2-g3 26 1 50 1 58 60 50 28

firstr is a1, and lastr is h1

r f2-g3 26 1 50 1 58 60 50 28

first 26 1 50 1 58 60 50 28

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

space e8 is e1

23 e1 e8-c8 26 1 50 1 58 60 50 28

11010 1 110010 1 111010 111100 110010 11100

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 110010 11100

q end e8-c8 26 1 50 1 24 60 50 28

bb end e8-c8 26 1 50 1 24 60 50 28

bw end e8-c8 26 1 50 1 24 60 50 28

firstr is a1, and lastr is h1

r e8-c8 26 1 50 1 24 60 50 28

first 26 1 50 1 24 60 50 28

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

space g3 is g1

24 g1 g3-e5 26 1 50 1 24 60 50 28

11010 1 110010 1 11000 111100 110010 11100

3 one bits in var g1

11010 1 110010 1 11000 111100 10010 11100

q end g3-e5 26 1 50 1 24 60 18 28

bb end g3-e5 26 1 50 1 24 60 18 28

bw end g3-e5 26 1 50 1 24 60 18 28

firstr is a1, and lastr is h1

r g3-e5 26 1 50 1 24 60 18 28

first 26 1 50 1 24 60 18 28

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

space h8 is h1

25 h1 h8-e5 26 1 50 1 24 60 18 28

11010 1 110010 1 11000 111100 10010 11100

3 one bits in var h1

11010 1 110010 1 11000 111100 10010 10100

q end h8-e5 26 1 50 1 24 60 18 20

bb end h8-e5 26 1 50 1 24 60 18 20

bw end h8-e5 26 1 50 1 24 60 18 20

firstr is a1, and lastr is f1

One Rook found

b1 1

c1 50

r h8-e5 8 1 50 1 24 28 18 20

first 8 1 50 1 24 28 18 20

1000 1 110010 1 11000 11100 10010 10100

c1

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

q end h8-e5 8 1 32 1 24 28 18 20

bb end h8-e5 8 1 32 1 24 28 2 20

bw end h8-e5 8 1 32 1 24 28 2 20

firstr is a1, and lastr is f1

One Rook found

b1 1

c1 32

r h8-e5 8 1 32 1 24 28 2 20

first 8 1 32 1 24 28 2 20

1000 1 100000 1 11000 11100 10 10100

c1

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

q end h8-e5 8 1 32 1 24 28 2 20

bb end h8-e5 8 1 32 1 24 28 2 20

bw end h8-e5 8 1 32 1 24 28 2 20

firstr is a1, and lastr is f1

One Rook found

b1 1

c1 32

r h8-e5 8 1 32 1 24 28 2 20

first 8 1 32 1 24 28 2 20

mv is g2-g3, p is #p, o is g2

space g2 is P

26 P g2-g3 8 1 32 1 24 28 2 20

1000 1 100000 1 11000 11100 10 10100

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

space e6 is d1

27 d1 e6-c5 8 1 32 1 24 28 2 20

1000 1 100000 1 11000 11100 10 10100

1 one bits in var d1

1000 1 100000 1 11000 11100 10 10100

c1

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

q end e6-c5 8 1 32 1 24 28 2 20

bb end e6-c5 8 1 32 1 24 28 2 20

bw end e6-c5 8 1 32 1 24 28 2 20

firstr is a1, and lastr is f1

One Rook found

b1 1

c1 32

r e6-c5 8 1 32 1 24 28 2 20

first 8 1 32 1 24 28 2 20

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

space f1 is f1

28 f1 f1-f8 8 1 32 1 24 28 2 20

1000 1 100000 1 11000 11100 10 10100

3 one bits in var f1

rook ride

f1 currently set to 28

f1 now set to 24

1000 1 100000 1 11000 11000 10 10100

c1

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

q end f1-f8 8 1 32 1 24 24 2 20

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

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

firstr is a1, and lastr is f1

One Rook found

b1 1

c1 32

r f1-f8 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-f8 8 1 32 1 24 24 2 4

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

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

firstr is a1, and lastr is f1

One Rook found

b1 1

c1 32

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

first 8 1 32 1 24 24 2 4

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

space d8 is @

29 @ d8-f8 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 d8-f8 8 1 32 1 24 24 2 4

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

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

firstr is a1, and lastr is f1

One Rook found

b1 1

c1 32

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

first 8 1 32 1 24 24 2 4

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

space e1 is e1

30 e1 e1-d1 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 e1-d1 8 1 32 1 24 24 2 4

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

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

firstr is a1, and lastr is f1

One Rook found

b1 1

c1 32

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

first 8 1 32 1 24 24 2 4

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

space c5 is d1

31 d1 c5-d3 8 1 32 1 24 24 2 4

1000 1 100000 1 11000 11000 10 100

1 one bits in var d1

1000 1 100000 1 11000 11000 10 100

c1

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

q end c5-d3 8 1 32 1 24 24 2 4

bb end c5-d3 8 1 32 1 24 24 2 4

bw end c5-d3 8 1 32 1 24 24 2 4

firstr is a1, and lastr is f1

One Rook found

b1 1

c1 32

r c5-d3 8 1 32 1 24 24 2 4

first 8 1 32 1 24 24 2 4

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

space c1 is c1

32 c1 c1-c2 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 c1-c2 8 1 32 1 24 24 2 4

bb end c1-c2 8 1 32 1 24 24 2 4

bw end c1-c2 8 1 32 1 24 24 2 4

firstr is a1, and lastr is f1

One Rook found

b1 1

c1 32

r c1-c2 8 1 32 1 24 24 2 4

first 8 1 32 1 24 24 2 4

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

space d3 is d1

33 d1 d3-f2 8 1 32 1 24 24 2 4

1000 1 100000 1 11000 11000 10 100

1 one bits in var d1

1000 1 100000 1 11000 11000 10 100

c1

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

q end d3-f2 8 1 32 1 24 24 2 4

bb end d3-f2 8 1 32 1 24 24 2 4

bw end d3-f2 8 1 32 1 24 24 2 4

firstr is a1, and lastr is f1

One Rook found

b1 1

c1 32

r d3-f2 8 1 32 1 24 24 2 4

first 8 1 32 1 24 24 2 4

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

space d1 is e1

34 e1 d1-e2 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 d1-e2 8 1 32 1 16 8 2 4

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

bw end d1-e2 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 d1-e2 8 1 32 1 16 8 2 4

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

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

first 8 1 32 1 16 8 2 4

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

space f2 is d1

35 d1 f2-h1 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var d1

1000 1 100000 1 10000 1000 10 100

c1

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

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

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

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

first 8 1 32 1 16 8 2 4

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

space a1 is a1

36 a1 a1-h1 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 a1-h1 8 1 32 1 16 8 2 4

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

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

first 8 1 32 1 16 8 2 4

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

space h7 is g1

37 g1 h7-g6 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 h7-g6 8 1 32 1 16 8 2 4

bb end h7-g6 8 1 32 1 16 8 2 4

bw end h7-g6 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

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

space e3 is d1

38 d1 e3-d5 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

1 one bits in var d1

1000 1 100000 1 10000 1000 10 100

c1

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

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

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

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

first 8 1 32 1 16 8 2 4

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

space d7 is c1

39 c1 d7-g4 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 d7-g4 8 1 32 1 16 8 2 4

bb end d7-g4 8 1 32 1 16 8 2 4

bw end d7-g4 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

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

space e2 is e1

40 e1 e2-e1 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 e2-e1 8 1 32 1 16 8 2 4

bb end e2-e1 8 1 32 1 16 8 2 4

bw end e2-e1 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

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

space g6 is g1

41 g1 g6-h5 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 g6-h5 8 1 32 1 16 8 2 4

bb end g6-h5 8 1 32 1 16 8 2 4

bw end g6-h5 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

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

space d2 is b1

42 b1 d2-c4 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 d2-c4 8 1 32 1 16 8 2 4

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

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

first 8 1 32 1 16 8 2 4

mv is g4-f3, p is #p, o is g4

space g4 is c1

43 c1 g4-f3 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 g4-f3 8 1 32 1 16 8 2 4

bb end g4-f3 8 1 32 1 16 8 2 4

bw end g4-f3 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

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

space c4 is b1

44 b1 c4-e5 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 c4-e5 8 1 32 1 16 8 2 4

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

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

first 8 1 32 1 16 8 2 4

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

space f3 is c1

45 c1 f3-h1 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 f3-h1 8 1 32 1 16 8 2 4

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

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

first 8 1 32 1 16 8 2 4

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

space e1 is e1

46 e1 e1-d2 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 e1-d2 8 1 32 1 16 8 2 4

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

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

first 8 1 32 1 16 8 2 4

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

space f8 is @

47 @ f8-f2 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 f8-f2 8 1 32 1 16 8 2 4

bb end f8-f2 8 1 32 1 16 8 2 4

bw end f8-f2 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

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

space d2 is e1

48 e1 d2-d3 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 d2-d3 8 1 32 1 16 8 2 4

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

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

first 8 1 32 1 16 8 2 4

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

space h1 is c1

49 c1 h1-f1 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 h1-f1 8 1 32 1 16 8 2 4

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

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

first 8 1 32 1 16 8 2 4

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

space d3 is e1

50 e1 d3-d4 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 d3-d4 8 1 32 1 16 8 2 4

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

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

first 8 1 32 1 16 8 2 4

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

space c7 is p

51 p c7-c5 8 1 32 1 16 8 2 4

1000 1 100000 1 10000 1000 10 100

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

space d4 is e1

52 e1 d4-e3 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 d4-e3 8 1 32 1 16 8 2 4

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

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

first 8 1 32 1 16 8 2 4

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

space f2 is @

53 @ f2-c2 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 f2-c2 8 1 32 1 16 8 2 4

bb end f2-c2 8 1 32 1 16 8 2 4

bw end f2-c2 8 1 32 1 16 8 2 4

first 8 1 32 1 16 8 2 4

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

space b3 is P

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

1000 1 100000 1 10000 1000 10 100

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

space f1 is c1

55 c1 f1-e2 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 f1-e2 8 1 32 1 16 8 2 4

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

bw end f1-e2 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 @ from d8 to f8

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. c2-c3 
1... h7-h6 
2. e2-e4 
2... g8-h7 
3. f2-f3 
3... g7-g5 
4. g1-f2 
4... b8-c6 
5. b2-b3 
5... d7-d6 
6. d2-d4 
6... f7-f5 
7. b1-d2 
7... c8-d7 
8. d1-e3 
8... f5-e4 
9. d4-d5 
9... c6-e5 
10. f3-e4 
10... e7-e6 
11. d5-e6 
11... d8-e6 
12. f2-g3 
12... e8-c8 
13. g3-e5 
13... h8-e5 
14. g2-g3 
14... e6-c5 
15. f1-f8 
15... d8-f8 
16. e1-d1 
16... c5-d3 
17. c1-c2 
17... d3-f2 
18. d1-e2 
18... f2-h1 
19. a1-h1 
19... h7-g6 
20. e3-d5 
20... d7-g4 
21. e2-e1 
21... g6-h5 
22. d2-c4 
22... g4-f3 
23. c4-e5 
23... f3-h1 
24. e1-d2 
24... f8-f2 
25. d2-d3 
25... h1-f1 
26. d3-d4 
26... c7-c5 
27. d4-e3 
27... f2-c2 
28. b3-b4 
28... f1-e2

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