def game(display=True): """Play a game of chess with the AI. Args: display (bool, optional): If enabled, this creates an image of the chess board every turn in a file "board.png". Defaults to True. """ # Initialise Stockfish engine and board engine = chess_engine.SimpleEngine.popen_uci("./stockfish") board = Board() # Game loop, run until game over engine_turn = True if player == 'black' else False while not board.is_game_over(): # Computer's move if engine_turn: # Get engine move and update board. print('Thinking... ') engine_move = engine.play( board, chess_engine.Limit(engine_time_per_move)).move print(f'Moved {engine_move}') board.push(engine_move) # After the engine's move, if display is enabled, display the board. if display: # Get SVG for board state = draw_board(board, orientation=orientation, lastmove=board.peek()) # Write the SVG to a temporary file board.svg with open('board.svg', 'w+') as f: f.write(state) # Convert the temporary SVG to a PNG with size 1024x1024, and remove # temporary file. The 1024x1024 size is arbitrary, the height and width # just have to be the same value to make it a square or the image will # look stretched out. # ! NOTE: this command only works on Unix-like systems. subprocess.run( 'inkscape -z -f board.svg -w 1024 -h 1024 -e board.png > /dev/null 2>&1' + '&& rm board.svg', shell=True) # Player's move. else: print() move = get_move(board) board.push(move) # Next turn. If it was the computer's turn, # now it's the player's turn, and vice versa. engine_turn = not engine_turn # End the engine so the process doesn't hang. engine.quit() print(''.join(['\n', 'Game Over', '\n']))
def analyze_board(self, board: chess.Board): """Analyzes the board with the uci_engine and creates a Position.""" print('Analyzing') info = self.uci_engine.analyse(board, engine.Limit(depth=20)) assert 'score' in info and 'pv' in info pv = ' '.join([str(move) for move in info['pv']]) score = info['score'].relative.score(mate_score=10000) print(f'score={score}, pv={pv}') return Position(None, get_fen(board), score, 20, pv)
def evaluate(self, position): if self.engine is None: self.start_engine() info = self.engine.analyse( position, engine.Limit(nodes=self.get_option("nodes"), time=self.get_option("movetime"))) print(info["pv"]) return info["pv"][0]
def suggest_move(self): filename = grab_pieces.shot_board(QtWidgets.qApp) board_arr = self.recognizer.recognize_board(filename) board_fen = fen.create_fen(board_arr, white=self.is_white) board = chess.Board(fen=board_fen) if not board.is_valid(): raise RuntimeError('Check captured board at: %s' % filename) result = self.engine.play(board, chess_engine.Limit(time=0.1)) line = fen.uci_move_to_line(result.move.uci(), white=self.is_white) self.point_from = QPoint(*line.from_) self.point_to = QPoint(*line.to_) self.update()
async def get_score(e, env): board = env.board evaltime = 0.005 info = await e.analyse(board, limit=engine.Limit(time=evaltime)) score = info['score'].white().score(mate_score=10000) if score > 1.5: return 1 elif score < -1.5: return -1 else: return 0
def move(): sys.stdout.flush() r = request.get_json(force=True) time = r['time'] pgn = r['pgn'] c = chess.pgn.read_game(io.StringIO(pgn)) engine = e.SimpleEngine.popen_uci( os.path.dirname(os.path.abspath(__file__)) + ENGINE_FILE) board = chess.Board() if c: for i in c.mainline_moves(): board.push(i) res = engine.play(board, e.Limit(time=time), info=chess.engine.INFO_ALL) engine.quit() return jsonify({ 'move': str(res.move), 'from': str(res.move)[0:2], 'to': str(res.move)[2:], 'eval': str(res.info['score']) })
def play_game(li, game_id, user_profile, config): response = li.get_game_stream(game_id) lines = response.iter_lines() #Initial response of stream will be the full game info. Store it initial_state = json.loads(next(lines).decode('utf-8')) game = model.Game(initial_state, user_profile["username"], li.baseUrl, config.get("abort_time", 20)) timelim=game.state["btime"]/1000 timelim=timelim/60 timep=round(timelim/85*60,1) if timep>10: timep=10 elif timep<0.3: timep=0.3 board = setup_board(game) cfg = config["engine"] if type(board).uci_variant=="chess": engine_path = os.path.join(cfg["dir"], cfg["name"]) bookname="book.bin" elif type(board).uci_variant=="atomic": engine_path = os.path.join(cfg["dir"], cfg["lcname"]) bookname="bookchen.bin" else: engine_path = os.path.join(cfg["dir"], cfg["fairyname"]) bookname="bookchen.bin" engineeng = engine.SimpleEngine.popen_uci(engine_path) engineeng.configure({'Threads':5}) engineeng.configure({'Hash':120}) engineeng.configure({'EvalFile':'nn-0e698aa9eb8b.nnue'}) engineeng.configure({'Use NNUE':True}) logger.info("Game Details: {}".format(game)) delay_seconds = config.get("rate_limiting_delay", 0)/1000 if is_engine_move(game, board.move_stack) and not is_game_over(game): with chess.polyglot.open_reader(bookname) as reader: movesob=[] weight=[] for entry in reader.find_all(board): movesob.append(entry.move) weight.append(entry.weight) if len(weight)==0 or max(weight)<9: move=engineeng.play(board,engine.Limit(time=timep)) board.push(move.move) li.make_move(game.id, move.move) time.sleep(delay_seconds) else: move=movesob[weight.index(max(weight))] board.push(move) li.make_move(game.id, move) with chess.polyglot.open_reader(bookname) as reader: while not terminated: try: binary_chunk = next(lines) except(StopIteration): break upd = json.loads(binary_chunk.decode('utf-8')) if binary_chunk else None u_type = upd["type"] if upd else "ping" if not board.is_game_over(): if u_type == "gameState": game.state=upd moves = upd["moves"].split() board = update_board(board, moves[-1]) if not is_game_over(game) and is_engine_move(game, moves): moves=[] weight=[] for entry in reader.find_all(board): moves.append(entry.move) weight.append(entry.weight) if len(weight)==0 or max(weight)<9: if game.is_white: timelim=game.state["wtime"]/1000 else: timelim=game.state["btime"]/1000 divtime=85-int(len(board.move_stack)/2) if divtime<1: timep=1 else: timep=round(timelim/divtime,1) if timep>10: timep=10 elif timep<0.3: timep=0.3 move=engineeng.play(board,engine.Limit(time=timep)) board.push(move.move) li.make_move(game.id, move.move) time.sleep(delay_seconds) else: move=moves[weight.index(max(weight))] board.push(move) li.make_move(game.id, move) if board.turn == chess.WHITE: game.ping(config.get("abort_time", 20), (upd["wtime"] + upd["winc"]) / 1000 + 60) else: game.ping(config.get("abort_time", 20), (upd["btime"] + upd["binc"]) / 1000 + 60) elif u_type == "ping": if game.should_abort_now(): logger.info(" Aborting {} by lack of activity".format(game.url())) li.abort(game.id) break elif game.should_terminate_now(): logger.info(" Terminating {} by lack of activity".format(game.url())) if game.is_abortable(): li.abort(game.id) break else: break logger.info("game over") engineeng.quit()
def play_game(li, game_id, user_profile, config): seventydone=False eightydone=False ninetydone=False global gamessss gamessss+=1 response = li.get_game_stream(game_id) lines = response.iter_lines() bullet=False #Initial response of stream will be the full game info. Store it initial_state = json.loads(next(lines).decode('utf-8')) game = model.Game(initial_state, user_profile["username"], li.baseUrl, config.get("abort_time", 20)) timelim=game.state["btime"]/1000 timelim=timelim/60 if timelim>=0.5 and timelim<=2: bullet=True time=round(timelim/100*60,1) if time>6: time=6 elif time<0.3: time=0.3 if bullet: time=0.3 board = setup_board(game) cfg = config["engine"] if type(board).uci_variant=="chess": engine_path = os.path.join(cfg["dir"], cfg["name"]) bookname="book.bin" elif type(board).uci_variant=="atomic": engine_path = os.path.join(cfg["dir"], cfg["lcname"]) bookname="bookchen.bin" else: engine_path = os.path.join(cfg["dir"], cfg["fairyname"]) bookname="bookchen.bin" engineeng = engine.SimpleEngine.popen_uci(engine_path) engineeng.configure({'Threads':5}) engineeng.configure({'Hash':120}) logger.info("+++ {}".format(game)) if is_engine_move(game, board.move_stack) and not is_game_over(game): with chess.polyglot.open_reader(bookname) as reader: movesob=[] weight=[] for entry in reader.find_all(board): movesob.append(entry.move) weight.append(entry.weight) if len(weight)==0 or max(weight)<9: move=engineeng.play(board,engine.Limit(time=time)) board.push(move.move) li.make_move(game.id, move.move) else: move=movesob[weight.index(max(weight))] board.push(move) li.make_move(game.id, move) with chess.polyglot.open_reader(bookname) as reader: while not terminated: try: binary_chunk = next(lines) except(StopIteration): break upd = json.loads(binary_chunk.decode('utf-8')) if binary_chunk else None u_type = upd["type"] if upd else "ping" if not board.is_game_over(): if u_type == "gameState": game.state=upd moves = upd["moves"].split() board = update_board(board, moves[-1]) if not is_game_over(game) and is_engine_move(game, moves): moves=[] weight=[] for entry in reader.find_all(board): moves.append(entry.move) weight.append(entry.weight) if len(weight)==0 or max(weight)<9: move=engineeng.play(board,engine.Limit(time=time)) board.push(move.move) li.make_move(game.id, move.move) else: move=moves[weight.index(max(weight))] board.push(move) li.make_move(game.id, move) if board.turn == chess.WHITE: game.ping(config.get("abort_time", 20), (upd["wtime"] + upd["winc"]) / 1000 + 60) else: game.ping(config.get("abort_time", 20), (upd["btime"] + upd["binc"]) / 1000 + 60) if len(board.move_stack)>70 and time>1.7 and not seventydone: time-=1 seventydone=True if len(board.move_stack)>80 and time>1.7 and not eightydone: time-=1 eightydone=True if len(board.move_stack)>90 and time>1.7 and not ninetydone: time-=1 ninetydone=True elif u_type == "ping": if game.should_abort_now(): logger.info(" Aborting {} by lack of activity".format(game.url())) li.abort(game.id) break elif game.should_terminate_now(): logger.info(" Terminating {} by lack of activity".format(game.url())) if game.is_abortable(): li.abort(game.id) break else: logger.info("game over") gamessss-=1 engineeng.quit() break
def play_game(li, game_id, engine_factory, user_profile, config): li.chat( game_id, "player", "βπ ππ¦πππͺ π ππ @πππ€π₯ππ£_πΉππ ππ¦πππ ππ ππ₯π πππππ€π ππ πππ§ πππ πππ¦π πΎπ π π ππ¦ππ :π» " ) li.chat( game_id, "spectator", "βπ ππ¦πͺπ€ π ππ @πππ€π₯ππ£_πΉππ ππ¦πππ ππ ππ₯π πππππ€π ππ πππ§ πππ πππ¦π πΎπ π π ππ¦ππ :π» " ) response = li.get_game_stream(game_id) lines = response.iter_lines() bullet = False #Initial response of stream will be the full game info. Store it initial_state = json.loads(next(lines).decode('utf-8')) game = model.Game(initial_state, user_profile["username"], li.baseUrl, config.get("abort_time", 20)) timelim = game.state["btime"] / 1000 timelim = timelim / 60 if timelim >= 0.5 and timelim <= 2: bullet = True time = round(timelim / 150 * 60, 1) if time > 6: time = 6 elif time < 0.3: time = 0.3 if bullet: time = 0.2 board = setup_board(game) cfg = config["engine"] if type(board).uci_variant == "chess": engine_path = os.path.join(cfg["dir"], cfg["name"]) bookname = "book.bin" elif type(board).uci_variant == "atomic": engine_path = os.path.join(cfg["dir"], cfg["lcname"]) bookname = "bookchen.bin" else: engine_path = os.path.join(cfg["dir"], cfg["fairyname"]) bookname = "bookchen.bin" engineeng = engine.SimpleEngine.popen_uci(engine_path) logger.info("+++ {}".format(game)) if is_engine_move(game, board.move_stack) and not is_game_over(game): with chess.polyglot.open_reader(bookname) as reader: movesob = [] weight = [] for entry in reader.find_all(board): movesob.append(entry.move) weight.append(entry.weight) if len(weight) == 0: move = engineeng.play(board, engine.Limit(time=time)) board.push(move.move) li.make_move(game.id, move.move) else: move = movesob[weight.index(max(weight))] board.push(move) li.make_move(game.id, move) with chess.polyglot.open_reader(bookname) as reader: while not terminated: try: binary_chunk = next(lines) except (StopIteration): break upd = json.loads( binary_chunk.decode('utf-8')) if binary_chunk else None u_type = upd["type"] if upd else "ping" if not board.is_game_over(): if u_type == "gameState": game.state = upd moves = upd["moves"].split() board = update_board(board, moves[-1]) if not is_game_over(game) and is_engine_move(game, moves): moves = [] weight = [] for entry in reader.find_all(board): moves.append(entry.move) weight.append(entry.weight) if len(weight) == 0: move = engineeng.play(board, engine.Limit(time=time)) board.push(move.move) li.make_move(game.id, move.move) else: move = moves[weight.index(max(weight))] board.push(move) li.make_move(game.id, move) if board.turn == chess.WHITE: game.ping(config.get("abort_time", 20), (upd["wtime"] + upd["winc"]) / 1000 + 60) else: game.ping(config.get("abort_time", 20), (upd["btime"] + upd["binc"]) / 1000 + 60) elif u_type == "ping": if game.should_abort_now(): logger.info( " Aborting {} by lack of activity".format( game.url())) li.abort(game.id) break elif game.should_terminate_now(): logger.info( " Terminating {} by lack of activity".format( game.url())) if game.is_abortable(): li.abort(game.id) break else: logger.info("game over") engineeng.quit() break
str(pathlib.Path().absolute()) + "/stockfish12") board = Board() raw = open("lichess_elite_2020-09.pgn", encoding="utf-8") games = {"games": []} for i in tqdm(range(1000)): g = pgn.read_game(raw) try: length = int(str(g.end()).split('.')[0]) except ValueError: pass rand = random.randint(int(length / 3), int(4 * length / 5)) board = g.board() for move in g.mainline_moves(): if rand == 0: break board.push(move) rand -= 1 f = board.fen() info = stock.analyse(board, engine.Limit(depth=20), info=engine.INFO_SCORE) try: games["games"].append({ "fen": f, "score": int(str(info["score"].relative)) }) except ValueError: pass with open('games.json', 'w') as outfile: json.dump(games, outfile)
/, *, checkpoint: Optional[int] = None) -> None: kwds = {x: [] for x in ("X", "y_1", "y_2")} _, uci_protocol = await engine.popen_uci( _path("../lib/stockfish/stockfish")) with open(file) as f: savez = lambda: np.savez( _path(f"../data/npz/{pathlib.PurePath(f.name).stem}"), **kwds) while True: try: try: play_result = await uci_protocol.play( board := random.choice( tuple(pgn.read_game(f).mainline())).board(), limit=engine.Limit(time=.1), info=engine.INFO_SCORE) except AttributeError: break for kwd, x in zip( kwds.values(), (bitboard(board, dtype=int), moves.index( (play_result.move if board.turn else chess.Move( *(len(chess.SQUARES) - np.array( (play_result.move.from_square, play_result.move.to_square)) - 1), promotion=play_result.move.promotion)).uci()), tanh(play_result.info["score"].relative.score( mate_score=7625), k=.0025))):