par pitié

This commit is contained in:
vaisse
2026-02-06 11:00:03 +01:00
parent 05871232bd
commit 98c6b4678e
4 changed files with 97 additions and 96 deletions

View File

@@ -35,10 +35,11 @@ public class HeuristicBot extends AbstractGamePlayer {
int size = board.getSize(); int size = board.getSize();
int center = size / 2; int center = size / 2;
float score = 0; float score = 0;
//HexBoard simBoard = (HexBoard) board.safeCopy();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) { for (int j = 0; j < size; j++) {
if (board.getPlayerAt(i, j) == Player.PLAYER1) { if (board.getCellPlayer(i, j) == Player.PLAYER1) {
score += Math.abs(i - center) + Math.abs(j - center); // Distance from center score += Math.abs(i - center) + Math.abs(j - center); // Distance from center
} }
} }

View File

@@ -79,7 +79,7 @@ public class MiniMaxBot extends AbstractGamePlayer {
int score = 0; int score = 0;
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) { for (int j = 0; j < size; j++) {
if (board.getPlayerAt(i, j) == Player.PLAYER1) { if (board.getCellPlayer(i, j) == Player.PLAYER1) {
score += Math.abs(i - center) + Math.abs(j - center); // Distance from center score += Math.abs(i - center) + Math.abs(j - center); // Distance from center
} }
} }

View File

@@ -37,7 +37,7 @@ public class MonteCarloBot extends AbstractGamePlayer {
private float monteCarloSimulation(HexBoard board) { private float monteCarloSimulation(HexBoard board) {
RandomBot simBot = new RandomBot(Player.PLAYER1, new Random().nextLong()); RandomBot simBot = new RandomBot(Player.PLAYER1, new Random().nextLong());
HexBoard simBoard = board.safeCopy(); HexBoard simBoard = (HexBoard) board.safeCopy();
int wins = 0; int wins = 0;
int simulations = 0; int simulations = 0;
@@ -51,7 +51,7 @@ public class MonteCarloBot extends AbstractGamePlayer {
wins++; wins++;
} }
simulations++; simulations++;
simBoard = board.safeCopy(); // Reset the board for the next simulation simBoard = (HexBoard) board.safeCopy(); // Reset the board for the next simulation
} }
return (float) wins / simulations; return (float) wins / simulations;

View File

