Esempio n. 1
0
class Engine:
    def __init__(self, skill_level):
        parameters = {
            "Write Debug Log": "false",
            "Contempt": 0,
            "Min Split Depth": 0,
            "Threads": 1,
            "Ponder": "false",
            "Hash": 16,
            "MultiPV": 1,
            "Skill Level": skill_level,
            "Move Overhead": 30,
            "Minimum Thinking Time": 20,
            "Slow Mover": 80,
            "UCI_Chess960": "false",
        }
        self.engine = Stockfish("resources/stockfish.exe",
                                parameters=parameters)
        self.engine.set_depth(ENGINE_DEPTH)

    def set_position(self, fen):
        self.engine.set_fen_position(fen)

    def get_move(self, time):
        return self.engine.get_best_move_time(time)
Esempio n. 2
0
class Moves:
    def __init__(self):
        self.best_move = ''
        self.stockfish = Stockfish(
            "stockfish_14_linux_x64_avx2/stockfish_14_x64_avx2")
        self.positions2 = ""
        self.pos_temp = 0
        self.curr_position = (Fen().start_position_list()).copy()

    def current_position(self):
        return self.curr_position

    def change_position(self, position):
        start_pos = position[0:2].lower()
        stop_pos = position[2:4].lower()

        for key, value in self.curr_position.items():
            if key == start_pos:
                moved_obj = value
        self.curr_position[start_pos] = None
        self.curr_position[stop_pos] = moved_obj
        return self.curr_position

    def curr_fen(self):
        self.positions2 = ''
        for ix, value in enumerate(self.curr_position.values()):
            # import ipdb
            # ipdb.set_trace()
            if ix % 8 == 0 and ix != 0:
                if self.pos_temp > 0:
                    self.positions2 += str(self.pos_temp)
                self.positions2 += "/"
                self.pos_temp = 0
            if not value:
                self.pos_temp += 1
            else:
                if self.pos_temp > 0:
                    self.positions2 += str(self.pos_temp)
                    self.pos_temp = 0
                self.positions2 += value
                print(self.positions2)
        return self.positions2 + ' b KQkq - 0 1'

    def stock_best(self):
        self.stockfish.set_fen_position(self.curr_fen())
        self.best_move = self.stockfish.get_best_move_time(10)
        return self.best_move
Esempio n. 3
0
class StockfishPlayer:
    def __init__(self, game, level):
        self.game = game
        self.engine = Stockfish('engines/stockfish',
                                parameters={
                                    "Threads": 4,
                                    "Skill Level": level
                                })

    def play(self, board):
        fen = board.fen()
        self.engine.set_fen_position(fen)

        move_uci = chess.Move.from_uci(self.engine.get_best_move_time(100))
        if move_uci not in list(board.legal_moves):
            log.error("Wrong move chosen by Stockfish! Check code")
            move_uci = random.choice(list(board.legal_moves))

        action = move_uci.from_square * 64 + move_uci.to_square

        return action
Esempio n. 4
0
    def get_from_to_move(maxtrix, image):
        move = input("Чей ход?[w/b]: ").lower()

        board = chess.Board(Detector.mat_to_fen(matrix, move))
        fen = board.fen()

        stockfish = Stockfish(
            "./Engines/stockfish_13_win_x64/stockfish_13_win_x64.exe",
            parameters={
                "Threads": os.cpu_count(),
                "Minimum Thinking Time": 30
            })

        stockfish.set_fen_position(fen)
        best_move = stockfish.get_best_move_time(1000)

        print("best move", best_move)
        x1, y1, x2, y2 = Detector.get_from_to(best_move, move)

        # print(x1, y1, x2, y2)
        cv2.rectangle(image, (x1, y1), (x1 + 100, y1 + 100), (0, 0, 255), 2)
        cv2.rectangle(image, (x2, y2), (x2 + 100, y2 + 100), (255, 0, 0), 2)
