Compare commits
5 Commits
05871232bd
...
legitbugfi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fe13b946b1 | ||
|
|
c278b18872 | ||
|
|
e0a2c2642a | ||
|
|
c9e559fe12 | ||
|
|
98c6b4678e |
BIN
build/fr/iut_fbleau/HexGame/HeuristicBot.class
Normal file
BIN
build/fr/iut_fbleau/HexGame/HeuristicBot.class
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build/fr/iut_fbleau/HexGame/MiniMaxBot.class
Normal file
BIN
build/fr/iut_fbleau/HexGame/MiniMaxBot.class
Normal file
Binary file not shown.
BIN
build/fr/iut_fbleau/HexGame/MonteCarloBot.class
Normal file
BIN
build/fr/iut_fbleau/HexGame/MonteCarloBot.class
Normal file
Binary file not shown.
Binary file not shown.
BIN
build/fr/iut_fbleau/HexGame/Simulation.class
Normal file
BIN
build/fr/iut_fbleau/HexGame/Simulation.class
Normal file
Binary file not shown.
1
javaAPI/.~lock.arena_results.csv#
Normal file
1
javaAPI/.~lock.arena_results.csv#
Normal file
@@ -0,0 +1 @@
|
||||
,vaisse,salle235-12,06.02.2026 11:29,file:///export/home/an23/vaisse/.config/libreoffice/4;
|
||||
7
javaAPI/arena_results.csv
Normal file
7
javaAPI/arena_results.csv
Normal file
@@ -0,0 +1,7 @@
|
||||
Bot 1, Bot 2, Winner
|
||||
RandomBot,MiniMaxBot,WIN
|
||||
RandomBot,HeuristicBot,WIN
|
||||
RandomBot,MonteCarloBot,WIN
|
||||
MiniMaxBot,HeuristicBot,WIN
|
||||
MiniMaxBot,MonteCarloBot,WIN
|
||||
HeuristicBot,MonteCarloBot,WIN
|
||||
|
@@ -26,5 +26,6 @@ public abstract class AbstractGamePlayer {
|
||||
* @throws IllegalStateException if the Situation is already in the bookmarks
|
||||
*/
|
||||
public abstract AbstractPly giveYourMove(IBoard p);
|
||||
public abstract Boolean jesuisMinimax();
|
||||
|
||||
}
|
||||
|
||||
@@ -12,11 +12,13 @@ public class Arena {
|
||||
|
||||
private List<AbstractGamePlayer> bots = new ArrayList<>();
|
||||
private FileWriter csvWriter;
|
||||
private int board_size;
|
||||
|
||||
public Arena() {
|
||||
public Arena(int size) {
|
||||
try {
|
||||
csvWriter = new FileWriter("arena_results.csv");
|
||||
csvWriter.append("Bot 1, Bot 2, Winner\n");
|
||||
this.board_size = size;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -51,12 +53,12 @@ public class Arena {
|
||||
}
|
||||
|
||||
private Result playMatch(AbstractGamePlayer bot1, AbstractGamePlayer bot2) {
|
||||
IBoard board = new HexBoard(11);
|
||||
IBoard board = new HexBoard(this.board_size);
|
||||
EnumMap<Player, AbstractGamePlayer> players = new EnumMap<>(Player.class);
|
||||
players.put(Player.PLAYER1, bot1);
|
||||
players.put(Player.PLAYER2, bot2);
|
||||
|
||||
Simulation simulation = new Simulation(board, players);
|
||||
return simulation.run();
|
||||
return simulation.runForArena();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,12 @@ import fr.iut_fbleau.GameAPI.Player;
|
||||
|
||||
public class ArenaMain {
|
||||
public static void main(String[] args) {
|
||||
Arena arena = new Arena();
|
||||
arena.addBot(new RandomBot(Player.PLAYER1, 12345L)); // Correct constructor usage
|
||||
int size = 7;
|
||||
if (args.length >= 1) {
|
||||
try { size = Integer.parseInt(args[0]); } catch (NumberFormatException ignored) {}
|
||||
}
|
||||
Arena arena = new Arena(size);
|
||||
arena.addBot(new RandomBot(Player.PLAYER1, 24015L)); // Correct constructor usage
|
||||
arena.addBot(new MiniMaxBot(Player.PLAYER2));
|
||||
arena.addBot(new HeuristicBot(Player.PLAYER1));
|
||||
arena.addBot(new MonteCarloBot(Player.PLAYER2)); // Correct constructor usage
|
||||
|
||||
@@ -8,6 +8,10 @@ public class HeuristicBot extends AbstractGamePlayer {
|
||||
super(me); // Correct constructor usage
|
||||
}
|
||||
|
||||
public Boolean jesuisMinimax(){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractPly giveYourMove(IBoard board) {
|
||||
HexBoard hb = (HexBoard) board;
|
||||
@@ -35,10 +39,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));
|
||||
|
||||
|
||||
if (args.length>=2 && args[1].equals("autoplay")) {
|
||||
Simulation sim = new Simulation(board, players);
|
||||
res = sim.run();
|
||||
} else {
|
||||
AbstractGame game = new AbstractGame(board, players) {};
|
||||
Result res = game.run();
|
||||
res = game.run();
|
||||
}
|
||||
|
||||
System.out.println(board);
|
||||
System.out.println("Résultat (du point de vue de PLAYER1) : " + res);
|
||||
|
||||
@@ -18,6 +18,10 @@ public class HumanConsolePlayer extends AbstractGamePlayer {
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
public Boolean jesuisMinimax(){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractPly giveYourMove(IBoard board) {
|
||||
if (!(board instanceof HexBoard)) {
|
||||
|
||||
@@ -10,6 +10,10 @@ public class MiniMaxBot extends AbstractGamePlayer {
|
||||
super(me); // Correct constructor usage
|
||||
}
|
||||
|
||||
public Boolean jesuisMinimax(){
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractPly giveYourMove(IBoard board) {
|
||||
HexBoard hb = (HexBoard) board;
|
||||
@@ -79,7 +83,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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,10 @@ public class MonteCarloBot extends AbstractGamePlayer {
|
||||
super(me); // Correct constructor usage
|
||||
}
|
||||
|
||||
public Boolean jesuisMinimax(){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractPly giveYourMove(IBoard board) {
|
||||
HexBoard hb = (HexBoard) board;
|
||||
@@ -37,7 +41,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 +55,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;
|
||||
|
||||
@@ -19,6 +19,10 @@ public class RandomBot extends AbstractGamePlayer {
|
||||
this.rng = rng;
|
||||
}
|
||||
|
||||
public Boolean jesuisMinimax(){
|
||||
return false;
|
||||
}
|
||||
|
||||
public RandomBot(Player me, long seed) {
|
||||
this(me, new Random(seed));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -150,7 +152,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 = A;
|
||||
HexPly bestcasemove;
|
||||
@@ -187,15 +189,13 @@ public class Simulation extends AbstractGame {
|
||||
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);
|
||||
return MonteCarlo(position, Player.PLAYER2);
|
||||
} else {
|
||||
float bestcase = B;
|
||||
HexPly bestcasemove;
|
||||
@@ -235,8 +235,6 @@ private float explMINAB(HexBoard position, int depth, float A, float B){
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private AbstractPly GiveBestMove(IBoard board) {
|
||||
if (!(board instanceof HexBoard)) {
|
||||
throw new IllegalArgumentException("Ce joueur attend un HexBoard.");
|
||||
@@ -269,5 +267,27 @@ private float explMINAB(HexBoard position, int depth, float A, float B){
|
||||
return simCurrentBoard.getResult();
|
||||
}
|
||||
|
||||
public Result runForArena(){
|
||||
while(!simCurrentBoard.isGameOver()){
|
||||
AbstractGamePlayer player = simmapPlayers.get(simCurrentBoard.getCurrentPlayer());
|
||||
IBoard board = simCurrentBoard.safeCopy();
|
||||
AbstractPly ply;
|
||||
if(player.jesuisMinimax()){
|
||||
ply = GiveBestMove(board);
|
||||
} else {
|
||||
ply = player.giveYourMove(board);
|
||||
}
|
||||
HexPly concretePly = (HexPly) ply;
|
||||
|
||||
if (simCurrentBoard.isLegal(ply)) {
|
||||
simCurrentBoard.doPly(ply);
|
||||
taken.add(new Integer[]{concretePly.getRow(), concretePly.getCol()});
|
||||
System.out.println("Player "+player+" goes ("+concretePly.getRow()+","+concretePly.getCol()+")");
|
||||
}
|
||||
else throw new IllegalStateException("Player "+ player + " is a bloody cheat. He tried playing : "+concretePly.getRow()+","+concretePly.getCol()+" I give up.");
|
||||
}
|
||||
return simCurrentBoard.getResult();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user