From 1c039106d9746b33cc670c9f7309dfdaf3de6637 Mon Sep 17 00:00:00 2001 From: Yorick Barbanneau Date: Fri, 15 Dec 2023 00:24:28 +0100 Subject: [PATCH] Add weight calculation heuristic --- src/classes/Engines.py | 14 ++++++++++++-- src/classes/Heuristic.py | 38 ++++++++++++++++++++++++++++++++++++++ src/game.py | 10 +++++++++- 3 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 src/classes/Heuristic.py diff --git a/src/classes/Engines.py b/src/classes/Engines.py index c3b4ea5..8e96283 100644 --- a/src/classes/Engines.py +++ b/src/classes/Engines.py @@ -1,4 +1,5 @@ import random, math +from .Heuristic import ReversiHeuristic class PlayerEngine: def __init__(self, logger, options: dict = {}): @@ -88,7 +89,11 @@ class MinmaxPlayerEngine(PlayerEngine): move = '' if depth == 0: leafs +=1 - return board.heuristique(), nodes, leafs + if self.options['heuristic'] == 'weight': + score = ReversiHeuristic(board).get() + else: + score = board.heuristique() + return score, nodes, leafs if friend_move: value = -math.inf @@ -150,7 +155,12 @@ class AlphabetaPlayerEngine(PlayerEngine): leafs = 0 if depth == 0 : leafs +=1 - return board.heuristique(), nodes, leafs + self.logger.debug("option: {}".format(self.options)) + if self.options['heuristic'] == 'weight': + score = ReversiHeuristic(self.logger).get(board) + else: + score = board.heuristique() + return score, nodes, leafs if friend_move: value = -math.inf diff --git a/src/classes/Heuristic.py b/src/classes/Heuristic.py new file mode 100644 index 0000000..13ae8ee --- /dev/null +++ b/src/classes/Heuristic.py @@ -0,0 +1,38 @@ +class ReversiHeuristic(): + def __init__(self, logger, weight = [1, 2, 10, 20]): + self.logger = logger + self.weight = weight + + def get(self, board): + size = board.get_board_size() + score = 0 + weights = self._get_weight(size) + for pos_x in range(size): + for pos_y in range(size): + if board._board[pos_x][pos_y] == board._nextPlayer: + score += weights[pos_x][pos_y] + else: + score -= weights[pos_x][pos_y] + return score + + def _get_weight(self, size): + w = [[ 0 for _ in range(size)] for _ in range(size)] + + 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] + + # 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] + + # 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: + w[pos_x][pos_y] = self.weight[0] + return w diff --git a/src/game.py b/src/game.py index 027ab8d..f503be9 100755 --- a/src/game.py +++ b/src/game.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 + from classes.Reversi import Board from classes.Engines import RandomPlayerEngine, HumanPlayerEngine, MinmaxPlayerEngine, AlphabetaPlayerEngine import logging as log @@ -31,6 +32,12 @@ def parse_aguments(): default=3, ) + parser.add_argument('-H', '--heuristic', + help='Define heutistic engine', + choices=['board', 'weight'], + default='board', + ) + debug_group = parser.add_mutually_exclusive_group() debug_group.add_argument('-V', '--verbose', help='Verbose output', @@ -75,7 +82,8 @@ if __name__ == '__main__': args.white_engine )) options = { - 'depth': args.depth + 'depth': args.depth, + 'heuristic': args.heuristic } wplayer = engines[args.white_engine](logger, options) bplayer = engines[args.black_engine](logger, options)