Make pep8 happy

This commit is contained in:
Yorick Barbanneau 2023-12-22 13:08:26 +01:00
parent 807ae7daa6
commit 6e2d2c2a7b
4 changed files with 181 additions and 131 deletions

View file

@ -1,8 +1,12 @@
import random, math, time, signal import random
import math
import signal
""" """
Base player engine Base player engine
""" """
class PlayerEngine: class PlayerEngine:
""" """
@ -12,6 +16,7 @@ class PlayerEngine:
@param heuristic: HeuristicClass object to calculate tree heuristic @param heuristic: HeuristicClass object to calculate tree heuristic
@param options: hashtable containing options @param options: hashtable containing options
""" """
def __init__(self, player, logger, heuristic, options: dict = {}): def __init__(self, player, logger, heuristic, options: dict = {}):
# init logger do display informations # init logger do display informations
self.player = player self.player = player
@ -28,9 +33,10 @@ class PlayerEngine:
get move get move
@param board: Board @param board: Board
""" """
def get_move(self, board): def get_move(self, board):
self.logger.info("engine: {} - player:{}".format( self.logger.info("engine: {} - player:{}".format(
self._get_class_name(), self._get_class_name(),
self._get_player_name(self.player) self._get_player_name(self.player)
)) ))
@ -39,6 +45,7 @@ class PlayerEngine:
@param none @param none
@return: array @return: array
""" """
def get_player_moves(self, board): def get_player_moves(self, board):
moves = board.legal_moves() moves = board.legal_moves()
if self.options['randomize_moves'] is True: if self.options['randomize_moves'] is True:
@ -50,6 +57,7 @@ class PlayerEngine:
@param player: int @param player: int
@return: string @return: string
""" """
def _get_player_name(self, player): def _get_player_name(self, player):
return 'White (O)' if self.player == 2 else 'Black (X)' return 'White (O)' if self.player == 2 else 'Black (X)'
@ -63,24 +71,27 @@ class PlayerEngine:
def _show_better_move(self, move, heuristic): def _show_better_move(self, move, heuristic):
self.logger.debug(" -> Found a better move: {},{} | heuristic:{}".format( self.logger.debug(" -> Found a better move: {},{} | heuristic:{}".format(
chr(move[1] + 65),move[2], chr(move[1] + 65), move[2],
heuristic heuristic
)) ))
def _get_class_name(self): def _get_class_name(self):
return self.__class__.__name__ return self.__class__.__name__
""" """
Random game engine Random game engine
""" """
class RandomPlayerEngine(PlayerEngine):
class RandomPlayerEngine(PlayerEngine):
""" """
Get move return a random move based on Board.legal_moves Get move return a random move based on Board.legal_moves
@param player: int @param player: int
@return: array @return: array
""" """
def get_move(self, board): def get_move(self, board):
super().get_move(board) super().get_move(board)
moves = board.legal_moves() moves = board.legal_moves()
@ -90,14 +101,16 @@ class RandomPlayerEngine(PlayerEngine):
""" """
Human player engine. Human player engine.
""" """
class HumanPlayerEngine(PlayerEngine):
class HumanPlayerEngine(PlayerEngine):
""" """
Get move return a move based on user input Get move return a move based on user input
@param board: Board @param board: Board
@return: array @return: array
""" """
def get_move(self, board): def get_move(self, board):
super() super()
move = None move = None
@ -114,6 +127,7 @@ class HumanPlayerEngine(PlayerEngine):
@param input: string @param input: string
@return: array @return: array
""" """
def validate_input(self, input, board): def validate_input(self, input, board):
if input == 'print': if input == 'print':
print("\n{}".format(board.show_board())) print("\n{}".format(board.show_board()))
@ -124,7 +138,7 @@ class HumanPlayerEngine(PlayerEngine):
for m in board.legal_moves(): for m in board.legal_moves():
text += " {}{}".format(chr(65+m[1]), m[2]) text += " {}{}".format(chr(65+m[1]), m[2])
print(text) print(text)
return None return None
if len(input) != 2: if len(input) != 2:
@ -141,13 +155,14 @@ class HumanPlayerEngine(PlayerEngine):
self.logger.error("Invalid input must be [A-J][0-9] (was {})".format(input)) self.logger.error("Invalid input must be [A-J][0-9] (was {})".format(input))
return None return None
return [board._nextPlayer, x, y] return [board._nextPlayer, x, y]
""" """
MinMax player engine MinMax player engine
""" """
class MinmaxPlayerEngine(PlayerEngine): class MinmaxPlayerEngine(PlayerEngine):
@ -156,12 +171,12 @@ class MinmaxPlayerEngine(PlayerEngine):
@param board: Board @param board: Board
@return: array @return: array
""" """
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']) move, score = self._call(board, self.options['depth'])
return move return move
""" """
First part of the minmax algorithm, it get the best player move based on First part of the minmax algorithm, it get the best player move based on
max value max value
@ -169,6 +184,7 @@ class MinmaxPlayerEngine(PlayerEngine):
@param depth: search depth @param depth: search depth
@return: move and max heuristic @return: move and max heuristic
""" """
def _call(self, board, depth): def _call(self, board, depth):
value = -math.inf value = -math.inf
nodes = 1 nodes = 1
@ -194,12 +210,12 @@ class MinmaxPlayerEngine(PlayerEngine):
@param board: Board @param board: Board
@param friend_move: boolean does function maximise (player turn) or not (opponent turn) @param friend_move: boolean does function maximise (player turn) or not (opponent turn)
@param depth: search depth @param depth: search depth
@return: heuristic score, nodes ans leafs processed @return: heuristic score, nodes ans leafs processed
""" """
def checkMinMax(self, board, friend_move:bool, depth :int = 2):
def checkMinMax(self, board, friend_move: bool, depth: int = 2):
nodes = 1 nodes = 1
leafs = 0 leafs = 0
move = []
if depth == 0 or board.is_game_over() or self.interrupt_search: if depth == 0 or board.is_game_over() or self.interrupt_search:
leafs +=1 leafs +=1
return self.heuristic.get(board, self.player), nodes, leafs return self.heuristic.get(board, self.player), nodes, leafs
@ -209,11 +225,11 @@ class MinmaxPlayerEngine(PlayerEngine):
moves = self.get_player_moves(board) moves = self.get_player_moves(board)
for m in moves: for m in moves:
board.push(m) board.push(m)
v, n, l = self.checkMinMax(board, False, depth - 1) v, n, le = self.checkMinMax(board, False, depth - 1)
if v > value: if v > value:
value = v value = v
nodes += n nodes += n
leafs += l leafs += le
board.pop() board.pop()
else: else:
@ -221,14 +237,15 @@ class MinmaxPlayerEngine(PlayerEngine):
moves = self.get_player_moves(board) moves = self.get_player_moves(board)
for m in moves: for m in moves:
board.push(m) board.push(m)
v, n, l = self.checkMinMax(board, True, depth - 1) v, n, le = self.checkMinMax(board, True, depth - 1)
if v < value: if v < value:
value = v value = v
board.pop(); board.pop()
nodes += n nodes += n
leafs += l leafs += le
return value, nodes, leafs return value, nodes, leafs
class AlphabetaPlayerEngine(PlayerEngine): class AlphabetaPlayerEngine(PlayerEngine):
def get_move(self, board): def get_move(self, board):
@ -243,6 +260,7 @@ class AlphabetaPlayerEngine(PlayerEngine):
@param depth: search depth @param depth: search depth
@return: move and max heuristic @return: move and max heuristic
""" """
def _call(self, board, depth): def _call(self, board, depth):
self.logger.debug("Enter AlphaBeta function") self.logger.debug("Enter AlphaBeta function")
alpha = -math.inf alpha = -math.inf
@ -253,11 +271,11 @@ class AlphabetaPlayerEngine(PlayerEngine):
moves = self.get_player_moves(board) moves = self.get_player_moves(board)
for m in moves: for m in moves:
board.push(m) board.push(m)
value, n, l = self.checkAlphaBeta(board, False, depth - 1, alpha, beta) value, n, le = self.checkAlphaBeta(board, False, depth - 1, alpha, beta)
board.pop() board.pop()
nodes += n nodes += n
leafs += l leafs += le
if value >= alpha: if value >= alpha:
alpha = value alpha = value
move = m move = m
self._show_better_move(move, alpha) self._show_better_move(move, alpha)
@ -268,15 +286,17 @@ class AlphabetaPlayerEngine(PlayerEngine):
""" """
recursive function to apply alphabeta recursive function to apply alphabeta
@param board: Board @param board: Board
@param friend_move: boolean does function maximise (player turn) or not (opponent turn) @param friend_move: boolean does function maximise (player turn) or
not (opponent turn)
@param depth: search depth @param depth: search depth
@return: heuristic score, nodes ans leafs processed @return: heuristic score, nodes ans leafs processed
""" """
def checkAlphaBeta(self, board, friend_move : bool, depth, alpha, beta):
def checkAlphaBeta(self, board, friend_move: bool, depth, alpha, beta):
nodes = 1 nodes = 1
leafs = 0 leafs = 0
if depth == 0 or board.is_game_over() or self.interrupt_search: if depth == 0 or board.is_game_over() or self.interrupt_search:
leafs +=1 leafs += 1
return self.heuristic.get(board, self.player), nodes, leafs return self.heuristic.get(board, self.player), nodes, leafs
if friend_move: if friend_move:
@ -284,11 +304,11 @@ class AlphabetaPlayerEngine(PlayerEngine):
moves = self.get_player_moves(board) moves = self.get_player_moves(board)
for m in moves: for m in moves:
board.push(m) board.push(m)
v, n, l = self.checkAlphaBeta(board, False, depth - 1, alpha, beta) v, n, le = self.checkAlphaBeta(board, False, depth - 1, alpha, beta)
board.pop() board.pop()
alpha = max(alpha,v) alpha = max(alpha, v)
nodes += n nodes += n
leafs += l leafs += le
if alpha >= beta: if alpha >= beta:
return beta, nodes, leafs return beta, nodes, leafs
return alpha, nodes, leafs return alpha, nodes, leafs
@ -297,11 +317,11 @@ class AlphabetaPlayerEngine(PlayerEngine):
moves = self.get_player_moves(board) moves = self.get_player_moves(board)
for m in moves: for m in moves:
board.push(m) board.push(m)
v, n, l = self.checkAlphaBeta(board, True, depth - 1, alpha, beta) v, n, le = self.checkAlphaBeta(board, True, depth - 1, alpha, beta)
board.pop(); board.pop()
beta = min(beta, v) beta = min(beta, v)
nodes += n nodes += n
leafs += l leafs += le
if alpha >= beta: if alpha >= beta:
return alpha, nodes, leafs return alpha, nodes, leafs
return beta, nodes, leafs return beta, nodes, leafs
@ -313,6 +333,7 @@ class MinmaxDeepeningPlayerEngine(MinmaxPlayerEngine):
@param board: Board @param board: Board
@return: array @return: array
""" """
def get_move(self, board): def get_move(self, board):
super().get_move(board) super().get_move(board)
self.interrupt_search = False self.interrupt_search = False
@ -325,7 +346,7 @@ class MinmaxDeepeningPlayerEngine(MinmaxPlayerEngine):
# 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
# numbers of avaible place # numbers of avaible place
max_depth = (board.get_board_size()**2) - ( max_depth = (board.get_board_size()**2) - (
board.get_nb_pieces()[0] + board.get_nb_pieces()[1]) board.get_nb_pieces()[0] + board.get_nb_pieces()[1])
depth = self.options['depth'] if self.options['depth'] <= max_depth else max_depth depth = self.options['depth'] if self.options['depth'] <= max_depth else max_depth
@ -357,7 +378,6 @@ class MinmaxDeepeningPlayerEngine(MinmaxPlayerEngine):
self.interrupt_search = True self.interrupt_search = True
class AlphaBetaDeepeningPlayerEngine(AlphabetaPlayerEngine): class AlphaBetaDeepeningPlayerEngine(AlphabetaPlayerEngine):
""" """
@ -365,6 +385,7 @@ class AlphaBetaDeepeningPlayerEngine(AlphabetaPlayerEngine):
@param board: Board @param board: Board
@return: array @return: array
""" """
def get_move(self, board): def get_move(self, board):
self.interrupt_search = False self.interrupt_search = False
@ -376,7 +397,7 @@ class AlphaBetaDeepeningPlayerEngine(AlphabetaPlayerEngine):
# 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
# numbers of avaible place # numbers of avaible place
max_depth = (board.get_board_size()**2) - ( max_depth = (board.get_board_size()**2) - (
board.get_nb_pieces()[0] + board.get_nb_pieces()[1]) board.get_nb_pieces()[0] + board.get_nb_pieces()[1])
depth = self.options['depth'] if self.options['depth'] <= max_depth else max_depth depth = self.options['depth'] if self.options['depth'] <= max_depth else max_depth
@ -402,6 +423,7 @@ class AlphaBetaDeepeningPlayerEngine(AlphabetaPlayerEngine):
""" """
define an handler for the alarm signal define an handler for the alarm signal
""" """
def alarm_handler(self, signal, frame): def alarm_handler(self, signal, frame):
self.logger.debug("Raise SIGALMR Signal") self.logger.debug("Raise SIGALMR Signal")
self.interrupt_search = True self.interrupt_search = True

