forked from thomasahle/sunfish
/
test.py
142 lines (124 loc) · 3.97 KB
/
test.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import sys
import re
from sunfish import Position, MATE_VALUE, search, parse, render, bound
def parseFEN(fen):
""" Parses a string in Forsyth-Edwards Notation into a Position """
board, color, castling, enpas, hclock, fclock = fen.split()
board = re.sub('\d', (lambda m: '.'*int(m.group(0))), board)
board = ' '*21 + ' '.join(board.split('/')[::-1]) + ' '*21
wc = ('Q' in castling, 'K' in castling)
bc = ('k' in castling, 'q' in castling)
ep = parse(enpas) if enpas != '-' else 0
pos = Position(board, 0, wc, bc, ep, 0)
return pos if color == 'w' else pos.rotate()
###############################################################################
# Playing test
###############################################################################
def xboard():
""" Play as a black engine in the CECP/XBoard protocol """
pos = parseFEN('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1')
while True:
smove = input()
if smove == 'quit':
break
elif smove == 'protover 2':
print('feature myname="Sunfish" usermove=1 done=1')
continue
elif smove.startswith('usermove'):
smove = smove[9:]
m = parse(smove[0:2]), parse(smove[2:4])
pos = pos.move(m)
# Respond
m, _ = search(pos)
print("move %s%s" % (render(119-m[0]), render(119-m[1])))
pos = pos.move(m)
else:
print("Didn't understand command '%s'" % smove)
continue
def selfplay():
""" Start a game sunfish vs. sunfish """
pos = parseFEN('rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1')
for d in range(200):
# Always print the board from the same direction
if d % 2 == 0: pos = pos.rotate()
print('\n'.join(pos.board[i:i+10] for i in range(100,0,-10)))
if d % 2 == 0: pos = pos.rotate()
m, _ = search(pos)
if m is None:
print("Game over")
break
print("\nmove %s%s" % tuple(map(render,m)))
pos = pos.move(m)
###############################################################################
# Perft test
###############################################################################
def allperft(path, depth=4):
for d in range(1, depth+1):
print("Going to depth %d" % d)
with open(path) as f:
for line in f:
parts = line.split(';')
print(parts[0])
pos, score = parseFEN(parts[0]), int(parts[d])
res = perft(pos, d)
if res != score:
print('=========================================')
print("ERROR at depth %d. Gave %d rather than %d" % (d, res, score))
print('=========================================')
if d == 1:
print(pos)
perft(pos, d, divide=True)
return
print('')
def perft(pos, depth, divide=False):
if depth == 0:
return 1
res = 0
for m in pos.genMoves():
pos1 = pos.move(m)
# Make sure the move was legal
if not any(pos1.value(m) >= MATE_VALUE for m in pos1.genMoves()):
sub = perft(pos1, depth-1, False)
if divide:
print(" "*depth+render(m[0])+render(m[1]), sub)
res += sub
return res
###############################################################################
# Find mate test
###############################################################################
def allmate(path):
with open(path) as f:
for line in f:
line = line.strip()
print(line)
pos = parseFEN(line)
_, score = search(pos, maxn=1e9)
if score < MATE_VALUE:
print("Unable to find mate. Only got score = %d" % score)
break
def quickmate(path, depth):
""" Similar to allmate, but uses the `bound` function directly to only
search for moves that will win us the game """
with open(path) as f:
for line in f:
line = line.strip()
print(line)
pos = parseFEN(line)
for d in range(depth, 99):
score = bound(pos, MATE_VALUE, d)
if score >= MATE_VALUE:
break
print(d, score)
else:
print("Unable to find mate. Only got score = %d" % score)
return
# Python 2 compatability
if sys.version_info[0] == 2:
input = raw_input
if __name__ == '__main__':
#allperft('queen.epd')
#quickmate('mate1.epd', 3)
#quickmate('mate2.epd', 5)
#quickmate('mate3.epd', 7)
#selfplay()
xboard()