Factorize code to remove dulicate parts
This commit is contained in:
parent
6979749d5d
commit
dd70d575d4
1 changed files with 29 additions and 46 deletions
|
@ -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):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue