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 e2-e4, p is #p, o is e2

space e2 is P

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

11011 111101 111011 111101 111011 111101 111011 11101

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

space b7 is p

1 p b7-b6 27 61 59 61 59 61 59 29

11011 111101 111011 111101 111011 111101 111011 11101

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

space b2 is P

2 P b2-b3 27 61 59 61 59 61 59 29

11011 111101 111011 111101 111011 111101 111011 11101

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

space e7 is p

3 p e7-e5 27 61 59 61 59 61 59 29

11011 111101 111011 111101 111011 111101 111011 11101

mv is N f1-e3, p is N, o is f1

space f1 is f1

4 f1 N f1-e3 27 61 59 61 59 61 59 29

11011 111101 111011 111101 111011 111101 111011 11101

5 one bits in var f1

11011 111101 111011 111101 111011 1 111011 11101

q end N f1-e3 27 61 59 61 59 1 59 29

bb end N f1-e3 27 61 59 61 59 1 59 29

bw end N f1-e3 27 61 59 61 59 1 59 29

firstr is a1, and lastr is h1

r N f1-e3 27 61 59 61 59 1 59 29

first 27 61 59 61 59 1 59 29

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

space d7 is p

5 p d7-d6 27 61 59 61 59 1 59 29

11011 111101 111011 111101 111011 1 111011 11101

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

space b1 is b1

6 b1 N b1-c3 27 61 59 61 59 1 59 29

11011 111101 111011 111101 111011 1 111011 11101

5 one bits in var b1

11011 1 111011 111101 111011 1 111011 11101

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

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

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

firstr is a1, and lastr is h1

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

first 27 1 59 61 59 1 59 29

11010 1 111010 111100 111010 1 111010 11100

q end N b1-c3 26 1 58 60 58 1 58 28

bb end N b1-c3 26 1 58 60 58 1 58 28

bw end N b1-c3 26 1 58 60 58 1 58 28

firstr is a1, and lastr is h1

r N b1-c3 26 1 58 60 58 1 58 28

first 26 1 58 60 58 1 58 28

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

space f8 is f1

7 f1 f8-g6 26 1 58 60 58 1 58 28

11010 1 111010 111100 111010 1 111010 11100

1 one bits in var f1

11010 1 111010 111100 111010 1 111010 11100

q end f8-g6 26 1 58 60 58 1 58 28

bb end f8-g6 26 1 58 60 58 1 58 28

bw end f8-g6 26 1 58 60 58 1 58 28

firstr is a1, and lastr is h1

r f8-g6 26 1 58 60 58 1 58 28

first 26 1 58 60 58 1 58 28

mv is B d1-g4, p is B, o is d1

space d1 is d1

8 d1 B d1-g4 26 1 58 60 58 1 58 28

11010 1 111010 111100 111010 1 111010 11100

4 one bits in var d1

11010 1 111010 100 111010 1 111010 11100

q end B d1-g4 26 1 58 4 58 1 58 28

bb end B d1-g4 26 1 58 4 58 1 58 28

bw end B d1-g4 26 1 58 4 58 1 58 24

firstr is a1, and lastr is h1

r B d1-g4 26 1 58 4 58 1 58 24

first 26 1 58 4 58 1 58 24

11010 1 111010 100 111010 1 111010 11000

q end B d1-g4 26 1 58 4 58 1 58 24

bb end B d1-g4 26 1 58 4 58 1 58 24

bw end B d1-g4 26 1 58 4 58 1 58 24

firstr is a1, and lastr is h1

r B d1-g4 26 1 58 4 58 1 58 24

first 26 1 58 4 58 1 58 24

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

space b8 is b1

9 b1 b8-d7 26 1 58 4 58 1 58 24

11010 1 111010 100 111010 1 111010 11000

1 one bits in var b1

11010 1 111010 100 111010 1 111010 11000

q end b8-d7 26 1 58 4 58 1 58 24

bb end b8-d7 26 1 58 4 58 1 58 24

