24-add-uci-layer #39
@@ -2,12 +2,16 @@
|
||||
import sys, shlex
|
||||
import ctypes as C
|
||||
from binding.python_c_ffi import ChessFFI, Board, Move, WHITE, Q, R, B, N, q, r, b, n
|
||||
from scripts.evaluation import RandomEval
|
||||
|
||||
|
||||
START_FEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
|
||||
PROMO_MAP = {"q": (Q, q), "r": (R, r), "b": (B, b), "n": (N, n)}
|
||||
ONE_MINUTE = 60000
|
||||
THREE_MINUTES = ONE_MINUTE * 3
|
||||
FIVE_MINUTES = ONE_MINUTE * 5
|
||||
TEN_MINUTES = ONE_MINUTE * 10
|
||||
THIRTY_MINUTES = ONE_MINUTE * 30
|
||||
|
||||
|
||||
def flushln(s: str):
|
||||
sys.stdout.write(s + "\n")
|
||||
@@ -64,6 +68,10 @@ class UCIEngine:
|
||||
"MoveOverhead": 100,
|
||||
}
|
||||
|
||||
self.default_depth = 6
|
||||
self.short_depth = 5
|
||||
self.long_depth = 7
|
||||
|
||||
self.wtime = None
|
||||
self.btime = None
|
||||
|
||||
@@ -74,7 +82,7 @@ class UCIEngine:
|
||||
seed = time.time_ns()
|
||||
s32 = int(seed) & 0xFFFFFFFF
|
||||
|
||||
libc = C.CDLL("libc.so.6") # on Ubuntu
|
||||
libc = C.CDLL("libc.so.6")
|
||||
libc.srand.argtypes = (C.c_uint,)
|
||||
libc.srand.restype = None
|
||||
libc.srand(C.c_uint(s32))
|
||||
@@ -84,14 +92,14 @@ class UCIEngine:
|
||||
def cmd_uci(self):
|
||||
flushln("id name joshsbot")
|
||||
flushln("id author Josh")
|
||||
# declare supported options properly
|
||||
# UCI options. Do we even need these? We just use this interface
|
||||
# for the lichess-bot. It's not like we plan on using them?
|
||||
flushln("option name Depth type spin default 3 min 1 max 64")
|
||||
flushln("option name WindowCp type spin default 50 min 0 max 1000")
|
||||
flushln("option name Move Overhead type spin default 100 min 0 max 5000")
|
||||
flushln("uciok")
|
||||
|
||||
|
||||
|
||||
def cmd_isready(self):
|
||||
flushln("readyok")
|
||||
|
||||
@@ -100,14 +108,6 @@ class UCIEngine:
|
||||
self.ffi.load_fen(self.board, START_FEN)
|
||||
|
||||
|
||||
def get_my_time(self):
|
||||
"""Return remaining time (ms) for the side to move."""
|
||||
if self.board.side_to_move == WHITE:
|
||||
return self.wtime
|
||||
else:
|
||||
return self.btime
|
||||
|
||||
|
||||
def cmd_position(self, args):
|
||||
# Reset to startpos or fen
|
||||
if args[0] == "startpos":
|
||||
@@ -124,37 +124,31 @@ class UCIEngine:
|
||||
for mstr in args[1:]:
|
||||
m = uci_to_move(mstr, self.ffi, self.board)
|
||||
if m:
|
||||
nxt = Board()
|
||||
if self.ffi.apply_move_on_copy(self.board, nxt, m):
|
||||
self.board = nxt
|
||||
next_board = Board()
|
||||
if self.ffi.apply_move_on_copy(self.board, next_board, m):
|
||||
self.board = next_board
|
||||
|
||||
|
||||
def cmd_go(self, args):
|
||||
depth = 3
|
||||
wtime, btime = None, None
|
||||
|
||||
# parse depth
|
||||
if "depth" in args:
|
||||
i = args.index("depth")
|
||||
depth = int(args[i + 1])
|
||||
|
||||
# parse clocks (milliseconds from lichess)
|
||||
if "wtime" in args:
|
||||
wtime = int(args[args.index("wtime") + 1])
|
||||
if "btime" in args:
|
||||
btime = int(args[args.index("btime") + 1])
|
||||
|
||||
# store them so you can use/log later
|
||||
self.wtime, self.btime = wtime, btime
|
||||
|
||||
mytime = self.get_my_time()
|
||||
|
||||
best = Move()
|
||||
if mytime >= ONE_MINUTE:
|
||||
ok = self.ffi._c_ai_find_best_move_with_window(self.board, 6, 3, best)
|
||||
if mytime >= TEN_MINUTES:
|
||||
ok = self.ffi._c_ai_find_best_move_with_window(self.board, self.long_depth, 3, best)
|
||||
elif mytime < TEN_MINUTES and mytime >= ONE_MINUTE:
|
||||
ok = self.ffi._c_ai_find_best_move_with_window(self.board, self.default_depth, 3, best)
|
||||
else:
|
||||
ok = self.ffi._c_ai_find_best_move_with_window(self.board, 5, 3, best)
|
||||
|
||||
ok = self.ffi._c_ai_find_best_move_with_window(self.board, self.short_depth, 3, best)
|
||||
|
||||
if ok:
|
||||
flushln(f"bestmove {move_to_uci(best)}")
|
||||
@@ -162,6 +156,14 @@ class UCIEngine:
|
||||
flushln("bestmove 0000")
|
||||
|
||||
|
||||
def get_my_time(self):
|
||||
"""Return remaining time (ms) for the side to move."""
|
||||
if self.board.side_to_move == WHITE:
|
||||
return self.wtime
|
||||
else:
|
||||
return self.btime
|
||||
|
||||
|
||||
def cmd_setoption(self, tokens):
|
||||
try:
|
||||
i_name = tokens.index("name")
|
||||
|
||||
Reference in New Issue
Block a user