""" Base class for heuristic object """ class HeuristicEngine: """ Init method @param logger: logging object (display verbose and debug messages) @param options: hashtable contains options like board size or heuristic weight """ def __init__(self, logger, options): self.logger = logger self.options = options self.logger.info("Heuristic engine {}, options:{}".format( self.__class__.__name__, self.options )) def get(): raise NotImplementedError """ Score based heuristic class """ class ScoreHeuristicEngine(HeuristicEngine): """ Get score @param board: reversi board object @return score: int """ def get(self, board, player): return board.heuristique(player) """ Weight based heuristic class """ class WeightHeuristicEngine(HeuristicEngine): """ Init method @param logger: logging object (display verbose and debug messages) @param options: hashtable contains options like board size or heuristic weight """ def __init__(self, logger, options): super().__init__(logger, options) self.weights = self._get_weight_array() self.logger.debug("{}".format(self.show_weights())) """ Get score @param board: reversi board object @param player: int concerned player @return int """ def get(self, board, player): score = self.get_weight(board, player) return score """ Get score based on weight based on a weight-table built on object creation @param board: reversi board object @param player: int concerned player @return int """ def get_weight(self, board, player): score = 0 size = self.options['size'] w = [[ 0 for _ in range(size)] for _ in range(size)] for pos_x in range(self.options['size']): for pos_y in range(self.options['size']): p = board._board[pos_x][pos_y] if p == player: score += self.weights[pos_x][pos_y] w[pos_x][pos_y] = self.weights[pos_x][pos_y] elif p != player and p != board._EMPTY: score -= self.weights[pos_x][pos_y] w[pos_x][pos_y] = -self.weights[pos_x][pos_y] return score """ Get weight array calculated with weight given with options @param : none @return 2D array """ def _get_weight_array(self): size = self.options['size'] w = [[ 0 for _ in range(size)] for _ in range(size)] padding = size // 5 center = size // 2 full_range = range(self.options['size']) center_range = range(center - padding, center + padding) for pos_y in full_range: for pos_x in full_range: # Elements in the corner if pos_x in [0, size -1] and pos_y in [0,size - 1]: w[pos_x][pos_y] = self.options['weight'][3] # corners are a bad place! 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]): w[pos_x][pos_y] = self.options['weight'][0] # in diagonale of the corner too 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) 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) : w[pos_x][pos_y] = int(self.options['weight'][0] * 0.75) # center border : cool but not so... elif (pos_x in center_range and pos_y in [0, size-1]) or \ pos_y in center_range and pos_x in [0, size-1]: w[pos_x][pos_y] = int(self.options['weight'][2] // 1.25) # Elements on the border elif pos_x in [0, size -1] or pos_y in [0, size -1]: w[pos_x][pos_y] = self.options['weight'][2] # Element the center elif pos_x in center_range and pos_y in center_range: w[pos_x][pos_y] = self.options['weight'][1] return w """ Create a "displayable" array of value dor the calculated weight table @input none @return string """ def show_weights(self): display = "\n |" sep = "\n----" for x in range(self.options['size']): display += "{:^3}|".format(x) sep += '----' display += sep + "\n" for x in range(self.options['size']): display += "{:^3}|".format(str(x)) for y in range(self.options['size']): display += "{:^3}|".format(self.weights[x][y]) display += "\n" return display """ Full heuristic class """ class FullHeuristicEngine(WeightHeuristicEngine): """ Get score @param board: reversi board object @param player: int concerned player @return int """ def get(self, board, player): return self.get_weight(board, player) + board.heuristique(player)