bw end b8-d7 26 1 58 4 58 1 58 24

firstr is a1, and lastr is h1

r b8-d7 26 1 58 4 58 1 58 24

first 26 1 58 4 58 1 58 24

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

space e3 is f1

10 f1 N e3-c4 26 1 58 4 58 1 58 24

11010 1 111010 100 111010 1 111010 11000

1 one bits in var f1

11010 1 111010 100 111010 1 111010 11000

q end N e3-c4 26 1 58 4 58 1 58 24

bb end N e3-c4 26 1 58 4 58 1 58 24

bw end N e3-c4 26 1 58 4 58 1 58 24

firstr is a1, and lastr is h1

r N e3-c4 26 1 58 4 58 1 58 24

first 26 1 58 4 58 1 58 24

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

space h7 is p

11 p h7-h5 26 1 58 4 58 1 58 24

11010 1 111010 100 111010 1 111010 11000

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

space g4 is d1

12 d1 B g4-f3 26 1 58 4 58 1 58 24

11010 1 111010 100 111010 1 111010 11000

1 one bits in var d1

11010 1 111010 100 111010 1 111010 11000

q end B g4-f3 26 1 58 4 58 1 58 24

bb end B g4-f3 26 1 58 4 58 1 58 24

bw end B g4-f3 26 1 58 4 58 1 58 24

firstr is a1, and lastr is h1

r B g4-f3 26 1 58 4 58 1 58 24

first 26 1 58 4 58 1 58 24

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

space d7 is b1

13 b1 d7-c5 26 1 58 4 58 1 58 24

11010 1 111010 100 111010 1 111010 11000

1 one bits in var b1

11010 1 111010 100 111010 1 111010 11000

q end d7-c5 26 1 58 4 58 1 58 24

bb end d7-c5 26 1 58 4 58 1 58 24

bw end d7-c5 26 1 58 4 58 1 58 24

firstr is a1, and lastr is h1

r d7-c5 26 1 58 4 58 1 58 24

first 26 1 58 4 58 1 58 24

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

space d2 is P

14 P d2-d3 26 1 58 4 58 1 58 24

11010 1 111010 100 111010 1 111010 11000

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

space g6 is f1

15 f1 g6-f4 26 1 58 4 58 1 58 24

11010 1 111010 100 111010 1 111010 11000

1 one bits in var f1

11010 1 111010 100 111010 1 111010 11000

q end g6-f4 26 1 58 4 58 1 58 24

bb end g6-f4 26 1 58 4 58 1 58 24

bw end g6-f4 26 1 58 4 58 1 58 24

firstr is a1, and lastr is h1

r g6-f4 26 1 58 4 58 1 58 24

first 26 1 58 4 58 1 58 24

mv is N c3-e2, p is N, o is c3

space c3 is b1

16 b1 N c3-e2 26 1 58 4 58 1 58 24

11010 1 111010 100 111010 1 111010 11000

1 one bits in var b1

11010 1 111010 100 111010 1 111010 11000

q end N c3-e2 26 1 58 4 58 1 58 24

bb end N c3-e2 26 1 58 4 58 1 58 24

bw end N c3-e2 26 1 58 4 58 1 58 24

firstr is a1, and lastr is h1

r N c3-e2 26 1 58 4 58 1 58 24

first 26 1 58 4 58 1 58 24

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

space f4 is f1

17 f1 f4-d3 26 1 58 4 58 1 58 24

11010 1 111010 100 111010 1 111010 11000

1 one bits in var f1

11010 1 111010 100 111010 1 111010 11000

q end f4-d3 26 1 58 4 58 1 58 24

bb end f4-d3 26 1 58 4 58 1 58 24

bw end f4-d3 26 1 58 4 58 1 58 24

firstr is a1, and lastr is h1

r f4-d3 26 1 58 4 58 1 58 24

first 26 1 58 4 58 1 58 24

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

space c2 is P

18 P c2-d3 26 1 58 4 58 1 58 24

