-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuci.py
126 lines (97 loc) · 3.09 KB
/
uci.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
import sys
import time
from position import parse_fen, print_position
from constants import start_position
from moves import make_move, parse_move, get_move_uci
from search import Black_numba, random_move, search
from perft import uci_perft
class Game:
def __init__(self):
self.pos = parse_fen(start_position)
self.bot = Black_numba()
self.moves = []
self.root = True
def parse_position(command, game):
"""
parse 'position' uci command
eg: position startpos moves e2e4 e7e5 f1c4 g8f6
position fen k7/6R1/2K5/8/8/8/8/8 w - - 16 9
"""
param = command.split()
index = command.find("moves")
move_list = [] if index == -1 else command[index:].split()[1:]
if not game.root:
move = parse_move(game.pos, move_list[-1])
game.pos = make_move(game.pos, move)
game.root = False
else:
if param[1] == "fen":
fen_part = command if index == -1 else command[:index]
_, _, fen = fen_part.split(maxsplit=2)
game.pos = parse_fen(fen)
for uci_move in move_list:
move = parse_move(game.pos, uci_move)
game.pos = make_move(game.pos, move)
def parse_go(command, game):
"""parse 'go' uci command"""
d = 12
t = 60000
n = 10 ** 9
_, *params = command.split()
# vivement 3.10!
for p, v in zip(*2 * (iter(params),)):
print(p, v)
if p == "perft":
uci_perft(game.pos, depth=5)
return
elif p == "depth":
d = int(v)
elif p == "movetime":
t = int(v)
elif p == "nodes":
n = int(v)
elif p == "wtime":
if not game.pos.side:
t = int(v) // 40
elif p == "btime":
if game.pos.side:
t = int(v) // 40
_, move, _ = search(
game.bot, game.pos, print_info=True, depth_limit=d, time_limit=t, node_limit=n
)
best_move = get_move_uci(move)
ponder = get_move_uci(game.bot.pv_table[0][1])
print(f"bestmove {best_move} ponder {ponder}")
def main():
"""
The main input/output loop.
This implements a slice of the UCI protocol.
"""
game = Game()
while True:
msg = input()
print(f">>> {msg}", file=sys.stderr)
if msg == "quit":
break
elif msg == "uci":
print("id name black_numba")
print("id author Avo-k")
print("uciok")
elif msg == "isready":
print("readyok")
elif msg == "ucinewgame":
game = Game()
elif msg[:8] == "position":
parse_position(msg, game)
elif msg[:2] == "go":
parse_go(msg, game)
elif msg == "d":
print_position(game.pos)
elif msg == "pv":
print(game.bot.pv_table[0][:10])
if __name__ == "__main__":
print("compiling...")
compiling_time = time.perf_counter()
search(Black_numba(), parse_fen(start_position), print_info=False, depth_limit=2)
print(f"compiled in {time.perf_counter() - compiling_time:.2f} seconds")
main()