diff --git a/src/classes/Engines.py b/src/classes/Engines.py index 305a199..e19bd1a 100644 --- a/src/classes/Engines.py +++ b/src/classes/Engines.py @@ -1,10 +1,10 @@ import random, math -from .Heuristic import ReversiHeuristic class PlayerEngine: - def __init__(self, logger, options: dict = {}): + def __init__(self, logger, heuristic, options: dict = {}): # init logger do display informations self.logger = logger + self.heuristic = heuristic self.options = options self.logger.info("Init engine {}, options:{}".format( self.__class__.__name__, @@ -91,11 +91,7 @@ class MinmaxPlayerEngine(PlayerEngine): move = '' if depth == 0: leafs +=1 - if self.options['heuristic'] == 'weight': - score = ReversiHeuristic(board).get() - else: - score = board.heuristique() - return score, nodes, leafs + return self.heuristic.get(board), nodes, leafs if friend_move: value = -math.inf @@ -157,11 +153,7 @@ class AlphabetaPlayerEngine(PlayerEngine): leafs = 0 if depth == 0 : leafs +=1 - if self.options['heuristic'] == 'weight': - score = ReversiHeuristic(self.logger).get(board) - else: - score = board.heuristique() - return score, nodes, leafs + return self.heuristic.get(board), nodes, leafs if friend_move: value = -math.inf diff --git a/src/classes/Heuristic.py b/src/classes/Heuristic.py index 13ae8ee..bb20a70 100644 --- a/src/classes/Heuristic.py +++ b/src/classes/Heuristic.py @@ -1,12 +1,30 @@ -class ReversiHeuristic(): - def __init__(self, logger, weight = [1, 2, 10, 20]): +class HeuristicEngine: + def __init__(self, logger, options): self.logger = logger - self.weight = weight + self.options = options + self.logger.info("Heuristic engine {}, options:{}".format( + self.__class__.__name__, + self.options + )) + + def get(): + raise NotImplementedError + +class ScoreHeuristicEngine(HeuristicEngine): + def get(board): + return board.heuristique() + + +class WeightHeuristicEngine(HeuristicEngine): def get(self, board): - size = board.get_board_size() + score = get_weight(board) + return score + + def get_weight(self, board): score = 0 - weights = self._get_weight(size) + size = board.get_board_size() + weights = self._get_weight_array(size) for pos_x in range(size): for pos_y in range(size): if board._board[pos_x][pos_y] == board._nextPlayer: @@ -14,25 +32,28 @@ class ReversiHeuristic(): else: score -= weights[pos_x][pos_y] return score - - def _get_weight(self, size): - w = [[ 0 for _ in range(size)] for _ in range(size)] + def _get_weight_array(self, size): + w = [[ 0 for _ in range(size)] for _ in range(size)] + padding = size // 5 + center = size // 2 for pos_y in range(size): for pos_x in range(size): # Elements in the corner if pos_x in [0, size -1] and pos_y in [0,size - 1]: - w[pos_x][pos_y] = self.weight[3] + w[pos_x][pos_y] = self.weight[2] # Elements on the border elif pos_x in [0, size -1] or pos_y in [0, size -1]: - w[pos_x][pos_y] = self.weight[2] + w[pos_x][pos_y] = self.weight[1] # Element the center - elif pos_x in range( int(size // 2 - 2), size // 2 + 2) and pos_y in range( size // 2 - 2, size // 2 + 2): - w[pos_x][pos_y] = self.weight[1] - - else: + elif pos_x in range( center - padding, center + padding) and pos_y in range(center - padding, center + padding): w[pos_x][pos_y] = self.weight[0] return w + +class FullHeuristicEngine(WeightHeuristicEngine): + + def get(self, board): + return self.get_weight(board) + board.heuristique() diff --git a/src/game.py b/src/game.py index 7db3514..9e6f4dc 100755 --- a/src/game.py +++ b/src/game.py @@ -2,6 +2,7 @@ from classes.Reversi import Board from classes.Engines import RandomPlayerEngine, HumanPlayerEngine, MinmaxPlayerEngine, AlphabetaPlayerEngine +from classes.Heuristic import ScoreHeuristicEngine, WeightHeuristicEngine, FullHeuristicEngine import logging as log import argparse as arg from classes.CustomFormater import CustomFormatter @@ -12,7 +13,7 @@ Function to parse command line arguments """ def parse_aguments(): engines_choices=['random', 'human', 'minmax', 'alphabeta'] - heuristic_choices=['weight',] + heuristic_choices=['score', 'weight', 'full'] parser = arg.ArgumentParser('Playing Reversi with (virtual) friend') parser.add_argument('-we', '--white-engine', @@ -41,13 +42,13 @@ def parse_aguments(): parser.add_argument('-bh', '--black-heuristic-engine', help='Black player heutistic engine', - choices=['board', 'weight'], + choices= heuristic_choices, default='board', ) parser.add_argument('-wh', '--white-heuristic-engine', help='White player heutistic engine', - choices=['board', 'weight'], + choices=heuristic_choices, default='board', ) @@ -65,12 +66,17 @@ def parse_aguments(): Main Function """ if __name__ == '__main__': - engines = { + player_engines = { "random": RandomPlayerEngine, "human": HumanPlayerEngine, "minmax": MinmaxPlayerEngine, "alphabeta": AlphabetaPlayerEngine, } + heuristic_engine = { + "score": ScoreHeuristicEngine, + "weight": ScoreHeuristicEngine, + "full": ScoreHeuristicEngine, + } print("Stating PyReverso...") args = parse_aguments() logger = log.getLogger() @@ -93,14 +99,20 @@ if __name__ == '__main__': args.black_engine, args.white_engine )) - wplayer = engines[args.white_engine](logger, { - 'depth': args.white_depth_exploration, - 'heuristic': args.white_heuristic_engine - }) - bplayer = engines[args.black_engine](logger, { - 'depth': args.black_depth_exploration, - 'heuristic': args.black_heuristic_engine - }) + wplayer = player_engines[args.white_engine]( + logger, + heuristic_engine[args.white_heuristic_engine], + { + 'depth': args.white_depth_exploration, + } + ) + bplayer = player_engines[args.black_engine]( + logger, + heuristic_engine[args.black_heuristic_engine], + { + 'depth': args.black_depth_exploration, + } + ) while ( not game.is_game_over()): if game._nextPlayer == 1: move = bplayer.get_move(game)