Initial commit — sujet TP1 IIA (Minimax / Alpha-Beta)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
78
.gitignore
vendored
Normal file
78
.gitignore
vendored
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
# Directories #
|
||||||
|
/build/
|
||||||
|
/bin/
|
||||||
|
target/
|
||||||
|
|
||||||
|
# OS Files #
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
*.class
|
||||||
|
|
||||||
|
# Package Files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.ear
|
||||||
|
*.db
|
||||||
|
|
||||||
|
######################
|
||||||
|
# Windows
|
||||||
|
######################
|
||||||
|
|
||||||
|
# Windows image file caches
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Folder config file
|
||||||
|
Desktop.ini
|
||||||
|
|
||||||
|
######################
|
||||||
|
# OSX
|
||||||
|
######################
|
||||||
|
|
||||||
|
.DS_Store
|
||||||
|
.svn
|
||||||
|
|
||||||
|
# Thumbnails
|
||||||
|
._*
|
||||||
|
|
||||||
|
# Files that might appear on external disk
|
||||||
|
.Spotlight-V100
|
||||||
|
.Trashes
|
||||||
|
|
||||||
|
|
||||||
|
######################
|
||||||
|
# Eclipse
|
||||||
|
######################
|
||||||
|
|
||||||
|
*.pydevproject
|
||||||
|
.project
|
||||||
|
.metadata
|
||||||
|
bin/**
|
||||||
|
tmp/**
|
||||||
|
tmp/**/*
|
||||||
|
*.tmp
|
||||||
|
*.bak
|
||||||
|
*.swp
|
||||||
|
*~.nib
|
||||||
|
local.properties
|
||||||
|
.classpath
|
||||||
|
.settings/
|
||||||
|
.loadpath
|
||||||
|
/src/main/resources/rebel.xml
|
||||||
|
# External tool builders
|
||||||
|
.externalToolBuilders/
|
||||||
|
|
||||||
|
# Locally stored "Eclipse launch configurations"
|
||||||
|
*.launch
|
||||||
|
|
||||||
|
# CDT-specific
|
||||||
|
.cproject
|
||||||
|
|
||||||
|
# PDT-specific
|
||||||
|
.buildpath
|
||||||
|
|
||||||
|
|
||||||
|
######################
|
||||||
|
# Gradle
|
||||||
|
######################
|
||||||
|
|
||||||
|
.gradle/
|
||||||
35
build.gradle
Normal file
35
build.gradle
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* This file was generated by the Gradle 'init' task.
|
||||||
|
*
|
||||||
|
* This generated file contains a sample Java Library project to get you started.
|
||||||
|
* For more details take a look at the Java Libraries chapter in the Gradle
|
||||||
|
* User Manual available at https://docs.gradle.org/6.3/userguide/java_library_plugin.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
// Apply the java-library plugin to add support for Java Library
|
||||||
|
id 'java-library'
|
||||||
|
id 'eclipse'
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceCompatibility = 11.0
|
||||||
|
targetCompatibility = 11.0
|
||||||
|
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
// Use jcenter for resolving dependencies.
|
||||||
|
// You can declare any Maven/Ivy/file repository here.
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
// This dependency is exported to consumers, that is to say found on their compile classpath.
|
||||||
|
//api 'org.apache.commons:commons-math3:3.6.1'
|
||||||
|
|
||||||
|
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
|
||||||
|
//implementation 'com.google.guava:guava:28.2-jre'
|
||||||
|
|
||||||
|
// Use JUnit test framework
|
||||||
|
testImplementation 'junit:junit:4.12'
|
||||||
|
}
|
||||||
|
|
||||||
10
settings.gradle
Normal file
10
settings.gradle
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
/*
|
||||||
|
* This file was generated by the Gradle 'init' task.
|
||||||
|
*
|
||||||
|
* The settings file is used to specify which projects to include in your build.
|
||||||
|
*
|
||||||
|
* Detailed information about configuring a multi-project build in Gradle can be found
|
||||||
|
* in the user manual at https://docs.gradle.org/6.3/userguide/multi_project_builds.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
rootProject.name = 'iialib'
|
||||||
186
src/main/java/games/dominos/DominosBoard.java
Normal file
186
src/main/java/games/dominos/DominosBoard.java
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
package games.dominos;
|
||||||
|
|
||||||
|
import iialib.games.model.IBoard;
|
||||||
|
import iialib.games.model.Player;
|
||||||
|
import iialib.games.model.Score;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class DominosBoard implements IBoard<DominosMove, DominosRole, DominosBoard> {
|
||||||
|
|
||||||
|
private static int DEFAULT_GRID_SIZE = 7;
|
||||||
|
|
||||||
|
// --------- Class Attribute ---------
|
||||||
|
|
||||||
|
public static int GRID_SIZE = DEFAULT_GRID_SIZE;
|
||||||
|
|
||||||
|
private enum SQUARE {
|
||||||
|
EMPTY, VERTICAL, HORIZONTAL
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------------------- Attributes ---------------------
|
||||||
|
|
||||||
|
private final SQUARE[][] boardGrid;
|
||||||
|
|
||||||
|
// ---------------------- Constructors ---------------------
|
||||||
|
|
||||||
|
public DominosBoard() {
|
||||||
|
boardGrid = new SQUARE[GRID_SIZE][GRID_SIZE];
|
||||||
|
for (int i = 0; i < GRID_SIZE; i++)
|
||||||
|
for (int j = 0; j < GRID_SIZE; j++)
|
||||||
|
boardGrid[i][j] = SQUARE.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
public DominosBoard(DominosBoard other) {
|
||||||
|
boardGrid = other.copyGrid();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private DominosBoard(SQUARE[][] other) {
|
||||||
|
boardGrid = new SQUARE[GRID_SIZE][GRID_SIZE];
|
||||||
|
for (int i = 0; i < GRID_SIZE; i++)
|
||||||
|
System.arraycopy(other[i], 0, boardGrid[i], 0, GRID_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------- Getters / Setters -------------------
|
||||||
|
|
||||||
|
protected int retGridSize(int n) {
|
||||||
|
return GRID_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setGridSize(int n) {
|
||||||
|
GRID_SIZE = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------- IBoard Methods ---------------------
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DominosBoard play(DominosMove move, DominosRole playerRole) {
|
||||||
|
SQUARE[][] newGrid = copyGrid();
|
||||||
|
int x = move.x;
|
||||||
|
int y = move.y;
|
||||||
|
if (playerRole == DominosRole.VERTICAL) {
|
||||||
|
newGrid[x][y] = SQUARE.VERTICAL;
|
||||||
|
newGrid[x + 1][y] = SQUARE.VERTICAL;
|
||||||
|
} else {
|
||||||
|
newGrid[x][y] = SQUARE.HORIZONTAL;
|
||||||
|
newGrid[x][y + 1] = SQUARE.HORIZONTAL;
|
||||||
|
}
|
||||||
|
return new DominosBoard(newGrid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayList<DominosMove> possibleMoves(DominosRole playerRole) {
|
||||||
|
if (playerRole == DominosRole.VERTICAL) {
|
||||||
|
return freeVerticalMoves();
|
||||||
|
} else {
|
||||||
|
return freeHorizontalMoves();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValidMove(DominosMove move, DominosRole playerRole) {
|
||||||
|
int x = move.x;
|
||||||
|
int y = move.y;
|
||||||
|
return (boardGrid[x][y] == SQUARE.EMPTY)
|
||||||
|
&& ((playerRole == DominosRole.VERTICAL) ? (boardGrid[x + 1][y] == SQUARE.EMPTY)
|
||||||
|
: (boardGrid[x][y + 1] == SQUARE.EMPTY));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isGameOver() {
|
||||||
|
return (this.nbHorizontalMoves() == 0) || (this.nbVerticalMoves() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------- Other Methods ---------------------
|
||||||
|
|
||||||
|
|
||||||
|
private ArrayList<DominosMove> freeVerticalMoves() {
|
||||||
|
ArrayList<DominosMove> allPossibleMoves = new ArrayList<>();
|
||||||
|
for (int i = 0; i < GRID_SIZE- 1; i++) { // lines
|
||||||
|
for (int j = 0; j < GRID_SIZE ; j++) { // columns
|
||||||
|
if ((boardGrid[i][j] == SQUARE.EMPTY) && (boardGrid[i + 1][j] == SQUARE.EMPTY)) // possible move
|
||||||
|
allPossibleMoves.add(new DominosMove(i, j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return allPossibleMoves;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayList<DominosMove> freeHorizontalMoves() {
|
||||||
|
ArrayList<DominosMove> allPossibleMoves = new ArrayList<>();
|
||||||
|
for (int i = 0; i < GRID_SIZE; i++) { // lines
|
||||||
|
for (int j = 0; j < GRID_SIZE - 1; j++) { // columns
|
||||||
|
if ((boardGrid[i][j] == SQUARE.EMPTY) && (boardGrid[i ][j+ 1] == SQUARE.EMPTY)) // possible move
|
||||||
|
allPossibleMoves.add(new DominosMove(i, j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return allPossibleMoves;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SQUARE[][] copyGrid() {
|
||||||
|
SQUARE[][] newGrid = new SQUARE[GRID_SIZE][GRID_SIZE];
|
||||||
|
for (int i = 0; i < GRID_SIZE; i++)
|
||||||
|
System.arraycopy(boardGrid[i], 0, newGrid[i], 0, GRID_SIZE);
|
||||||
|
return newGrid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder retstr = new StringBuilder(new String(""));
|
||||||
|
for (int i = 0; i < GRID_SIZE; i++) {
|
||||||
|
for (int j = 0; j < GRID_SIZE; j++)
|
||||||
|
if (boardGrid[i][j] == SQUARE.EMPTY)
|
||||||
|
retstr.append("-");
|
||||||
|
else if (boardGrid[i][j] == SQUARE.VERTICAL)
|
||||||
|
retstr.append("V");
|
||||||
|
else // damier[i][j] == NOIR
|
||||||
|
retstr.append("H");
|
||||||
|
retstr.append("\n");
|
||||||
|
}
|
||||||
|
return retstr.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int nbHorizontalMoves() {
|
||||||
|
int nbMoves = 0;
|
||||||
|
for (int i = 0; i < GRID_SIZE; i++) {
|
||||||
|
for (int j = 0; j < GRID_SIZE - 1; j++) {
|
||||||
|
if (boardGrid[i][j] == SQUARE.EMPTY && boardGrid[i][j + 1] == SQUARE.EMPTY)
|
||||||
|
nbMoves++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nbMoves;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int nbVerticalMoves() {
|
||||||
|
int nbMoves = 0;
|
||||||
|
for (int i = 0; i < GRID_SIZE; i++) {
|
||||||
|
for (int j = 0; j < GRID_SIZE - 1; j++) {
|
||||||
|
if (boardGrid[j][i] == SQUARE.EMPTY && boardGrid[j + 1][i] == SQUARE.EMPTY)
|
||||||
|
nbMoves++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nbMoves;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayList<Score<DominosRole>> getScores() {
|
||||||
|
ArrayList<Score<DominosRole>> scores = new ArrayList<Score<DominosRole>>();
|
||||||
|
if(this.isGameOver()) {
|
||||||
|
if (nbHorizontalMoves() == 0) {
|
||||||
|
scores.add(new Score<DominosRole>(DominosRole.HORIZONTAL,Score.Status.LOOSE,0));
|
||||||
|
scores.add(new Score<DominosRole>(DominosRole.VERTICAL,Score.Status.WIN,1));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
scores.add(new Score<DominosRole>(DominosRole.HORIZONTAL,Score.Status.WIN,1));
|
||||||
|
scores.add(new Score<DominosRole>(DominosRole.VERTICAL,Score.Status.LOOSE,0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
}
|
||||||
|
return scores;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
45
src/main/java/games/dominos/DominosGame.java
Normal file
45
src/main/java/games/dominos/DominosGame.java
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package games.dominos;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import iialib.games.algs.AIPlayer;
|
||||||
|
import iialib.games.algs.AbstractGame;
|
||||||
|
import iialib.games.algs.GameAlgorithm;
|
||||||
|
import iialib.games.algs.algorithms.MiniMax;
|
||||||
|
|
||||||
|
public class DominosGame extends AbstractGame<DominosMove, DominosRole, DominosBoard> {
|
||||||
|
|
||||||
|
DominosGame(ArrayList<AIPlayer<DominosMove, DominosRole, DominosBoard>> players, DominosBoard board) {
|
||||||
|
super(players, board);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
DominosRole roleV = DominosRole.VERTICAL;
|
||||||
|
DominosRole roleH = DominosRole.HORIZONTAL;
|
||||||
|
|
||||||
|
GameAlgorithm<DominosMove, DominosRole, DominosBoard> algV = new MiniMax<DominosMove, DominosRole, DominosBoard>(
|
||||||
|
roleV, roleH, DominosHeuristics.hVertical, 4); // Minimax depth 4
|
||||||
|
|
||||||
|
GameAlgorithm<DominosMove, DominosRole, DominosBoard> algH = new MiniMax<DominosMove, DominosRole, DominosBoard>(
|
||||||
|
roleH, roleV, DominosHeuristics.hHorizontal, 2); // Minimax depth 2
|
||||||
|
|
||||||
|
AIPlayer<DominosMove, DominosRole, DominosBoard> playerV = new AIPlayer<DominosMove, DominosRole, DominosBoard>(
|
||||||
|
roleV, algV);
|
||||||
|
|
||||||
|
AIPlayer<DominosMove, DominosRole, DominosBoard> playerH = new AIPlayer<DominosMove, DominosRole, DominosBoard>(
|
||||||
|
roleH, algH);
|
||||||
|
|
||||||
|
ArrayList<AIPlayer<DominosMove, DominosRole, DominosBoard>> players = new ArrayList<AIPlayer<DominosMove, DominosRole, DominosBoard>>();
|
||||||
|
|
||||||
|
players.add(playerV); // First Player
|
||||||
|
players.add(playerH); // Second Player
|
||||||
|
|
||||||
|
// Setting the initial Board
|
||||||
|
DominosBoard initialBoard = new DominosBoard();
|
||||||
|
|
||||||
|
DominosGame game = new DominosGame(players, initialBoard);
|
||||||
|
game.runGame();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
23
src/main/java/games/dominos/DominosHeuristics.java
Normal file
23
src/main/java/games/dominos/DominosHeuristics.java
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package games.dominos;
|
||||||
|
|
||||||
|
import iialib.games.algs.IHeuristic;
|
||||||
|
|
||||||
|
public class DominosHeuristics {
|
||||||
|
|
||||||
|
public static IHeuristic<DominosBoard,DominosRole> hVertical = (board,role) -> {
|
||||||
|
/* TODO */
|
||||||
|
|
||||||
|
|
||||||
|
return 0; // TODO
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
public static IHeuristic<DominosBoard,DominosRole> hHorizontal = (board,role) -> {
|
||||||
|
/* TODO */
|
||||||
|
|
||||||
|
|
||||||
|
return 0; // TODO
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
19
src/main/java/games/dominos/DominosMove.java
Normal file
19
src/main/java/games/dominos/DominosMove.java
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package games.dominos;
|
||||||
|
|
||||||
|
import iialib.games.model.IMove;
|
||||||
|
|
||||||
|
public class DominosMove implements IMove {
|
||||||
|
|
||||||
|
public final int x;
|
||||||
|
public final int y;
|
||||||
|
|
||||||
|
DominosMove(int x, int y){
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Move{" + x + "," + y + "}";
|
||||||
|
}
|
||||||
|
}
|
||||||
8
src/main/java/games/dominos/DominosRole.java
Normal file
8
src/main/java/games/dominos/DominosRole.java
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
package games.dominos;
|
||||||
|
|
||||||
|
import iialib.games.model.IRole;
|
||||||
|
|
||||||
|
public enum DominosRole implements IRole{
|
||||||
|
HORIZONTAL, // For the player playing its tiles hally
|
||||||
|
VERTICAL // For the player playing its tiles vertically
|
||||||
|
}
|
||||||
54
src/main/java/games/otherGame/otherGameBoard.java
Normal file
54
src/main/java/games/otherGame/otherGameBoard.java
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
package games.otherGame;
|
||||||
|
|
||||||
|
import iialib.games.model.IBoard;
|
||||||
|
import iialib.games.model.Player;
|
||||||
|
import iialib.games.model.Score;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class otherGameBoard implements IBoard<otherGameMove, otherGameRole, otherGameBoard> {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------- Attributes ---------------------
|
||||||
|
// Attributes
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
|
||||||
|
// --------------------- IBoard Methods ---------------------
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayList<otherGameMove> possibleMoves(otherGameRole playerRole) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public otherGameBoard play(otherGameMove move, otherGameRole playerRole) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValidMove(otherGameMove move, otherGameRole playerRole) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isGameOver() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayList<Score<otherGameRole>> getScores() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------- Other Methods ---------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
19
src/main/java/games/otherGame/otherGameMove.java
Normal file
19
src/main/java/games/otherGame/otherGameMove.java
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package games.otherGame;
|
||||||
|
|
||||||
|
import iialib.games.model.IMove;
|
||||||
|
|
||||||
|
public class otherGameMove implements IMove {
|
||||||
|
|
||||||
|
public final int x;
|
||||||
|
public final int y;
|
||||||
|
|
||||||
|
otherGameMove(int x, int y){
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Move{" + x + "," + y + "}";
|
||||||
|
}
|
||||||
|
}
|
||||||
8
src/main/java/games/otherGame/otherGameRole.java
Normal file
8
src/main/java/games/otherGame/otherGameRole.java
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
package games.otherGame;
|
||||||
|
|
||||||
|
import iialib.games.model.IRole;
|
||||||
|
|
||||||
|
public enum otherGameRole implements IRole{
|
||||||
|
HORIZONTAL, // For the player playing its tiles hally
|
||||||
|
VERTICAL // For the player playing its tiles vertically
|
||||||
|
}
|
||||||
33
src/main/java/iialib/games/algs/AIPlayer.java
Normal file
33
src/main/java/iialib/games/algs/AIPlayer.java
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
package iialib.games.algs;
|
||||||
|
|
||||||
|
import iialib.games.model.IBoard;
|
||||||
|
import iialib.games.model.IMove;
|
||||||
|
import iialib.games.model.IRole;
|
||||||
|
import iialib.games.model.Player;
|
||||||
|
|
||||||
|
public class AIPlayer<Move extends IMove,Role extends IRole, Board extends IBoard<Move,Role,Board>> extends Player<Role> {
|
||||||
|
|
||||||
|
private GameAlgorithm< Move,Role,Board> ai;
|
||||||
|
|
||||||
|
public void setAi(GameAlgorithm<Move, Role, Board> ai) {
|
||||||
|
this.ai = ai;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AIPlayer(Role role) {
|
||||||
|
super(role);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AIPlayer(Role role,GameAlgorithm<Move,Role,Board> alg) {
|
||||||
|
super(role);
|
||||||
|
this.ai = alg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Move bestMove(Board board) {
|
||||||
|
return(ai.bestMove(board,this.getRole()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Board playMove(Board board, Move move) {
|
||||||
|
return(board.play(move, this.getRole()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
56
src/main/java/iialib/games/algs/AbstractGame.java
Normal file
56
src/main/java/iialib/games/algs/AbstractGame.java
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package iialib.games.algs;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import iialib.games.model.IBoard;
|
||||||
|
import iialib.games.model.IMove;
|
||||||
|
import iialib.games.model.IRole;
|
||||||
|
import iialib.games.model.Score;
|
||||||
|
|
||||||
|
public abstract class AbstractGame<Move extends IMove, Role extends IRole, Board extends IBoard<Move,Role,Board>> {
|
||||||
|
|
||||||
|
// Attributes
|
||||||
|
Board currentBoard;
|
||||||
|
|
||||||
|
ArrayList<AIPlayer<Move,Role,Board>> players;
|
||||||
|
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
public AbstractGame(ArrayList<AIPlayer<Move,Role,Board>> players,Board initialBoard){
|
||||||
|
this.currentBoard = initialBoard;
|
||||||
|
this.players = players;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
public void runGame() {
|
||||||
|
int index = 0;
|
||||||
|
AIPlayer<Move,Role,Board> currentPlayer = players.get(index);
|
||||||
|
System.out.println("Game begining - First player is : " + currentPlayer);
|
||||||
|
System.out.println("The board is :");
|
||||||
|
System.out.println(currentBoard);
|
||||||
|
|
||||||
|
while(!currentBoard.isGameOver()) {
|
||||||
|
System.out.println("Next player is :" + currentPlayer);
|
||||||
|
Move nextMove = currentPlayer.bestMove(currentBoard);
|
||||||
|
System.out.println("Best Move is :" + nextMove);
|
||||||
|
currentBoard = currentPlayer.playMove(currentBoard, nextMove);
|
||||||
|
System.out.println("The board is :");
|
||||||
|
System.out.println(currentBoard);
|
||||||
|
index = 1 - index;
|
||||||
|
currentPlayer = players.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Game over !");
|
||||||
|
ArrayList<Score<Role>> scores = currentBoard.getScores();
|
||||||
|
for(AIPlayer<Move,Role,Board> p: players)
|
||||||
|
for(Score<Role> s : scores)
|
||||||
|
if(p.getRole() == s.getRole())
|
||||||
|
System.out.println("" + p + " score is : " + s.getStatus() + " " + s.getScore());
|
||||||
|
;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
12
src/main/java/iialib/games/algs/GameAlgorithm.java
Normal file
12
src/main/java/iialib/games/algs/GameAlgorithm.java
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package iialib.games.algs;
|
||||||
|
|
||||||
|
import iialib.games.model.IBoard;
|
||||||
|
import iialib.games.model.IMove;
|
||||||
|
import iialib.games.model.IRole;
|
||||||
|
import iialib.games.model.Player;
|
||||||
|
|
||||||
|
public interface GameAlgorithm< Move extends IMove, Role extends IRole, Board extends IBoard<Move,Role,Board>> {
|
||||||
|
|
||||||
|
Move bestMove(Board board,Role playerRole);
|
||||||
|
|
||||||
|
}
|
||||||
17
src/main/java/iialib/games/algs/IHeuristic.java
Normal file
17
src/main/java/iialib/games/algs/IHeuristic.java
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package iialib.games.algs;
|
||||||
|
|
||||||
|
import iialib.games.model.IBoard;
|
||||||
|
import iialib.games.model.IMove;
|
||||||
|
import iialib.games.model.IRole;
|
||||||
|
import iialib.games.model.Player;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface IHeuristic<Board extends IBoard<?,Role, Board>,Role extends IRole> {
|
||||||
|
|
||||||
|
public static int MIN_VALUE = java.lang.Integer.MIN_VALUE;
|
||||||
|
public static int MAX_VALUE = java.lang.Integer.MAX_VALUE;
|
||||||
|
|
||||||
|
int eval(Board board,Role role);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
84
src/main/java/iialib/games/algs/algorithms/MiniMax.java
Normal file
84
src/main/java/iialib/games/algs/algorithms/MiniMax.java
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
package iialib.games.algs.algorithms;
|
||||||
|
|
||||||
|
import iialib.games.algs.GameAlgorithm;
|
||||||
|
import iialib.games.algs.IHeuristic;
|
||||||
|
import iialib.games.model.IBoard;
|
||||||
|
import iialib.games.model.IMove;
|
||||||
|
import iialib.games.model.IRole;
|
||||||
|
|
||||||
|
public class MiniMax<Move extends IMove,Role extends IRole,Board extends IBoard<Move,Role,Board>> implements GameAlgorithm<Move,Role,Board> {
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
/** Defaut value for depth limit
|
||||||
|
*/
|
||||||
|
private final static int DEPTH_MAX_DEFAUT = 4;
|
||||||
|
|
||||||
|
// Attributes
|
||||||
|
/** Role of the max player
|
||||||
|
*/
|
||||||
|
private final Role playerMaxRole;
|
||||||
|
|
||||||
|
/** Role of the min player
|
||||||
|
*/
|
||||||
|
private final Role playerMinRole;
|
||||||
|
|
||||||
|
/** Algorithm max depth
|
||||||
|
*/
|
||||||
|
private int depthMax = DEPTH_MAX_DEFAUT;
|
||||||
|
|
||||||
|
|
||||||
|
/** Heuristic used by the max player
|
||||||
|
*/
|
||||||
|
private IHeuristic<Board, Role> h;
|
||||||
|
|
||||||
|
//
|
||||||
|
/** number of internal visited (developed) nodes (for stats)
|
||||||
|
*/
|
||||||
|
private int nbNodes;
|
||||||
|
|
||||||
|
/** number of leaves nodes nodes (for stats)
|
||||||
|
|
||||||
|
*/
|
||||||
|
private int nbLeaves;
|
||||||
|
|
||||||
|
// --------- Constructors ---------
|
||||||
|
|
||||||
|
public MiniMax(Role playerMaxRole, Role playerMinRole, IHeuristic<Board, Role> h) {
|
||||||
|
this.playerMaxRole = playerMaxRole;
|
||||||
|
this.playerMinRole = playerMinRole;
|
||||||
|
this.h = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
public MiniMax(Role playerMaxRole, Role playerMinRole, IHeuristic<Board, Role> h, int depthMax) {
|
||||||
|
this(playerMaxRole, playerMinRole, h);
|
||||||
|
this.depthMax = depthMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IAlgo METHODS =============
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Move bestMove(Board board, Role playerRole) {
|
||||||
|
System.out.println("[MiniMax]");
|
||||||
|
|
||||||
|
Move bestMove = null;
|
||||||
|
// TODO
|
||||||
|
return bestMove;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PUBLIC METHODS ==============
|
||||||
|
*/
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "MiniMax(ProfMax=" + depthMax + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PRIVATE METHODS ===============
|
||||||
|
*/
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
53
src/main/java/iialib/games/model/IBoard.java
Normal file
53
src/main/java/iialib/games/model/IBoard.java
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
package iialib.games.model;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to chararacterize the boards.he
|
||||||
|
* It has to be impemented by some class in a real game.
|
||||||
|
*
|
||||||
|
* @param <Move> Class implementing the moves for the game
|
||||||
|
* @param <Role> Class implementing the roles for the game
|
||||||
|
* @param <Board> Class implementing the boards for the game
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface IBoard<Move extends IMove, Role extends IRole, Board extends IBoard<Move,Role,Board>> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the possible moves a player having the playerRole
|
||||||
|
* @param playerRole
|
||||||
|
* @return a list of all possible moves for the player having the playerRole
|
||||||
|
*/
|
||||||
|
ArrayList<Move> possibleMoves(Role playerRole);
|
||||||
|
|
||||||
|
/** play move on the board, played by a player having the playerRole
|
||||||
|
*
|
||||||
|
* @param move
|
||||||
|
* @param playerRole
|
||||||
|
* @return the successor board
|
||||||
|
*/
|
||||||
|
Board play(Move move, Role playerRole);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checks that move is valid for the player having the playerRole
|
||||||
|
* @param move
|
||||||
|
* @param playerRole
|
||||||
|
* @return yes if the move is valid for playerRole
|
||||||
|
*/
|
||||||
|
boolean isValidMove(Move move, Role playerRole);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checks that the board corresponds to an end of game
|
||||||
|
* @return yes if the game completed
|
||||||
|
*/
|
||||||
|
boolean isGameOver();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the scores for each role (when the game is over)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ArrayList<Score<Role>> getScores();
|
||||||
|
|
||||||
|
}
|
||||||
11
src/main/java/iialib/games/model/IMove.java
Normal file
11
src/main/java/iialib/games/model/IMove.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package iialib.games.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* used to characterize game moves
|
||||||
|
* It has to be implemented by some class in a real game
|
||||||
|
*/
|
||||||
|
public interface IMove {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
15
src/main/java/iialib/games/model/IRole.java
Normal file
15
src/main/java/iialib/games/model/IRole.java
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package iialib.games.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to represent characterize the role in the game of the different players
|
||||||
|
*
|
||||||
|
* It has to be implemented by some class for a real game.
|
||||||
|
* Generally it is just an enum for representing what distinguishes the players in the game
|
||||||
|
* e.g. the colors( BLACK, WHITE), the Position (NORTH, SOUTH), ...
|
||||||
|
*
|
||||||
|
* Exemple
|
||||||
|
* enum Colors {BLACK,WHITE} implements IRole
|
||||||
|
*/
|
||||||
|
public interface IRole {
|
||||||
|
|
||||||
|
}
|
||||||
56
src/main/java/iialib/games/model/Player.java
Normal file
56
src/main/java/iialib/games/model/Player.java
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package iialib.games.model;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* used to associate an real player identifier to a role
|
||||||
|
*
|
||||||
|
* @param <Role>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
public class Player<Role extends IRole> {
|
||||||
|
|
||||||
|
// ----------- Attributes ------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the role of the player in the game
|
||||||
|
*/
|
||||||
|
Role role;
|
||||||
|
/**
|
||||||
|
* An (optional) identifier characterizing the player having that role in the game
|
||||||
|
* This is useful for instance in a tournament, for keeping tra
|
||||||
|
*/
|
||||||
|
String id;
|
||||||
|
|
||||||
|
// ----------- Getters / Setters ------------
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Role getRole() {
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRole(Role role) {
|
||||||
|
this.role = role;
|
||||||
|
}
|
||||||
|
// ----------- Constructors ------------
|
||||||
|
|
||||||
|
public Player(Role role) {
|
||||||
|
this.role = role;
|
||||||
|
this.id = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Player(Role role, String id) {
|
||||||
|
this(role);
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------- Other Methods ------------
|
||||||
|
public String toString() {
|
||||||
|
return "" + role + ( id.isEmpty() ? "" : " (" + id + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
60
src/main/java/iialib/games/model/Score.java
Normal file
60
src/main/java/iialib/games/model/Score.java
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package iialib.games.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* class used to describe the score corresponding to each player role when the game is over
|
||||||
|
*/
|
||||||
|
public class Score<Role extends IRole> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public enum Status {WIN,LOOSE,TIE};
|
||||||
|
|
||||||
|
// ----------- Attributes ------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private Role role;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private Status status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* score can be just 1/0 or a real score depending on the game
|
||||||
|
*/
|
||||||
|
private int score;
|
||||||
|
|
||||||
|
// ----------- Constructors ------------
|
||||||
|
|
||||||
|
|
||||||
|
public Score(Role role, Status status, int score) {
|
||||||
|
super();
|
||||||
|
this.role = role;
|
||||||
|
this.status = status;
|
||||||
|
this.score = score;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------- Getter / Setters ------------
|
||||||
|
|
||||||
|
public Role getRole() {
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Status getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getScore() {
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------- Other public methods ------------
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "Score <" + role + "," + status + "," + score + ">";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user