Skip to content

Commit 31ac375

Browse files
ryanhsthomasahle
authored andcommitted
simple implementation of uci protocol (thomasahle#43)
* simple implementation of uci protocol * checkout sunfish.py to previous commit * simplify uci.py, import Unbuffered from xboard.py
1 parent ff164af commit 31ac375

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed

uci.py

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
#!/usr/bin/env pypy -u
2+
# -*- coding: utf-8 -*-
3+
4+
from __future__ import print_function
5+
from __future__ import division
6+
import importlib
7+
import re
8+
import sys
9+
import time
10+
11+
import tools
12+
import sunfish
13+
14+
from tools import WHITE, BLACK
15+
from xboard import Unbuffered, sunfish, input
16+
sys.stdout = Unbuffered(sys.stdout)
17+
18+
def main():
19+
pos = tools.parseFEN(tools.FEN_INITIAL)
20+
searcher = sunfish.Searcher()
21+
forced = False
22+
color = WHITE
23+
our_time, opp_time = 1000, 1000 # time in centi-seconds
24+
show_thinking = True
25+
26+
# print name of chess engine
27+
print('Sunfish')
28+
29+
stack = []
30+
while True:
31+
if stack:
32+
smove = stack.pop()
33+
else: smove = input()
34+
35+
if smove == 'quit':
36+
break
37+
38+
elif smove == 'uci':
39+
print('uciok')
40+
41+
elif smove == 'isready':
42+
print('readyok')
43+
44+
elif smove == 'ucinewgame':
45+
stack.append('position fen ' + tools.FEN_INITIAL)
46+
47+
elif smove.startswith('position'):
48+
params = smove.split(' ', 2)
49+
if params[1] == 'fen':
50+
fen = params[2]
51+
pos = tools.parseFEN(fen)
52+
color = WHITE if fen.split()[1] == 'w' else BLACK
53+
54+
elif smove.startswith('go'):
55+
# default options
56+
depth = 1000
57+
movetime = -1
58+
59+
# parse parameters
60+
params = smove.split(' ')
61+
if len(params) == 1: continue
62+
63+
i = 0
64+
while i < len(params):
65+
param = params[i]
66+
if param == 'depth':
67+
i += 1
68+
depth = int(params[i])
69+
if param == 'movetime':
70+
i += 1
71+
movetime = int(params[i])
72+
i += 1
73+
74+
forced = False
75+
76+
moves_remain = 40
77+
78+
start = time.time()
79+
ponder = None
80+
for _ in searcher._search(pos):
81+
moves = tools.pv(searcher, pos, include_scores=False)
82+
83+
if show_thinking:
84+
entry = searcher.tp_score.get((pos, searcher.depth, True))
85+
score = int(round((entry.lower + entry.upper)/2))
86+
usedtime = int((time.time() - start) * 1000)
87+
moves_str = moves if len(moves) < 15 else ''
88+
print('info depth {} score {} time {} nodes {} {}'.format(searcher.depth, score, usedtime, searcher.nodes, moves_str))
89+
90+
if len(moves) > 5:
91+
ponder = moves[1]
92+
93+
if movetime > 0 and (time.time() - start) * 1000 > movetime:
94+
break
95+
96+
if searcher.depth >= depth:
97+
break
98+
99+
entry = searcher.tp_score.get((pos, searcher.depth, True))
100+
m, s = searcher.tp_move.get(pos), entry.lower
101+
# We only resign once we are mated.. That's never?
102+
if s == -sunfish.MATE_UPPER:
103+
print('resign')
104+
else:
105+
moves = moves.split(' ')
106+
if len(moves) > 1:
107+
print('bestmove ' + moves[0] + ' ponder ' + moves[1])
108+
else:
109+
print('bestmove ' + moves[0])
110+
111+
elif smove.startswith('time'):
112+
our_time = int(smove.split()[1])
113+
114+
elif smove.startswith('otim'):
115+
opp_time = int(smove.split()[1])
116+
117+
else:
118+
pass
119+
120+
if __name__ == '__main__':
121+
main()

0 commit comments

Comments
 (0)