comment code

This commit is contained in:
Quentin Legot 2021-02-26 14:26:54 +01:00
parent 710298150e
commit b2e97e1dc8
7 changed files with 64 additions and 7 deletions

View File

@ -23,16 +23,26 @@ public class Main {
System.out.println(game.toString()); System.out.println(game.toString());
game = game.play(player.play(game)); game = game.play(player.play(game));
} }
endGame(game); endGame(game, p1, p2);
} }
/**
* The method will interpret the arguments and return a {@link Player} instance depending on the arguments given
* <ul><li>argument 0 {@code int}: player 1 depth search</li>
* <li>argument 1 {@code int}: player 2 depth search</li>
* <li>argument 2 {@code boolean}: true if player should be {@link AlphaBetaPlayer} instance,
* {@link NegamaxPlayer} otherwise</li></ul>
* If arguments are missing or invalid, default value will be use {@code (4, 4, true)}
* @param args program arguments, given when user write the command to execute the program
* @return Player 1 and 2 instance
*/
public static Player[] extractArgs(String[] args) { public static Player[] extractArgs(String[] args) {
Player p1; Player p1;
Player p2; Player p2;
int depthP1 = 4; int depthP1 = 4;
int depthP2 = 4; int depthP2 = 4;
boolean useAlphaBeta = false; boolean useAlphaBeta = true;
try { try {
if(args.length >= 3) { // les paramètres > 3 sont ignorés if(args.length >= 3) { // les paramètres > 3 sont ignorés
depthP1 = Integer.parseInt(args[0]); depthP1 = Integer.parseInt(args[0]);
@ -63,12 +73,12 @@ public class Main {
return board; return board;
} }
public static void endGame(State game) { public static void endGame(State game, Player p1, Player p2) {
System.out.println(game.toString()); System.out.println(game.toString());
System.out.println(game.getN1()+" "+ game.getN2()); System.out.println(game.getN1()+" "+ game.getN2());
System.out.println(game.getWinner() + " a gagné la partie"); System.out.println(game.getWinner() + " a gagné la partie");
System.out.println("Score joueur 1 -> " + game.getN1()); System.out.println("Score joueur 1 -> " + game.getScore(p1));
System.out.println("Score joueur 2 -> "+ game.getN2()); System.out.println("Score joueur 2 -> "+ game.getScore(p2));
} }
} }

View File

@ -35,7 +35,7 @@ public class MainStats {
} }
writer.close(); writer.close();
writer2.close(); writer2.close();
Main.endGame(game); Main.endGame(game, p1, p2);
} }
} }

View File

@ -12,6 +12,12 @@ public class Point {
this.y = y; this.y = y;
} }
/**
* check if {@code other} point is considered as jump
* @param other arrival point
* @param board current {@link State} situation
* @return {@code true} if other is considered as a jump depending of {@code this}, {@code false} otherwise
*/
public boolean isJump(Point other, Player[][] board) { public boolean isJump(Point other, Player[][] board) {
double value = Math.pow(other.x - this.x, 2) + Math.pow(other.y - this.y, 2); double value = Math.pow(other.x - this.x, 2) + Math.pow(other.y - this.y, 2);
return (value == 4 || value == 8) && board[(x+other.getX())/2][(y+other.getY())/2] != null; return (value == 4 || value == 8) && board[(x+other.getX())/2][(y+other.getY())/2] != null;

View File

@ -7,6 +7,11 @@ import java.util.List;
public class State { public class State {
/**
* Contains previous situations of the {@link State#board}, if the game return in a situation which have already
* been played, the game ends.
* We only keep the 10 previous situations due to performances issues
*/
public static List<Player[][]> previousSituations = new LinkedList<>(); public static List<Player[][]> previousSituations = new LinkedList<>();
private final Player[][] board; private final Player[][] board;
@ -26,9 +31,18 @@ public class State {
} }
public boolean isOver() { public boolean isOver() {
return n1 == 0 || n2 == 0 || (getMove(player1).isEmpty() && getMove(player2).isEmpty()) || previousSituations.contains(this.board); return n1 == 0 || n2 == 0 || (getMove(player1).isEmpty() && getMove(player2).isEmpty())
|| previousSituations.contains(this.board);
} }
/**
* The method check every possible movement which can do {@code player}'s pawns and add the movement in a list when
* there is no-one on the {@link State#board board}. the left side of the {@link Pair tuple} contains the position
* where the pawn currently is and the right side the position where it can go by cloning itself or jumping over an
* other pawn
* @param player the player whose possible movements will be checked
* @return a {@link LinkedList list} containing every movement which can do {@code player} in this current situation
*/
public LinkedList<Pair<Point, Point>> getMove(Player player) { public LinkedList<Pair<Point, Point>> getMove(Player player) {
// Pair<Depart, Arrivee> // Pair<Depart, Arrivee>
LinkedList<Pair<Point, Point>> moves = new LinkedList<>(); LinkedList<Pair<Point, Point>> moves = new LinkedList<>();
@ -78,6 +92,14 @@ public class State {
return null; return null;
} }
/**
* The method create a copy of itself and modify this copy depending on the {@code move} parameter, it'll clone or jump
* a pawn from the left side of {@code move} to the right side, switch current player and recalculate players' score
* @param move a {@link Pair tuple} containing 2 elements,
* the left side contains the starting point (where is the point)
* and the right side contains the point where it'll clone or jump
* @return a modified copy of the current situation
*/
public State play(Pair<Point,Point> move) { public State play(Pair<Point,Point> move) {
if(previousSituations.size() == 10) // on ne garde que les 10 dernieres situations par soucis de perfs if(previousSituations.size() == 10) // on ne garde que les 10 dernieres situations par soucis de perfs
previousSituations.remove(0); previousSituations.remove(0);

View File

@ -10,6 +10,13 @@ public class AlphaBetaPlayer extends Player{
super(depth); super(depth);
} }
/**
* This method will find the best move to try to win the game by searching all possible movement given by
* {@link State#getMove(Player)} in the limit of {@link Player#depth}
* @see AlphaBetaPlayer#alphabeta(State, int, int, int)
* @see Player#play(State)
* @see NegamaxPlayer#play(State)
*/
@Override @Override
public Pair<Point, Point> play(State game) { public Pair<Point, Point> play(State game) {
int bestValue = Integer.MIN_VALUE; int bestValue = Integer.MIN_VALUE;

View File

@ -10,6 +10,13 @@ public class NegamaxPlayer extends Player {
super(depth); super(depth);
} }
/**
* This method will find the best move to try to win the game by searching all possible movement given by
* {@link State#getMove(Player)} in the limit of {@link Player#depth}
* @see NegamaxPlayer#negamax(State, int)
* @see AlphaBetaPlayer#play(State)
* @see Player#play(State)
*/
@Override @Override
public Pair<Point, Point> play(State game) { public Pair<Point, Point> play(State game) {
int bestValue = Integer.MIN_VALUE; int bestValue = Integer.MIN_VALUE;

View File

@ -18,6 +18,11 @@ public abstract class Player {
return this.complexity; return this.complexity;
} }
/**
* @param board current {@link State} situation
* @return a {@link Pair tuple} with on the left side the starting point of a pawn and on the right side the arrival
* point
*/
public abstract Pair<Point, Point> play(State board); public abstract Pair<Point, Point> play(State board);
protected int evaluate(State game){ protected int evaluate(State game){