11010 1 111010 100 111010 1 111010 11000

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

space c5 is b1

19 b1 c5-d3 26 1 58 4 58 1 58 24

11010 1 111010 100 111010 1 111010 11000

1 one bits in var b1

11010 1 111010 100 111010 1 111010 11000

q end c5-d3 26 1 58 4 58 1 58 24

bb end c5-d3 26 1 58 4 58 1 58 24

bw end c5-d3 26 1 58 4 58 1 58 24

firstr is a1, and lastr is h1

r c5-d3 26 1 58 4 58 1 58 24

first 26 1 58 4 58 1 58 24

mv is Q e1-c3, p is Q, o is e1

space e1 is e1

20 e1 Q e1-c3 26 1 58 4 58 1 58 24

11010 1 111010 100 111010 1 111010 11000

4 one bits in var e1

11010 1 111010 100 10000 1 111010 11000

queen before Q e1-c3 26 1 58 4 16 1 58 24

queen after Q e1-c3 10 1 42 4 16 1 42 8

q end Q e1-c3 10 1 42 4 16 1 42 8

bb end Q e1-c3 10 1 42 4 16 1 42 8

bw end Q e1-c3 10 1 42 4 16 1 42 8

firstr is a1, and lastr is h1

One Rook found

r Q e1-c3 10 1 42 4 16 1 34 8

first 10 1 42 4 16 1 34 8

1010 1 101010 100 10000 1 100010 1000

q end Q e1-c3 10 1 42 4 16 1 34 8

bb end Q e1-c3 10 1 42 4 16 1 34 8

bw end Q e1-c3 10 1 42 4 16 1 34 8

firstr is a1, and lastr is h1

One Rook found

r Q e1-c3 10 1 42 4 16 1 34 8

first 10 1 42 4 16 1 34 8

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

space d3 is b1

21 b1 d3-c1 10 1 42 4 16 1 34 8

1010 1 101010 100 10000 1 100010 1000

1 one bits in var b1

1010 1 101010 100 10000 1 100010 1000

q end d3-c1 10 1 42 4 16 1 34 8

bb end d3-c1 10 1 42 4 16 1 34 8

bw end d3-c1 10 1 42 4 16 1 34 8

firstr is a1, and lastr is h1

One Rook found

r d3-c1 10 1 42 4 16 1 34 8

first 10 1 42 4 16 1 34 8

mv is N e2-c1, p is N, o is e2

space e2 is b1

22 b1 N e2-c1 10 1 42 4 16 1 34 8

1010 1 101010 100 10000 1 100010 1000

1 one bits in var b1

1010 1 101010 100 10000 1 100010 1000

q end N e2-c1 10 1 42 4 16 1 34 8

bb end N e2-c1 10 1 42 4 16 1 34 8

bw end N e2-c1 10 1 42 4 16 1 34 8

firstr is a1, and lastr is h1

One Rook found

r N e2-c1 10 1 42 4 16 1 34 8

first 10 1 42 4 16 1 34 8

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

space h5 is p

23 p h5-h4 10 1 42 4 16 1 34 8

1010 1 101010 100 10000 1 100010 1000

mv is N c4-d6, p is N, o is c4

space c4 is f1

24 f1 N c4-d6 10 1 42 4 16 1 34 8

1010 1 101010 100 10000 1 100010 1000

1 one bits in var f1

1010 1 101010 100 10000 1 100010 1000

q end N c4-d6 10 1 42 4 16 1 34 8

bb end N c4-d6 10 1 42 4 16 1 34 8

bw end N c4-d6 10 1 42 4 16 1 34 8

firstr is a1, and lastr is h1

One Rook found

r N c4-d6 10 1 42 4 16 1 34 8

first 10 1 42 4 16 1 34 8

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

space e8 is e1

25 e1 e8-d7 10 1 42 4 16 1 34 8

1010 1 101010 100 10000 1 100010 1000

1 one bits in var e1

1010 1 101010 100 10000 1 100010 1000

