Implement heuristics classes

This commit is contained in:
Yorick Barbanneau 2023-12-16 23:02:36 +01:00
parent 3784faeaed
commit a1812aaedf
3 changed files with 63 additions and 38 deletions

View file

@ -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

View file

@ -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()

View file

@ -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)