@@ -3,6 +3,7 @@ package fr.iut_fbleau.HexGame;
import fr.iut_fbleau.GameAPI.*; import fr.iut_fbleau.GameAPI.*;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Random;
public class Simulation extends AbstractGame { public class Simulation extends AbstractGame {
@@ -27,18 +28,19 @@ public class Simulation extends AbstractGame {
//METHODES //METHODES
/*Le jeu de Hex ne peut jamais finir avec le résultat null. En utilisant cette propriété, on peut avoir cet algorithme simplifié du monte-carlo*/ /*Le jeu de Hex ne peut jamais finir avec le résultat null. En utilisant cette propriété, on peut avoir cet algorithme simplifié du monte-carlo*/
private float MonteCarlo(HexBoard position){ private float MonteCarlo(HexBoard position, Player current){
RandomBot simplay = new RandomBot(); RandomBot simplay = new RandomBot(current, new Random().nextLong());
HexBoard simpos = position.safeCopy(); HexBoard simpos = position;
LinkedList<Integer[]> ctaken = taken; LinkedList<Integer[]> ctaken = taken;
HexPly testmove; HexPly testmove;
float wins = 0; float wins = 0;
float losses = 0; float losses = 0;
int count = 0;
for(int i=0; i<EVALDEPTH; i++){ for(int i=0; i<EVALDEPTH; i++){
while(!simpos.isGameOver()){ while(!simpos.isGameOver()){
count++;
testmove = (HexPly) simplay.giveYourMove(simpos); testmove = (HexPly) simplay.giveYourMove(simpos);
if(!ctaken.contains(t) && simpos.isLegal(testmove)){ if(!ctaken.contains(new Integer[]{testmove.getRow(), testmove.getCol()}) && simpos.isLegal(testmove)){
ctaken.add(new Integer[]{testmove.getRow(), testmove.getCol()}); ctaken.add(new Integer[]{testmove.getRow(), testmove.getCol()});
simpos.doPly(testmove); simpos.doPly(testmove);
if(simpos.getResult()==Result.LOSS){ if(simpos.getResult()==Result.LOSS){
@@ -48,16 +50,16 @@ public class Simulation extends AbstractGame {
} }
} }
} }
simpos = position.safeCopy(); //System.out.println("count:"+count);
for (int j=0; j<count; j++) {
simpos.undoPly();
}
ctaken = taken; ctaken = taken;
count = 0;
} }
System.out.println(" wins : "+wins+"/losses : "+losses);
if(wins>=losses){ System.out.println(" eval : "+(wins-losses)/EVALDEPTH);
return losses/wins; return (wins-losses)/EVALDEPTH;
} else {
return -(wins/losses);
}
} }
private float explMAX(HexBoard position, int depth){ private float explMAX(HexBoard position, int depth){
@@ -66,7 +68,7 @@ public class Simulation extends AbstractGame {
} else if (position.getResult()==Result.WIN){ } else if (position.getResult()==Result.WIN){
return 1.0f; return 1.0f;
} else if (depth==MAXDEPTH) { } else if (depth==MAXDEPTH) {
return MonteCarlo(position); return MonteCarlo(position, Player.PLAYER1);
} else { } else {
float bestcase = -1.0f; float bestcase = -1.0f;
HexPly bestcasemove; HexPly bestcasemove;
@@ -108,7 +110,7 @@ public class Simulation extends AbstractGame {
} else if (position.getResult()==Result.WIN){ } else if (position.getResult()==Result.WIN){
return 1.0f; return 1.0f;
} else if (depth==MAXDEPTH) { } else if (depth==MAXDEPTH) {
return MonteCarlo(position); return MonteCarlo(position, Player.PLAYER2);
} else { } else {
float bestcase = 1.0f; float bestcase = 1.0f;
HexPly bestcasemove; HexPly bestcasemove;
@@ -145,94 +147,92 @@ public class Simulation extends AbstractGame {
} }
private float explMAXAB(HexBoard position, int depth, float A, float B){ private float explMAXAB(HexBoard position, int depth, float A, float B){
if (position.getResult() == Result.LOSS) { if (position.getResult()==Result.LOSS) {
return -1.0f; return -1.0f;
} else if (position.getResult() == Result.WIN) { } else if (position.getResult()==Result.WIN){
return 1.0f; return 1.0f;
} else if (depth == MAXDEPTH) { } else if (depth==MAXDEPTH) {
return MonteCarlo(position); return MonteCarlo(position, Player.PLAYER1);
} else { } else {
float bestcase = A; float bestcase = A;
HexPly bestcasemove; HexPly bestcasemove;
HexPly testmove; HexPly testmove;
for (int i = 0; i < position.getSize(); i++) { for (int i=0; i<position.getSize(); i++) {
for (int j = 0; j < position.getSize(); j++) { for (int j=0; j<position.getSize(); j++) {
if (depth == 0) { if(depth==0){
//System.out.println("MAX New Line :"); //System.out.println("MAX New Line :");
} }
Integer[] t = new Integer[]{i, j}; Integer[] t = new Integer[]{i, j};
testmove = new HexPly(Player.PLAYER1, i, j); testmove = new HexPly(Player.PLAYER1, i, j);
if (!taken.contains(t) && position.isLegal(testmove)) { if(!taken.contains(t) && position.isLegal(testmove)){
//System.out.println(" MAX test move : "+Integer.toString(i)+","+Integer.toString(j)); //System.out.println(" MAX test move : "+Integer.toString(i)+","+Integer.toString(j));
taken.add(t); taken.add(t);
position.doPly(testmove); position.doPly(testmove);
float val = explMINAB(position, depth + 1, bestcase, B); float val = explMINAB(position, depth+1, bestcase, B);
if (val >= bestcase) { if (val >= bestcase) {
//System.out.println(" MAX new best case"); //System.out.println(" MAX new best case");
bestcase = val; bestcase = val;
bestcasemove = testmove; bestcasemove = testmove;
if (depth == 0) { if (depth==0) {
this.bestoutcome = bestcase; this.bestoutcome = bestcase;
this.bestmove = bestcasemove; this.bestmove = bestcasemove;
} }
if (bestcase >= B) { if(bestcase>=B){
return bestcase; return bestcase;
} }
}
position.undoPly();
taken.remove(t);
}
} }
position.undoPly();
taken.remove(t);
}
} }
} return bestcase;
return bestcase;
} }
} }
private float explMINAB(HexBoard position, int depth, float A, float B){
if (position.getResult()==Result.LOSS) {
return -1.0f;
} else if (position.getResult()==Result.WIN){
return 1.0f;
} else if (depth==MAXDEPTH) {
return MonteCarlo(position, Player.PLAYER2);
} else {
float bestcase = B;
HexPly bestcasemove;
HexPly testmove;
for (int i=0; i<position.getSize(); i++) {
for (int j=0; j<position.getSize(); j++) {
if(depth==0){
//System.out.println("MIN New Line :");
}
Integer[] t = new Integer[]{i, j};
testmove = new HexPly(Player.PLAYER2, i, j);
if(!taken.contains(t) && position.isLegal(testmove)){
//System.out.println(" MIN test move : "+Integer.toString(i)+","+Integer.toString(j));
taken.add(t);
position.doPly(testmove);
float val = explMAXAB(position, depth+1, A, bestcase);
if (val <= bestcase) {
//System.out.println(" MIN new best case");
bestcase = val;
bestcasemove = testmove;
if (depth==0) {
this.bestoutcome = bestcase;
this.bestmove = bestcasemove;
}
if(bestcase<=A){
return bestcase;
}
}
position.undoPly();
private float explMINAB(HexBoard position, int depth, float A, float B){ taken.remove(t);
if (position.getResult() == Result.LOSS) { }
return -1.0f;
} else if (position.getResult() == Result.WIN) {
return 1.0f;
} else if (depth == MAXDEPTH) {
return MonteCarlo(position);
} else {
float bestcase = B;
HexPly bestcasemove;
HexPly testmove;
for (int i = 0; i < position.getSize(); i++) {
for (int j = 0; j < position.getSize(); j++) {
if (depth == 0) {
//System.out.println("MIN New Line :");
}
Integer[] t = new Integer[]{i, j};
testmove = new HexPly(Player.PLAYER2, i, j);
if (!taken.contains(t) && position.isLegal(testmove)) {
//System.out.println(" MIN test move : "+Integer.toString(i)+","+Integer.toString(j));
taken.add(t);
position.doPly(testmove);
float val = explMAXAB(position, depth + 1, A, bestcase);
if (val <= bestcase) {
//System.out.println(" MIN new best case");
bestcase = val;
bestcasemove = testmove;
if (depth == 0) {
this.bestoutcome = bestcase;
this.bestmove = bestcasemove;
} }
if (bestcase <= A) {
return bestcase;
}
}
position.undoPly();
taken.remove(t);
} }
} return bestcase;
} }
return bestcase;
} }
}