Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e0a2c2642a | |||
| c9e559fe12 | |||
| 98c6b4678e |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -35,10 +35,11 @@ public class HeuristicBot extends AbstractGamePlayer {
|
||||
int size = board.getSize();
|
||||
int center = size / 2;
|
||||
float score = 0;
|
||||
//HexBoard simBoard = (HexBoard) board.safeCopy();
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package fr.iut_fbleau.HexGame;
|
||||
|
||||
import fr.iut_fbleau.GameAPI.*;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.Scanner;
|
||||
|
||||
@@ -11,7 +10,7 @@ import java.util.Scanner;
|
||||
public class HexMain {
|
||||
|
||||
public static void main(String[] args) {
|
||||
int size = 11;
|
||||
int size = 7;
|
||||
if (args.length >= 1) {
|
||||
try { size = Integer.parseInt(args[0]); } catch (NumberFormatException ignored) {}
|
||||
}
|
||||
@@ -19,12 +18,19 @@ public class HexMain {
|
||||
HexBoard board = new HexBoard(size);
|
||||
|
||||
Scanner sc = new Scanner(System.in);
|
||||
Result res;
|
||||
EnumMap<Player, AbstractGamePlayer> players = new EnumMap<>(Player.class);
|
||||
players.put(Player.PLAYER1, new HumanConsolePlayer(Player.PLAYER1, sc));
|
||||
players.put(Player.PLAYER2, new HumanConsolePlayer(Player.PLAYER2, sc));
|
||||
|
||||
AbstractGame game = new AbstractGame(board, players) {};
|
||||
Result res = game.run();
|
||||
|
||||
if (args.length>=2 && args[1].equals("autoplay")) {
|
||||
Simulation sim = new Simulation(board, players);
|
||||
res = sim.run();
|
||||
} else {
|
||||
AbstractGame game = new AbstractGame(board, players) {};
|
||||
res = game.run();
|
||||
}
|
||||
|
||||
System.out.println(board);
|
||||
System.out.println("Résultat (du point de vue de PLAYER1) : " + res);
|
||||
|
||||
@@ -79,7 +79,7 @@ public class MiniMaxBot extends AbstractGamePlayer {
|
||||
int score = 0;
|
||||
for (int i = 0; i < size; i++) {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public class MonteCarloBot extends AbstractGamePlayer {
|
||||
|
||||
private float monteCarloSimulation(HexBoard board) {
|
||||
RandomBot simBot = new RandomBot(Player.PLAYER1, new Random().nextLong());
|
||||
HexBoard simBoard = board.safeCopy();
|
||||
HexBoard simBoard = (HexBoard) board.safeCopy();
|
||||
int wins = 0;
|
||||
int simulations = 0;
|
||||
|
||||
@@ -51,7 +51,7 @@ public class MonteCarloBot extends AbstractGamePlayer {
|
||||
wins++;
|
||||
}
|
||||
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;
|
||||
|
||||
@@ -3,6 +3,7 @@ package fr.iut_fbleau.HexGame;
|
||||
import fr.iut_fbleau.GameAPI.*;
|
||||
import java.util.EnumMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Random;
|
||||
|
||||
|
||||
public class Simulation extends AbstractGame {
|
||||
@@ -27,18 +28,19 @@ public class Simulation extends AbstractGame {
|
||||
|
||||
//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();
|
||||
private float MonteCarlo(HexBoard position, Player current){
|
||||
RandomBot simplay = new RandomBot(current, new Random().nextLong());
|
||||
HexBoard simpos = position;
|
||||
LinkedList<Integer[]> ctaken = taken;
|
||||
HexPly testmove;
|
||||
float wins = 0;
|
||||
float losses = 0;
|
||||
|
||||
int count = 0;
|
||||
for(int i=0; i<EVALDEPTH; i++){
|
||||
while(!simpos.isGameOver()){
|
||||
count++;
|
||||
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()});
|
||||
simpos.doPly(testmove);
|
||||
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;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
if(wins>=losses){
|
||||
return losses/wins;
|
||||
} else {
|
||||
return -(wins/losses);
|
||||
}
|
||||
|
||||
System.out.println(" wins : "+wins+"/losses : "+losses);
|
||||
System.out.println(" eval : "+(wins-losses)/EVALDEPTH);
|
||||
return (wins-losses)/EVALDEPTH;
|
||||
}
|
||||
|
||||
private float explMAX(HexBoard position, int depth){
|
||||
@@ -66,7 +68,7 @@ public class Simulation extends AbstractGame {
|
||||
} else if (position.getResult()==Result.WIN){
|
||||
return 1.0f;
|
||||
} else if (depth==MAXDEPTH) {
|
||||
return MonteCarlo(position);
|
||||
return MonteCarlo(position, Player.PLAYER1);
|
||||
} else {
|
||||
float bestcase = -1.0f;
|
||||
HexPly bestcasemove;
|
||||
@@ -108,7 +110,7 @@ public class Simulation extends AbstractGame {
|
||||
} else if (position.getResult()==Result.WIN){
|
||||
return 1.0f;
|
||||
} else if (depth==MAXDEPTH) {
|
||||
return MonteCarlo(position);
|
||||
return MonteCarlo(position, Player.PLAYER2);
|
||||
} else {
|
||||
float bestcase = 1.0f;
|
||||
HexPly bestcasemove;
|
||||
@@ -145,94 +147,92 @@ public class Simulation extends AbstractGame {
|
||||
}
|
||||
|
||||
private float explMAXAB(HexBoard position, int depth, float A, float B){
|
||||
if (position.getResult() == Result.LOSS) {
|
||||
if (position.getResult()==Result.LOSS) {
|
||||
return -1.0f;
|
||||
} else if (position.getResult() == Result.WIN) {
|
||||
} else if (position.getResult()==Result.WIN){
|
||||
return 1.0f;
|
||||
} else if (depth == MAXDEPTH) {
|
||||
return MonteCarlo(position);
|
||||
} else if (depth==MAXDEPTH) {
|
||||
return MonteCarlo(position, Player.PLAYER1);
|
||||
} 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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
} 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;
|
||||
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();
|
||||
taken.remove(t);
|
||||
}
|
||||
}
|
||||
if (bestcase <= A) {
|
||||
return bestcase;
|
||||
}
|
||||
}
|
||||
|
||||
position.undoPly();
|
||||
taken.remove(t);
|
||||
}
|
||||
}
|
||||
return bestcase;
|
||||
}
|
||||
return bestcase;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user