q end e8-d7 10 1 42 4 16 1 34 8

bb end e8-d7 10 1 42 4 16 1 34 8

bw end e8-d7 10 1 42 4 16 1 34 8

firstr is a1, and lastr is h1

One Rook found

r e8-d7 10 1 42 4 16 1 34 8

first 10 1 42 4 16 1 34 8

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

space d6 is f1

26 f1 d6-c8 10 1 42 4 16 1 34 8

1010 1 101010 100 10000 1 100010 1000

1 one bits in var f1

1010 1 101010 100 10000 1 100010 1000

q end d6-c8 10 1 42 4 16 1 34 8

bb end d6-c8 10 1 42 4 16 1 34 8

bw end d6-c8 10 1 42 4 16 1 34 8

firstr is a1, and lastr is h1

One Rook found

r d6-c8 10 1 42 4 16 1 34 8

first 10 1 42 4 16 1 34 8

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

space d7 is e1

27 e1 d7-c8 10 1 42 4 16 1 34 8

1010 1 101010 100 10000 1 100010 1000

1 one bits in var e1

1010 1 101010 100 10000 1 100010 1000

q end d7-c8 10 1 42 4 16 1 34 8

bb end d7-c8 10 1 42 4 16 1 34 8

bw end d7-c8 10 1 42 4 16 1 34 8

firstr is a1, and lastr is h1

One Rook found

r d7-c8 10 1 42 4 16 1 34 8

first 10 1 42 4 16 1 34 8

mv is h2-h3, p is #p, o is h2

space h2 is P

28 P h2-h3 10 1 42 4 16 1 34 8

1010 1 101010 100 10000 1 100010 1000

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

space c7 is p

29 p c7-c5 10 1 42 4 16 1 34 8

1010 1 101010 100 10000 1 100010 1000

mv is N c1-d3, p is N, o is c1

space c1 is b1

30 b1 N c1-d3 10 1 42 4 16 1 34 8

1010 1 101010 100 10000 1 100010 1000

1 one bits in var b1

1010 1 101010 100 10000 1 100010 1000

q end N c1-d3 10 1 42 4 16 1 34 8

bb end N c1-d3 10 1 42 4 16 1 34 8

bw end N c1-d3 10 1 42 4 16 1 34 8

firstr is a1, and lastr is h1

One Rook found

r N c1-d3 10 1 42 4 16 1 34 8

first 10 1 42 4 16 1 34 8

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

space h8 is h1

31 h1 h8-h6 10 1 42 4 16 1 34 8

1010 1 101010 100 10000 1 100010 1000

1 one bits in var h1

1010 1 101010 100 10000 1 100010 1000

q end h8-h6 10 1 42 4 16 1 34 8

bb end h8-h6 10 1 42 4 16 1 34 8

bw end h8-h6 10 1 42 4 16 1 34 8

firstr is a1, and lastr is h1

One Rook found

r h8-h6 10 1 42 4 16 1 34 8

first 10 1 42 4 16 1 34 8

mv is N d3-f4, p is N, o is d3

space d3 is b1

32 b1 N d3-f4 10 1 42 4 16 1 34 8

1010 1 101010 100 10000 1 100010 1000

1 one bits in var b1

1010 1 101010 100 10000 1 100010 1000

q end N d3-f4 10 1 42 4 16 1 34 8

bb end N d3-f4 10 1 42 4 16 1 34 8

bw end N d3-f4 10 1 42 4 16 1 34 8

firstr is a1, and lastr is h1

One Rook found

r N d3-f4 10 1 42 4 16 1 34 8

first 10 1 42 4 16 1 34 8

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

space h6 is h1

33 h1 h6-d6 10 1 42 4 16 1 34 8

1010 1 101010 100 10000 1 100010 1000

1 one bits in var h1

1010 1 101010 100 10000 1 100010 1000

q end h6-d6 10 1 42 4 16 1 34 8

bb end h6-d6 10 1 42 4 16 1 34 8

