def evaluation_from_board(board: chess.Board, evaluation_depth: int = 22) -> Dict: board_fen = board.fen() stockfish = Stockfish("/opt/homebrew/Cellar/stockfish/13/bin/stockfish") stockfish.set_depth(evaluation_depth) # set engine depth stockfish.set_fen_position(board_fen) return stockfish.get_evaluation()
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)
def generate_random_advantage_position(evaluation_depth: int): stockfish = Stockfish("/opt/homebrew/Cellar/stockfish/13/bin/stockfish") stockfish.set_depth(evaluation_depth) # set engine depth while True: board = chess.Board() end_game = False for i in range(random.randint(10, 200)): move = random.choice(list(board.legal_moves)) board.push(move) if board.is_game_over(): end_game = True print("Final position") break if not end_game: board_fen = board.fen() stockfish.set_fen_position(board_fen) position_evaluation = stockfish.get_evaluation() print( f"Position_evaluation: {position_evaluation}, fen = {board_fen}" ) if position_evaluation['type'] == 'cp' and abs( position_evaluation["value"]) < 300 and abs( position_evaluation["value"] ) > 1000: # rule out when no big advantage print( f"position_evaluation: {position_evaluation}. Passing: rule out when no big advantage" ) pass elif position_evaluation['type'] == 'mate' and position_evaluation[ 'value'] <= 1: # rule out mate in 1 print( f"position_evaluation: {position_evaluation}. Passing: rule out mate in 1" ) pass else: if board.turn == chess.WHITE and position_evaluation[ "value"] <= 0: # not an advantage white print(f"Turn: {board.turn}") print( f"position_evaluation: {position_evaluation}. Passing: not an advantage for white" ) pass elif board.turn == chess.BLACK and position_evaluation[ "value"] >= 0: # not an advantage black print(f"Turn: {board.turn}") print( f"position_evaluation: {position_evaluation}. Passing: not an advantage for black" ) pass else: yield board, board_fen, position_evaluation
BestMove=None MinEval=100000 moves = ListEveryLegalMove(ChessBoard.Board,ChessBoard.WhiteToMove,ChessBoard.Castle) for move in moves: SBoard,SCastle,SWhiteToMove=deepcopy(ChessBoard.Board),ChessBoard.Castle,ChessBoard.WhiteToMove ChessBoard.Move(move) Eval=Search(depth-1,-10000,10000,True) if Eval<MinEval: MinEval=Eval BestMove=move ChessBoard.Board,ChessBoard.Castle,ChessBoard.WhiteToMove=SBoard,SCastle,SWhiteToMove return BestMove #To use traning function u have to have stockfish installed in this directory stockfish=Stockfish("./stockfish_13/stockfish_13") stockfish.set_depth(1) model=tf.keras.models.load_model('Data/Data') accuracy=[] round=1 def Train(ChessBoard,WhiteToMove,Castle): global round global model round+=1 fen_position=ToPositionInFENNotation(ChessBoard,WhiteToMove,Castle) stockfish.set_fen_position(fen_position) info=stockfish.get_evaluation() if info["type"]=="mate": print('mate in',info['value']) else: info=info['value']
class Ai(Player): def __init__(self, color: str, game): """ une classe pour l'ordinateur Parameters ---------- color : str la couleur des pièces game: Game le jeu """ super().__init__() self.name = f"ai{color}" self.color = color self.check = False self.game = game # variables propres self.engine = Stockfish( path="stockfish/stockfish_13_win_x64_bmi2.exe", parameters=self.game.settings["parameters"], ) self.steps = self.game.settings["number_of_steps"] self.depth = self.game.settings["depth"] def en_avant_pawn(self, board) -> np.array: """ clone de la méthode de la classe Board\\ ne modifie pas les valeurs étant donné qu'on ne déplace pas de pièces dans le tableau courant\\ mais dans des tableaux provisoires """ for i in range(8): # ligne for j in range(8): # colonne piece = board[i, j] if piece is not None: if piece.pawn_forward >= 2: piece.pawn_forward = 0 piece.pawn_forward += piece.pawn_forward return board def get_move(self) -> str: move = self.game.board.last_move indexes = ["a", "b", "c", "d", "e", "f", "g", "h"] y1 = str(8 - move[0][0]) y2 = str(8 - move[1][0]) x1 = indexes[move[0][1]] x2 = indexes[move[1][1]] return x1 + y1 + x2 + y2 def get_pos(self, move: str) -> list({tuple({int})}): indexes = ["a", "b", "c", "d", "e", "f", "g", "h"] x1, y1, x2, y2 = move[:4] x1 = indexes.index(x1) x2 = indexes.index(x2) y1 = 8 - int(y1) y2 = 8 - int(y2) return [(y1, x1), (y2, x2)] def empty(self, board, color: str) -> set({tuple({int})}): """ clone de la méthode de la classe Board\\ ne modifie pas les valeurs étant donné qu'on ne déplace pas de pièces dans le tableau courant\\ mais dans des tableaux provisoires """ res = set() for i in range(8): # ligne for j in range(8): # colonne piece = board[i, j] if piece is None or piece.color != color: res.add((i, j)) return res def play(self): """ joue le coup de l'ia """ # affichage textsurface = font.render( "modélisation...", True, self.game.data["ai_thinking_indicator_color"]) self.game.screen.blit(textsurface, (720, 25)) pygame.display.flip() # si l'ia ne joue pas le premier coup de la partie if self.game.board.last_move[0][0] >= 0: moves = self.game.all_moves # on récupère les coups précédents # !print("last moves :", moves) self.engine.set_position(moves) # meilleur coup self.engine.set_depth(self.depth) move = self.engine.get_best_move() self.engine.set_depth(2) # !print("best move :", move) # nouvelle position pour le moteur self.engine.set_position([move]) # !print() getpos = self.get_pos(move) from_index = getpos[0] to_index = getpos[1] # affichage pygame.draw.rect(self.game.screen, self.game.data["background_color"], (720, 25, 100, 20)) textsurface = font.render( "réflexion...", True, self.game.data["ai_thinking_indicator_color"]) self.game.screen.blit(textsurface, (720, 25)) pygame.display.flip() # préparer les coups board = self.game.board.board for i in range(8): for j in range(8): piece = board[i, j] if piece is not None: piece.viable = piece.accessible( board, (i, j)).intersection(self.empty(board, piece.color)) piece.viable = piece.accessible_with_checked( (i, j), piece.viable, board) # jouer le coup piece = self.game.board.board[from_index] if len(move) == 5: piece.promoted = move[4] if to_index in piece.viable: piece.move_to(self.game, self.game.board.board, from_index, to_index) else: print("error : illegal move played by ai\nsearching new move...\n") self.play_alt() self.game.next_player() # joueur suivant def play_alt(self): """ permet à l'ordinateur de jouer son tour """ self.tree = Node( self.color, None, self.game.board.deep_copy(self.game.board.board), ((0, 0), (0, 0)), ) steps = self.steps start = time.time() # durée de la réflexion totale # on construit l'arbre des coups pygame.draw.rect(self.game.screen, self.game.data["background_color"], (720, 25, 100, 20)) textsurface = font.render( "modélisation...", True, self.game.data["ai_thinking_indicator_color"]) self.game.screen.blit(textsurface, (720, 25)) pygame.display.flip() self.build(self.tree, steps, self.color) # on cherche le meilleur coup pygame.draw.rect(self.game.screen, self.game.data["background_color"], (720, 25, 100, 20)) textsurface = font.render( "réflexion...", True, self.game.data["ai_thinking_indicator_color"]) self.game.screen.blit(textsurface, (720, 25)) pygame.display.flip() self.tree.get_values(self.game.board.get_score) # on modifie le nombre d'étape au besoin end = time.time() if end - start <= 0.5 and not self.check: if self.steps + 1 <= self.settings["max_number_of_steps"]: self.steps += self.settings["number_of_steps_increase_allowed"] move = () # on joue ce coup for child in self.tree.list_of_leaves: if child.value == self.tree.value: move = child.move break from_index = move[0] to_index = move[1] self.game.board.board[from_index].move_to(self.game, self.game.board.board, from_index, to_index) # on passe au joueur suivant self.game.next_player() def build(self, current_node: Node, remaining_steps: int, color: str): if remaining_steps == 0: current_node.value = self.game.board.get_score(current_node.board) return board = current_node.board.copy() list_of_pieces = [] # création de la liste des pièces de la bonne couleur for i in range(8): for j in range(8): piece = board[i, j] if piece is not None and piece.color == color: list_of_pieces.append((piece, (i, j))) # pour chaque pièce for piece, from_index in list_of_pieces: piece.viable = piece.accessible(board, from_index).intersection( self.empty(board, piece.color)) piece.viable = piece.accessible_with_checked( from_index, piece.viable, board) # pour chaque déplacement viable for to_index in piece.viable: new_board = board.copy() new_board = self.en_avant_pawn(new_board) piece.move_to(None, new_board, from_index, to_index) if piece.name == "pion": if to_index[0] == 0 or to_index[0] == 7: new_board[to_index] = Dame(piece.color) new_node = Node( color, current_node, new_board, (from_index, to_index), ) color = ("b", "n")[color == "b"] current_node.__append__(new_node) self.build(new_node, remaining_steps - 1, color)
class Player(abc.ABC): """ An abstract class for player. """ QUIT_MOVE = 'a1a1' def __init__(self, first: bool, host: str, port: int, skill_level: Optional[int], depth: Optional[int], stockfish: Optional[str]): """ Initialize a player. Args: first: Is the player going first. host: The host of the game. port: The port in the host of the game. skill_level: Still level for stockfish. depth: Depth to search for best move for stockfish. stockfish: Path to the stockfish executable to use. """ self.player_turn = first self.host = host self.port = port self.skill_level = skill_level self.depth = depth self.moves = [] self.socket = None self.stockfish = Stockfish(stockfish or "./stockfish") if self.skill_level is not None: self.stockfish.set_skill_level(self.skill_level) if self.depth is not None: self.stockfish.set_depth(self.depth) def get_turns(self) -> List[str]: """ Get previous turns to the game from the other player, gets the board to the desired initial state. Returns: The pre turns set by the other player. """ moves_num = struct.unpack('H', self.socket.recv(2))[0] moves = [] for _ in range(moves_num): moves.append(self.socket.recv(5).decode('utf-8').rstrip('\0')) return moves def forward_turns(self, moves: Optional[List[str]] = None): """ Send previous turns to the game to the other player. Args: moves: The pre turns set by this player. """ if moves is None: moves = [] self.socket.send(struct.pack('H', len(moves))) for move in moves: self.socket.send(move.ljust(5, '\0').encode('utf-8')) def set_turns(self, moves: List[str]): """ Set the pre turns of the game. Args: moves: The pre turns of the game. """ self.moves = moves self.player_turn ^= len(moves) % 2 def choose_move(self): """ Choose a move to perform. Chooses the move using stockfish and sends it to the other player. """ self.stockfish.set_position(self.moves) move = self.stockfish.get_best_move() if not move: raise RuntimeError('game over') print('Move chosen:', move) self.socket.send(move.ljust(5, '\0').encode('utf-8')) self.moves.append(move) def get_move(self): """ Get the move done by the other player. """ move = self.socket.recv(5).decode('utf-8').rstrip('\0') if move == self.QUIT_MOVE: raise RuntimeError('game over') self.moves.append(move) print('Move got:', move) def turn(self): """ Perform a single turn, either get the move done by the other player, or do a move. """ if self.player_turn: self.choose_move() else: self.get_move() self.player_turn = not self.player_turn def print_board(self): """ Print the current board's state. """ self.stockfish.set_position(self.moves) print(self.stockfish.get_board_visual()) def __del__(self): """ Destruct a player. Disconnects the socket. """ self.socket and self.socket.close()
def create_fish(): s = Stockfish() #parameters={'Threads':cpu_count()}) s.set_depth(20) #print(s.get_parameters()) return s
import requests import json from stockfish import Stockfish stockfish = Stockfish('stockfish_20090216_x64_bmi2.exe', parameters={ "Threads": 8, "Minimum Thinking Time": 300 }) stockfish.set_depth(15) stockfish.set_skill_level(25) api_key = 'REPLACE_WITH_API_KEY' headers = {'Authorization': f'Bearer {api_key}'} game_state_url = 'https://lichess.org/api/stream/event' game_id = 'placeholder' is_checkmate = False bot_challenges = False while True: state_session = requests.Session() request = state_session.get(game_state_url, headers=headers, stream=True) for line in request.iter_lines(): if len(line) == 0: print('Request response is empty.') if len(line) != 0: challenge_state_json = json.loads(line) if challenge_state_json['type'] == 'challenge': print('BOT_NAME has been challenged.') challenge_id = challenge_state_json['challenge']['id']
from interface import * from connexion import connection, reconnect from stockfish import Stockfish sf = Stockfish( r"C:\Users\dyildiz\Downloads\stockfish_12_win_x64_avx2\stockfish_20090216_x64_avx2.exe", parameters={ "Threads": 3, "Hash": 2048, "Skill Level": 20, "Minimum Thinking Time": 1, "Slow Mover": 200 }) sf.set_depth(17) chromedriver = "path/to/chromedriver" driver = initialise(chromedriver) driver = reconnect(driver) # driver = connection(driver) driver.get("https://www.chess.com/play/online") sleep(10) while (True): print("Search for a new Game") home = time.time() ng = False while (not ng): sleep(1) ng = nouveau_jeu(driver) if (time.time() - home) > 30: print("Cannot play a new game")