heuristic-arena-abminmax #17
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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,37 +147,37 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,40 +189,38 @@ public class Simulation extends AbstractGame {
|
|||||||
return bestcase;
|
return bestcase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private float explMINAB(HexBoard position, int depth, float A, float B){
|
||||||
|
if (position.getResult()==Result.LOSS) {
|
||||||
private float explMINAB(HexBoard position, int depth, float A, float B){
|
|
||||||
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.PLAYER2);
|
||||||
} else {
|
} else {
|
||||||
float bestcase = B;
|
float bestcase = B;
|
||||||
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("MIN New Line :");
|
//System.out.println("MIN New Line :");
|
||||||
}
|
}
|
||||||
Integer[] t = new Integer[]{i, j};
|
Integer[] t = new Integer[]{i, j};
|
||||||
testmove = new HexPly(Player.PLAYER2, i, j);
|
testmove = new HexPly(Player.PLAYER2, i, j);
|
||||||
if (!taken.contains(t) && position.isLegal(testmove)) {
|
if(!taken.contains(t) && position.isLegal(testmove)){
|
||||||
//System.out.println(" MIN test move : "+Integer.toString(i)+","+Integer.toString(j));
|
//System.out.println(" MIN test move : "+Integer.toString(i)+","+Integer.toString(j));
|
||||||
taken.add(t);
|
taken.add(t);
|
||||||
position.doPly(testmove);
|
position.doPly(testmove);
|
||||||
float val = explMAXAB(position, depth + 1, A, bestcase);
|
float val = explMAXAB(position, depth+1, A, bestcase);
|
||||||
if (val <= bestcase) {
|
if (val <= bestcase) {
|
||||||
//System.out.println(" MIN new best case");
|
//System.out.println(" MIN 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 <= A) {
|
if(bestcase<=A){
|
||||||
return bestcase;
|
return bestcase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -232,7 +232,7 @@ private float explMINAB(HexBoard position, int depth, float A, float B){
|
|||||||
}
|
}
|
||||||
return bestcase;
|
return bestcase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user