Untitled

mail@pastecode.io avatar
unknown
plain_text
a month ago
8.8 kB
1
Indexable
Never
package laboratoire4.linesofaction;

import laboratoire4.tictactoe.Joueur;

import java.awt.Point;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

import static laboratoire4.linesofaction.GenerateurMvt.generateMoves;
import static laboratoire4.linesofaction.Plateau.*;

public class AlgorithmeJeu {

    int tour = 0;

    public String jouerCoupServeur(Plateau plateau){

        Move move = choixProchainCoup(plateau, plateau.getJoueurActuel());

        String coup = Plateau.traductionPoint(move.from());

        if(plateau.plateauJeu[move.to().x][move.to().y] == plateau.getJoueurAdverse()){
            plateau.updateMapsFrom(move.from());
        }else{

            plateau.updateMaps(move.from(), move.to());
        }

        plateau.updateBoardAndLists(move.from(), move.to(), plateau.getJoueurActuel());

        System.out.println("NOUS: " +coup + Plateau.traductionPoint(move.to()));
        plateau.afficherJeu();
        return coup + Plateau.traductionPoint(move.to());
    }

    public Move choixProchainCoup(Plateau plateau, int joueur){
        Point bestGoing = null;
        Point bestFrom = null;

        int scoreMax = Integer.MIN_VALUE;

        ArrayList<Point> pions = new ArrayList<>(plateau.getPionsActuel());

        for(Point pion : pions) {

            LinkedList<Point> coupPossibles = generateMoves(plateau, pion, plateau.getJoueurActuel());

            for (Point coup : coupPossibles) {
                Joueur prochain = joueur == plateau.getJoueurActuel() ? Joueur.MIN : Joueur.MAX;

                int valeurCase = plateau.plateauJeu[coup.x][coup.y];

                jouerCoup(plateau, pion, coup);
                int meilleurScore = miniMaxAlphaBeta(plateau, pion, coup, prochain, Integer.MIN_VALUE, Integer.MAX_VALUE, 4);
                jouerCoup(plateau, coup, pion);

                if(valeurCase == plateau.getJoueurAdverse()){
                    plateau.ajoutPion(coup, plateau.getJoueurAdverse());
                }

                if (scoreMax < meilleurScore) {
                    bestGoing = coup;
                    bestFrom = pion;
                    scoreMax = meilleurScore;
                }
            }
        }

        assert bestGoing != null;
        assert bestFrom != null;

        return new Move(bestFrom, bestGoing);
    }

    public void jouerCoup(Plateau plateau, Point from, Point going){
        int joueurActuel = plateau.getJoueurActuel();
        int joueurAdverse = plateau.getJoueurAdverse();
        boolean mange = plateau.plateauJeu[going.x][going.y] == joueurAdverse;

        if(mange){
            plateau.updateMapsFrom(from);

        }else{

            plateau.updateMaps(from, going);
        }

        plateau.updateBoardAndLists(from, going, joueurActuel);
    }

    public void jouerCoupAdverseServeur(String coup, Plateau plateau){

        Plateau.Move move = traductionString(coup);
        Point from = move.from();
        Point going = move.to();

        if(plateau.plateauJeu[going.x][going.y] == plateau.getJoueurActuel()){

            plateau.updateMapsFrom(from);
        }else{

            plateau.updateMaps(from, going);
        }

        plateau.updateBoardAndLists(from, going, plateau.getJoueurAdverse());
        System.out.println("ADVERSAIRE: " +coup);
        plateau.afficherJeu();
    }

    public void jouerCoupAdverse(Point from, Point going, Plateau plateau){
        int joueurActuel = plateau.getJoueurActuel();
        int joueurAdverse = plateau.getJoueurAdverse();
        boolean mange = plateau.plateauJeu[going.x][going.y] == joueurActuel;

        if(mange){
            plateau.updateMapsFrom(from);

        }else{

            plateau.updateMaps(from, going);
        }

        plateau.updateBoardAndLists(from, going, joueurAdverse);

    }

