Exemplo n.º 1
0
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']))
Exemplo n.º 2
0
 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)
Exemplo n.º 3
0
 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]
Exemplo n.º 4
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()
Exemplo n.º 5
0
 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
Exemplo n.º 6
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'])
    })
Exemplo n.º 7
0
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()              
Exemplo n.º 8
0
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
Exemplo n.º 9
0
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
Exemplo n.º 10
0
    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)
Exemplo n.º 11
0
             /,
             *,
             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))):