def allmate(path): with open(path) as f: for line in f: line = line.strip() print(line) pos = chess.Board(line) _, score, _ = amwafish.search(amwafish.Searcher(), pos, secs=3600) if score < amwafish.MATE_LOWER: print("Unable to find mate. Only got score = %d" % score) break
def selfplay(secs=1): """ Start a game amwafish vs. amwafish """ 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(amwafish.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 = chess.Board(line) searcher = amwafish.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 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 = amwafish.Position(chess.Board(line)) searcher = amwafish.Searcher() for d in range(min_depth, 99): score = searcher.bound(pos, amwafish.MATE_LOWER, d, d, root=True) if score >= amwafish.MATE_LOWER: print(searcher.tp_move.get(pos)) break print('Score at depth {}: {}'.format(d, score)) else: print("Unable to find mate. Only got score = %d" % score) return
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 = chess.Board(line) searcher = amwafish.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 quickdraw(f, depth): k, n = 0, 0 for line in f: line = line.strip() print(line) n += 1 pos = amwafish.Position(chess.Board(line)) searcher = amwafish.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 findbest(f, times): pos = chess.Board() searcher = amwafish.Searcher() print('Printing best move after seconds', times) print('-'*60) totalpoints = 0 totaltests = 0 for line in f: opts = pos.set_epd(line) #am = pos.epd() # 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 = opts['am'] if 'am' in opts else None bm = 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, _, _ = amwafish.search(searcher, pos, t) mark = pos.san(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 main(): parser = argparse.ArgumentParser() parser.add_argument('module', help='sunfish.py file (without .py)', type=str, default='amwafish', nargs='?') parser.add_argument('--tables', metavar='pst', help='alternative pst table', type=str, default=None) args = parser.parse_args() amwafish = importlib.import_module(args.module) #logging.basicConfig(filename='amwafish.log', level=logging.DEBUG) out = Unbuffered(sys.stdout) def output(line): print(line, file=out) logging.debug(line) pos = chess.Board() searcher = amwafish.Searcher() our_time, opp_time = 1000, 1000 # time in centi-seconds show_thinking = True options = {} eval_function = evaluation.get_evaluation_function() stack = [] while True: logging.debug(f'>>> in loop ') if stack: smove = stack.pop() else: smove = input() logging.debug(f'>>> {smove} ') if smove.startswith('setoption'): optionMatcher = re.compile( "setoption name (?P<name>.*) value (?P<value>.*)") match = optionMatcher.match(smove) if match: options[match.group("name")] = match.group("value") if smove == 'quit': break elif smove == 'uci': output('id name amwafish') output('id author Sven Wambecq') output('uciok') elif smove == 'isready': output('readyok') elif smove == 'ucinewgame': stack.append('position fen ' + chess.STARTING_FEN) elif smove.startswith('position fen'): _, _, data = smove.split(' ', 2) try: fen, moves = data.split('moves') moves = moves.strip().split(' ') except ValueError: fen = data moves = [] try: chess960 = options["UCI_Chess960"] == "true" except KeyError: chess960 = False try: board = get_variant(options["UCI_Variant"])(fen, chess960=chess960) eval_function = evaluation.get_evaluation_function( options["UCI_Variant"]) except KeyError: board = chess.Board() eval_function = evaluation.Classical() for move in moves: board.push(chess.Move.from_uci(move)) pos = board elif smove.startswith('position startpos'): params = smove.split(' ') pos = chess.Board() if len(params) > 2 and params[2] == 'moves': for move in params[3:]: pos.push(chess.Move.from_uci(move)) 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 for sdepth, _move, _score in searcher.search(pos, eval_function, maxdepth=depth, maxtime=our_time / moves_remain / 1000): pass else: if _move: output('bestmove ' + _move.uci()) elif smove.startswith('time'): our_time = int(smove.split()[1]) elif smove.startswith('otim'): opp_time = int(smove.split()[1]) else: pass
def setUp(self): self._searcher = amwafish.Searcher()
def setUpPosition(fen): board = chess.Board(fen) pos = amwafish.Position(board, evaluation.Classical(), depth=0) searcher = amwafish.Searcher() return pos, searcher