    private int evaluationCoup(Plateau plateau, Point coup, Point going) {
        float eulerActuel = 0f;
        for (int row = -1; row < 8; ++row) {
            for (int col = -1; col < 8; ++col) {
                eulerActuel += plateau.calculateQuadValue(plateau.getJoueurActuel(), row, col);
            }
        }
        float eulerAdverse = 0f;
        for (int row = -1; row < 8; ++row) {
            for (int col = -1; col < 8; ++col) {
                eulerAdverse += plateau.calculateQuadValue(plateau.getJoueurAdverse(), row, col);
            }
        }

        eulerActuel *= 2f;
        eulerAdverse *= 2f;

        var dist = -plateau.averageCenterOfMassDistance(plateau.getJoueurActuel()) * 10;

        return (int)Math.round(dist - eulerActuel + eulerAdverse) + (plateau.checkWin(plateau.getPionsActuel().get(0)) ? 100 : 0) + (plateau.checkWin(plateau.getPionsAdverse().get(0)) ? -100 : 0);
    }

    public int miniMaxAlphaBeta(Plateau plateau, Point from, Point going, Joueur joueur, int alpha, int beta, final int profondeur){

        int maxScore = Integer.MIN_VALUE;
        int minScore = Integer.MAX_VALUE;

        if (profondeur <= 0) {
            return evaluationCoup(plateau, from, going);
        }

        if(joueur == Joueur.MAX) {
            ArrayList<Point> pions = new ArrayList<>(plateau.getPionsActuel());
            for(Point pion : pions) {
                LinkedList<Point> coupsPossibles = generateMoves(plateau, pion, plateau.getJoueurActuel());

                for (Point coup : coupsPossibles) {
                    boolean mange = plateau.plateauJeu[coup.x][coup.y] == plateau.getJoueurAdverse();
                    float oldEulerRed = plateau.eulerNumberRed;
                    float oldEulerBlack = plateau.eulerNumberBlack;

                    jouerCoup(plateau, pion, coup);

                    maxScore = Integer.max(maxScore, miniMaxAlphaBeta(plateau, pion, coup, Joueur.MIN, alpha, beta, profondeur - 1));
                    alpha = Integer.max(alpha, maxScore);

                    jouerCoup(plateau, coup, pion);

                    if(mange){

                        plateau.ajoutPion(coup, plateau.getJoueurAdverse());
                    }

                    plateau.eulerNumberRed = oldEulerRed;
                    plateau.eulerNumberBlack = oldEulerBlack;

                    if (beta <= alpha) {
                        return maxScore;
                    }
                }
            }
            return maxScore;
        }else {

            ArrayList<Point> pions = new ArrayList<>(plateau.getPionsAdverse());
            for(Point pion : pions) {
                LinkedList<Point> coupsPossibles = generateMoves(plateau, pion, plateau.getJoueurAdverse());

                for (Point coup : coupsPossibles) {
                    boolean mange = plateau.plateauJeu[coup.x][coup.y] == plateau.getJoueurActuel();
                    float oldEulerRed = plateau.eulerNumberRed;
                    float oldEulerBlack = plateau.eulerNumberBlack;

                    jouerCoupAdverse(pion, coup, plateau);

                    minScore = Integer.min(minScore, miniMaxAlphaBeta(plateau, pion, coup, Joueur.MAX, alpha, beta, profondeur - 1));
                    beta = Integer.min(beta, minScore);

                    jouerCoupAdverse(coup, pion, plateau);

                    if(mange){

                        plateau.ajoutPion(coup, plateau.getJoueurActuel());
                    }

                    plateau.eulerNumberRed = oldEulerRed;
                    plateau.eulerNumberBlack = oldEulerBlack;

                    if (beta <= alpha) {
                        return minScore;
                    }

                }
            }
            return minScore;
        }
    }

    private int validationPointage(int symbole, Plateau plateau){
        if (symbole == plateau.getJoueurActuel()){
            return 100;
        }else if (symbole == plateau.getJoueurAdverse()){
            return -100;
        }
        return -1;
    }

    private Move choixCoupAleatoire(Plateau plateau){
        Point from = plateau.getPionsActuel().get(new Random().nextInt(plateau.getPionsActuel().size()));
        LinkedList<Point> moves = generateMoves(plateau, from, plateau.getJoueurActuel());

        while(moves.size() == 0){
            from = plateau.getPionsActuel().get(new Random().nextInt(plateau.getPionsActuel().size()));
            moves = generateMoves(plateau, from, plateau.getJoueurActuel());
        }

        Point going = moves.get(new Random().nextInt(moves.size()));

        return new Move(from, going);
    }
}
Leave a Comment