From 7f97fdba7482cc1d7a53ceb99cc89999a0a330cf Mon Sep 17 00:00:00 2001 From: Yuriy Danyliuk Date: Sat, 6 Nov 2021 19:13:06 +0200 Subject: [PATCH] Improve the function for calculating SEV Count how close the player and the opponent are to victory If the opponent is too close, then start to place walls --- .../MinimaxScoreFunctionForTwoPlayers.cs | 39 +++++++++++-------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/Quoridor.Controllers/PlayerControllers/AI/Strong/MinimaxAdapters/MinimaxScoreFunctionForTwoPlayers.cs b/Quoridor.Controllers/PlayerControllers/AI/Strong/MinimaxAdapters/MinimaxScoreFunctionForTwoPlayers.cs index f88e4f2..8d32e36 100644 --- a/Quoridor.Controllers/PlayerControllers/AI/Strong/MinimaxAdapters/MinimaxScoreFunctionForTwoPlayers.cs +++ b/Quoridor.Controllers/PlayerControllers/AI/Strong/MinimaxAdapters/MinimaxScoreFunctionForTwoPlayers.cs @@ -7,7 +7,7 @@ namespace Quoridor.Controllers.PlayerControllers.AI.Strong.MinimaxAdapters { public static class MinimaxScoreFunction { - public static double CalculateForTwoPlayers(MinimaxStateAdapter minimaxAdapter, Player player) + public static double CalculateForTwoPlayers(MinimaxStateAdapter minimaxAdapter, IPlayer player) { if (minimaxAdapter is null) { @@ -25,22 +25,30 @@ public static double CalculateForTwoPlayers(MinimaxStateAdapter minimaxAdapter, " Parameter name: " + nameof(quoridorModel.Players)); } - Player firstPlayer = (Player)quoridorModel.Players[0]; - Player secondPlayer = (Player)quoridorModel.Players[1]; - double score; // A number that shows how close the player is to victory + IPlayer firstPlayer = quoridorModel.Players[0]; + IPlayer secondPlayer = quoridorModel.Players[1]; + IPlayer opponent = player == firstPlayer ? secondPlayer : firstPlayer; - if (player == firstPlayer) - { - score = CalculateForPlayer(firstPlayer, quoridorModel); - } - else - { - score = CalculateForPlayer(secondPlayer, quoridorModel); - } - return score; + return CalculateForPlayer(player, opponent, quoridorModel); } + static double CalculateForPlayer(IPlayer player, IPlayer opponent, QuoridorModel quoridorModel) + { + // Maximum number of steps to win in a straight line + int maxStepsToVictory = quoridorModel.Field.Height - 1; - static double CalculateForPlayer(Player player, QuoridorModel quoridorModel) + // A number that shows how close the player is to victory + double score = maxStepsToVictory / CalculateStepsToVictoryForPlayer(player, quoridorModel); + + double opponentStepsToVictory = CalculateStepsToVictoryForPlayer(opponent, quoridorModel); + + if (opponentStepsToVictory < 2) + score -= maxStepsToVictory / opponentStepsToVictory; + else if (opponentStepsToVictory < 4) + score -= maxStepsToVictory / opponentStepsToVictory / 2; + + return score; + } + static double CalculateStepsToVictoryForPlayer(IPlayer player, QuoridorModel quoridorModel) { IFieldNode finded = AStar.FindTheShortestPath(quoridorModel.Field, player.Position, player.Goal.Item2, player.Goal.Item1); @@ -54,8 +62,7 @@ static double CalculateForPlayer(Player player, QuoridorModel quoridorModel) fieldNode = fieldNode.PreviousPathNode; } } - // Value inversely proportional to the number of steps to victory - return (double)(quoridorModel.Field.Height - 1) / stepsToVictory; + return stepsToVictory; } } } \ No newline at end of file