From dd70d575d42d9ac4f80e9b5ddb787102feb55e1f Mon Sep 17 00:00:00 2001 From: Yorick Barbanneau Date: Wed, 20 Dec 2023 21:37:59 +0100 Subject: [PATCH] Factorize code to remove dulicate parts --- src/classes/Engines.py | 75 ++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 46 deletions(-) diff --git a/src/classes/Engines.py b/src/classes/Engines.py index 534699f..d31c5fc 100644 --- a/src/classes/Engines.py +++ b/src/classes/Engines.py @@ -71,13 +71,17 @@ class MinmaxPlayerEngine(PlayerEngine): def get_move(self, board): super().get_move(board) + move, score = self._call(board, self.options['depth']) + return move + + def _call(self, board, depth): value = -math.inf nodes = 1 leafs = 0 move = [] for m in self.get_player_moves(board): board.push(m) - v, n, l = self.checkMinMax(board, False, self.options['depth'] - 1) + v, n, l = self.checkMinMax(board, False, depth - 1) if v > value: value = v move = m @@ -94,7 +98,7 @@ class MinmaxPlayerEngine(PlayerEngine): leafs, value )) - return move + return move, value def checkMinMax(self, board, friend_move:bool, depth :int = 2): nodes = 1 @@ -131,6 +135,10 @@ class AlphabetaPlayerEngine(PlayerEngine): def get_move(self, board): super().get_move(board) + move, heuristic = self._call(board, self.options['depth']) + return move + + def _call(self, board, depth): self.logger.debug("Enter AlphaBeta function") alpha = -math.inf beta = math.inf @@ -139,7 +147,7 @@ class AlphabetaPlayerEngine(PlayerEngine): move = [] for m in self.get_player_moves(board): board.push(m) - value, n, l = self.checkAlphaBeta(board, False, self.options['depth'] - 1, alpha, beta) + value, n, l = self.checkAlphaBeta(board, False, depth - 1, alpha, beta) board.pop() nodes += n leafs += l @@ -156,7 +164,7 @@ class AlphabetaPlayerEngine(PlayerEngine): leafs, alpha )) - return move + return move, alpha def checkAlphaBeta(self, board, friend_move : bool, depth, alpha, beta): @@ -209,9 +217,7 @@ class MinmaxDeepeningPlayerEngine(MinmaxPlayerEngine): signal.signal(signal.SIGALRM, self.alarm_handler) signal.alarm(self.options['time_limit']) depth = 1 - value = -math.inf - nodes = 1 - leafs = 0 + heuristic = -math.inf move = None # We can go deeper than blank place in our board, then we must get @@ -222,21 +228,14 @@ class MinmaxDeepeningPlayerEngine(MinmaxPlayerEngine): # Iterate depth while our alarm does not trigger and there is enougth # avaiable move to play while not self.interrupt_search and depth <= max_depth: - for m in board.legal_moves(): - board.push(m) - v, n, l = self.checkMinMax(board, False, depth - 1) - if v > value: - value = v - move = m - self.logger.debug("found a better move: {} (heuristic:{})".format( - move, - value - )) - nodes += n - leafs += l - board.pop() + current_move, current_heuristic = self._call(board, depth) + # return the current move onli if heuristic is better than previous + # iteration + if current_heuristic > heuristic: + move = current_move + depth = depth + 1 - self.logger.debug("id_minmax - depth reached: {} | max depth : {}".format( + self.logger.debug("id_minmax - depth reached: {} | max depth : {}".format( depth - 1, max_depth )) @@ -250,18 +249,15 @@ class MinmaxDeepeningPlayerEngine(MinmaxPlayerEngine): class AlphaBetaDeepeningPlayerEngine(AlphabetaPlayerEngine): + def get_move(self, board): - #super().get_move(board) self.interrupt_search = False # Get an alarm signal to stop iterations signal.signal(signal.SIGALRM, self.alarm_handler) signal.alarm(self.options['time_limit']) depth = 1 - alpha = -math.inf - beta = math.inf - nodes = 1 - leafs = 0 + heuristic = -math.inf move = None # We can go deeper than blank place in our board, then we must get @@ -272,30 +268,17 @@ class AlphaBetaDeepeningPlayerEngine(AlphabetaPlayerEngine): # Iterate depth while our alarm does not trigger and there is enougth # avaiable move to play while not self.interrupt_search and depth <= max_depth: - for m in board.legal_moves(): - board.push(m) - v, n, l = self.checkAlphaBeta(board, False, depth - 1, alpha, beta) - board.pop() - nodes += n - leafs += l - if v >= alpha: - alpha = v - move = m - self.logger.debug("found a better move: {} (heuristic:{})".format( - move, - alpha - )) + current_move, current_heuristic = self._call(board, depth) + # return the current move only if heuristic is better than previous + # iteration can be possible id iteration is stopped by timer + if current_heuristic > heuristic: + move = current_move depth = depth + 1 - self.logger.info("id_alphabeta - depth reached: {} | max depth : {}".format( + + self.logger.debug("id_minmax - depth reached: {} | max depth : {}".format( depth - 1, max_depth )) - self.logger.info("Tree statistics:\n\tnodes:{}\n\tleafs:{}\n\theuristic:{}".format( - nodes, - leafs, - alpha - )) - return move def alarm_handler(self, signal, frame):