bw end h6-d6 10 1 42 4 16 1 34 8

firstr is a1, and lastr is h1

One Rook found

r h6-d6 10 1 42 4 16 1 34 8

first 10 1 42 4 16 1 34 8

mv is Q c3-e5, p is Q, o is c3

space c3 is e1

34 e1 Q c3-e5 10 1 42 4 16 1 34 8

1010 1 101010 100 10000 1 100010 1000

1 one bits in var e1

1010 1 101010 100 10000 1 100010 1000

q end Q c3-e5 10 1 42 4 16 1 34 8

bb end Q c3-e5 10 1 42 4 16 1 34 8

bw end Q c3-e5 10 1 42 4 16 1 34 8

firstr is a1, and lastr is h1

One Rook found

r Q c3-e5 10 1 42 4 16 1 34 8

first 10 1 42 4 16 1 34 8

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

space d8 is d1

35 d1 d8-f6 10 1 42 4 16 1 34 8

1010 1 101010 100 10000 1 100010 1000

1 one bits in var d1

1010 1 101010 100 10000 1 100010 1000

q end d8-f6 10 1 42 4 16 1 34 8

bb end d8-f6 10 1 42 4 16 1 34 8

bw end d8-f6 10 1 42 4 16 1 34 8

firstr is a1, and lastr is h1

One Rook found

r d8-f6 10 1 42 4 16 1 34 8

first 10 1 42 4 16 1 34 8

mv is Q e5-d6, p is Q, o is e5

space e5 is e1

36 e1 Q e5-d6 10 1 42 4 16 1 34 8

1010 1 101010 100 10000 1 100010 1000

1 one bits in var e1

1010 1 101010 100 10000 1 100010 1000

q end Q e5-d6 10 1 42 4 16 1 34 8

bb end Q e5-d6 10 1 42 4 16 1 34 8

bw end Q e5-d6 10 1 42 4 16 1 34 8

firstr is a1, and lastr is h1

One Rook found

r Q e5-d6 10 1 42 4 16 1 34 8

first 10 1 42 4 16 1 34 8

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

space f6 is d1

37 d1 f6-a1 10 1 42 4 16 1 34 8

1010 1 101010 100 10000 1 100010 1000

1 one bits in var d1

1010 1 101010 100 10000 1 100010 1000

q end f6-a1 10 1 42 4 16 1 34 8

bb end f6-a1 10 1 42 4 16 1 34 8

bw end f6-a1 10 1 42 4 16 1 34 8

firstr is a1, and lastr is h1

One Rook found

r f6-a1 10 1 42 4 16 1 34 8

first 10 1 42 4 16 1 34 8

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

space h1 is h1

38 h1 R h1-f1 10 1 42 4 16 1 34 8

1010 1 101010 100 10000 1 100010 1000

1 one bits in var h1

1010 1 101010 100 10000 1 100010 1000

q end R h1-f1 10 1 42 4 16 1 34 8

bb end R h1-f1 10 1 42 4 16 1 34 8

bw end R h1-f1 10 1 42 4 16 1 34 8

firstr is a1, and lastr is h1

One Rook found

r R h1-f1 10 1 42 4 16 1 34 8

first 10 1 42 4 16 1 34 8

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

space a1 is d1

39 d1 a1-d4 10 1 42 4 16 1 34 8

1010 1 101010 100 10000 1 100010 1000

1 one bits in var d1

1010 1 101010 100 10000 1 100010 1000

q end a1-d4 10 1 42 4 16 1 34 8

bb end a1-d4 10 1 42 4 16 1 34 8

bw end a1-d4 10 1 42 4 16 1 34 8

firstr is a1, and lastr is h1

One Rook found

r a1-d4 10 1 42 4 16 1 34 8

first 10 1 42 4 16 1 34 8

mv is R f1-c1, p is R, o is f1

space f1 is h1

40 h1 R f1-c1 10 1 42 4 16 1 34 8

1010 1 101010 100 10000 1 100010 1000

1 one bits in var h1