View file

@ -1,7 +1,8 @@
""" """
Base class for heuristic object Base class for heuristic object
""" """
class HeuristicEngine: class HeuristicEngine:
""" """
@ -9,6 +10,7 @@ class HeuristicEngine:
@param logger: logging object (display verbose and debug messages) @param logger: logging object (display verbose and debug messages)
@param options: hashtable contains options like board size or heuristic weight @param options: hashtable contains options like board size or heuristic weight
""" """
def __init__(self, logger, options): def __init__(self, logger, options):
self.logger = logger self.logger = logger
self.options = options self.options = options
@ -20,9 +22,12 @@ class HeuristicEngine:
def get(): def get():
raise NotImplementedError raise NotImplementedError
""" """
Score based heuristic class Score based heuristic class
""" """
class ScoreHeuristicEngine(HeuristicEngine): class ScoreHeuristicEngine(HeuristicEngine):
""" """
@ -30,12 +35,15 @@ class ScoreHeuristicEngine(HeuristicEngine):
@param board: reversi board object @param board: reversi board object
@return score: int @return score: int
""" """
def get(self, board, player): def get(self, board, player):
return board.heuristique(player) return board.heuristique(player)
""" """
Weight based heuristic class Weight based heuristic class
""" """
class WeightHeuristicEngine(HeuristicEngine): class WeightHeuristicEngine(HeuristicEngine):
""" """
@ -43,22 +51,22 @@ class WeightHeuristicEngine(HeuristicEngine):
@param logger: logging object (display verbose and debug messages) @param logger: logging object (display verbose and debug messages)
@param options: hashtable contains options like board size or heuristic weight @param options: hashtable contains options like board size or heuristic weight
""" """
def __init__(self, logger, options): def __init__(self, logger, options):
super().__init__(logger, options) super().__init__(logger, options)
self.weights = self._get_weight_array() self.weights = self._get_weight_array()
self.logger.debug("{}".format(self.show_weights())) self.logger.debug("{}".format(self.show_weights()))
""" """
Get score Get score
@param board: reversi board object @param board: reversi board object
@param player: int concerned player @param player: int concerned player
@return int @return int
""" """
def get(self, board, player): def get(self, board, player):
score = self.get_weight(board, player) score = self.get_weight(board, player)
return score return score
""" """
Get score based on weight based on a weight-table built on object creation Get score based on weight based on a weight-table built on object creation
@ -66,13 +74,14 @@ class WeightHeuristicEngine(HeuristicEngine):
@param player: int concerned player @param player: int concerned player
@return int @return int
""" """
def get_weight(self, board, player): def get_weight(self, board, player):
score = 0 score = 0
size = self.options['size'] size = self.options['size']
w = [[ 0 for _ in range(size)] for _ in range(size)] w = [[0 for _ in range(size)] for _ in range(size)]
for pos_x in range(self.options['size']): for pos_x in range(self.options['size']):
for pos_y in range(self.options['size']): for pos_y in range(self.options['size']):
p = board._board[pos_x][pos_y] p = board._board[pos_x][pos_y]
if p == player: if p == player:
score += self.weights[pos_x][pos_y] score += self.weights[pos_x][pos_y]
w[pos_x][pos_y] = self.weights[pos_x][pos_y] w[pos_x][pos_y] = self.weights[pos_x][pos_y]
@ -81,15 +90,16 @@ class WeightHeuristicEngine(HeuristicEngine):
score -= self.weights[pos_x][pos_y] score -= self.weights[pos_x][pos_y]
w[pos_x][pos_y] = -self.weights[pos_x][pos_y] w[pos_x][pos_y] = -self.weights[pos_x][pos_y]
return score return score
""" """
Get weight array calculated with weight given with options Get weight array calculated with weight given with options
@param : none @param : none
@return 2D array @return 2D array
""" """
def _get_weight_array(self): def _get_weight_array(self):
size = self.options['size'] size = self.options['size']
w = [[ 0 for _ in range(size)] for _ in range(size)] w = [[0 for _ in range(size)] for _ in range(size)]
padding = size // 5 padding = size // 5
center = size // 2 center = size // 2
full_range = range(self.options['size']) full_range = range(self.options['size'])
@ -99,20 +109,20 @@ class WeightHeuristicEngine(HeuristicEngine):
for pos_x in full_range: for pos_x in full_range:
# Elements in the corner # Elements in the corner
if pos_x in [0, size -1] and pos_y in [0,size - 1]: if pos_x in [0, size -1] and pos_y in [0, size - 1]:
w[pos_x][pos_y] = self.options['weight'][3] w[pos_x][pos_y] = self.options['weight'][3]
# corners are a bad place! # corners are a bad place!
elif (pos_x in [0, size - 1] and pos_y in [size - 2, 1]) or \ elif (pos_x in [0, size - 1] and pos_y in [size - 2, 1]) or \
(pos_x in [1, size -2] and pos_y in [0, size - 1]): (pos_x in [1, size - 2] and pos_y in [0, size - 1]):
w[pos_x][pos_y] = self.options['weight'][0] w[pos_x][pos_y] = self.options['weight'][0]
# in diagonale of the corner too # in diagonale of the corner too
elif pos_x in [size - 2, 1] and pos_y in [size - 2, 1]: elif pos_x in [size - 2, 1] and pos_y in [size - 2, 1]:
w[pos_x][pos_y] = int(self.options['weight'][0] * 1.5) w[pos_x][pos_y] = int(self.options['weight'][0] * 1.5)
elif pos_x in [1,size - 2] and pos_y in range(2, size - 2) or \ elif pos_x in [1, size - 2] and pos_y in range(2, size - 2) or \
pos_y in [1,size - 2] and pos_x in range(2, size - 2) : pos_y in [1, size - 2] and pos_x in range(2, size - 2):
w[pos_x][pos_y] = int(self.options['weight'][0] * 0.75) w[pos_x][pos_y] = int(self.options['weight'][0] * 0.75)
# center border : cool but not so... # center border : cool but not so...
@ -121,13 +131,13 @@ class WeightHeuristicEngine(HeuristicEngine):
w[pos_x][pos_y] = int(self.options['weight'][2] // 1.25) w[pos_x][pos_y] = int(self.options['weight'][2] // 1.25)
# Elements on the border # Elements on the border
elif pos_x in [0, size -1] or pos_y in [0, size -1]: elif pos_x in [0, size - 1] or pos_y in [0, size - 1]:
w[pos_x][pos_y] = self.options['weight'][2] w[pos_x][pos_y] = self.options['weight'][2]
# Element the center # Element the center
elif pos_x in center_range and pos_y in center_range: elif pos_x in center_range and pos_y in center_range:
w[pos_x][pos_y] = self.options['weight'][1] w[pos_x][pos_y] = self.options['weight'][1]
return w return w
""" """
@ -135,12 +145,13 @@ class WeightHeuristicEngine(HeuristicEngine):
@input none @input none
@return string @return string
""" """
def show_weights(self): def show_weights(self):
display = "\n |" display = "\n |"
sep = "\n----" sep = "\n----"
for x in range(self.options['size']): for x in range(self.options['size']):
display += "{:^3}|".format(x) display += "{:^3}|".format(x)
sep += '----' sep += '----'
display += sep + "\n" display += sep + "\n"
for x in range(self.options['size']): for x in range(self.options['size']):
display += "{:^3}|".format(str(x)) display += "{:^3}|".format(str(x))
@ -149,16 +160,20 @@ class WeightHeuristicEngine(HeuristicEngine):
display += "\n" display += "\n"
return display return display
""" """
Full heuristic class Full heuristic class
""" """
class FullHeuristicEngine(WeightHeuristicEngine): class FullHeuristicEngine(WeightHeuristicEngine):
""" """
Get score Get score
@param board: reversi board object @param board: reversi board object
@param player: int concerned player @param player: int concerned player
@return int @return int
""" """
def get(self, board, player): def get(self, board, player):
return self.get_weight(board, player) + board.heuristique(player) return self.get_weight(board, player) + board.heuristique(player)

View file

@ -227,7 +227,7 @@ class Board:
display += " {} |".format(str(x)) display += " {} |".format(str(x))
for y in range(self.get_board_size()): for y in range(self.get_board_size()):
display += " {} |".format(self._piece2str(self._board[x][y])) display += " {} |".format(self._piece2str(self._board[x][y]))
display += "\n"#+sep+"\n" display += "\n"
return display + sep + '\n' return display + sep + '\n'
def __str__(self): def __str__(self):

View file

@ -12,96 +12,109 @@ from classes.CustomFormater import CustomFormatter
""" """
Function to parse command line arguments Function to parse command line arguments
""" """
def parse_aguments(): def parse_aguments():
engines_choices=['random', 'human', 'minmax', 'alphabeta', 'id_minmax', 'id_alphabeta'] engines_choices = ['random', 'human', 'minmax', 'alphabeta', 'id_minmax', 'id_alphabeta']
heuristic_choices=['score', 'weight', 'full'] heuristic_choices = ['score', 'weight', 'full']
parser = arg.ArgumentParser('Playing Reversi with (virtual) friend') parser = arg.ArgumentParser('Playing Reversi with (virtual) friend')
parser.add_argument('-we', '--white-engine', parser.add_argument('-we',
choices=engines_choices, '--white-engine',
help='white player engine (random)', choices=engines_choices,
default='random' help='white player engine (random)',
) default='random'
)
parser.add_argument('-be', '--black-engine', parser.add_argument('-be',
choices=engines_choices, '--black-engine',
help='black player engine (random)', choices=engines_choices,
default='random' help='black player engine (random)',
) default='random'
)
parser.add_argument('-bd', '--black-depth-exploration', parser.add_argument('-bd',
help='Black player exploration depth (minmax or alphabeta engine)', '--black-depth-exploration',
type=int, help='Black player exploration depth (minmax or alphabeta engine)',
default=3, type=int,
) default=3,
)
parser.add_argument('-wd', '--white-depth-exploration', parser.add_argument('-wd',
help='White player exploration depth (minmax or alphabeta engine)', '--white-depth-exploration',
type=int, help='White player exploration depth (minmax or alphabeta engine)',
default=3, type=int,
) default=3,
)
parser.add_argument('-bh', '--black-heuristic-engine', parser.add_argument('-bh',
help='Black player heutistic engine', '--black-heuristic-engine',
choices= heuristic_choices, help='Black player heutistic engine',
default='score', choices= heuristic_choices,
) default='score',
)
parser.add_argument('-wh', '--white-heuristic-engine', parser.add_argument('-wh',
help='White player heutistic engine', '--white-heuristic-engine',
choices=heuristic_choices, help='White player heutistic engine',
default='score', choices=heuristic_choices,
) default='score',
)
parser.add_argument('-br', '--black-randomize-moves', parser.add_argument('-br',
help='Apply a random function on moves list before explore the game tree - black player', '--black-randomize-moves',
type=bool, help='Apply a random function on moves list before explore the game tree - black player',
default=True, type=bool,
) default=True,
)
parser.add_argument('-wr', '--white-randomize-moves', parser.add_argument('-wr',
help='Apply a random function on moves list before explore the game tree - white player', '--white-randomize-moves',
type=bool, help='Apply a random function on moves list before explore the game tree - white player',
default=True, type=bool,
) default=True,
)
parser.add_argument('-bt', '--black-player-deepening-time', parser.add_argument('-bt',
help='Time interval in seconds for Iterative Deepening - black player', '--black-player-deepening-time',
type=int, help='Time interval in seconds for Iterative Deepening - black player',
default=10, type=int,
) default=10,
)
parser.add_argument('-wt', '--white-player-deepening-time', parser.add_argument('-wt',
help='Time interval in seconds for Iterative Deepening - black player', '--white-player-deepening-time',
type=int, help='Time interval in seconds for Iterative Deepening - black player',
default=10, type=int,
) default=10,
)
parser.add_argument('--weight', parser.add_argument('--weight',
help='Weight table for weight based heuristic engines', help='Weight table for weight based heuristic engines',
type=int, type=int,
nargs=4, nargs=4,
default=[-5, 2, 10,25] default=[-5, 2, 10,25]
) )
parser.add_argument('-r', '--recursions', parser.add_argument('-r',
help='Number parties to play', '--recursions',
type=int, help='Number parties to play',
default=1 type=int,
) default=1
)
parser.add_argument('--show-weights-table', parser.add_argument('--show-weights-table',
help='Display weight table used in \'weight\' and \'full\' heuristic calculation and exit', help='Display weight table used in \'weight\' and \'full\' heuristic calculation and exit',
action='store_true', action='store_true',
) )
debug_group = parser.add_mutually_exclusive_group() debug_group = parser.add_mutually_exclusive_group()
debug_group.add_argument('-V', '--verbose', debug_group.add_argument('-V', '--verbose',
help='Verbose output', help='Verbose output',
action='store_true') action='store_true')
debug_group.add_argument('-d', '--debug', debug_group.add_argument('-d', '--debug',
help='Activate debug mode', help='Activate debug mode',
action='store_true') action='store_true')
return parser.parse_args() return parser.parse_args()
@ -129,11 +142,11 @@ if __name__ == '__main__':
tty_handler = log.StreamHandler() tty_handler = log.StreamHandler()
tty_handler.setFormatter(CustomFormatter()) tty_handler.setFormatter(CustomFormatter())
logger.addHandler(tty_handler) logger.addHandler(tty_handler)
# IT shoud be better implemented but no time to make it clean # IT shoud be better implemented but no time to make it clean
if args.show_weights_table: if args.show_weights_table:
print("{}".format( print("{}".format(
heuristic_engine['weight'](logger,{ heuristic_engine['weight'](logger, {
'weight': args.weight, 'weight': args.weight,
'size': 10 'size': 10
}).show_weights() }).show_weights()
@ -144,7 +157,7 @@ if __name__ == '__main__':
if args.verbose is True: if args.verbose is True:
logger.setLevel(log.INFO) logger.setLevel(log.INFO)
logger.info('VERBOSE mode activated') logger.info('VERBOSE mode activated')
if args.debug is True: if args.debug is True:
logger.setLevel(log.DEBUG) logger.setLevel(log.DEBUG)
logger.debug('DEBUG mode activated') logger.debug('DEBUG mode activated')
@ -153,14 +166,14 @@ if __name__ == '__main__':
args.black_engine, args.black_engine,
args.white_engine args.white_engine
)) ))
logger.debug("Weight value {}".format( args.weight )) logger.debug("Weight value {}".format(args.weight))
wplayer = player_engines[args.white_engine]( wplayer = player_engines[args.white_engine](
game._WHITE, game._WHITE,
logger, logger,
heuristic_engine[args.white_heuristic_engine]( heuristic_engine[args.white_heuristic_engine](
logger, { logger, {
'weight': args.weight, 'weight': args.weight,
'size': game.get_board_size() 'size': game.get_board_size()
} }
), ),
{ {
@ -173,7 +186,7 @@ if __name__ == '__main__':
game._BLACK, game._BLACK,
logger, logger,
heuristic_engine[args.black_heuristic_engine]( heuristic_engine[args.black_heuristic_engine](
logger, { logger, {
'weight': args.weight, 'weight': args.weight,
'size': game.get_board_size() 'size': game.get_board_size()
} }
@ -205,7 +218,7 @@ if __name__ == '__main__':
move[2] move[2]
)) ))
game.push(move) game.push(move)
parties.append([recursions, game._nbBLACK, black_time, game._nbWHITE, white_time]) parties.append([recursions, game._nbBLACK, black_time, game._nbWHITE, white_time])
score = game._nbBLACK - game._nbWHITE score = game._nbBLACK - game._nbWHITE
if score == 0: if score == 0: