Version finale
This commit is contained in:
parent
7416df8a17
commit
48f2b72c40
|
@ -8,7 +8,7 @@
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/out" />
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
|
@ -4,11 +4,20 @@
|
||||||
<option name="autoReloadType" value="SELECTIVE" />
|
<option name="autoReloadType" value="SELECTIVE" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="41395b4b-3252-492c-a869-5f4dab107186" name="Changes" comment="Gitignore">
|
<list default="true" id="41395b4b-3252-492c-a869-5f4dab107186" name="Changes" comment="Limite la longueur d'un coup sous les 5 secondes">
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/misc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/main/java/laboratoire4/Main.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/laboratoire4/Main.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/pom.xml" beforeDir="false" afterPath="$PROJECT_DIR$/pom.xml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/laboratoire4/game/PusherGame.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/laboratoire4/game/PusherGame.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/laboratoire4/pawns/PawnUtils.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/laboratoire4/pawns/PawnUtils.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/laboratoire4/strategies/AttackStrategy.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/laboratoire4/strategies/AttackStrategy.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/main/java/laboratoire4/strategies/DefenseStrategy.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/laboratoire4/strategies/DefenseStrategy.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/main/java/laboratoire4/strategies/DefenseStrategy.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/laboratoire4/strategies/DefenseStrategy.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/laboratoire4/strategies/ImmediateDefenseStrategy.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/laboratoire4/strategies/ImmediateDefenseStrategy.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/laboratoire4/strategies/MasterStrategy.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/laboratoire4/strategies/MasterStrategy.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/main/java/laboratoire4/strategies/MiniMaxStrategy.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/laboratoire4/strategies/MiniMaxStrategy.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/main/java/laboratoire4/strategies/MiniMaxStrategy.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/laboratoire4/strategies/MiniMaxStrategy.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/laboratoire4/strategies/RandomStrategy.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/laboratoire4/strategies/RandomStrategy.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/laboratoire4/strategies/Strategy.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/laboratoire4/strategies/Strategy.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/laboratoire4/strategies/WinningStrategy.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/laboratoire4/strategies/WinningStrategy.java" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<list id="98b8a79f-2f53-42bf-96da-7af322697a0d" name="Changes by acastonguay" comment="" />
|
<list id="98b8a79f-2f53-42bf-96da-7af322697a0d" name="Changes by acastonguay" comment="" />
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
|
@ -49,23 +58,26 @@
|
||||||
<option name="hideEmptyMiddlePackages" value="true" />
|
<option name="hideEmptyMiddlePackages" value="true" />
|
||||||
<option name="showLibraryContents" value="true" />
|
<option name="showLibraryContents" value="true" />
|
||||||
</component>
|
</component>
|
||||||
<component name="PropertiesComponent">{
|
<component name="PropertiesComponent"><![CDATA[{
|
||||||
"keyToString": {
|
"keyToString": {
|
||||||
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
||||||
"codeWithMe.voiceChat.enabledByDefault": "false",
|
"codeWithMe.voiceChat.enabledByDefault": "false",
|
||||||
"git-widget-placeholder": "william",
|
"git-widget-placeholder": "william",
|
||||||
"last_opened_file_path": "/home/william/Dev/Projects",
|
"last_opened_file_path": "/home/william/Dev/Projects",
|
||||||
"node.js.detected.package.eslint": "true",
|
"node.js.detected.package.eslint": "true",
|
||||||
"node.js.detected.package.tslint": "true",
|
"node.js.detected.package.tslint": "true",
|
||||||
"node.js.selected.package.eslint": "(autodetect)",
|
"node.js.selected.package.eslint": "(autodetect)",
|
||||||
"node.js.selected.package.tslint": "(autodetect)",
|
"node.js.selected.package.tslint": "(autodetect)",
|
||||||
"nodejs_package_manager_path": "npm",
|
"nodejs_package_manager_path": "npm",
|
||||||
"settings.editor.selected.configurable": "reference.settings.ide.settings.new.ui",
|
"project.structure.last.edited": "Libraries",
|
||||||
"vue.rearranger.settings.migration": "true"
|
"project.structure.proportion": "0.15",
|
||||||
|
"project.structure.side.proportion": "0.2",
|
||||||
|
"settings.editor.selected.configurable": "reference.projectsettings.compiler.javacompiler",
|
||||||
|
"vue.rearranger.settings.migration": "true"
|
||||||
}
|
}
|
||||||
}</component>
|
}]]></component>
|
||||||
<component name="RunManager" selected="Application.Main">
|
<component name="RunManager" selected="Application.Main">
|
||||||
<configuration name="Client" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
|
<configuration name="Client" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
|
||||||
<option name="MAIN_CLASS_NAME" value="laboratoire4.Client" />
|
<option name="MAIN_CLASS_NAME" value="laboratoire4.Client" />
|
||||||
|
@ -198,7 +210,14 @@
|
||||||
<option name="project" value="LOCAL" />
|
<option name="project" value="LOCAL" />
|
||||||
<updated>1681237323963</updated>
|
<updated>1681237323963</updated>
|
||||||
</task>
|
</task>
|
||||||
<option name="localTasksCounter" value="9" />
|
<task id="LOCAL-00009" summary="Limite la longueur d'un coup sous les 5 secondes">
|
||||||
|
<created>1681238632769</created>
|
||||||
|
<option name="number" value="00009" />
|
||||||
|
<option name="presentableId" value="LOCAL-00009" />
|
||||||
|
<option name="project" value="LOCAL" />
|
||||||
|
<updated>1681238632769</updated>
|
||||||
|
</task>
|
||||||
|
<option name="localTasksCounter" value="10" />
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
<component name="TypeScriptGeneratedFilesManager">
|
<component name="TypeScriptGeneratedFilesManager">
|
||||||
|
@ -212,17 +231,7 @@
|
||||||
<MESSAGE value="Plus d'heuristiques" />
|
<MESSAGE value="Plus d'heuristiques" />
|
||||||
<MESSAGE value="Beaucoup de changements" />
|
<MESSAGE value="Beaucoup de changements" />
|
||||||
<MESSAGE value="Gitignore" />
|
<MESSAGE value="Gitignore" />
|
||||||
<option name="LAST_COMMIT_MESSAGE" value="Gitignore" />
|
<MESSAGE value="Limite la longueur d'un coup sous les 5 secondes" />
|
||||||
</component>
|
<option name="LAST_COMMIT_MESSAGE" value="Limite la longueur d'un coup sous les 5 secondes" />
|
||||||
<component name="XDebuggerManager">
|
|
||||||
<breakpoint-manager>
|
|
||||||
<breakpoints>
|
|
||||||
<line-breakpoint enabled="true" type="java-line">
|
|
||||||
<url>file://$PROJECT_DIR$/src/main/java/laboratoire4/strategies/MasterStrategy.java</url>
|
|
||||||
<line>20</line>
|
|
||||||
<option name="timeStamp" value="2" />
|
|
||||||
</line-breakpoint>
|
|
||||||
</breakpoints>
|
|
||||||
</breakpoint-manager>
|
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
19
pom.xml
19
pom.xml
|
@ -9,9 +9,24 @@
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>11</maven.compiler.source>
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
<maven.compiler.target>11</maven.compiler.target>
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>laboratoire4.Main</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -6,9 +6,8 @@ import laboratoire4.pawns.Pawn;
|
||||||
import laboratoire4.pawns.PawnMovement;
|
import laboratoire4.pawns.PawnMovement;
|
||||||
import laboratoire4.pawns.Pushed;
|
import laboratoire4.pawns.Pushed;
|
||||||
import laboratoire4.pawns.Pusher;
|
import laboratoire4.pawns.Pusher;
|
||||||
import laboratoire4.strategies.MasterStrategy;
|
|
||||||
import laboratoire4.strategies.Strategy;
|
|
||||||
import laboratoire4.strategies.EvaluationResult;
|
import laboratoire4.strategies.EvaluationResult;
|
||||||
|
import laboratoire4.strategies.MasterStrategy;
|
||||||
|
|
||||||
public class PusherGame implements Game {
|
public class PusherGame implements Game {
|
||||||
private final Player player;
|
private final Player player;
|
||||||
|
@ -47,11 +46,14 @@ public class PusherGame implements Game {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String runNextMove() {
|
public String runNextMove() {
|
||||||
// MiniMaxResult result = MiniMax.miniMax(this);
|
EvaluationResult result = MasterStrategy.getInstance(this).getNextMove();
|
||||||
EvaluationResult result = MasterStrategy.getInstance().getNextMove(this);
|
if (result == null) {
|
||||||
|
// Ce n'est pas censé arriver, on réessaie
|
||||||
|
System.err.println("Aucune résultat n'a été retourné!");
|
||||||
|
result = MasterStrategy.getInstance(this).getNextMove();
|
||||||
|
}
|
||||||
|
|
||||||
Pawn pawn = board[result.getRow()][result.getCol()];
|
Pawn pawn = board[result.getRow()][result.getCol()];
|
||||||
// System.out.println(result.getScore());
|
|
||||||
|
|
||||||
String initialPosition = pawn.getPosition();
|
String initialPosition = pawn.getPosition();
|
||||||
move(pawn, result.getMovement());
|
move(pawn, result.getMovement());
|
||||||
|
|
|
@ -136,10 +136,10 @@ public class PawnUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends IPawn> Collection<Action<T>> getActions(Game game, boolean max) {
|
public static <T extends IPawn> Collection<Action<T>> getActions(Game game, boolean max) {
|
||||||
return getActions(game, max, true);
|
return getActions(game, max, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends IPawn> Collection<Action<T>> getActions(Game game, boolean max, boolean excludeDefense) {
|
public static <T extends IPawn> Collection<Action<T>> getActions(Game game, boolean max, boolean excludeDefense, boolean excludeDanger) {
|
||||||
List<Action<T>> actions = new ArrayList<>();
|
List<Action<T>> actions = new ArrayList<>();
|
||||||
PawnMovement[] movements = PawnMovement.values();
|
PawnMovement[] movements = PawnMovement.values();
|
||||||
|
|
||||||
|
@ -160,13 +160,23 @@ public class PawnUtils {
|
||||||
|
|
||||||
for (PawnMovement movement : movements) {
|
for (PawnMovement movement : movements) {
|
||||||
if (pawn.isMoveValid(game.getBoard(), movement)) {
|
if (pawn.isMoveValid(game.getBoard(), movement)) {
|
||||||
|
if (excludeDanger && PawnUtils.canBeCaptured(game, pawn.getRow() + pawn.getDirection(), pawn.getCol() + movement.getMove(), pawn.getPlayer())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
actions.add(new Action<>(pawn, movement));
|
actions.add(new Action<>(pawn, movement));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (excludeDefense && actions.isEmpty()) {
|
if (actions.isEmpty()) {
|
||||||
return getActions(game, max, false);
|
if (excludeDanger && excludeDefense) {
|
||||||
|
return getActions(game, max, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (excludeDefense) {
|
||||||
|
return getActions(game, max, false, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Collections.shuffle(actions);
|
Collections.shuffle(actions);
|
||||||
|
|
|
@ -9,22 +9,27 @@ import laboratoire4.pawns.PawnUtils;
|
||||||
import laboratoire4.pawns.SimulatedPawn;
|
import laboratoire4.pawns.SimulatedPawn;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class AttackStrategy extends MiniMaxStrategy {
|
public class AttackStrategy extends MiniMaxStrategy {
|
||||||
private static final int ATTACK_DISTANCE_FROM_GOAL = 4;
|
private static final int ATTACK_DISTANCE_FROM_GOAL = 4;
|
||||||
|
|
||||||
private long originalMinPawnCount;
|
private long originalMinPushedCount;
|
||||||
|
private long originalMinPusherCount;
|
||||||
private long originalMaxPusherCount;
|
private long originalMaxPusherCount;
|
||||||
|
|
||||||
|
protected AttackStrategy(Game game) {
|
||||||
|
super(game);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EvaluationResult getNextMove(Game game) {
|
public EvaluationResult getNextMove() {
|
||||||
originalMinPawnCount = GameUtils.getMinPawnsAsStream(game.getBoard(), game.getPlayer()).count();
|
originalMinPushedCount = GameUtils.getMinPawnsAsStream(game.getBoard(), game.getPlayer()).filter(p -> !p.isPusher()).count();
|
||||||
|
originalMinPusherCount = GameUtils.getMinPawnsAsStream(game.getBoard(), game.getPlayer()).filter(IPawn::isPusher).count();
|
||||||
originalMaxPusherCount = GameUtils.getMaxPawnsAsStream(game.getBoard(), game.getPlayer())
|
originalMaxPusherCount = GameUtils.getMaxPawnsAsStream(game.getBoard(), game.getPlayer())
|
||||||
.filter(IPawn::isPusher)
|
.filter(IPawn::isPusher)
|
||||||
.count();
|
.count();
|
||||||
|
|
||||||
return super.getNextMove(game);
|
return super.getNextMove();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -35,40 +40,59 @@ public class AttackStrategy extends MiniMaxStrategy {
|
||||||
return Integer.MIN_VALUE;
|
return Integer.MIN_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
long pusherCount = getMaxPawns().stream().filter(IPawn::isPusher).count();
|
// region Pions max perdus
|
||||||
if (pusherCount == 0) {
|
Collection<SimulatedPawn> maxPawns = getMaxPawns();
|
||||||
return Integer.MIN_VALUE;
|
long pusherCount = maxPawns.stream().filter(IPawn::isPusher).count();
|
||||||
}
|
score -= Math.pow((originalMaxPusherCount - pusherCount) * 10, 2);
|
||||||
score -= Math.pow(originalMaxPusherCount - pusherCount, 2);
|
// endregion
|
||||||
|
|
||||||
for (SimulatedPawn pawn : getMaxPawns()) {
|
// region Pions min capturés
|
||||||
if (pawn.getRow() == pawn.getPlayer().getGoal()) {
|
long minPusherCount = getMinPawns().stream().filter(IPawn::isPusher).count();
|
||||||
return Integer.MAX_VALUE;
|
long minPushedCount = getMinPawns().stream().filter(p -> !p.isPusher()).count();
|
||||||
}
|
score += (originalMinPushedCount - minPushedCount) * 5;
|
||||||
|
score += (originalMinPusherCount - minPusherCount) * 10;
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
for (SimulatedPawn pawn : maxPawns) {
|
||||||
|
int distanceFromGoal = PawnUtils.distanceFromGoal(pawn);
|
||||||
|
if (distanceFromGoal <= ATTACK_DISTANCE_FROM_GOAL) {
|
||||||
|
score += ATTACK_DISTANCE_FROM_GOAL - distanceFromGoal + 1;
|
||||||
|
|
||||||
if (PawnUtils.hasEasyWinPath(game.getBoard(), pawn)) {
|
if (PawnUtils.hasEasyWinPath(game.getBoard(), pawn)) {
|
||||||
return Integer.MAX_VALUE / 2;
|
score += Integer.MAX_VALUE / distanceFromGoal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// int distanceFromGoal = PawnUtils.distanceFromGoal(pawn);
|
int row = pawn.getRow();
|
||||||
// if (distanceFromGoal <= ATTACK_DISTANCE_FROM_GOAL) {
|
int col = pawn.getCol();
|
||||||
// score += ATTACK_DISTANCE_FROM_GOAL - distanceFromGoal + 1;
|
|
||||||
|
if (row > 0 && row < 7) {
|
||||||
|
IPawn facingPawn = game.getBoard()[row + pawn.getDirection()][col];
|
||||||
|
if (facingPawn != null && !PawnUtils.areSamePlayers(pawn, facingPawn)) {
|
||||||
|
// On bloque potentiellement un pion adverse, qui ne peut pas nous attaquer
|
||||||
|
score += 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (col > 0) {
|
||||||
|
// IPawn leftPawn = game.getBoard()[row][col - 1];
|
||||||
|
// if (leftPawn != null && !PawnUtils.areSamePlayers(pawn, leftPawn)) {
|
||||||
|
// score += 5;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (col < 7) {
|
||||||
|
// IPawn rightPawn = game.getBoard()[row][col + 1];
|
||||||
|
// if (rightPawn != null && !PawnUtils.areSamePlayers(pawn, rightPawn)) {
|
||||||
|
// score += 5;
|
||||||
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if (pawn.isPusher() && PawnUtils.canBeCaptured(game, pawn)) {
|
|
||||||
score -= 10; // On ne veut pas nécessairement bouger où on peut être capturé facilement
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
int minPawnCount = getMinPawns().size();
|
|
||||||
long capturedPawnCount = originalMinPawnCount - minPawnCount;
|
|
||||||
score += Math.pow(capturedPawnCount, 2);
|
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getWeight(Game game) {
|
public int getWeight() {
|
||||||
Collection<IPawn> maxPawns = GameUtils.getMaxPawns(game.getBoard(), game.getPlayer());
|
Collection<IPawn> maxPawns = GameUtils.getMaxPawns(game.getBoard(), game.getPlayer());
|
||||||
|
|
||||||
int maxWeight = 0;
|
int maxWeight = 0;
|
||||||
|
|
|
@ -4,6 +4,7 @@ import laboratoire4.Action;
|
||||||
import laboratoire4.IPawn;
|
import laboratoire4.IPawn;
|
||||||
import laboratoire4.game.Game;
|
import laboratoire4.game.Game;
|
||||||
import laboratoire4.game.GameUtils;
|
import laboratoire4.game.GameUtils;
|
||||||
|
import laboratoire4.pawns.PawnMovement;
|
||||||
import laboratoire4.pawns.PawnUtils;
|
import laboratoire4.pawns.PawnUtils;
|
||||||
import laboratoire4.pawns.SimulatedPawn;
|
import laboratoire4.pawns.SimulatedPawn;
|
||||||
|
|
||||||
|
@ -13,30 +14,32 @@ import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class DefenseStrategy extends MiniMaxStrategy {
|
public class DefenseStrategy extends MiniMaxStrategy {
|
||||||
private static final int DEFENSE_DISTANCE_FROM_HOME = 3;
|
private static final int DEFENSE_DISTANCE_FROM_HOME = 2;
|
||||||
private static final int PAWN_DEFENSE_DISTANCE = 3;
|
private static final int PAWN_DEFENSE_DISTANCE = 3;
|
||||||
|
|
||||||
private final Map<IPawn, Integer> dangerousPawns = new HashMap<>();
|
private final Map<IPawn, Integer> dangerousPawns;
|
||||||
|
|
||||||
|
public DefenseStrategy(Game game) {
|
||||||
|
super(game);
|
||||||
|
|
||||||
|
dangerousPawns = getDangerousPawns(game);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EvaluationResult getNextMove(Game game) {
|
public EvaluationResult getNextMove() {
|
||||||
for (IPawn pawn : GameUtils.getMinPawns(game.getBoard(), game.getPlayer())) {
|
|
||||||
int distance = PawnUtils.distanceFromGoal(pawn);
|
|
||||||
|
|
||||||
if (distance <= DEFENSE_DISTANCE_FROM_HOME) {
|
|
||||||
dangerousPawns.put(pawn, DEFENSE_DISTANCE_FROM_HOME - distance + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dangerousPawns.isEmpty()) {
|
if (dangerousPawns.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.getNextMove(game);
|
return super.getNextMove();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getWeight(Game game) {
|
public int getWeight() {
|
||||||
|
if (dangerousPawns.isEmpty()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Collection<IPawn> minPawns = GameUtils.getMinPawns(game.getBoard(), game.getPlayer());
|
Collection<IPawn> minPawns = GameUtils.getMinPawns(game.getBoard(), game.getPlayer());
|
||||||
Collection<IPawn> maxPawns = GameUtils.getMaxPawns(game.getBoard(), game.getPlayer());
|
Collection<IPawn> maxPawns = GameUtils.getMaxPawns(game.getBoard(), game.getPlayer());
|
||||||
int maxWeight = 0;
|
int maxWeight = 0;
|
||||||
|
@ -78,8 +81,11 @@ public class DefenseStrategy extends MiniMaxStrategy {
|
||||||
Collection<SimulatedPawn> minPawns = getMinPawns();
|
Collection<SimulatedPawn> minPawns = getMinPawns();
|
||||||
|
|
||||||
for (SimulatedPawn pawn : minPawns) {
|
for (SimulatedPawn pawn : minPawns) {
|
||||||
if (pawn.getRow() == pawn.getPlayer().getGoal()) {
|
for (PawnMovement movement : PawnMovement.values()) {
|
||||||
return Integer.MIN_VALUE;
|
if (PawnUtils.canBeCaptured(game, pawn.getRow() + pawn.getDirection(), pawn.getCol() + movement.getMove(), pawn.getPlayer())) {
|
||||||
|
// Ce pion ennemi est aussi en danger s'il bouge !
|
||||||
|
score += 5;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +94,7 @@ public class DefenseStrategy extends MiniMaxStrategy {
|
||||||
.filter(p -> p.getOriginalRow() == dangerousPawn.getRow() && p.getOriginalCol() == dangerousPawn.getCol())
|
.filter(p -> p.getOriginalRow() == dangerousPawn.getRow() && p.getOriginalCol() == dangerousPawn.getCol())
|
||||||
.findFirst();
|
.findFirst();
|
||||||
|
|
||||||
if (simulated.isEmpty()) {
|
if (!simulated.isPresent()) {
|
||||||
// Le pion a été capturé !
|
// Le pion a été capturé !
|
||||||
score += Math.pow(dangerousPawns.get(dangerousPawn), 3);
|
score += Math.pow(dangerousPawns.get(dangerousPawn), 3);
|
||||||
} else {
|
} else {
|
||||||
|
@ -97,10 +103,12 @@ public class DefenseStrategy extends MiniMaxStrategy {
|
||||||
score -= Math.pow(DEFENSE_DISTANCE_FROM_HOME - distance + 1, 3);
|
score -= Math.pow(DEFENSE_DISTANCE_FROM_HOME - distance + 1, 3);
|
||||||
|
|
||||||
for (SimulatedPawn pawn : maxPawns) {
|
for (SimulatedPawn pawn : maxPawns) {
|
||||||
|
if (PawnUtils.distanceFromHome(pawn) <= DEFENSE_DISTANCE_FROM_HOME) { // On ne veut pas que nos attaquants s'approchent des pions ennemis
|
||||||
score += PAWN_DEFENSE_DISTANCE - distanceFromCapture(pawn, simulated.get()) * 5;
|
score += PAWN_DEFENSE_DISTANCE - distanceFromCapture(pawn, simulated.get()) * 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (SimulatedPawn pawn : maxPawns) {
|
for (SimulatedPawn pawn : maxPawns) {
|
||||||
if (PawnUtils.canBeCaptured(game, pawn)) {
|
if (PawnUtils.canBeCaptured(game, pawn)) {
|
||||||
|
@ -115,10 +123,16 @@ public class DefenseStrategy extends MiniMaxStrategy {
|
||||||
int col = pawn.getCol();
|
int col = pawn.getCol();
|
||||||
int row = pawn.getRow();
|
int row = pawn.getRow();
|
||||||
|
|
||||||
if (col > 0 && PawnUtils.areSamePlayers(pawn, game.getBoard()[col - 1][row])) {
|
if (col > 0 && PawnUtils.areSamePlayers(pawn, game.getBoard()[row][col - 1])) {
|
||||||
score += 5;
|
score += 5;
|
||||||
}
|
}
|
||||||
if (col < 7 && PawnUtils.areSamePlayers(pawn, game.getBoard()[col + 1][row])) {
|
if (col < 7 && PawnUtils.areSamePlayers(pawn, game.getBoard()[row][col + 1])) {
|
||||||
|
score += 5;
|
||||||
|
}
|
||||||
|
if (row > 0 && PawnUtils.areSamePlayers(pawn, game.getBoard()[row - 1][col])) {
|
||||||
|
score += 5;
|
||||||
|
}
|
||||||
|
if (row < 7 && PawnUtils.areSamePlayers(pawn, game.getBoard()[row + 1][col])) {
|
||||||
score += 5;
|
score += 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,19 +140,6 @@ public class DefenseStrategy extends MiniMaxStrategy {
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Collection<Action<IPawn>> getActions(boolean max) {
|
|
||||||
Collection<SimulatedPawn> pawns = max ? getMaxPawns() : getMinPawns();
|
|
||||||
|
|
||||||
long defensivePawnCount = pawns.stream()
|
|
||||||
.filter(IPawn::isPusher)
|
|
||||||
.filter(p -> p.getRow() != p.getPlayer().getHome())
|
|
||||||
.filter(p -> PawnUtils.distanceFromHome(p) <= DEFENSE_DISTANCE_FROM_HOME)
|
|
||||||
.count();
|
|
||||||
|
|
||||||
return PawnUtils.getActions(game, max, defensivePawnCount > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int distanceFromCapture(IPawn max, IPawn min) {
|
private int distanceFromCapture(IPawn max, IPawn min) {
|
||||||
int rowDistance = Math.abs(min.getRow() - max.getRow());
|
int rowDistance = Math.abs(min.getRow() - max.getRow());
|
||||||
int colDistance = Math.abs(min.getCol() - max.getCol());
|
int colDistance = Math.abs(min.getCol() - max.getCol());
|
||||||
|
@ -155,5 +156,23 @@ public class DefenseStrategy extends MiniMaxStrategy {
|
||||||
return rowDistance;
|
return rowDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Map<IPawn, Integer> getDangerousPawns(Game game) {
|
||||||
|
Map<IPawn, Integer> dangerousPawns = new HashMap<>();
|
||||||
|
|
||||||
|
for (IPawn pawn : GameUtils.getMinPawns(game.getBoard(), game.getPlayer())) {
|
||||||
|
int distance = PawnUtils.distanceFromGoal(pawn);
|
||||||
|
|
||||||
|
if (distance <= DEFENSE_DISTANCE_FROM_HOME) {
|
||||||
|
// Les pions proches de nous qui ne peuvent pas bouger peuvent être ignorés
|
||||||
|
for (PawnMovement movement : PawnMovement.values()) {
|
||||||
|
if (pawn.isMoveValid(game.getBoard(), movement)) {
|
||||||
|
dangerousPawns.put(pawn, DEFENSE_DISTANCE_FROM_HOME - distance + 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dangerousPawns;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,17 @@ import laboratoire4.pawns.PawnMovement;
|
||||||
import laboratoire4.pawns.PawnUtils;
|
import laboratoire4.pawns.PawnUtils;
|
||||||
|
|
||||||
public class ImmediateDefenseStrategy implements Strategy {
|
public class ImmediateDefenseStrategy implements Strategy {
|
||||||
private static final int IMM_DEFENSE_DISTANCE_FROM_HOME = 1;
|
private static final int IMM_DEFENSE_DISTANCE_FROM_HOME = 2;
|
||||||
|
|
||||||
|
private final Game game;
|
||||||
|
|
||||||
|
public ImmediateDefenseStrategy(Game game) {
|
||||||
|
this.game = game;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EvaluationResult getNextMove(Game game) {
|
public EvaluationResult getNextMove() {
|
||||||
// On utilise pas la méthode utilitaire, car on veut bouger la ligne de défense si nécessaire
|
// On n'utilise pas la méthode utilitaire, car on veut bouger la ligne de défense si nécessaire
|
||||||
for (IPawn pawn : GameUtils.getMaxPawns(game.getBoard(), game.getPlayer())) {
|
for (IPawn pawn : GameUtils.getMaxPawns(game.getBoard(), game.getPlayer())) {
|
||||||
if (PawnUtils.distanceFromHome(pawn) > IMM_DEFENSE_DISTANCE_FROM_HOME) {
|
if (PawnUtils.distanceFromHome(pawn) > IMM_DEFENSE_DISTANCE_FROM_HOME) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -36,7 +42,7 @@ public class ImmediateDefenseStrategy implements Strategy {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getWeight(Game game) {
|
public int getWeight() {
|
||||||
for (IPawn pawn : GameUtils.getMaxPawns(game.getBoard(), game.getPlayer())) {
|
for (IPawn pawn : GameUtils.getMaxPawns(game.getBoard(), game.getPlayer())) {
|
||||||
if (PawnUtils.distanceFromHome(pawn) > IMM_DEFENSE_DISTANCE_FROM_HOME) {
|
if (PawnUtils.distanceFromHome(pawn) > IMM_DEFENSE_DISTANCE_FROM_HOME) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -5,25 +5,28 @@ import laboratoire4.game.Game;
|
||||||
public class MasterStrategy implements Strategy {
|
public class MasterStrategy implements Strategy {
|
||||||
private static Strategy instance;
|
private static Strategy instance;
|
||||||
|
|
||||||
public static Strategy getInstance() {
|
public static Strategy getInstance(Game game) {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
instance = new MasterStrategy();
|
instance = new MasterStrategy(game);
|
||||||
}
|
}
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MasterStrategy() {
|
private final Game game;
|
||||||
|
|
||||||
|
private MasterStrategy(Game game) {
|
||||||
|
this.game = game;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EvaluationResult getNextMove(Game game) {
|
public EvaluationResult getNextMove() {
|
||||||
long startMs = System.currentTimeMillis();
|
long startMs = System.currentTimeMillis();
|
||||||
|
|
||||||
Strategy strategy = getBestStrategy(game);
|
Strategy strategy = getBestStrategy();
|
||||||
System.out.println(strategy.getClass().getSimpleName());
|
System.out.println(strategy.getClass().getSimpleName());
|
||||||
|
|
||||||
EvaluationResult result = strategy.getNextMove(game);
|
EvaluationResult result = strategy.getNextMove();
|
||||||
|
|
||||||
long endMs = System.currentTimeMillis();
|
long endMs = System.currentTimeMillis();
|
||||||
System.out.printf("Temps: %d ms\n", endMs - startMs);
|
System.out.printf("Temps: %d ms\n", endMs - startMs);
|
||||||
|
@ -31,19 +34,19 @@ public class MasterStrategy implements Strategy {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Strategy getBestStrategy(Game game) {
|
private Strategy getBestStrategy() {
|
||||||
Strategy[] strategies = new Strategy[]{
|
Strategy[] strategies = new Strategy[]{
|
||||||
new ImmediateDefenseStrategy(),
|
new ImmediateDefenseStrategy(game),
|
||||||
new WinningStrategy(),
|
new WinningStrategy(game),
|
||||||
new DefenseStrategy(),
|
new DefenseStrategy(game),
|
||||||
new AttackStrategy()
|
new AttackStrategy(game)
|
||||||
};
|
};
|
||||||
|
|
||||||
int maxWeight = 0;
|
int maxWeight = 0;
|
||||||
Strategy bestStrategy = null;
|
Strategy bestStrategy = null;
|
||||||
|
|
||||||
for (Strategy strategy : strategies) {
|
for (Strategy strategy : strategies) {
|
||||||
int weight = strategy.getWeight(game);
|
int weight = strategy.getWeight();
|
||||||
if (weight == WEIGHT_MAX) {
|
if (weight == WEIGHT_MAX) {
|
||||||
return strategy;
|
return strategy;
|
||||||
}
|
}
|
||||||
|
@ -58,11 +61,11 @@ public class MasterStrategy implements Strategy {
|
||||||
return bestStrategy;
|
return bestStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new RandomStrategy();
|
return new RandomStrategy(game);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getWeight(Game game) {
|
public int getWeight() {
|
||||||
return WEIGHT_MAX;
|
return WEIGHT_MAX;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,27 +5,31 @@ import laboratoire4.IPawn;
|
||||||
import laboratoire4.game.Game;
|
import laboratoire4.game.Game;
|
||||||
import laboratoire4.game.GameUtils;
|
import laboratoire4.game.GameUtils;
|
||||||
import laboratoire4.game.SimulatedGame;
|
import laboratoire4.game.SimulatedGame;
|
||||||
|
import laboratoire4.pawns.Pawn;
|
||||||
import laboratoire4.pawns.PawnMovement;
|
import laboratoire4.pawns.PawnMovement;
|
||||||
import laboratoire4.pawns.PawnUtils;
|
import laboratoire4.pawns.PawnUtils;
|
||||||
import laboratoire4.pawns.SimulatedPawn;
|
import laboratoire4.pawns.SimulatedPawn;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public abstract class MiniMaxStrategy implements Strategy {
|
public abstract class MiniMaxStrategy implements Strategy {
|
||||||
private static final int MAX_DEPTH = 6;
|
private static final int MAX_DEPTH = 6;
|
||||||
private static final long MAX_TIME_MS = 4500; // Moins de 5 secondes, car le tour n'est pas complètement fini
|
private static final long MAX_TIME_MS = 4800; // Moins de 5 secondes, car le tour n'est pas complètement fini
|
||||||
|
|
||||||
protected SimulatedGame game;
|
protected SimulatedGame game;
|
||||||
protected long startTimeMs;
|
protected long startTimeMs;
|
||||||
|
|
||||||
@Override
|
protected MiniMaxStrategy(Game game) {
|
||||||
public EvaluationResult getNextMove(Game game) {
|
this.game = new SimulatedGame(game.getBoard(), game.getPlayer());
|
||||||
return miniMax(game);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private EvaluationResult miniMax(Game game) {
|
@Override
|
||||||
this.game = new SimulatedGame(game.getBoard(), game.getPlayer());
|
public EvaluationResult getNextMove() {
|
||||||
|
return miniMax();
|
||||||
|
}
|
||||||
|
|
||||||
|
private EvaluationResult miniMax() {
|
||||||
EvaluationResult maxResult = null;
|
EvaluationResult maxResult = null;
|
||||||
int maxScore = Integer.MIN_VALUE;
|
int maxScore = Integer.MIN_VALUE;
|
||||||
startTimeMs = System.currentTimeMillis();
|
startTimeMs = System.currentTimeMillis();
|
||||||
|
@ -89,7 +93,7 @@ public abstract class MiniMaxStrategy implements Strategy {
|
||||||
PawnMovement movement = action.getMovement();
|
PawnMovement movement = action.getMovement();
|
||||||
|
|
||||||
game.move(pawn, movement);
|
game.move(pawn, movement);
|
||||||
int score = max(depth + 1, alpha, Math.min(beta, minScore)) * -1;
|
int score = max(depth + 1, alpha, Math.min(beta, minScore));
|
||||||
game.revertMove();
|
game.revertMove();
|
||||||
|
|
||||||
if (score < minScore) {
|
if (score < minScore) {
|
||||||
|
@ -119,7 +123,47 @@ public abstract class MiniMaxStrategy implements Strategy {
|
||||||
private int evaluate() {
|
private int evaluate() {
|
||||||
int score = evaluateSimulation();
|
int score = evaluateSimulation();
|
||||||
|
|
||||||
// Logique générale
|
Collection<SimulatedPawn> maxPawns = getMaxPawns();
|
||||||
|
|
||||||
|
if (maxPawns.stream().noneMatch(IPawn::isPusher)) {
|
||||||
|
return Integer.MIN_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getMinPawns().stream().anyMatch(p -> p.getRow() == p.getPlayer().getGoal())) {
|
||||||
|
return Integer.MIN_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IPawn pawn : maxPawns) {
|
||||||
|
if (pawn.getRow() == pawn.getPlayer().getGoal()) {
|
||||||
|
return Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PawnUtils.canBeCaptured(game, pawn)) {
|
||||||
|
// On peut être capturé
|
||||||
|
score -= 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (PawnMovement movement : PawnMovement.values()) {
|
||||||
|
if (pawn.isMoveValid(game.getBoard(), movement) && !PawnUtils.canBeCaptured(game, pawn.getRow() + pawn.getDirection(), pawn.getCol() + movement.getMove(), pawn.getPlayer())) {
|
||||||
|
// On ne peut pas être capturé en faisant ce mouvement
|
||||||
|
score += 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// region Lignes ennemies
|
||||||
|
for (IPawn pawn : getMinPawns()) {
|
||||||
|
int row = pawn.getRow();
|
||||||
|
int col = pawn.getCol();
|
||||||
|
|
||||||
|
if (row > 0 && PawnUtils.areSamePlayers(pawn, game.getBoard()[row - 1][col])) {
|
||||||
|
score -= 5;
|
||||||
|
}
|
||||||
|
if (row < 0 && PawnUtils.areSamePlayers(pawn, game.getBoard()[row + 1][col])) {
|
||||||
|
score -= 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// endregion
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,10 +16,16 @@ import java.util.stream.Collectors;
|
||||||
*/
|
*/
|
||||||
public class RandomStrategy implements Strategy {
|
public class RandomStrategy implements Strategy {
|
||||||
private static final int PAWN_TO_MOVE = 2;
|
private static final int PAWN_TO_MOVE = 2;
|
||||||
|
|
||||||
private final Random random = new Random();
|
private final Random random = new Random();
|
||||||
|
private final Game game;
|
||||||
|
|
||||||
|
public RandomStrategy(Game game) {
|
||||||
|
this.game = game;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EvaluationResult getNextMove(Game game) {
|
public EvaluationResult getNextMove() {
|
||||||
Collection<IPawn> outsideHomePushers = GameUtils.getMaxPawnsAsStream(game.getBoard(), game.getPlayer())
|
Collection<IPawn> outsideHomePushers = GameUtils.getMaxPawnsAsStream(game.getBoard(), game.getPlayer())
|
||||||
.filter(IPawn::isPusher)
|
.filter(IPawn::isPusher)
|
||||||
.filter(p -> p.getRow() != p.getPlayer().getHome())
|
.filter(p -> p.getRow() != p.getPlayer().getHome())
|
||||||
|
@ -38,7 +44,7 @@ public class RandomStrategy implements Strategy {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getWeight(Game game) {
|
public int getWeight() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,11 +9,11 @@ import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public interface Strategy {
|
public interface Strategy {
|
||||||
public static final int WEIGHT_MAX = 10;
|
int WEIGHT_MAX = 10;
|
||||||
|
|
||||||
EvaluationResult getNextMove(Game game);
|
EvaluationResult getNextMove();
|
||||||
|
|
||||||
int getWeight(Game game);
|
int getWeight();
|
||||||
|
|
||||||
static List<Action<IPawn>> getValidActions(Game game) {
|
static List<Action<IPawn>> getValidActions(Game game) {
|
||||||
List<IPawn> maxPawns = Arrays.stream(game.getBoard())
|
List<IPawn> maxPawns = Arrays.stream(game.getBoard())
|
||||||
|
|
|
@ -13,8 +13,16 @@ import java.util.stream.Collectors;
|
||||||
public class WinningStrategy implements Strategy {
|
public class WinningStrategy implements Strategy {
|
||||||
private Action<IPawn> winningAction;
|
private Action<IPawn> winningAction;
|
||||||
|
|
||||||
|
public WinningStrategy(Game game) {
|
||||||
|
winningAction = findImmediateWinningAction(game);
|
||||||
|
if (winningAction == null) {
|
||||||
|
// On cherche un chemin où on peut gagner quoi qu'il arrive
|
||||||
|
winningAction = findWinningPath(game);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EvaluationResult getNextMove(Game game) {
|
public EvaluationResult getNextMove() {
|
||||||
if (winningAction == null) {
|
if (winningAction == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -24,13 +32,7 @@ public class WinningStrategy implements Strategy {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getWeight(Game game) {
|
public int getWeight() {
|
||||||
winningAction = findImmediateWinningAction(game);
|
|
||||||
if (winningAction == null) {
|
|
||||||
// On cherche un chemin où on peut gagner quoi qu'il arrive
|
|
||||||
winningAction = findWinningPath(game);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (winningAction != null) {
|
if (winningAction != null) {
|
||||||
return WEIGHT_MAX;
|
return WEIGHT_MAX;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue