Factorize code to remove dulicate parts

This commit is contained in:
Yorick Barbanneau 2023-12-20 21:37:59 +01:00
parent 6979749d5d
commit dd70d575d4

View file

@ -71,13 +71,17 @@ class MinmaxPlayerEngine(PlayerEngine):
def get_move(self, board): def get_move(self, board):
super().get_move(board) super().get_move(board)
move, score = self._call(board, self.options['depth'])
return move
def _call(self, board, depth):
value = -math.inf value = -math.inf
nodes = 1 nodes = 1
leafs = 0 leafs = 0
move = [] move = []
for m in self.get_player_moves(board): for m in self.get_player_moves(board):
board.push(m) 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: if v > value:
value = v value = v
move = m move = m
@ -94,7 +98,7 @@ class MinmaxPlayerEngine(PlayerEngine):
leafs, leafs,
value value
)) ))
return move return move, value
def checkMinMax(self, board, friend_move:bool, depth :int = 2): def checkMinMax(self, board, friend_move:bool, depth :int = 2):
nodes = 1 nodes = 1
@ -131,6 +135,10 @@ class AlphabetaPlayerEngine(PlayerEngine):
def get_move(self, board): def get_move(self, board):
super().get_move(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") self.logger.debug("Enter AlphaBeta function")
alpha = -math.inf alpha = -math.inf
beta = math.inf beta = math.inf
@ -139,7 +147,7 @@ class AlphabetaPlayerEngine(PlayerEngine):
move = [] move = []
for m in self.get_player_moves(board): for m in self.get_player_moves(board):
board.push(m) 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() board.pop()
nodes += n nodes += n
leafs += l leafs += l
@ -156,7 +164,7 @@ class AlphabetaPlayerEngine(PlayerEngine):
leafs, leafs,
alpha alpha
)) ))
return move return move, alpha
def checkAlphaBeta(self, board, friend_move : bool, depth, alpha, beta): 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.signal(signal.SIGALRM, self.alarm_handler)
signal.alarm(self.options['time_limit']) signal.alarm(self.options['time_limit'])
depth = 1 depth = 1
value = -math.inf heuristic = -math.inf
nodes = 1
leafs = 0
move = None move = None
# We can go deeper than blank place in our board, then we must get # We can go deeper than blank place in our board, then we must get
@ -222,19 +228,12 @@ class MinmaxDeepeningPlayerEngine(MinmaxPlayerEngine):
# Iterate depth while our alarm does not trigger and there is enougth # Iterate depth while our alarm does not trigger and there is enougth
# avaiable move to play # avaiable move to play
while not self.interrupt_search and depth <= max_depth: while not self.interrupt_search and depth <= max_depth:
for m in board.legal_moves(): current_move, current_heuristic = self._call(board, depth)
board.push(m) # return the current move onli if heuristic is better than previous
v, n, l = self.checkMinMax(board, False, depth - 1) # iteration
if v > value: if current_heuristic > heuristic:
value = v move = current_move
move = m
self.logger.debug("found a better move: {} (heuristic:{})".format(
move,
value
))
nodes += n
leafs += l
board.pop()
depth = depth + 1 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, depth - 1,
@ -250,18 +249,15 @@ class MinmaxDeepeningPlayerEngine(MinmaxPlayerEngine):
class AlphaBetaDeepeningPlayerEngine(AlphabetaPlayerEngine): class AlphaBetaDeepeningPlayerEngine(AlphabetaPlayerEngine):
def get_move(self, board): def get_move(self, board):
#super().get_move(board)
self.interrupt_search = False self.interrupt_search = False
# Get an alarm signal to stop iterations # Get an alarm signal to stop iterations
signal.signal(signal.SIGALRM, self.alarm_handler) signal.signal(signal.SIGALRM, self.alarm_handler)
signal.alarm(self.options['time_limit']) signal.alarm(self.options['time_limit'])
depth = 1 depth = 1
alpha = -math.inf heuristic = -math.inf
beta = math.inf
nodes = 1
leafs = 0
move = None move = None
# We can go deeper than blank place in our board, then we must get # 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 # Iterate depth while our alarm does not trigger and there is enougth
# avaiable move to play # avaiable move to play
while not self.interrupt_search and depth <= max_depth: while not self.interrupt_search and depth <= max_depth:
for m in board.legal_moves(): current_move, current_heuristic = self._call(board, depth)
board.push(m) # return the current move only if heuristic is better than previous
v, n, l = self.checkAlphaBeta(board, False, depth - 1, alpha, beta) # iteration can be possible id iteration is stopped by timer
board.pop() if current_heuristic > heuristic:
nodes += n move = current_move
leafs += l
if v >= alpha:
alpha = v
move = m
self.logger.debug("found a better move: {} (heuristic:{})".format(
move,
alpha
))
depth = depth + 1 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, depth - 1,
max_depth max_depth
)) ))
self.logger.info("Tree statistics:\n\tnodes:{}\n\tleafs:{}\n\theuristic:{}".format(
nodes,
leafs,
alpha
))
return move return move
def alarm_handler(self, signal, frame): def alarm_handler(self, signal, frame):