j'ai écrit des trucs, mais il faut encore tester. Faites pas de merge pour l'instant #16
@@ -10,7 +10,8 @@ public class Simulation extends AbstractGame {
|
|||||||
//ATTRIBUTS
|
//ATTRIBUTS
|
||||||
private HexPly bestmove;
|
private HexPly bestmove;
|
||||||
private float bestoutcome;
|
private float bestoutcome;
|
||||||
private int MAXDEPTH = 6;
|
private int MAXDEPTH = 9;
|
||||||
|
private int EVALDEPTH = 10;
|
||||||
private LinkedList<Integer[]> taken = new LinkedList<Integer[]>();
|
private LinkedList<Integer[]> taken = new LinkedList<Integer[]>();
|
||||||
|
|
||||||
//ATTRIBUTS QUE JE NE VOUDRAIS PAS CRÉER IDÉALEMENT
|
//ATTRIBUTS QUE JE NE VOUDRAIS PAS CRÉER IDÉALEMENT
|
||||||
@@ -25,13 +26,47 @@ 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*/
|
||||||
|
private float MonteCarlo(HexBoard position){
|
||||||
|
RandomBot simplay = new RandomBot();
|
||||||
|
HexBoard simpos = position.safeCopy();
|
||||||
|
LinkedList<Integer[]> ctaken = taken;
|
||||||
|
HexPly testmove;
|
||||||
|
float wins = 0;
|
||||||
|
float losses = 0;
|
||||||
|
|
||||||
|
for(int i=0; i<EVALDEPTH; i++){
|
||||||
|
while(!simpos.isGameOver()){
|
||||||
|
testmove = (HexPly) simplay.giveYourMove(simpos);
|
||||||
|
if(!ctaken.contains(t) && simpos.isLegal(testmove)){
|
||||||
|
ctaken.add(new Integer[]{testmove.getRow(), testmove.getCol()});
|
||||||
|
simpos.doPly(testmove);
|
||||||
|
if(simpos.getResult()==Result.LOSS){
|
||||||
|
losses++;
|
||||||
|
} else if(simpos.getResult()==Result.WIN){
|
||||||
|
wins++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
simpos = position.safeCopy();
|
||||||
|
ctaken = taken;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(wins>=losses){
|
||||||
|
return losses/wins;
|
||||||
|
} else {
|
||||||
|
return -(wins/losses);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private float explMAX(HexBoard position, int depth){
|
private float explMAX(HexBoard position, int depth){
|
||||||
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 0f;
|
return MonteCarlo(position);
|
||||||
} else {
|
} else {
|
||||||
float bestcase = -1.0f;
|
float bestcase = -1.0f;
|
||||||
HexPly bestcasemove;
|
HexPly bestcasemove;
|
||||||
@@ -73,7 +108,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 0f;
|
return MonteCarlo(position);
|
||||||
} else {
|
} else {
|
||||||
float bestcase = 1.0f;
|
float bestcase = 1.0f;
|
||||||
HexPly bestcasemove;
|
HexPly bestcasemove;
|
||||||
@@ -109,6 +144,97 @@ public class Simulation extends AbstractGame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private float explMAXAB(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);
|
||||||
|
} else {
|
||||||
|
float bestcase = A;
|
||||||
|
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("MAX New Line :");
|
||||||
|
}
|
||||||
|
Integer[] t = new Integer[]{i, j};
|
||||||
|
testmove = new HexPly(Player.PLAYER1, i, j);
|
||||||
|
if(!taken.contains(t) && position.isLegal(testmove)){
|
||||||
|
//System.out.println(" MAX test move : "+Integer.toString(i)+","+Integer.toString(j));
|
||||||
|
taken.add(t);
|
||||||
|
position.doPly(testmove);
|
||||||
|
float val = explMINAB(position, depth+1, bestcase, B);
|
||||||
|
if (val >= bestcase) {
|
||||||
|
//System.out.println(" MAX new best case");
|
||||||
|
bestcase = val;
|
||||||
|
bestcasemove = testmove;
|
||||||
|
if (depth==0) {
|
||||||
|
this.bestoutcome = bestcase;
|
||||||
|
this.bestmove = bestcasemove;
|
||||||
|
}
|
||||||
|
if(bestcase>=B){
|
||||||
|
return bestcase;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
position.undoPly();
|
||||||
|
taken.remove(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bestcase;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private float explMINAB(HexBoard position, int depth, A, 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);
|
||||||
|
} 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private AbstractPly GiveBestMove(IBoard board) {
|
private AbstractPly GiveBestMove(IBoard board) {
|
||||||
if (!(board instanceof HexBoard)) {
|
if (!(board instanceof HexBoard)) {
|
||||||
throw new IllegalArgumentException("Ce joueur attend un HexBoard.");
|
throw new IllegalArgumentException("Ce joueur attend un HexBoard.");
|
||||||
@@ -116,9 +242,9 @@ public class Simulation extends AbstractGame {
|
|||||||
HexBoard hb = (HexBoard) board;
|
HexBoard hb = (HexBoard) board;
|
||||||
float bestcase;
|
float bestcase;
|
||||||
if(hb.getCurrentPlayer()==Player.PLAYER1){
|
if(hb.getCurrentPlayer()==Player.PLAYER1){
|
||||||
bestcase = explMAX(hb, 0);
|
bestcase = explMAXAB(hb, 0, -1.0f, 1.0f);
|
||||||
} else {
|
} else {
|
||||||
bestcase = explMIN(hb, 0);
|
bestcase = explMINAB(hb, 0, -1.0f, 1.0f);
|
||||||
}
|
}
|
||||||
return this.bestmove;
|
return this.bestmove;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user