Esempio n. 5
0
def main(player1="Player 1",
         player2="Player 2",
         mode="STANDARD",
         bot_bool=False,
         bot_difficulty=6):

    # resetting the variables in the .json file#
    json_file = open(r'components\constants.json', 'r')
    json_content = json.load(json_file)
    json_content["round_int"] = 0
    json_file.close()
    json_file = open(r'components\constants.json', 'w')
    json_file.writelines(json.dumps(json_content))
    json_file.close()

    Pieces.white_is_checked = False
    Pieces.black_is_checked = False
    Pieces.checking_piece = None

    #initiating pygame#
    pygame.init()

    player1 = "Spieler 1" if player1 == "" else player1
    player2 = "Spieler 2" if player2 == "" else player2

    #Constants#
    BLACK = (0, 0, 0)
    GREY = (50, 50, 50)
    WHITE = (255, 255, 255)
    BG_COLOR_1 = (0, 152, 163)
    BG_COLOR_2 = (2, 112, 120)

    #reading the constants from the json file#
    json_file = open(os.getcwd() + r"\components\constants.json", "r")
    json_content = json.load(json_file)
    round_int = json_content["round_int"]
    tile_size = json_content["tile_size"]
    anchor_point_s = (json_content["anchor_point_s_x"] * tile_size,
                      json_content["anchor_point_s_y"] * tile_size)
    anchor_point_h = (json_content["anchor_point_h_x"] * tile_size,
                      json_content["anchor_point_h_y"] * tile_size)
    anchor_point_hud = (json_content["anchor_point_hud_x"] * tile_size,
                        json_content["anchor_point_hud_y"] * tile_size)
    json_file.close()

    #setting up the variables for a new and fresh game#
    screen_size = (11 * tile_size, 11 * tile_size)
    font = pygame.font.SysFont("DejaVu Sans", int(tile_size * 0.2))
    font_titles = pygame.font.SysFont("DejaVu Sans", int(tile_size * 0.25))
    go = True
    timer = Clock(time=5)

    #creating the surfaces#
    screen = pygame.display.set_mode(screen_size, 0, 0)
    s = pygame.Surface((8 * tile_size, 8 * tile_size))
    hud = pygame.Surface((10.25 * tile_size, 2 * tile_size))
    p1 = pygame.Surface((3 * tile_size, 1.5 * tile_size))
    p2 = pygame.Surface((3 * tile_size, 1.5 * tile_size))
    h = Hud((2 * tile_size, 8 * tile_size))
    screen.fill(BG_COLOR_1)
    hud.fill(BG_COLOR_2)
    h.fill(BG_COLOR_2)
    h.print(pos=(0.6 * tile_size, 20), label='Spielhistorie', font=font)

    #window caption#
    pygame.display.set_caption("Chess")

    #creating a clock for the ingame ticks#
    clock = pygame.time.Clock()

    #creating the board on the subsurface#
    board = Board(master=s,
                  width=8,
                  height=8,
                  tile_size=tile_size,
                  color_a=(245, 216, 188),
                  color_b=(176, 142, 109),
                  color_t1=(240, 230, 221),
                  color_t2=(201, 181, 163),
                  anchor_point=anchor_point_s)

    #loading the images for the pieces#
    images = {
        "white_pawn_img": pygame.image.load(r'assets/white_pawn.png'),
        "white_rook_img": pygame.image.load(r'assets/white_rook.png'),
        "white_knight_img": pygame.image.load(r'assets/white_knight.png'),
        "white_bishop_img": pygame.image.load(r'assets/white_bishop.png'),
        "white_queen_img": pygame.image.load(r'assets/white_queen.png'),
        "white_king_img": pygame.image.load(r'assets/white_king.png'),
        "black_pawn_img": pygame.image.load(r'assets/black_pawn.png'),
        "black_rook_img": pygame.image.load(r'assets/black_rook.png'),
        "black_knight_img": pygame.image.load(r'assets/black_knight.png'),
        "black_bishop_img": pygame.image.load(r'assets/black_bishop.png'),
        "black_queen_img": pygame.image.load(r'assets/black_queen.png'),
        "black_king_img": pygame.image.load(r'assets/black_king.png')
    }
    #loading the icons for the buttons#
    quit_icon = pygame.image.load(r'assets/quit.png')
    takeback_icon = pygame.image.load(r'assets/takeback.png')
    resign_icon = pygame.image.load(r'assets/resign_flag.png')
    test_icon = pygame.image.load(r'assets/lightbulb.png')

    #creating the board
    build_board(mode, s, images)

    #creating the chessbot based on .json parameters
    bot = Stockfish(b'components\stockfish_20011801_x64.exe')
    bot.set_skill_level(bot_difficulty)

    quit_button = Button(x=8.5 * tile_size,
                         y=0.4 * tile_size,
                         w=int(0.6 * tile_size),
                         h=int(0.6 * tile_size),
                         color_b=BLACK,
                         color_in=GREY,
                         color_t=WHITE,
                         command=quit,
                         icon=quit_icon,
                         imaginary_x=anchor_point_hud[0],
                         imaginary_y=anchor_point_hud[1])

    resign_button = Button(x=9.2 * tile_size,
                           y=0.4 * tile_size,
                           w=int(0.6 * tile_size),
                           h=int(0.6 * tile_size),
                           color_b=BLACK,
                           color_in=GREY,
                           color_t=WHITE,
                           command=lambda: [decideWhoLost(round_int)],
                           icon=resign_icon,
                           imaginary_x=anchor_point_hud[0],
                           imaginary_y=anchor_point_hud[1])

    test_zone_button = Testmode_Button(
        x=9.2 * tile_size,
        y=0.4 * tile_size + 0.74 * tile_size,
        w=int(0.6 * tile_size),
        h=int(0.6 * tile_size),
        color_b=BLACK,
        color_in=GREY,
        color_t=WHITE,
        command1=lambda: [
            Board.change_testmode(),
            #Pieces.change_ignore_me_standard(),
            Pieces.crop_move_done(),
            Pieces.kill_board(),
            build_board(mode, s, images),
            Pieces.build_from_list(screen=s),
            Pieces.set_round(Pieces.round_safe)
        ],
        command2=lambda: [
            Board.change_testmode(),
            #Pieces.change_ignore_me_standard(),
            Pieces.safe_round()
        ],
        icon=test_icon,
        imaginary_x=anchor_point_hud[0],
        imaginary_y=anchor_point_hud[1],
        deaf=False)

    if bot_bool:
        command = lambda: [
            takeback(board, s, takeback_button),
            takeback(board, s, takeback_button)
        ]
    else:
        command = lambda: [takeback(board, s, takeback_button)]

    takeback_button = Button(x=8.5 * tile_size,
                             y=0.4 * tile_size + 0.74 * tile_size,
                             w=int(0.6 * tile_size),
                             h=int(0.6 * tile_size),
                             color_b=BLACK,
                             color_in=GREY,
                             color_t=WHITE,
                             command=command,
                             icon=takeback_icon,
                             imaginary_x=anchor_point_hud[0],
                             imaginary_y=anchor_point_hud[1])

    start_sound = mixer.Sound("assets/sounds/board-start.mp3")
    start_sound.play()

    #the mainloop#
    while go:
        #setting the framerate#
        clock.tick(60)

        #refreshing the round counter#
        json_file = open(os.getcwd() + r"\components\constants.json", "r")
        json_content = json.load(json_file)
        round_int = json_content["round_int"]
        json_file.close()

        #drawing the board#
        # if not Board.game_over:
        board.draw_board()

        #updating the bot with the new game state#
        bot.set_fen_position(Pieces.give_FEN())

        #detecting, if the game is over, or not
        if not Board.game_over:
            Pieces.detectingCheck()
            Board.game_over = Pieces.detectGameOver(round_int=round_int)

        #end the game if the game is over#
        if Board.game_over or Board.resign_w or Board.resign_b:
            if Pieces.white_is_checked or Board.resign_w:
                board.end_screen('BLACK', s)
            elif Pieces.black_is_checked or Board.resign_b:
                board.end_screen('WHITE', s)
            else:
                board.end_screen('STALEMATE', s)
            takeback_button.active = False
            resign_button.active = False
            test_zone_button.active = False

        #checking if a pawn is promotable#
        for pawn in Pieces.all_pieces_list:
            if 'Pawn-B' in pawn.name and pawn.y == 7 * tile_size or 'Pawn-W' in pawn.name and pawn.y == 0 * tile_size:
                pawn.promotion()

        Pieces.detectingCheck()
        #highlighting the checked king#
        if Pieces.white_is_checked:
            for king in Pieces.all_pieces_list:
                if isinstance(king, Kings) and king.farbe == WHITE:
                    board.check(king_pos=(king.x, king.y))

        #highlighting the checked king#
        elif Pieces.black_is_checked:
            for king in Pieces.all_pieces_list:
                if isinstance(king, Kings) and king.farbe == BLACK:
                    board.check(king_pos=(king.x, king.y))

        #drawing all the pieces#
        # if not Board.game_over:
        for pieces in Pieces.all_pieces_list:
            pieces.draw(screen)

        #updating the mainsurface#
        pygame.display.update()

        #clearing the Subsurfaces#
        p1.fill(BG_COLOR_1)
        p2.fill(BG_COLOR_1)
        hud.fill(BG_COLOR_2)

        #refresh the time of the timers#
        timer.refreshTime()

        #creating the labels to be printed on the subsurfaces#
        Player_1_label = font_titles.render(player1, 1, BLACK)
        Player_2_label = font_titles.render(player2, 1, BLACK)
        timer_label = font_titles.render(timer.getTime(), 1, BLACK)

        #printing the labes on the subsurfaces#
        p1.blit(Player_1_label,
                (p1.get_width() / 2 - Player_1_label.get_width() / 2, 0))
        p2.blit(Player_2_label,
                (p2.get_width() / 2 - Player_2_label.get_width() / 2, 0))

        #creating the history
        h.fill(BG_COLOR_2)
        h.print((0.31 * tile_size, 20), 'Spielhistorie', font)
        for i in range(len(Pieces.moves_done)):
            fac_50 = 5 / 7 * tile_size
            fac_20 = 2 / 7 * tile_size
            h.print(pos=((i % 2) * fac_50 + fac_20,
                         (i // 2) * fac_20 + 2 * fac_20),
                    label=Pieces.moves_done[i],
                    font=font)

        #showing the taken pieces#
        Pieces.taken_pieces.sort(key=lambda x: x.value, reverse=False)
        white_loss = [[], []]
        black_loss = [[], []]
        for piece in Pieces.taken_pieces:
            if piece.farbe == (0, 0, 0):
                if len(black_loss[0]) < 8:
                    black_loss[0].append(piece)
                else:
                    black_loss[1].append(piece)
            elif piece.farbe == WHITE:
                if len(white_loss[0]) < 8:
                    white_loss[0].append(piece)
                else:
                    white_loss[1].append(piece)

        for line in black_loss:
            for piece in line:
                p1.blit(
                    pygame.transform.scale(piece.image,
                                           (tile_size // 3, tile_size // 3)),
                    ((line.index(piece) * 11 / 32 + 6 / 40) * tile_size,
                     (black_loss.index(line) + 1) * 0.5 * tile_size))
        for line in white_loss:
            for piece in line:
                p2.blit(
                    pygame.transform.scale(piece.image,
                                           (tile_size // 3, tile_size // 3)),
                    ((line.index(piece) * 11 / 32 + 6 / 40) * tile_size,
                     (white_loss.index(line) + 1) * 0.5 * tile_size))

        value_white = 0
        value_black = 0

        for piece in Pieces.taken_pieces:
            if piece.farbe == (0, 0, 0):
                value_black += piece.value
            elif piece.farbe == WHITE:
                value_white += piece.value

        label = font.render('+' + str(abs(int(value_white - value_black))),
                            True, BLACK)
        if int(value_white - value_black) > 0:
            if len(white_loss[0]) < 8:
                p2.blit(label,
                        ((len(white_loss[0]) * 11 / 32 + 6 / 40) * tile_size,
                         0.55 * tile_size))
            else:
                p2.blit(label,
                        ((len(white_loss[1]) * 11 / 32 + 6 / 40) * tile_size,
                         1.05 * tile_size))
        elif int(value_white - value_black) < 0:
            if len(black_loss[0]) < 8:
                p1.blit(label,
                        ((len(black_loss[0]) * 11 / 32 + 6 / 40) * tile_size,
                         0.55 * tile_size))
            else:
                p1.blit(label,
                        ((len(black_loss[1]) * 11 / 32 + 6 / 40) * tile_size,
                         1.05 * tile_size))

        #updating the hud#
        if round_int % 2 == 0:
            pygame.draw.rect(hud, BLACK, [
                0.45 * tile_size, 0.2 * tile_size, 3.1 * tile_size,
                1.6 * tile_size
            ])
        elif round_int % 2 == 1:
            pygame.draw.rect(hud, BLACK, [
                4.45 * tile_size, 0.2 * tile_size, 3.1 * tile_size,
                1.6 * tile_size
            ])
        hud.blit(p1, (0.5 * tile_size, 0.25 * tile_size))
        hud.blit(p2, (4.5 * tile_size, 0.25 * tile_size))
        hud.blit(timer_label, (3.65 * tile_size, 0.75 * tile_size))

        #creating the buttons on the hud
        resign_button.draw(screen=hud)
        quit_button.draw(screen=hud)
        takeback_button.draw(screen=hud)
        test_zone_button.draw(screen=hud)

        items = [quit_button, resign_button, takeback_button, test_zone_button]

        #bliting the subsurfaces on the mainsurface
        screen.blit(s, anchor_point_s)
        screen.blit(h, anchor_point_h)
        screen.blit(hud, anchor_point_hud)

        #bot moves#
        if round_int % 2 == 1 and bot_bool and not Board.game_over and not Board.test_mode:
            opt_move = bot.get_best_move_time(random.randint(400, 1200))
            for piece in Pieces.all_pieces_list:
                if piece.farbe == BLACK:
                    move = piece.move_from_pos(
                        move=opt_move,
                        board=board,
                        screen=screen,
                        takeback_button=takeback_button,
                        ignore_me=Pieces.ignore_me_standard)
                    if move != None:
                        break

        #checking for events#
        else:
            for event in pygame.event.get():

                for item in items:
                    item.processEvent(event)

                #closing the screen by clicking the X#
                if event.type == pygame.QUIT:
                    go = False

                #Keyboard-Inputs#
                if event.type == pygame.KEYDOWN:

                    #kill window if ESC is pressed#
                    if event.key == pygame.K_ESCAPE:
                        Pieces.white_is_checked = False
                        Pieces.black_is_checked = False
                        Pieces.checking_piece = None

                        json_file = open(r'components\constants.json', 'r')
                        json_content = json.load(json_file)
                        json_content["round_int"] = 0
                        json_file.close()
                        json_file = open(r'components\constants.json', 'w')
                        json_file.writelines(json.dumps(json_content))
                        json_file.close()

                        quit()

                    #(TEMP) my information key (arrow down) to get certain information#
                    if event.key == pygame.K_DOWN:
                        print(Pieces.give_FEN())
                        #print([x.name for x in Pieces.all_pieces_list])
                        # for king in Pieces.all_pieces_list:
                        #     if "King-W" in king.name:
                        #         print(list(king.is_castle_legal()))

                #left mouse click#
                elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:

                    #getting the mouseposition and than correcting it by the relative position of the subsurface#
                    mouse_pos = pygame.mouse.get_pos()
                    mouse_pos = (mouse_pos[0] - anchor_point_s[0],
                                 mouse_pos[1] - anchor_point_s[1])

                    #checking if a Piece stands on the clicked tile#
                    if not Board.game_over:
                        for piece in Pieces.all_pieces_list:
                            if mouse_pos[0] >= piece.x and mouse_pos[
                                    1] >= piece.y:
                                if mouse_pos[
                                        0] < piece.x + tile_size and mouse_pos[
                                            1] < piece.y + tile_size:

                                    #if the clicked piece is one of the team that currently is to move...#

                                    with_bool = round_int % 2 == 0 and piece.farbe == (
                                        255, 255, 255)
                                    without_bool = round_int % 2 == 1 and piece.farbe == (
                                        0, 0, 0)

                                    if with_bool or without_bool:

                                        #...wait for the second mouse input#
                                        move_ = piece.move(
                                            board=board,
                                            screen=screen,
                                            takeback_button=takeback_button,
                                            ignore_me=Pieces.ignore_me_standard
                                        )

                                        move_ = move_[1][2:3] + move_[2] + str(
                                            move_[0][2:])

                                        #check if the white kiung is checked#
                                        Pieces.detectingCheck()

    #resetting class variables#
    Pieces.white_is_checked = False
    Pieces.black_is_checked = False
    Pieces.checking_piece = None

    #resetting the variables in the .json file#
    json_file = open(r'components\constants.json', 'r')
    json_content = json.load(json_file)
    json_content["round_int"] = 0
    json_file.close()
    json_file = open(r'components\constants.json', 'w')
    json_file.writelines(json.dumps(json_content))
    json_file.close()
Esempio n. 6
0
class SampleStockfish:
    """
    Stockfish player class.
    """
    def __init__(self, side, board, max_time_per_move, time_control):
        """
        Initialize player class to implement Stockfish.

        side: str
          Either 'white' or 'black' for the side that the player is expected to play

        board: Board (default: chess.Board())
          Initial board configuration (the default is just the normal board).

        max_time_per_move: float (default: None)
          Max. thinking time (in sec) to be passed to the players.
        
        time_control: 2-tuple of floats (default: None)
          The time control, formatted as (x, y) where the time control is x minutes
          with a y second increment. This argument is distinct from max_time_per_move.
        """
        self.name = 'Stockfish'
        
        self.side = side
        self.board = board
        self.max_time_per_move = max_time_per_move
        self.time_control = time_control
        
        # Manage time control
        if self.time_control is not None and self.max_time_per_move is not None:
            self.time_left = np.min([60 * self.time_control[0], self.max_time_per_move])
        elif self.time_control is not None:
            self.time_left = 60 * self.time_control[0]
        elif self.max_time_per_move is not None:
            self.time_left = self.max_time_per_move
        else:
            self.time_left = None
        
        # Start Stockfish
        from stockfish import Stockfish
        self.stockfish = Stockfish('./stockfish-11-win/Windows/stockfish_20011801_x64_modern.exe')
    
    def make_move(self):
        """
        Method to make a move. Returns the move in UCI.
        """
        self.stockfish.set_fen_position(self.board.fen())
        if self.time_left is not None:
            move = self.stockfish.get_best_move_time(0.8 * self.time_left * 1000)
        else:
            # If no time controls, make this 30 s
            move = self.stockfish.get_best_move_time(30 * 1000)
        
        self.board.push(chess.Move.from_uci(move))
        
        return move
    
    def receive_move(self, move, time_left=None):
        """
        Method to update board with move from the other side.
        
        move: str
          Move that opponent made
        
        time_left: float (default: None)
          Time remaining, if None, there is no global time control
        """
        self.board.push(chess.Move.from_uci(move))
        self.time_left = time_left
        
        return
    
    def request_draw(self):
        """
        Method to request a draw. Return True if want to request a draw, False if not.
        """
        return False
    
    def respond_draw(self):
        """
        Method to respond to a draw request. Return True if accept draw, False if not.
        """
        return False
    
    def receive_trash_talk(self, trash_talk):
        """
        Method to receive trash talk.
        """
        return
    
    def solicit_trash_talk(self):
        """
        Method to solicit trash talk. Return a string to solicit trash talk. If no trash
        talk, return none.
        """
        return None
Esempio n. 7
0
def stockfish_move(position, to_play):
    stockfish = Stockfish("/usr/games/stockfish")
    fen_line = position + " " + to_play + " KQkq - 0 0"
    stockfish.set_fen_position(fen_line)
    return stockfish.get_best_move_time(1000)
Esempio n. 8
0
class Chess_bot:
    def __init__(self):
        self.stockfish = Stockfish("./stockfish")
        self.knn_clf = joblib.load("train/model.pkl")

        #The board size. Should be 320 because thats what the model has been trained on
        self.board_size = 320

        self.checking = False
        self.bot_turn = True

    def find_color(self, img):
        tiles = self.get_tiles(img)

        #White if pawn at a2 is white else black
        self.white = self.knn_clf.predict([tiles[48]])[0] == 'P'

        self.board = chess.Board()

        #Set last board positions as a black board
        black_start = cv2.imread("black_board.png", cv2.IMREAD_GRAYSCALE)
        self.last_positions = self.knn_clf.predict(
            self.get_tiles(black_start)).reshape(8, 8)

        self.last_img = img

        return self.white

    def get_tiles(self, img):
        #Resize the image of the board
        board_img = cv2.resize(img, (self.board_size, self.board_size))

        tile_size = self.board_size // 8

        #initialize tiles array with 8 rows and columns
        tiles = list()

        for y in range(0, self.board_size, tile_size):
            for x in range(0, self.board_size, tile_size):
                tiles.append(board_img[y:y + tile_size,
                                       x:x + tile_size].flatten())

        return np.array(tiles)

    def turn(self, img, bot_move=False):
        """Return True if it's bot turn to make a move else False"""

        #If the new predicted board is different ==> new move is being made, wait till completion.
        if not np.array_equal(self.last_img, img):
            self.checking = True
            self.last_img = img
            return False
        elif self.checking:  #If images are equal and move has been made
            self.checking = False

            #Get new board layout
            tiles = self.get_tiles(img)
            board_pred = self.knn_clf.predict(tiles).reshape(8, 8)

            if np.array_equal(board_pred, self.last_positions):
                return False

            if not self.move(board_pred):
                self.last_positions = board_pred
                return False
            self.last_positions = board_pred

            print(self.board)
            return True
        else:
            return False

    def white_move(self, img):
        tiles = self.get_tiles(img)
        board_pred = self.knn_clf.predict(tiles).reshape(8, 8)
        if not np.array_equal(self.last_positions, board_pred):
            if not self.move(board_pred): return False
            self.last_positions = board_pred

            return True

    def move(self, new_pos):
        from_moves = []
        to_moves = []
        vals = {0: "a", 1: "b", 2: "c", 3: "d", 4: "e", 5: "f", 6: "g", 7: "h"}

        #Black and white have opposite coordinates
        Y_mod = 8 if self.white else -1
        X_mod = 7 if not self.white else 0

        for y in range(8):
            for x in range(8):
                if new_pos[y, x] != self.last_positions[y, x]:
                    pos = f"{vals[abs(x-X_mod)]}{abs(Y_mod-y)}"
                    from_moves.append(pos) if new_pos[y,x] == '1' \
                        else to_moves.append(pos)

        if len(to_moves) > 1 and len(to_moves) < 3:
            try:
                self.board.push_san("O-O")
            except ValueError:
                self.board.push_san("O-O-O")
            return True

        for from_move in from_moves:
            for to_move in to_moves:
                move = chess.Move.from_uci(f"{from_move}{to_move}")
                if move in self.board.legal_moves:
                    self.board.push(move)
                    return True

        print("Can't find any legal move")
        return False

    def execute_bestMove(self, borders):
        if not self.bot_turn:
            self.bot_turn = True
            return
        self.stockfish.set_fen_position(self.board.fen())

        #Get the best move from current position on a time constraint
        #Change it if you want the bot to play faster
        best_move = self.stockfish.get_best_move_time(750)
        print(
            f"Best move {'for opponent' if not self.bot_turn else ''} is: {best_move}"
        )

        #Stop the program if its checkmate
        if best_move == None:
            print("We won!!")
            return True

        #Get best_move start position [X,Y]
        from_pos = self.get_pos(best_move[:2], borders)
        #Get best_move end position [X,Y]
        to_pos = self.get_pos(best_move[2:], borders)

        #Drag the piece using the positions
        pyautogui.moveTo(from_pos[0], from_pos[1], 0.01)
        pyautogui.dragTo(
            from_pos[0], from_pos[1] + 1, button="left", duration=0.01
        )  #This small click is used to get the focus back on the browser window
        pyautogui.dragTo(to_pos[0],
                         to_pos[1],
                         button=f"{'left' if self.bot_turn else 'right'}",
                         duration=0.3)
        pyautogui.moveTo(2, 2, 0.01)

        self.bot_turn = not self.bot_turn

    def get_pos(self, tile, borders):
        """Get the position from the uci format position"""
        tile_size = (borders["maxX"] - borders["minX"]) // 8
        vals = {"a": 0, "b": 1, "c": 2, "d": 3, "e": 4, "f": 5, "g": 6, "h": 7}

        #Black and white have opposite coordinates
        Y_mod = -8 if self.white else -1
        X_mod = 7 if not self.white else 0

        x, y = abs(X_mod - vals[tile[0]]), abs(Y_mod + int(tile[1]))

        Xpos = x * tile_size + tile_size // 2 + borders['minX']
        Ypos = y * tile_size + tile_size // 2 + borders['minY']

        return [Xpos, Ypos]
Esempio n. 9
0
color = input("What color do you want to be? ")

moves = []
order = []

while True:
    if color == 'white' or color == 'w':
        order = ["Human player", "Stockfish"]
        s = Ser('b')
        print('Starting game...')
        break
    elif color == 'black' or color == 'b':
        order = ["Stockfish", "Human player"]
        s = Ser('w')
        print('Starting game...')
        first_move = stockfish.get_best_move_time(thinking)
        print(f'White moves: {board.san(chess.Move.from_uci(first_move))}')
        board.push_uci(first_move)
        moves.append(first_move)
        break
    else:
        print('Please enter white (w) or black (b)')
        color = input("What color do you want to be? ")

try:
    while True:
        resign = False
        human_move = input("Your move: ")

        while True:
            try: