def cruncher(thread_id: int): eval_nb = 0 build_coll = pymongo.MongoClient()['puzzler']['puzzle2'] engine = SimpleEngine.popen_uci('./stockfish') engine.configure({'Threads': 4}) engine_limit = chess.engine.Limit(depth=30, time=15, nodes=12_000_000) for doc in build_coll.find({"cp": None}): try: if ord(doc["_id"][4]) % threads != thread_id: continue puzzle = read(doc) board = puzzle.game.end().board() if board.is_checkmate(): cp = 999999999 eval_nb += 1 logger.info(f'{thread_id} {eval_nb} {puzzle.id}: mate') else: info = engine.analyse(board, limit=engine_limit) score = info["score"].pov(puzzle.pov) score_cp = score.score() cp = 999999999 if score.is_mate() else ( 999999998 if score_cp is None else score_cp) eval_nb += 1 logger.info( f'{thread_id} {eval_nb} {puzzle.id}: {cp} knps: {int(info["nps"] / 1000)} kn: {int(info["nodes"] / 1000)} depth: {info["depth"]} time: {info["time"]}' ) build_coll.update_one({"_id": puzzle.id}, {"$set": { "cp": cp }}) except Exception as e: print(doc) logger.error(e)
def cruncher(thread_id: int): eval_nb = 0 db = pymongo.MongoClient()['puzzler'] bad_coll = db['puzzle2_bad_maybe'] play_coll = db['puzzle2_puzzle'] engine = SimpleEngine.popen_uci('./stockfish') engine.configure({'Threads': 4}) for doc in bad_coll.find({"bad": {"$exists": False}}): try: if ord(doc["_id"][4]) % threads != thread_id: continue doc = play_coll.find_one({'_id': doc['_id']}) if not doc: continue puzzle = read(doc) board = puzzle.mainline[len(puzzle.mainline) - 2].board() info = engine.analyse( board, multipv=5, limit=chess.engine.Limit(nodes=30_000_000)) bad = False for score in [pv["score"].pov(puzzle.pov) for pv in info]: if score < Mate(1) and score > Cp(250): bad = True # logger.info(puzzle.id) bad_coll.update_one({"_id": puzzle.id}, {"$set": { "bad": bad }}) except Exception as e: logger.error(e)
def main() -> None: args = parse_args() setup_logging(args) # setup the engine enginepath = args.engine engine = SimpleEngine.popen_uci(enginepath) engine.configure({'Threads': args.threads}) with open(args.file) as pgn: for game in iter(lambda: chess.pgn.read_game(pgn), None): res = analyze_game(engine, game) if res is None: logger.debug("No only move sequence found.") else: node, solution, kind = res # Compose and print the puzzle puzzle: Dict[str, Any] = { 'game_id': game.headers.get("Site", "?")[20:], 'fen': node.board().fen(), 'ply': ply_of(node.board()), 'moves': list(map(lambda m: m.uci(), solution)), 'kind': kind, 'generator_version': version, } r = requests.post(post_url, json=puzzle) logger.info(r.text if r.ok else "FAILURE {}".format(r.text))
def cruncher(thread_id: int): db = pymongo.MongoClient()['puzzler'] round_coll = db['puzzle2_round'] play_coll = db['puzzle2_puzzle'] engine = SimpleEngine.popen_uci('./stockfish') engine.configure({'Threads': 2}) for doc in round_coll.aggregate([{ "$match": { "_id": { "$regex": "^lichess:" }, "t": { "$nin": ['+zugzwang', '-zugzwang'] } } }, { '$lookup': { 'from': 'puzzle2_puzzle', 'as': 'puzzle', 'localField': 'p', 'foreignField': '_id' } }, { '$unwind': '$puzzle' }, { '$replaceRoot': { 'newRoot': '$puzzle' } }]): try: if ord(doc["_id"][4]) % threads != thread_id: continue puzzle = read(doc) round_id = f'lichess:{puzzle.id}' zug = zugzwang(engine, puzzle) if zug: cook.log(puzzle) round_coll.update_one({"_id": round_id}, { "$addToSet": { "t": "+zugzwang" if zug else "-zugzwang" } }) play_coll.update_one({"_id": puzzle.id}, {"$set": { "dirty": True }}) except Exception as e: print(doc) logger.error(e) engine.close() exit(1) engine.close()
def _evaluate_positions(cls, data: List[str]) -> List[Tuple[str, float]]: log_after = 1000 start_time = time() local_start_time = time() analysed_positions: List[Tuple[str, float]] = [] stockfish = SimpleEngine.popen_uci(cls._stockfish_path) for position in data: score = stockfish.analyse(Board(fen=position), Limit(depth=10))["score"] analysed_positions.append((position, score.relative.wdl().expectation())) if len(analysed_positions) % log_after == 0: cls._log_evaluating_progress(f"{current_process().name}", start_time, local_start_time, len(analysed_positions), log_after, len(data)) local_start_time = time() stockfish.close() return analysed_positions
def get_stockfish(self): """ Load the stockfish engine from an asset file (searches for any file that starts with stockfish_10) """ prefixed = [ filename for filename in os.listdir('assets') if filename.startswith('stockfish_10') ] if len(prefixed) == 0: raise ValueError('Stockfish engine file not found. Download ' '"stockfish_10_x64", or whichever archatecture ' 'version suits the platform.') if len(prefixed) > 1: raise ValueError(f'Found multiple possible stockfish files: ' f'{prefixed}. Change prefix on (or remove) ' f'unwated files.') stock_file = f'assets/{prefixed[0]}' return SimpleEngine.popen_uci(stock_file)
def play(): data = request.get_json(force=True) engine = SimpleEngine.popen_uci(data.get("engine", "chesscli")) board = chess.Board(data["fen"]) result = engine.play(board, limit=chess.engine.Limit(time=0.5), info=chess.engine.INFO_ALL) return jsonify({ "bestmove": str(result.move), "ponder": str(result.ponder), "resigned": str(result.resigned), "draw_offered": str(result.draw_offered), "info": { "depth": result.info.get("depth"), "seldepth": result.info.get("seldepth"), "multipv": result.info.get("multipv"), "nodes": result.info.get("nodes"), "nps": result.info.get("nps"), "time": result.info.get("time"), "tbhits": result.info.get("tbhits"), "pv": [str(pv) for pv in result.info.get("pv", [])], }, })
import logging import random import chess from chess import WHITE from chess.engine import SimpleEngine from chessnn import BoardOptim, is_debug from chessnn.nn import NNChess from chessnn.player import NNPLayer if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG if is_debug() else logging.INFO) engine = SimpleEngine.popen_uci("stockfish") try: board = BoardOptim.from_chess960_pos(random.randint(0, 959)) nn = NNChess("nn.hdf5") white = NNPLayer("Lisa", WHITE, nn) white.board = board while not board.is_game_over(): if not white.makes_move(0): break result = engine.play(board, chess.engine.Limit(time=0.100)) board.push(result.move) logging.info("Result: %s", board.result()) finally:
def make_engine(executable: str, threads: int) -> SimpleEngine: engine = SimpleEngine.popen_uci(executable) engine.configure({'Threads': threads}) return engine
def instance() -> SimpleEngine: if not AnalysisEngine.engine: AnalysisEngine.engine = SimpleEngine.popen_uci( _stockfish_command()) return AnalysisEngine.engine
def _evaluate_position(cls, position: str) -> Tuple[str, float]: stockfish = SimpleEngine.popen_uci(cls._stockfish_path) score = stockfish.analyse(Board(fen=position), Limit(depth=10))["score"] stockfish.close() return position, score.relative.wdl().expectation()
def __init__(self, color) -> None: super().__init__("Stockfish", color) self.engine = SimpleEngine.popen_uci("stockfish")
def setUp(self): self.engine = SimpleEngine.popen_uci("chesscli")