bot alpha-beta + correctif + debut bot divin
This commit is contained in:
@@ -280,12 +280,23 @@ public class AvalamBoard extends AbstractBoard {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public IBoard safeCopy() {
|
public IBoard safeCopy() {
|
||||||
|
|
||||||
Tower[][] newGrid = new Tower[SIZE][SIZE];
|
Tower[][] newGrid = new Tower[SIZE][SIZE];
|
||||||
|
|
||||||
for (int r = 0; r < SIZE; r++)
|
for (int r = 0; r < SIZE; r++) {
|
||||||
for (int c = 0; c < SIZE; c++)
|
for (int c = 0; c < SIZE; c++) {
|
||||||
newGrid[r][c] = grid[r][c];
|
|
||||||
|
|
||||||
return new AvalamBoard(newGrid, getCurrentPlayer(), gameOver, result);
|
Tower t = grid[r][c];
|
||||||
|
if (t == null) {
|
||||||
|
newGrid[r][c] = null;
|
||||||
|
} else {
|
||||||
|
// Copie profonde : on recrée une nouvelle Tower indépendante
|
||||||
|
newGrid[r][c] = new Tower(t.getHeight(), t.getColor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// On conserve le joueur courant
|
||||||
|
return new AvalamBoard(newGrid, getCurrentPlayer());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
package fr.iut_fbleau.Avalam;
|
package fr.iut_fbleau.Avalam;
|
||||||
|
|
||||||
|
import fr.iut_fbleau.Bot.AlphaBetaBot;
|
||||||
|
// A FAIRE PLUS TARD (PVGOD)
|
||||||
|
// import fr.iut_fbleau.Bot.DivineBot;
|
||||||
import fr.iut_fbleau.Bot.IdiotBot;
|
import fr.iut_fbleau.Bot.IdiotBot;
|
||||||
import fr.iut_fbleau.GameAPI.AbstractPly;
|
import fr.iut_fbleau.GameAPI.AbstractPly;
|
||||||
import fr.iut_fbleau.GameAPI.Player;
|
import fr.iut_fbleau.GameAPI.Player;
|
||||||
@@ -9,24 +12,25 @@ import javax.swing.*;
|
|||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* La classe <code>AvalamWindow</code>
|
* La classe <code>AvalamWindow</code>
|
||||||
*
|
*
|
||||||
* Fenêtre principale (interface graphique) du jeu Avalam.
|
* Fenêtre principale (interface graphique) du jeu Avalam.
|
||||||
* Elle contient :
|
* Elle contient :
|
||||||
* - le plateau (BoardView)
|
* - le plateau (BoardView)
|
||||||
* - l’affichage du score (ScoreView)
|
* - l’affichage du score (ScoreView)
|
||||||
* - l’affichage du joueur courant (TurnView)
|
* - l’affichage du joueur courant (TurnView)
|
||||||
*
|
*
|
||||||
* Elle pilote un objet <code>AvalamBoard</code> (moteur du jeu).
|
* Elle pilote un objet <code>AvalamBoard</code> (moteur du jeu).
|
||||||
* Elle peut fonctionner en mode :
|
* Elle peut fonctionner en mode :
|
||||||
* - joueur vs joueur
|
* - joueur vs joueur
|
||||||
* - joueur vs bot idiot (aléatoire)
|
* - joueur vs bot idiot (aléatoire)
|
||||||
* - joueur vs bot alpha (préparé)
|
* - joueur vs bot alpha (cut-off)
|
||||||
*
|
* - joueur vs bot divin (PVGOD)
|
||||||
* @version 1.0
|
*
|
||||||
* Date :
|
* @version 1.0
|
||||||
* Licence :
|
* Date :
|
||||||
*/
|
* Licence :
|
||||||
|
*/
|
||||||
public class AvalamWindow extends JFrame {
|
public class AvalamWindow extends JFrame {
|
||||||
|
|
||||||
//Attributs
|
//Attributs
|
||||||
@@ -52,6 +56,20 @@ public class AvalamWindow extends JFrame {
|
|||||||
/** Bot idiot (utilisé si mode PVBOT). */
|
/** Bot idiot (utilisé si mode PVBOT). */
|
||||||
private final IdiotBot idiotBot;
|
private final IdiotBot idiotBot;
|
||||||
|
|
||||||
|
/** Bot Alpha-Beta (utilisé si mode PVALPHA). */
|
||||||
|
private final AlphaBetaBot alphaBot;
|
||||||
|
|
||||||
|
// A FAIRE PLUS TARD (PVGOD)
|
||||||
|
// /** Bot Divin (utilisé si mode PVGOD). */
|
||||||
|
// private final DivineBot divineBot;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A FAIRE PLUS TARD (PVGOD)
|
||||||
|
* On garde l'attribut à null pour ne pas casser la compilation,
|
||||||
|
* mais toute la logique PVGOD est désactivée/commentée.
|
||||||
|
*/
|
||||||
|
private final Object divineBot = null;
|
||||||
|
|
||||||
/** Indique si une animation de tour de bot est en cours. */
|
/** Indique si une animation de tour de bot est en cours. */
|
||||||
private boolean botAnimating = false;
|
private boolean botAnimating = false;
|
||||||
|
|
||||||
@@ -61,20 +79,39 @@ public class AvalamWindow extends JFrame {
|
|||||||
* Construit la fenêtre en mode joueur vs joueur.
|
* Construit la fenêtre en mode joueur vs joueur.
|
||||||
*/
|
*/
|
||||||
public AvalamWindow() {
|
public AvalamWindow() {
|
||||||
this(GameMode.PVP);
|
this(GameMode.PVP, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construit la fenêtre en fonction du mode choisi.
|
* Construit la fenêtre en fonction du mode choisi.
|
||||||
|
* Pour PVALPHA/PVGOD, la profondeur par défaut est 4.
|
||||||
*
|
*
|
||||||
* @param mode mode de jeu
|
* @param mode mode de jeu
|
||||||
*/
|
*/
|
||||||
public AvalamWindow(GameMode mode) {
|
public AvalamWindow(GameMode mode) {
|
||||||
|
this(mode, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construit la fenêtre en fonction du mode choisi.
|
||||||
|
* Si le mode est PVALPHA ou PVGOD, la profondeur est utilisée comme cut-off.
|
||||||
|
*
|
||||||
|
* @param mode mode de jeu
|
||||||
|
* @param alphaDepth profondeur de recherche pour Alpha-Beta / Bot Divin
|
||||||
|
*/
|
||||||
|
public AvalamWindow(GameMode mode, int alphaDepth) {
|
||||||
super("Avalam");
|
super("Avalam");
|
||||||
|
|
||||||
this.mode = mode;
|
this.mode = mode;
|
||||||
|
|
||||||
this.idiotBot = (mode == GameMode.PVBOT) ? new IdiotBot(botPlayer) : null;
|
this.idiotBot = (mode == GameMode.PVBOT) ? new IdiotBot(botPlayer) : null;
|
||||||
|
|
||||||
|
int depth = Math.max(1, alphaDepth);
|
||||||
|
this.alphaBot = (mode == GameMode.PVALPHA) ? new AlphaBetaBot(botPlayer, depth) : null;
|
||||||
|
|
||||||
|
// A FAIRE PLUS TARD (PVGOD)
|
||||||
|
// this.divineBot = (mode == GameMode.PVGOD) ? new DivineBot(botPlayer, depth) : null;
|
||||||
|
|
||||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
setLayout(new BorderLayout());
|
setLayout(new BorderLayout());
|
||||||
|
|
||||||
@@ -109,7 +146,7 @@ public class AvalamWindow extends JFrame {
|
|||||||
setLocationRelativeTo(null);
|
setLocationRelativeTo(null);
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
|
|
||||||
// Si un jour le bot doit commencer, on peut déclencher ici.
|
// Si un jour le bot devait commencer (pas le cas ici), on le ferait jouer ici.
|
||||||
maybePlayBotTurn();
|
maybePlayBotTurn();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,7 +198,7 @@ public class AvalamWindow extends JFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fait jouer le bot en deux étapes visibles :
|
* Fait jouer le bot (idiot / alpha / divin) en deux étapes visibles :
|
||||||
* 1) sélection de la tour (affiche les coups légaux)
|
* 1) sélection de la tour (affiche les coups légaux)
|
||||||
* 2) attente 1 seconde
|
* 2) attente 1 seconde
|
||||||
* 3) déplacement vers la destination
|
* 3) déplacement vers la destination
|
||||||
@@ -170,18 +207,42 @@ public class AvalamWindow extends JFrame {
|
|||||||
*/
|
*/
|
||||||
private void maybePlayBotTurn() {
|
private void maybePlayBotTurn() {
|
||||||
|
|
||||||
if (mode != GameMode.PVBOT) return;
|
// Mode joueur vs joueur : aucun bot
|
||||||
|
if (mode == GameMode.PVP) return;
|
||||||
|
|
||||||
|
// Sécurité
|
||||||
if (board.isGameOver()) return;
|
if (board.isGameOver()) return;
|
||||||
if (board.getCurrentPlayer() != botPlayer) return;
|
if (board.getCurrentPlayer() != botPlayer) return;
|
||||||
if (botAnimating) return;
|
if (botAnimating) return;
|
||||||
|
|
||||||
|
// Vérifier qu'on a bien le bot correspondant
|
||||||
|
if (mode == GameMode.PVBOT && idiotBot == null) return;
|
||||||
|
if (mode == GameMode.PVALPHA && alphaBot == null) return;
|
||||||
|
|
||||||
|
// A FAIRE PLUS TARD (PVGOD)
|
||||||
|
// if (mode == GameMode.PVGOD && divineBot == null) return;
|
||||||
|
|
||||||
|
// A FAIRE PLUS TARD (PVGOD)
|
||||||
|
// Pour l'instant, si PVGOD est sélectionné, on ne joue pas de coup bot.
|
||||||
|
if (mode == GameMode.PVGOD) return;
|
||||||
|
|
||||||
botAnimating = true;
|
botAnimating = true;
|
||||||
|
|
||||||
// Désactiver les interactions du joueur pendant le tour du bot.
|
// Désactiver les interactions du joueur pendant le tour du bot.
|
||||||
boardView.setInteractionEnabled(false);
|
boardView.setInteractionEnabled(false);
|
||||||
|
|
||||||
// Choix d’un coup sur une copie sûre
|
// Choix d’un coup sur une copie sûre
|
||||||
AbstractPly botMove = idiotBot.giveYourMove(board.safeCopy());
|
AbstractPly botMove;
|
||||||
|
if (mode == GameMode.PVBOT) {
|
||||||
|
botMove = idiotBot.giveYourMove(board.safeCopy());
|
||||||
|
} else if (mode == GameMode.PVALPHA) {
|
||||||
|
botMove = alphaBot.giveYourMove(board.safeCopy());
|
||||||
|
} else {
|
||||||
|
// A FAIRE PLUS TARD (PVGOD)
|
||||||
|
// botMove = divineBot.giveYourMove(board.safeCopy());
|
||||||
|
botMove = null;
|
||||||
|
}
|
||||||
|
|
||||||
if (botMove == null) {
|
if (botMove == null) {
|
||||||
botAnimating = false;
|
botAnimating = false;
|
||||||
boardView.setInteractionEnabled(true);
|
boardView.setInteractionEnabled(true);
|
||||||
|
|||||||
@@ -6,5 +6,6 @@ package fr.iut_fbleau.Avalam;
|
|||||||
public enum GameMode {
|
public enum GameMode {
|
||||||
PVP, // joueur vs joueur
|
PVP, // joueur vs joueur
|
||||||
PVBOT, // joueur vs bot idiot
|
PVBOT, // joueur vs bot idiot
|
||||||
PVALPHA // joueur vs bot alpha (préparé)
|
PVALPHA, // joueur vs bot alpha
|
||||||
|
PVGOD // joueur vs bot stratégique
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ public class Main {
|
|||||||
String[] options = {
|
String[] options = {
|
||||||
"joueur vs joueur",
|
"joueur vs joueur",
|
||||||
"joueur vs botidiot",
|
"joueur vs botidiot",
|
||||||
"joueur vs bot alpha"
|
"joueur vs bot alpha",
|
||||||
|
"joueur vs bot divin (NON IMPLEMENTE)"
|
||||||
};
|
};
|
||||||
|
|
||||||
int choice = JOptionPane.showOptionDialog(
|
int choice = JOptionPane.showOptionDialog(
|
||||||
@@ -28,20 +29,38 @@ public class Main {
|
|||||||
options[0]
|
options[0]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (choice == -1) System.exit(0);
|
||||||
|
|
||||||
GameMode mode;
|
GameMode mode;
|
||||||
if (choice == 1) mode = GameMode.PVBOT;
|
if (choice == 1) mode = GameMode.PVBOT;
|
||||||
else if (choice == 2) mode = GameMode.PVALPHA;
|
else if (choice == 2) mode = GameMode.PVALPHA;
|
||||||
|
else if (choice == 3) mode = GameMode.PVGOD;
|
||||||
else mode = GameMode.PVP;
|
else mode = GameMode.PVP;
|
||||||
|
|
||||||
// Si alpha choisi : non implémenté, on prévient et on lance en PVP (préparation).
|
// Pour ALPHA et GOD : demander une profondeur
|
||||||
if (mode == GameMode.PVALPHA) {
|
if (mode == GameMode.PVALPHA || mode == GameMode.PVGOD) {
|
||||||
JOptionPane.showMessageDialog(
|
|
||||||
|
String s = JOptionPane.showInputDialog(
|
||||||
null,
|
null,
|
||||||
"Bot Alpha-Beta non implémenté pour l'instant.\nLancement en joueur vs joueur.",
|
"Profondeur de recherche ?\n(Conseil 4)",
|
||||||
"Information",
|
(mode == GameMode.PVGOD ? "Bot Divin (PVGOD)" : "Bot Alpha-Beta"),
|
||||||
JOptionPane.INFORMATION_MESSAGE
|
JOptionPane.QUESTION_MESSAGE
|
||||||
);
|
);
|
||||||
mode = GameMode.PVP;
|
|
||||||
|
int depth = 4; // défaut
|
||||||
|
if (s != null) {
|
||||||
|
try { depth = Integer.parseInt(s.trim()); }
|
||||||
|
catch (Exception ignored) { depth = 4; }
|
||||||
|
} else {
|
||||||
|
// Annulation : on revient en PVP
|
||||||
|
new AvalamWindow(GameMode.PVP);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depth < 1) depth = 1;
|
||||||
|
|
||||||
|
new AvalamWindow(mode, depth);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
new AvalamWindow(mode);
|
new AvalamWindow(mode);
|
||||||
|
|||||||
@@ -1,22 +1,217 @@
|
|||||||
package fr.iut_fbleau.Bot;
|
package fr.iut_fbleau.Bot;
|
||||||
|
|
||||||
|
import fr.iut_fbleau.Avalam.AvalamBoard;
|
||||||
|
import fr.iut_fbleau.Avalam.Color;
|
||||||
|
import fr.iut_fbleau.Avalam.Tower;
|
||||||
import fr.iut_fbleau.GameAPI.AbstractGamePlayer;
|
import fr.iut_fbleau.GameAPI.AbstractGamePlayer;
|
||||||
import fr.iut_fbleau.GameAPI.AbstractPly;
|
import fr.iut_fbleau.GameAPI.AbstractPly;
|
||||||
import fr.iut_fbleau.GameAPI.IBoard;
|
import fr.iut_fbleau.GameAPI.IBoard;
|
||||||
import fr.iut_fbleau.GameAPI.Player;
|
import fr.iut_fbleau.GameAPI.Player;
|
||||||
|
import fr.iut_fbleau.GameAPI.Result;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bot Alpha-Beta (préparé).
|
* Bot Alpha-Beta avec cut-off (profondeur maximale).
|
||||||
* Pour l'instant non implémenté.
|
*
|
||||||
|
* Idée :
|
||||||
|
* - si on atteint la profondeur limite, on évalue la position (heuristique).
|
||||||
|
* - sinon, on explore les coups avec Alpha-Beta (minimax optimisé).
|
||||||
|
*
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public class AlphaBetaBot extends AbstractGamePlayer {
|
public class AlphaBetaBot extends AbstractGamePlayer {
|
||||||
|
|
||||||
public AlphaBetaBot(Player p) {
|
//Attributs
|
||||||
|
|
||||||
|
/** Joueur contrôlé par ce bot (PLAYER1 ou PLAYER2). */
|
||||||
|
private final Player me;
|
||||||
|
|
||||||
|
/** Profondeur maximale de recherche (cut-off). */
|
||||||
|
private final int maxDepth;
|
||||||
|
|
||||||
|
/** Générateur aléatoire pour départager des coups de même valeur. */
|
||||||
|
private final Random rng = new Random();
|
||||||
|
|
||||||
|
//Constructeur
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construit un bot Alpha-Beta.
|
||||||
|
*
|
||||||
|
* @param p joueur contrôlé par ce bot
|
||||||
|
* @param maxDepth profondeur maximale de recherche
|
||||||
|
*/
|
||||||
|
public AlphaBetaBot(Player p, int maxDepth) {
|
||||||
super(p);
|
super(p);
|
||||||
|
this.me = p;
|
||||||
|
this.maxDepth = Math.max(1, maxDepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Méthodes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Méthode appelée par GameAPI : le bot doit choisir un coup.
|
||||||
|
*
|
||||||
|
* @param board copie sûre de l'état de jeu (IBoard)
|
||||||
|
* @return un coup (AbstractPly) ou null si aucun coup possible
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public AbstractPly giveYourMove(IBoard board) {
|
public AbstractPly giveYourMove(IBoard board) {
|
||||||
throw new UnsupportedOperationException("AlphaBetaBot non implémenté pour l'instant.");
|
|
||||||
|
if (board == null || board.isGameOver()) return null;
|
||||||
|
|
||||||
|
List<AbstractPly> moves = listMoves(board);
|
||||||
|
if (moves.isEmpty()) return null;
|
||||||
|
|
||||||
|
boolean isMax = (board.getCurrentPlayer() == me);
|
||||||
|
int bestValue = isMax ? Integer.MIN_VALUE : Integer.MAX_VALUE;
|
||||||
|
|
||||||
|
List<AbstractPly> bestMoves = new ArrayList<>();
|
||||||
|
|
||||||
|
int alpha = Integer.MIN_VALUE;
|
||||||
|
int beta = Integer.MAX_VALUE;
|
||||||
|
|
||||||
|
for (AbstractPly m : moves) {
|
||||||
|
IBoard next = board.safeCopy();
|
||||||
|
next.doPly(m);
|
||||||
|
|
||||||
|
int value = alphaBeta(next, maxDepth - 1, alpha, beta);
|
||||||
|
|
||||||
|
if (isMax) {
|
||||||
|
if (value > bestValue) {
|
||||||
|
bestValue = value;
|
||||||
|
bestMoves.clear();
|
||||||
|
bestMoves.add(m);
|
||||||
|
} else if (value == bestValue) {
|
||||||
|
bestMoves.add(m);
|
||||||
}
|
}
|
||||||
|
alpha = Math.max(alpha, bestValue);
|
||||||
|
} else {
|
||||||
|
if (value < bestValue) {
|
||||||
|
bestValue = value;
|
||||||
|
bestMoves.clear();
|
||||||
|
bestMoves.add(m);
|
||||||
|
} else if (value == bestValue) {
|
||||||
|
bestMoves.add(m);
|
||||||
|
}
|
||||||
|
beta = Math.min(beta, bestValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bestMoves.get(rng.nextInt(bestMoves.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fonction récursive Alpha-Beta.
|
||||||
|
*/
|
||||||
|
private int alphaBeta(IBoard board, int depth, int alpha, int beta) {
|
||||||
|
|
||||||
|
if (board.isGameOver()) {
|
||||||
|
return terminalValue(board);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depth == 0) {
|
||||||
|
return evaluate(board);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isMax = (board.getCurrentPlayer() == me);
|
||||||
|
|
||||||
|
List<AbstractPly> moves = listMoves(board);
|
||||||
|
if (moves.isEmpty()) {
|
||||||
|
return evaluate(board);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isMax) {
|
||||||
|
int best = Integer.MIN_VALUE;
|
||||||
|
|
||||||
|
for (AbstractPly m : moves) {
|
||||||
|
IBoard next = board.safeCopy();
|
||||||
|
next.doPly(m);
|
||||||
|
|
||||||
|
int val = alphaBeta(next, depth - 1, alpha, beta);
|
||||||
|
best = Math.max(best, val);
|
||||||
|
alpha = Math.max(alpha, best);
|
||||||
|
|
||||||
|
if (alpha >= beta) break;
|
||||||
|
}
|
||||||
|
return best;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
int best = Integer.MAX_VALUE;
|
||||||
|
|
||||||
|
for (AbstractPly m : moves) {
|
||||||
|
IBoard next = board.safeCopy();
|
||||||
|
next.doPly(m);
|
||||||
|
|
||||||
|
int val = alphaBeta(next, depth - 1, alpha, beta);
|
||||||
|
best = Math.min(best, val);
|
||||||
|
beta = Math.min(beta, best);
|
||||||
|
|
||||||
|
if (alpha >= beta) break;
|
||||||
|
}
|
||||||
|
return best;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convertit le résultat final en valeur très grande (victoire/défaite).
|
||||||
|
* Result est du point de vue de PLAYER1.
|
||||||
|
*/
|
||||||
|
private int terminalValue(IBoard board) {
|
||||||
|
Result r = board.getResult();
|
||||||
|
if (r == null) return 0;
|
||||||
|
|
||||||
|
boolean botIsP1 = (me == Player.PLAYER1);
|
||||||
|
|
||||||
|
if (r == Result.DRAW) return 0;
|
||||||
|
|
||||||
|
if (botIsP1) {
|
||||||
|
return (r == Result.WIN) ? 100000 : -100000;
|
||||||
|
} else {
|
||||||
|
return (r == Result.LOSS) ? 100000 : -100000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Heuristique simple Avalam :
|
||||||
|
* score = (tours du bot) - (tours adverses)
|
||||||
|
*/
|
||||||
|
private int evaluate(IBoard board) {
|
||||||
|
|
||||||
|
if (!(board instanceof AvalamBoard)) return 0;
|
||||||
|
AvalamBoard b = (AvalamBoard) board;
|
||||||
|
|
||||||
|
Color botColor = (me == Player.PLAYER1) ? Color.YELLOW : Color.RED;
|
||||||
|
Color oppColor = (me == Player.PLAYER1) ? Color.RED : Color.YELLOW;
|
||||||
|
|
||||||
|
int botTowers = 0;
|
||||||
|
int oppTowers = 0;
|
||||||
|
|
||||||
|
for (int r = 0; r < AvalamBoard.SIZE; r++) {
|
||||||
|
for (int c = 0; c < AvalamBoard.SIZE; c++) {
|
||||||
|
Tower t = b.getTowerAt(r, c);
|
||||||
|
if (t == null) continue;
|
||||||
|
|
||||||
|
if (t.getColor() == botColor) botTowers++;
|
||||||
|
else if (t.getColor() == oppColor) oppTowers++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return botTowers - oppTowers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Récupère tous les coups légaux via iterator().
|
||||||
|
*/
|
||||||
|
private List<AbstractPly> listMoves(IBoard board) {
|
||||||
|
List<AbstractPly> moves = new ArrayList<>();
|
||||||
|
Iterator<AbstractPly> it = board.iterator();
|
||||||
|
while (it.hasNext()) moves.add(it.next());
|
||||||
|
return moves;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Affichage
|
||||||
}
|
}
|
||||||
|
|||||||
22
fr/iut_fbleau/Bot/DivineBot.java
Normal file
22
fr/iut_fbleau/Bot/DivineBot.java
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package fr.iut_fbleau.Bot;
|
||||||
|
|
||||||
|
import fr.iut_fbleau.Avalam.AvalamBoard;
|
||||||
|
import fr.iut_fbleau.Avalam.AvalamPly;
|
||||||
|
import fr.iut_fbleau.Avalam.Color;
|
||||||
|
import fr.iut_fbleau.Avalam.Tower;
|
||||||
|
import fr.iut_fbleau.GameAPI.AbstractGamePlayer;
|
||||||
|
import fr.iut_fbleau.GameAPI.AbstractPly;
|
||||||
|
import fr.iut_fbleau.GameAPI.IBoard;
|
||||||
|
import fr.iut_fbleau.GameAPI.Player;
|
||||||
|
import fr.iut_fbleau.GameAPI.Result;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bot "Divin" (fort) pour Avalam.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Objectif : trop fort. */
|
||||||
|
public class DivineBot{
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user