def move(self, gn_current): searcher = sunfish.Searcher() # assert(gn_current.board().turn == False) # parse UCI move into Sunfish format move crdn = str(gn_current.move) move = (sunfish.parse(crdn[0:2]), sunfish.parse(crdn[2:4])) self._pos = self._pos.move(move) t0 = time.time() # calls Sunfish's search function to find a move move, score = searcher.search(self._pos, self._maxn) print time.time() - t0, move, score self._pos = self._pos.move(move) crdn = sunfish.render(119 - move[0]) + sunfish.render(119 - move[1]) move = create_move(gn_current.board(), crdn) # updates game moves and returns board gn_new = chess.pgn.GameNode() gn_new.parent = gn_current gn_new.move = move return gn_new
def selfPlay(self, pstwhite, pstblack): if pstwhite is None or pstblack is None: print("Null PST in Selfplay") startpos = startingPositions[random.randrange(0, len(startingPositions))] firstturn = startpos.split(' ')[1] startindex = 1 if firstturn == 'b' else 0 startposindex = random.randrange(0, len(startingPositions)) pos = self.helper.parseFEN(startingPositions[startposindex], pstwhite) #Select a random starting opening secs = 1 for d in range(startindex, 20): print("move: " + str(d)) board = pos.board if d % 2 == 0 else pos.rotate().board pstCurrent = pstwhite if d % 2 == 0 else pstblack print("about to search") m, _ = sunfish.Searcher().search( pos, secs, pstCurrent ) #Modified Sunfish searcher that takes in variable piece tables print("finished searching") if m is None: #If there are no valid moves return "W" if d % 2 == 0 else "B" pos = pos.move( m, pstCurrent) #Modify the board state with the selected move. fen = self.helper.boardToFen(self.helper.removePadding(pos.board)) startingeval = startingPositonsEval[startposindex] return "W" if stockfishEvalFromPosition(fen) > startingeval else "B"
def sunfish_move_suggestion(self, secs): board = (" \n" " \n") for y in reversed(range(8)): board += ' ' for x in range(8): if self.grid[x][y] is None: board += '.' elif self.grid[x][y].color_name == "W": board += self.grid[x][y].nature_guess else: board += self.grid[x][y].nature_guess.lower() board += '\n' board += (" \n" " \n") pos = sunfish.Position(board, 0, (False, False), (False, False), 0, 0) if self.time % 2 == 1: pos = pos.rotate() searcher = sunfish.Searcher() move, score = searcher.search(pos, secs=secs) if move is None: raise IllegalMove("Sunfish didn't find a feasible move") if self.time % 2 == 1: move = (119 - move[0], 119 - move[1]) first_square, last_square = sunfish.render(move[0]), sunfish.render( move[1]) x1, y1, x2, y2 = self.translate_move((first_square, last_square)) return x1, y1, x2, y2
def test_3fold(self): sunfish.DRAW_TEST = True # Games where the last move is right, but the second to last move is wrong path_do = os.path.join(os.path.dirname(__file__), 'tests/3fold_do.pgn') # Games where the last move is wrong path_dont = os.path.join(os.path.dirname(__file__), 'tests/3fold_dont.pgn') with open(path_dont) as file: for i, (_pgn, pos_moves) in enumerate(tools.readPGN(file)): history = [] for pos, move in pos_moves: history.append(pos) last_pos, last_move = pos_moves[-1] # Maybe we just didn't like the position we were in. # This is a kind of crude way of testing that. if last_pos.score < 0: continue move, score, _ = tools.search(sunfish.Searcher(), pos, secs=.1, history=history[:-1]) if move == last_move: print('Score was', score, pos.score) print('Failed at', i) print(_pgn) self.assertNotEqual(move, last_move)
def findbest(f, times): pos = tools.parseFEN(tools.FEN_INITIAL) searcher = sunfish.Searcher() print('Printing best move after seconds', times) print('-' * 60) totalpoints = 0 totaltests = 0 for line in f: fen, opts = tools.parseEPD(line, opt_dict=True) if type(opts) != dict or ('am' not in opts and 'bm' not in opts): print("Line didn't have am/bm in opts", line, opts) continue pos = tools.parseFEN(fen) # am -> avoid move; bm -> best move am = tools.parseSAN(pos, opts['am']) if 'am' in opts else None bm = tools.parseSAN(pos, opts['bm']) if 'bm' in opts else None print('Looking for am/bm', opts.get('am'), opts.get('bm')) points = 0 print(opts.get('id', 'unnamed'), end=' ', flush=True) for t in times: move, _, _ = tools.search(searcher, pos, t) mark = tools.renderSAN(pos, move) if am and move != am or bm and move == bm: mark += '(1)' points += 1 else: mark += '(0)' print(mark, end=' ', flush=True) totaltests += 1 print(points) totalpoints += points print('-' * 60) print('Total Points: %d/%d', totalpoints, totaltests)
def move(self, gn_current): sys.path.append("/Users/Brennen/sunfish") import sunfish searcher = sunfish.Searcher() assert (gn_current.board().turn == False) # Apply last_move crdn = str(gn_current.move) move = (sunfish.parse(crdn[0:2]), sunfish.parse(crdn[2:4])) self._pos = self._pos.move(move) t0 = time.time() #print self._maxn move, score = searcher.search(self._pos, secs=5) print time.time() - t0, move, score self._pos = self._pos.move(move) crdn = sunfish.render(119 - move[0]) + sunfish.render(119 - move[1]) move = create_move(gn_current.board(), crdn) gn_new = chess.pgn.GameNode() gn_new.parent = gn_current gn_new.move = move return gn_new
def test_selfplay(self): pos = tools.parseFEN(tools.FEN_INITIAL) for d in range(200): m, score, _ = tools.search(sunfish.Searcher(), pos, .1) if m is None: self.assertTrue(score == 0 or abs(score) >= sunfish.MATE_LOWER) break pos = pos.move(m)
def allmate(path): with open(path) as f: for line in f: line = line.strip() print(line) pos = tools.parseFEN(line) _, score, _ = tools.search(sunfish.Searcher(), pos, secs=3600) if score < sunfish.MATE_LOWER: print("Unable to find mate. Only got score = %d" % score) break
def selfplay(secs=1): """ Start a game sunfish vs. sunfish """ pos = tools.parseFEN(tools.FEN_INITIAL) for d in range(200): # Always print the board from the same direction board = pos.board if d % 2 == 0 else pos.rotate().board print(' '.join(board)) m, _, _ = tools.search(sunfish.Searcher(), pos, secs) if m is None: print("Game over") break print("\nmove", tools.mrender(pos, m)) pos = pos.move(m)
def unstable(): secs = 1 unstables, total = 0, 0 path = os.path.join(os.path.dirname(__file__), 'tests/unstable_positions2') for line in open(path): pos = tools.parseFEN(line) searcher = sunfish.Searcher() start = time.time() for depth, _, _ in searcher.search(pos): if searcher.was_unstable or time.time() - start > secs: break #list(zip(range(depth), searcher._search(pos))) total += 1 if searcher.was_unstable: #print('got one at depth', searcher.depth) unstables += 1 print('{} / {}, at depth {}'.format(unstables, total, depth))
def __init__(self, white=True): self.pos = sunfish.Position(sunfish.initial, 0, (True, True), (True, True), 0, 0) self.searcher = sunfish.Searcher() self.isPlayerTurn = white self.isPlayerwhite = white self.board = chess.Board() context.log_level = 'error' data = { 'fen': "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR", 'move': "Start", 'player': "True", 'ann': "None" } r = requests.post("http://141.223.163.184:5000/saveinfo", json=data)
def quickmate(f, min_depth=1): """ Similar to allmate, but uses the `bound` function directly to only search for moves that will win us the game """ for line in f: line = line.strip() print(line) pos = tools.parseFEN(line) searcher = sunfish.Searcher() for d in range(min_depth, 99): score = searcher.bound(pos, sunfish.MATE_LOWER, d, root=True) if score >= sunfish.MATE_LOWER: #print(tools.pv(searcher, 0, pos)) break print('Score at depth {}: {}'.format(d, score)) else: print("Unable to find mate. Only got score = %d" % score) return print(tools.pv(searcher, pos, include_scores=False))
def quickdraw(f, depth): k, n = 0, 0 for line in f: line = line.strip() print(line) n += 1 pos = tools.parseFEN(line) searcher = sunfish.Searcher() for d in range(depth, 10): s0 = searcher.bound(pos, 0, d, root=True) s1 = searcher.bound(pos, 1, d, root=True) if s0 >= 0 and s1 < 1: k += 1 break else: print('depth {}, s0 {}, s1 {}'.format(d, s0, s1)) #print(d, s0, s1, tools.pv(0, pos)) else: print("Fail: Unable to find draw!") #return print(tools.pv(searcher, pos, False)) print('Found {}/{} draws'.format(k, n))
def benchmark(cnt=20, depth=3): path = os.path.join(os.path.dirname(__file__), 'tests/chessathome_openings.fen') random.seed(0) start = time.time() nodes = 0 for i, line in enumerate(random.sample(list(open(path)), cnt)): pos = tools.parseFEN(line) searcher = sunfish.Searcher() start1 = time.time() for search_depth, _, _ in searcher.search(pos): speed = int(round(searcher.nodes / (time.time() - start1))) print('Benchmark: {}/{}, Depth: {}, Speed: {:,}N/s'.format( i + 1, cnt, search_depth, speed), end='\r') sys.stdout.flush() if search_depth == depth: nodes += searcher.nodes break print() total_time = time.time() - start speed = int(round(nodes / total_time)) print('Total time: {}, Total nodes: {}, Average speed: {:,}N/s'.format( total_time, nodes, speed))
def main(): pos = tools.parseFEN(tools.FEN_INITIAL) searcher = sunfish.Searcher() forced = False color = WHITE our_time, opp_time = 1000, 1000 # time in centi-seconds show_thinking = False stack = [] while True: if stack: smove = stack.pop() else: smove = input() if smove == 'quit': break elif smove == 'protover 2': print('feature done=0') print('feature myname="Sunfish"') print('feature usermove=1') print('feature setboard=1') print('feature ping=1') print('feature sigint=0') print('feature variants="normal"') print('feature done=1') elif smove == 'new': stack.append('setboard ' + tools.FEN_INITIAL) elif smove.startswith('setboard'): _, fen = smove.split(' ', 1) pos = tools.parseFEN(fen) color = WHITE if fen.split()[1] == 'w' else BLACK elif smove == 'force': forced = True elif smove == 'go': forced = False moves_remain = 40 use = our_time / moves_remain # Let's follow the clock of our opponent if our_time >= 100 and opp_time >= 100: use *= our_time / opp_time start = time.time() for _ in searcher._search(pos): if show_thinking: ply = searcher.depth entry = searcher.tp_score.get((pos, ply, True)) score = int(round((entry.lower + entry.upper) / 2)) dual_score = '{}:{}'.format(entry.lower, entry.upper) used = int((time.time() - start) * 100 + .5) moves = tools.pv(searcher, pos, include_scores=False) print('{:>3} {:>8} {:>8} {:>13} \t{}'.format( ply, score, used, searcher.nodes, moves)) if time.time() - start > use / 100: break entry = searcher.tp_score.get((pos, searcher.depth, True)) m, s = searcher.tp_move.get(pos), entry.lower # We only resign once we are mated.. That's never? if s == -sunfish.MATE_UPPER: print('resign') else: print('move', tools.mrender(pos, m)) pos = pos.move(m) color = 1 - color elif smove.startswith('ping'): _, N = smove.split() print('pong', N) elif smove.startswith('usermove'): _, smove = smove.split() m = tools.mparse(color, smove) pos = pos.move(m) color = 1 - color if not forced: stack.append('go') elif smove.startswith('time'): our_time = int(smove.split()[1]) elif smove.startswith('otim'): opp_time = int(smove.split()[1]) elif smove.startswith('perft'): start = time.time() for d in range(1, 10): res = sum(1 for _ in tools.collect_tree_depth( tools.expand_position(pos), d)) print('{:>8} {:>8}'.format(res, time.time() - start)) elif smove.startswith('post'): show_thinking = True elif smove.startswith('nopost'): show_thinking = False elif any( smove.startswith(x) for x in ('xboard', 'random', 'hard', 'accepted', 'level')): pass else: print("Error (unkown command):", smove)
def main(): pos = tools.parseFEN(tools.FEN_INITIAL) searcher = sunfish.Searcher() forced = False color = WHITE our_time, opp_time = 1000, 1000 # time in centi-seconds show_thinking = True # print name of chess engine print('Sunfish') while True: smove = input() if smove == 'quit' or smove == 'stop': break elif smove == 'uci': print('id name Sunfish') print('uciok') elif smove == 'isready': print('readyok') elif smove == 'ucinewgame': pos = tools.parseFEN(tools.FEN_INITIAL) searcher = sunfish.Searcher() forced = False color = WHITE our_time, opp_time = 1000, 1000 # time in centi-seconds show_thinking = True elif smove.startswith('position'): params = smove.split(' ', 2) if params[1] == 'fen': fen = params[2] pos = tools.parseFEN(fen) color = WHITE if fen.split()[1] == 'w' else BLACK else: params = smove.split(' ') if len(params) == 1: continue i = 1 while i < len(params): param = params[i] if param == 'startpos': pos = tools.parseFEN(tools.FEN_INITIAL) color = WHITE elif param == 'moves': i += 1 # rest are moves while i < len(params): m0 = params[i] m = tools.mparse(color, m0) pos = pos.move(m) color = 1 - color i += 1 i += 1 elif smove.startswith('go'): # default options depth = 1000 movetime = -1 moves_remain = 40 tc = 0 # parse parameters params = smove.split(' ') if len(params) == 1: continue i = 0 while i < len(params): param = params[i] if param == 'depth': i += 1 depth = int(params[i]) elif param == 'movetime': i += 1 movetime = int(params[i]) elif param == 'wtime': i += 1 if color == WHITE: movetime = int(params[i]) tc = 1 elif param == 'btime': i += 1 if color == BLACK: movetime = int(params[i]) tc = 1 elif param == 'movestogo': i += 1 moves_remain = int(params[i]) i += 1 if tc == 1 and moves_remain > 0: movetime = movetime / moves_remain forced = False start = time.time() ponder = None for _ in searcher._search(pos): moves = tools.pv(searcher, pos, include_scores=False) if show_thinking: entry = searcher.tp_score.get((pos, searcher.depth, True)) score = int(round((entry.lower + entry.upper) / 2)) usedtime = int((time.time() - start) * 1000) moves_str = moves if len(moves) < 15 else '' print('info depth {} score {} time {} nodes {} {}'.format( searcher.depth, score, usedtime, searcher.nodes, moves_str)) if len(moves) > 5: ponder = moves[1] if movetime > 0 and (time.time() - start) * 1000 > movetime: break if searcher.depth >= depth: break entry = searcher.tp_score.get((pos, searcher.depth, True)) m, s = searcher.tp_move.get(pos), entry.lower moves = moves.split(' ') if len(moves) > 1: print('bestmove ' + moves[0] + ' ponder ' + moves[1]) else: print('bestmove ' + moves[0]) elif smove.startswith('time'): our_time = int(smove.split()[1]) elif smove.startswith('otim'): opp_time = int(smove.split()[1]) else: pass
def main(): pos = tools.parseFEN(tools.FEN_INITIAL) searcher = sunfish.Searcher() forced = False color = WHITE our_time, opp_time = 1000, 1000 # time in centi-seconds show_thinking = False options = {} history = [] stack = [] while True: if stack: smove = stack.pop() else: smove = input() print('>>>', smove, file=sys.stderr) sys.stderr.flush() # For Python 2.7 support if smove == 'quit': break elif smove == 'protover 2': print('feature done=0') print('feature myname="Sunfish"') print('feature usermove=1') print('feature setboard=1') print('feature ping=1') print('feature sigint=0') print('feature variants="normal"') print('feature option="qs_limit -spin {} -100 1000"'.format( sunfish.QS_LIMIT)) print('feature option="eval_roughness -spin {} 1 1000"'.format( sunfish.EVAL_ROUGHNESS)) print('feature option="draw_test -spin {} 0 1"'.format( int(sunfish.DRAW_TEST))) print('feature done=1') elif smove == 'new': stack.append('setboard ' + tools.FEN_INITIAL) # Clear out the old searcher, including the tables searcher = sunfish.Searcher() del history[:] elif smove.startswith('setboard'): _, fen = smove.split(' ', 1) pos = tools.parseFEN(fen) color = WHITE if fen.split()[1] == 'w' else BLACK del history[:] elif smove == 'force': forced = True elif smove.startswith('option'): _, aeqb = smove.split(maxsplit=1) if '=' in aeqb: name, val = aeqb.split('=') else: name, val = aeqb, True if name == 'qs_limit': sunfish.QS_LIMIT = int(val) if name == 'eval_roughness': sunfish.EVAL_ROUGHNESS = int(val) if name == 'draw_test': sunfish.DRAW_TEST = bool(int(val)) options[name] = val elif smove == 'go': forced = False moves_remain = 40 use = our_time / moves_remain # Let's follow the clock of our opponent if our_time >= 100 and opp_time >= 100: use *= our_time / opp_time start = time.time() for ply, move, score in searcher.search(pos, history): entry = searcher.tp_score.get((pos, ply, True)) score = int(round((entry.lower + entry.upper) / 2)) if show_thinking: used = int((time.time() - start) * 100 + .5) moves = tools.pv(searcher, pos, include_scores=False) seldepth = 0 nps = int(searcher.nodes / (time.time() - start) + .5) print('{:>3} {:>8} {:>8} {:>13} {:>1} {:>4} \t{}'.format( ply, score, used, searcher.nodes, seldepth, nps, moves)) print('# Hashfull: {:.3f}%; {} <= score < {}'.format( len(searcher.tp_score) / sunfish.TABLE_SIZE * 100, entry.lower, entry.upper)) # If found mate, just stop if entry.lower >= sunfish.MATE_UPPER: break if time.time() - start > use / 100: break # We sometimes make illegal moves when we're losing, # so it's safer to just resign. if score == -sunfish.MATE_UPPER: print('resign') else: print('move', tools.mrender(pos, move)) pos = pos.move(move) history.append(pos) color = 1 - color elif smove.startswith('ping'): _, N = smove.split() print('pong', N) elif smove.startswith('usermove'): _, smove = smove.split() m = tools.mparse(color, smove) pos = pos.move(m) history.append(pos) color = 1 - color if not forced: stack.append('go') elif smove.startswith('time'): our_time = int(smove.split()[1]) elif smove.startswith('otim'): opp_time = int(smove.split()[1]) elif smove.startswith('perft'): start = time.time() for d in range(1, 10): res = sum(1 for _ in tools.collect_tree_depth( tools.expand_position(pos), d)) print('{:>8} {:>8}'.format(res, time.time() - start)) elif smove.startswith('post'): show_thinking = True elif smove.startswith('nopost'): show_thinking = False elif any( smove.startswith(x) for x in ('xboard', 'random', 'hard', 'accepted', 'level', 'easy', 'st', 'result', '?')): print('# Ignoring command {}.'.format(smove)) elif smove.startswith('reject'): _, feature = smove.split( )[:2] # split(maxsplit=2) doesnt work in python2.7 print( '# Warning ({} rejected): Might not work as expected.'.format( feature)) else: print('# Warning (unkown command): {}. Treating as move.'.format( smove)) stack.append('usermove {}'.format(smove))
def reset_position(self): self.pos = sunfish.Position(sunfish.initial, 0, (True, True), (True, True), 0, 0, self.pst_padded) self.searcher = sunfish.Searcher()
def __init__(self, prefix): self.load_from_pckl(prefix) self.pos = sunfish.Position(sunfish.initial, 0, (True, True), (True, True), 0, 0, self.pst_padded) self.searcher = sunfish.Searcher()
def main(): logging.basicConfig(filename='sunfish.log', level=logging.DEBUG) out = Unbuffered(sys.stdout) def output(line): print(line, file=out) logging.debug(line) pos = tools.parseFEN(tools.FEN_INITIAL) searcher = sunfish.Searcher() color = WHITE our_time, opp_time = 1000, 1000 # time in centi-seconds show_thinking = True stack = [] while True: if stack: smove = stack.pop() else: smove = input() logging.debug(f'>>> {smove} ') if smove == 'quit': break elif smove == 'uci': output('id name Sunfish') output('id author Thomas Ahle & Contributors') output('uciok') elif smove == 'isready': output('readyok') elif smove == 'ucinewgame': stack.append('position fen ' + tools.FEN_INITIAL) elif smove.startswith('position fen'): _, _, fen = smove.split(' ', 2) pos = tools.parseFEN(fen) color = WHITE if fen.split()[1] == 'w' else BLACK elif smove.startswith('position startpos'): params = smove.split(' ') pos = tools.parseFEN(tools.FEN_INITIAL) color = WHITE if len(params) > 2 and params[2] == 'moves': for move in params[3:]: pos = pos.move(tools.mparse(color, move)) color = 1 - color elif smove.startswith('go'): # default options depth = 1000 movetime = -1 _, *params = smove.split(' ') for param, val in zip(*2*(iter(params),)): if param == 'depth': depth = int(val) if param == 'movetime': movetime = int(val) if param == 'wtime': our_time = int(val) if param == 'btime': opp_time = int(val) moves_remain = 40 start = time.time() ponder = None for sdepth, _move, _score in searcher.search(pos): moves = tools.pv(searcher, pos, include_scores=False) if show_thinking: entry = searcher.tp_score.get((pos, sdepth, True)) score = int(round((entry.lower + entry.upper)/2)) usedtime = int((time.time() - start) * 1000) moves_str = moves if len(moves) < 15 else '' output('info depth {} score cp {} time {} nodes {} pv {}'.format(sdepth, score, usedtime, searcher.nodes, moves_str)) if len(moves) > 5: ponder = moves[1] if movetime > 0 and (time.time() - start) * 1000 > movetime: break if (time.time() - start) * 1000 > our_time/moves_remain: break if sdepth >= depth: break entry = searcher.tp_score.get((pos, sdepth, True)) m, s = searcher.tp_move.get(pos), entry.lower # We only resign once we are mated.. That's never? if s == -sunfish.MATE_UPPER: output('resign') else: moves = moves.split(' ') if len(moves) > 1: output(f'bestmove {moves[0]} ponder {moves[1]}') else: output('bestmove ' + moves[0]) elif smove.startswith('time'): our_time = int(smove.split()[1]) elif smove.startswith('otim'): opp_time = int(smove.split()[1]) else: pass
def __init__(self): self.searcher = sf.Searcher() self.init()
def main(): logging.basicConfig(filename='sunfish.log', level=logging.DEBUG) pos = tools.parseFEN(tools.FEN_INITIAL) searcher = sunfish.Searcher() forced = False color = WHITE our_time, opp_time = 1000, 1000 # time in centi-seconds show_thinking = True # print name of chess engine print('Sunfish') stack = [] while True: if stack: smove = stack.pop() else: smove = input() logging.debug(smove) if smove == 'quit': break elif smove == 'uci': print('id name Sunfish') print('id author Thomas Ahle') print('uciok') elif smove == 'isready': print('readyok') elif smove == 'ucinewgame': stack.append('position fen ' + tools.FEN_INITIAL) elif smove.startswith('position fen'): params = smove.split(' ', 2) if params[1] == 'fen': fen = params[2] pos = tools.parseFEN(fen) color = WHITE if fen.split()[1] == 'w' else BLACK elif smove.startswith('position startpos'): params = smove.split(' ') #startpos pos = tools.parseFEN(tools.FEN_INITIAL) color = WHITE i = 0 while i < len(params): param = params[i] if param == 'moves': i += 1 while i < len(params): mymove = params[i] logging.debug(mymove) m = tools.mparse(color, mymove) logging.debug(m) pos = pos.move(m) color = 1 - color i += 1 i += 1 elif smove.startswith('go'): # default options depth = 1000 movetime = -1 # parse parameters params = smove.split(' ') if len(params) == 1: continue i = 0 while i < len(params): param = params[i] if param == 'depth': i += 1 depth = int(params[i]) if param == 'movetime': i += 1 movetime = int(params[i]) if param == 'wtime': i += 1 our_time = int(params[i]) if param == 'btime': i += 1 opp_time = int(params[i]) i += 1 forced = False moves_remain = 40 start = time.time() ponder = None for _ in searcher._search(pos): moves = tools.pv(searcher, pos, include_scores=False) if show_thinking: entry = searcher.tp_score.get((pos, searcher.depth, True)) score = int(round((entry.lower + entry.upper) / 2)) usedtime = int((time.time() - start) * 1000) moves_str = moves if len(moves) < 15 else '' print('info depth {} score cp {} time {} nodes {} pv {}'. format(searcher.depth, score, usedtime, searcher.nodes, moves_str)) logging.debug( 'info depth {} score cp {} time {} nodes {} pv {}'. format(searcher.depth, score, usedtime, searcher.nodes, moves_str)) if len(moves) > 5: ponder = moves[1] if movetime > 0 and (time.time() - start) * 1000 > movetime: break if (time.time() - start) * 1000 > our_time / moves_remain: break if searcher.depth >= depth: break entry = searcher.tp_score.get((pos, searcher.depth, True)) m, s = searcher.tp_move.get(pos), entry.lower # We only resign once we are mated.. That's never? if s == -sunfish.MATE_UPPER: print('resign') logging.debug('resign') else: moves = moves.split(' ') if len(moves) > 1: #print('bestmove ' + moves[0] + ' ponder ' + moves[1]) print('bestmove ' + moves[0]) logging.debug('bestmove ' + moves[0]) else: print('bestmove ' + moves[0]) logging.debug('bestmove ' + moves[0]) elif smove.startswith('time'): our_time = int(smove.split()[1]) elif smove.startswith('otim'): opp_time = int(smove.split()[1]) else: pass
def main(): parser = argparse.ArgumentParser() parser.add_argument('module', help='sunfish.py file (without .py)', type=str, default='sunfish', nargs='?') parser.add_argument('--tables', metavar='pst', help='alternative pst table', type=str, default=None) args = parser.parse_args() sunfish = importlib.import_module(args.module) if args.tables is not None: pst_module = importlib.import_module(args.tables) sunfish.pst = pst_module.pst logging.basicConfig(filename='sunfish.log', level=logging.DEBUG) out = Unbuffered(sys.stdout) def output(line): print(line, file=out) logging.debug(line) pos = tools.parseFEN(tools.FEN_INITIAL) searcher = sunfish.Searcher() color = WHITE our_time, opp_time = 1000, 1000 # time in centi-seconds show_thinking = True stack = [] while True: if stack: smove = stack.pop() else: smove = input() logging.debug(f'>>> {smove} ') if smove == 'quit': break elif smove == 'uci': output('id name Sunfish') output('id author Thomas Ahle & Contributors') output('uciok') elif smove == 'isready': output('readyok') elif smove == 'ucinewgame': stack.append('position fen ' + tools.FEN_INITIAL) # syntax specified in UCI # position [fen | startpos ] moves .... elif smove.startswith('position'): params = smove.split(' ') idx = smove.find('moves') if idx >= 0: moveslist = smove[idx:].split()[1:] else: moveslist = [] if params[1] == 'fen': if idx >= 0: fenpart = smove[:idx] else: fenpart = smove _, _, fen = fenpart.split(' ', 2) elif params[1] == 'startpos': fen = tools.FEN_INITIAL else: pass pos = tools.parseFEN(fen) color = WHITE if fen.split()[1] == 'w' else BLACK for move in moveslist: pos = pos.move(tools.mparse(color, move)) color = 1 - color elif smove.startswith('go'): # default options depth = 1000 movetime = -1 _, *params = smove.split(' ') for param, val in zip(*2*(iter(params),)): if param == 'depth': depth = int(val) if param == 'movetime': movetime = int(val) if param == 'wtime': our_time = int(val) if param == 'btime': opp_time = int(val) moves_remain = 40 start = time.time() ponder = None for sdepth, _move, _score in searcher.search(pos): moves = tools.pv(searcher, pos, include_scores=False) if show_thinking: entry = searcher.tp_score.get((pos, sdepth, True)) score = int(round((entry.lower + entry.upper)/2)) usedtime = int((time.time() - start) * 1000) moves_str = moves if len(moves) < 15 else '' output('info depth {} score cp {} time {} nodes {} pv {}'.format(sdepth, score, usedtime, searcher.nodes, moves_str)) if len(moves) > 5: ponder = moves[1] if movetime > 0 and (time.time() - start) * 1000 > movetime: break if (time.time() - start) * 1000 > our_time/moves_remain: break if sdepth >= depth: break entry = searcher.tp_score.get((pos, sdepth, True)) m, s = searcher.tp_move.get(pos), entry.lower # We only resign once we are mated.. That's never? if s == -sunfish.MATE_UPPER: output('resign') else: moves = moves.split(' ') if len(moves) > 1: output(f'bestmove {moves[0]} ponder {moves[1]}') else: output('bestmove ' + moves[0]) elif smove.startswith('time'): our_time = int(smove.split()[1]) elif smove.startswith('otim'): opp_time = int(smove.split()[1]) else: pass
def search(position, secs=1): return sunfish.Searcher().search(position, secs)
def __init__(self, secs=1): self._searcher = sunfish.Searcher() self._pos = sunfish.Position(sunfish.initial, 0, (True, True), (True, True), 0, 0) self._secs = secs
Piececlasses.list_of_pieces = [] previous_pieces = [] for i in DeeperBlue.position: for j in i: if not j == "empty": Piececlasses.list_of_pieces.append(Piececlasses.Piece(j)) sunfish.pos = sunfish.Position(sunfish.initial, 0, (True, True), (True, True), 0, 0) sunfish.searcher = sunfish.Searcher() #print (time.time() - t) count += 1 print(count) except KeyboardInterrupt: print("Write experience to file?") user_input = input("Your choice: ") while not user_input == "yes" and not user_input == "no":