1010 1 101010 100 10000 1 100010 1000

q end R f1-c1 10 1 42 4 16 1 34 8

bb end R f1-c1 10 1 42 4 16 1 34 8

bw end R f1-c1 10 1 42 4 16 1 34 8

firstr is a1, and lastr is h1

One Rook found

r R f1-c1 10 1 42 4 16 1 34 8

first 10 1 42 4 16 1 34 8

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

space c8 is e1

41 e1 c8-f8 10 1 42 4 16 1 34 8

1010 1 101010 100 10000 1 100010 1000

1 one bits in var e1

1010 1 101010 100 10000 1 100010 1000

q end c8-f8 10 1 42 4 16 1 34 8

bb end c8-f8 10 1 42 4 16 1 34 8

bw end c8-f8 10 1 42 4 16 1 34 8

firstr is a1, and lastr is h1

One Rook found

r c8-f8 10 1 42 4 16 1 34 8

first 10 1 42 4 16 1 34 8

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

space d6 is e1

42 e1 Q d6-c7 10 1 42 4 16 1 34 8

1010 1 101010 100 10000 1 100010 1000

1 one bits in var e1

1010 1 101010 100 10000 1 100010 1000

q end Q d6-c7 10 1 42 4 16 1 34 8

bb end Q d6-c7 10 1 42 4 16 1 34 8

bw end Q d6-c7 10 1 42 4 16 1 34 8

firstr is a1, and lastr is h1

One Rook found

r Q d6-c7 10 1 42 4 16 1 34 8

first 10 1 42 4 16 1 34 8

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

space g8 is g1

43 g1 g8-h8 10 1 42 4 16 1 34 8

1010 1 101010 100 10000 1 100010 1000

2 one bits in var g1

1010 1 101010 100 10000 1 100000 1000

q end g8-h8 10 1 10 4 16 1 32 8

bb end g8-h8 10 1 10 4 16 1 32 8

bw end g8-h8 10 1 10 4 16 1 32 8

firstr is a1, and lastr is h1

One Rook found

r g8-h8 10 1 10 4 16 1 32 8

first 10 1 10 4 16 1 32 8

1010 1 1010 100 10000 1 100000 1000

g1

Array
(
    [0] => a1
    [1] => b1
    [2] => c1
    [3] => d1
    [4] => e1
    [5] => f1
)

q end g8-h8 10 1 10 4 16 1 32 8

bb end g8-h8 10 1 10 4 16 1 32 8

bw end g8-h8 10 1 10 4 16 1 32 8

firstr is a1, and lastr is h1

One Rook found

r g8-h8 10 1 10 4 16 1 32 8

first 10 1 10 4 16 1 32 8

Continue because mv is empty

This game may have been too short to properly calculate the original position, and the calculated pattern of is inconsistent with randomly generated value of NRBQKBNR. If you think this game does have enough data to calculate the original position, please report it to Fergus Duniho.

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

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

1. e2-e4 
1... b7-b6 
2. b2-b3 
2... e7-e5 
3. N f1-e3 
3... d7-d6 
4. N b1-c3 
4... f8-g6 
5. B d1-g4 
5... b8-d7 
6. N e3-c4 
6... h7-h5 
7. B g4-f3 
7... d7-c5 
8. d2-d3 
8... g6-f4 
9. N c3-e2 
9... f4-d3 
10. c2-d3 
10... c5-d3 
11. Q e1-c3 
11... d3-c1 
12. N e2-c1 
12... h5-h4 
13. N c4-d6 
13... e8-d7 
14. d6-c8 
14... d7-c8 
15. h2-h3 
15... c7-c5 
16. N c1-d3 
16... h8-h6 
17. N d3-f4 
17... h6-d6 
18. Q c3-e5 
18... d8-f6 
19. Q e5-d6 
19... f6-a1 
20. R h1-f1 
20... a1-d4 
21. R f1-c1 
21... c8-f8 
22. Q d6-c7 
22... g8-h8

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