diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 09b0d05..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,15 +0,0 @@
-*.class
-
-# Package Files #
-*.jar
-*.war
-*.ear
-
-# Eclipse #
-target/
-bin/
-.settings/
-.classpath
-.project
-.idea/
-*.iml
diff --git a/README.md b/README.md
deleted file mode 100644
index 5004404..0000000
--- a/README.md
+++ /dev/null
@@ -1,67 +0,0 @@
-# Minimax4j
-
-Minimax4j is a JAVA implementation of the [minimax algorithm](http://en.wikipedia.org/wiki/Minimax).
-It is a simple but complete abstract API that let you concentrate on the evaluation function.
-
-```xml
-
- fr.avianey
- minimax4j
- 1.0.0
-
-```
-
-## Samples
-
-Samples are available in the minimax-sample project and provide basic implementations for the following IA :
-* Tic-Tac-Toe
-
-## Documentation
-
-The [Minimax4j javadoc](http://avianey.github.com/minimax4j/) is available on the github project page.
-
-## Licence
-
-```
-The MIT License (MIT)
-
-Copyright (c) 2015 Antoine Vianey
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-```
-
-## Contribute
-
-Feel free to contribute by sending pull requests.
-Abstract mechanism that would likely fit into the API are :
-* Transposition table (to optimize & test)
-* Quiescence search
-* Opening table
-* Best-First Search
-
-## Contributors
-
-* [@avianey](https://github.com/avianey) : creator
-
-## Who's using it ?
-
-List of projects using minimax4j :
-* [Reversi](https://play.google.com/store/apps/details?id=net.androgames.reversi) for Android on Google play ([@avianey](https://github.com/avianey))
-
-Fork the project and send a pull request to add your application in this list.
diff --git a/allclasses-frame.html b/allclasses-frame.html
new file mode 100644
index 0000000..cd901a9
--- /dev/null
+++ b/allclasses-frame.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+
diff --git a/fr/pixelprose/minimax4j/1.0.0/_maven.repositories b/fr/pixelprose/minimax4j/1.0.0/_maven.repositories
new file mode 100644
index 0000000..f2d1792
--- /dev/null
+++ b/fr/pixelprose/minimax4j/1.0.0/_maven.repositories
@@ -0,0 +1,4 @@
+#NOTE: This is an internal implementation file, its format can be changed without prior notice.
+#Thu Feb 28 13:42:40 CET 2013
+minimax4j-1.0.0.jar>=
+minimax4j-1.0.0.pom>=
diff --git a/fr/pixelprose/minimax4j/1.0.0/minimax4j-1.0.0.jar b/fr/pixelprose/minimax4j/1.0.0/minimax4j-1.0.0.jar
new file mode 100644
index 0000000..4389f53
Binary files /dev/null and b/fr/pixelprose/minimax4j/1.0.0/minimax4j-1.0.0.jar differ
diff --git a/fr/pixelprose/minimax4j/1.0.0/minimax4j-1.0.0.pom b/fr/pixelprose/minimax4j/1.0.0/minimax4j-1.0.0.pom
new file mode 100644
index 0000000..84f28ff
--- /dev/null
+++ b/fr/pixelprose/minimax4j/1.0.0/minimax4j-1.0.0.pom
@@ -0,0 +1,55 @@
+
+
+ 4.0.0
+ minimax4j
+ fr.pixelprose
+ minimax4j
+ 1.0.0
+
+ Minimax4j is a pure java implementation of the minimax algorithm.
+ It provides implementation of standard minimax but also provides alpha-beta pruning, negamax or negascout.
+ This project can be use to implement two-person zero-sum games of perfect information such as chess, reversi, connect four, ...
+
+
+
+ Antoine Vianey
+
+ developer
+
+ http://avianey.blogspot.com
+
+
+
+
+
+ GNU Lesser General Public License version 3
+ http://www.gnu.org/licenses/lgpl.html
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 2.5.1
+
+ 1.6
+ 1.6
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 2.8.1
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/fr/pixelprose/minimax4j/Difficulty.html b/fr/pixelprose/minimax4j/Difficulty.html
new file mode 100644
index 0000000..7f3d9eb
--- /dev/null
+++ b/fr/pixelprose/minimax4j/Difficulty.html
@@ -0,0 +1,214 @@
+
+
+
+
+
+
+Difficulty (minimax4j 1.0.0 API)
+
+
+
+
+
+
+
+
Returns an array containing the constants of this enum type, in
+the order they are declared. This method may be used to iterate
+over the constants as follows:
+
+for (IA.Algorithm c : IA.Algorithm.values())
+ System.out.println(c);
+
+
Returns:
an array containing the constants of this enum type, in
+the order they are declared
Returns the enum constant of this type with the specified name.
+The string must match exactly an identifier used to declare an
+enum constant in this type. (Extraneous whitespace characters are
+not permitted.)
+
Parameters:
name - the name of the enum constant to be returned.
public abstract class IA<M extends Move>
+extends Object
+
Abstract class implementing minimax and derivated decision rules for two-person zero-sum games of perfect information.
+ Extend this class to implement IA for several games, such as :
+
Play the given move and modify the state of the game.
+ This function must set correctly the turn of the next player
+ ... by calling the next() method for example.
Undo the given move and restore the state of the game.
+ This function must restore correctly the turn of the previous player
+ ... by calling the previous() method for example.
+ "Improvement (of the alpha beta pruning) can be achieved without
+ sacrificing accuracy, by using ordering heuristics to search parts
+ of the tree that are likely to force alpha-beta cutoffs early."
+ - Alpha-beta pruning on Wikipedia
Change current turn to the next player.
+ This method must not be used in conjunction with the makeMove() method.
+ Use it to implement a pass functionality.
Change current turn to the previous player.
+ This method must not be used in conjunction with the unmakeMove() method.
+ Use it to implement an undo functionality.
This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
+
+
+
+
+
Package
+
Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:
+
+
Interfaces (italic)
+
Classes
+
Enums
+
Exceptions
+
Errors
+
Annotation Types
+
+
+
+
Class/Interface
+
Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:
+
+
Class inheritance diagram
+
Direct Subclasses
+
All Known Subinterfaces
+
All Known Implementing Classes
+
Class/interface declaration
+
Class/interface description
+
+
+
Nested Class Summary
+
Field Summary
+
Constructor Summary
+
Method Summary
+
+
+
Field Detail
+
Constructor Detail
+
Method Detail
+
+
Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.
+
+
+
Annotation Type
+
Each annotation type has its own separate page with the following sections:
+
+
Annotation Type declaration
+
Annotation Type description
+
Required Element Summary
+
Optional Element Summary
+
Element Detail
+
+
+
+
Enum
+
Each enum has its own separate page with the following sections:
+
+
Enum declaration
+
Enum description
+
Enum Constant Summary
+
Enum Constant Detail
+
+
+
+
Use
+
Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.
+
+
+
Tree (Class Hierarchy)
+
There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with java.lang.Object. The interfaces do not inherit from java.lang.Object.
+
+
When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.
+
When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.
+
+
+
+
Deprecated API
+
The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.
+
+
+
Index
+
The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.
+
+
+
Prev/Next
+
These links take you to the next or previous class, interface, package, or related page.
+
+
+
Frames/No Frames
+
These links show and hide the HTML frames. All pages are available with or without frames.
+
+
+
All Classes
+
The All Classes link shows all classes and interfaces except non-static nested types.
+
+
+
Serialized Form
+
Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.
+
+
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..8987122
--- /dev/null
+++ b/index.html
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+minimax4j 1.0.0 API
+
+
+
+
diff --git a/minimax4j-sample/pom.xml b/minimax4j-sample/pom.xml
deleted file mode 100644
index 965326c..0000000
--- a/minimax4j-sample/pom.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-
-
- 4.0.0
- minimax4j-sample
- fr.avianey
- minimax4j-sample
- 1.0.1-SNAPSHOT
-
- Minimax4j is a pure java implementation of the minimax algorithm.
- It provides implementation of standard minimax but also provides alpha-beta pruning, negamax or negascout.
- This project can be use to implement two-person zero-sum games of perfect information such as chess, reversi, connect four, ...
-
-
-
- Antoine Vianey
-
- developer
-
- http://avianey.blogspot.com
-
-
-
-
-
- fr.avianey
- minimax4j
- 1.0.1-SNAPSHOT
-
-
- junit
- junit
- 4.8.2
- test
-
-
-
-
-
- GNU General Public License version 3
- http://www.gnu.org/licenses/
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.1
-
- 1.7
- 1.7
-
-
-
- org.apache.maven.plugins
- maven-javadoc-plugin
- 2.8.1
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/minimax4j-sample/src/main/java/fr/avianey/minimax4j/sample/tictactoe/TicTacToeMinimax.java b/minimax4j-sample/src/main/java/fr/avianey/minimax4j/sample/tictactoe/TicTacToeMinimax.java
deleted file mode 100644
index 975315a..0000000
--- a/minimax4j-sample/src/main/java/fr/avianey/minimax4j/sample/tictactoe/TicTacToeMinimax.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * This file is part of minimax4j.
- *
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2015 Antoine Vianey
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package fr.avianey.minimax4j.sample.tictactoe;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import fr.avianey.minimax4j.BasicMinimax;
-import fr.avianey.minimax4j.Minimax;
-
-/**
- * Simple TicTacToe IA to showcase the API.
- *
- * @author antoine vianey
- */
-public class TicTacToeMinimax extends BasicMinimax {
-
- static final int FREE = 0;
- static final int PLAYER_X = 1; // X
- static final int PLAYER_O = 2; // O
-
- private static final int GRID_SIZE = 3;
-
- /** The grid */
- private final int[][] grid;
-
- private int currentPlayer;
- private int turn = 0;
-
- public TicTacToeMinimax(Algorithm algo) {
- super(algo);
- this.grid = new int[GRID_SIZE][GRID_SIZE];
- newGame();
- }
-
- public void newGame() {
- for (int i = 0; i < GRID_SIZE; i++) {
- for (int j = 0; j < GRID_SIZE; j++) {
- grid[i][j] = FREE;
- }
- }
- // X start to play
- currentPlayer = PLAYER_X;
- turn = 0;
- }
-
- @Override
- public boolean isOver() {
- return hasWon(PLAYER_O) || hasWon(PLAYER_X) || turn == 9;
- }
-
- private boolean hasWon(int player) {
- return
- (player == grid[0][1] && player == grid[0][2] && player == grid[0][0])
- ||
- (player == grid[1][1] && player == grid[1][2] && player == grid[1][0])
- ||
- (player == grid[2][1] && player == grid[2][2] && player == grid[2][0])
- ||
- (player == grid[1][0] && player == grid[2][0] && player == grid[0][0])
- ||
- (player == grid[1][1] && player == grid[2][1] && player == grid[0][1])
- ||
- (player == grid[1][2] && player == grid[2][2] && player == grid[0][2])
- ||
- (player == grid[1][1] && player == grid[2][2] && player == grid[0][0])
- ||
- (player == grid[1][1] && player == grid[2][0] && player == grid[0][2]);
- }
-
- @Override
- public void makeMove(TicTacToeMove move) {
- grid[move.getX()][move.getY()] = currentPlayer;
- turn++;
- next();
- }
-
- @Override
- public void unmakeMove(TicTacToeMove move) {
- grid[move.getX()][move.getY()] = FREE;
- turn--;
- previous();
- }
-
- @Override
- public List getPossibleMoves() {
- List moves = new ArrayList<>(9);
- for (int i = 0; i < GRID_SIZE; i++) {
- for (int j = 0; j < GRID_SIZE; j++) {
- if (grid[i][j] == FREE) {
- moves.add(new TicTacToeMove(i, j, currentPlayer));
- }
- }
- }
- // moves can be sorted to optimize alpha-beta pruning
- // {1,1} is always the best move when available
- return moves;
- }
-
- @Override
- public double evaluate() {
- int eval = 0;
- if (hasWon(currentPlayer)) {
- // 2 for the win
- eval = 2;
- } else if (hasWon(3 - currentPlayer)) {
- // -2 for loosing
- eval = -2;
- } else if (grid[1][1] == currentPlayer) {
- // 1 for {1,1}
- eval = 1;
- } else if (grid[1][1] == 3 - currentPlayer) {
- // -1 for opponent {1,1}
- eval = -1;
- }
- return eval;
- }
-
- @Override
- public double maxEvaluateValue() {
- // evaluate return either -2, -1, 0, 1 or 2
- return 3;
- }
-
- @Override
- public void next() {
- currentPlayer = 3 - currentPlayer;
- }
-
- @Override
- public void previous() {
- currentPlayer = 3 - currentPlayer;
- }
-
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append(grid[0][0] == FREE ? " " : (grid[0][0] == PLAYER_O ? "O" : "X"));
- sb.append(grid[1][0] == FREE ? " " : (grid[1][0] == PLAYER_O ? "O" : "X"));
- sb.append(grid[2][0] == FREE ? " " : (grid[2][0] == PLAYER_O ? "O" : "X"));
- sb.append("\n");
- sb.append(grid[0][1] == FREE ? " " : (grid[0][1] == PLAYER_O ? "O" : "X"));
- sb.append(grid[1][1] == FREE ? " " : (grid[1][1] == PLAYER_O ? "O" : "X"));
- sb.append(grid[2][1] == FREE ? " " : (grid[2][1] == PLAYER_O ? "O" : "X"));
- sb.append("\n");
- sb.append(grid[0][2] == FREE ? " " : (grid[0][2] == PLAYER_O ? "O" : "X"));
- sb.append(grid[1][2] == FREE ? " " : (grid[1][2] == PLAYER_O ? "O" : "X"));
- sb.append(grid[2][2] == FREE ? " " : (grid[2][2] == PLAYER_O ? "O" : "X"));
- sb.append("\n");
- return sb.toString();
- }
-
-}
diff --git a/minimax4j-sample/src/main/java/fr/avianey/minimax4j/sample/tictactoe/TicTacToeMove.java b/minimax4j-sample/src/main/java/fr/avianey/minimax4j/sample/tictactoe/TicTacToeMove.java
deleted file mode 100644
index ce3c4b3..0000000
--- a/minimax4j-sample/src/main/java/fr/avianey/minimax4j/sample/tictactoe/TicTacToeMove.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * This file is part of minimax4j.
- *
- *
- * The MIT License (MIT)
-*
- * Copyright (c) 2015 Antoine Vianey
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package fr.avianey.minimax4j.sample.tictactoe;
-
-import fr.avianey.minimax4j.Move;
-
-/**
- * A basic move implementation : who and where...
- *
- * @author antoine vianey
- */
-public class TicTacToeMove implements Move {
-
- /** The player owning the move */
- private int player;
-
- /** x coordinate of the move */
- private int x;
- /** y coordinate of the move */
- private int y;
-
- public TicTacToeMove(int x, int y, int player) {
- this.x = x;
- this.y = y;
- this.player = player;
- }
-
- public int getX() {
- return x;
- }
-
- public void setX(int x) {
- this.x = x;
- }
-
- public int getY() {
- return y;
- }
-
- public void setY(int y) {
- this.y = y;
- }
-
- public int getPlayer() {
- return player;
- }
-
- public void setPlayer(int player) {
- this.player = player;
- }
-
- public String toString() {
- return (player == TicTacToeMinimax.PLAYER_O ? "O" : "X") + " (" + x + ";" + y + ")";
- }
-
-}
diff --git a/minimax4j-sample/src/main/java/fr/avianey/minimax4j/sample/tictactoe/TicTacToeParallelMinimax.java b/minimax4j-sample/src/main/java/fr/avianey/minimax4j/sample/tictactoe/TicTacToeParallelMinimax.java
deleted file mode 100644
index f68b5d8..0000000
--- a/minimax4j-sample/src/main/java/fr/avianey/minimax4j/sample/tictactoe/TicTacToeParallelMinimax.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * This file is part of minimax4j.
- *
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2015 Antoine Vianey
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package fr.avianey.minimax4j.sample.tictactoe;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import fr.avianey.minimax4j.ParallelMinimax;
-
-/**
- * Simple TicTacToe IA to showcase the API.
- *
- * @author antoine vianey
- */
-public class TicTacToeParallelMinimax extends ParallelMinimax {
-
- static final int FREE = 0;
- static final int PLAYER_X = 1; // X
- static final int PLAYER_O = 2; // O
-
- private static final int GRID_SIZE = 3;
-
- /** The grid */
- private final int[][] grid;
-
- private int currentPlayer;
- private int turn = 0;
-
- public TicTacToeParallelMinimax(Algorithm algo) {
- super(algo);
- this.grid = new int[GRID_SIZE][GRID_SIZE];
- newGame();
- }
-
- private TicTacToeParallelMinimax(Algorithm algo, int[][] grid, int turn, int currentPlayer) {
- this(algo);
- this.currentPlayer = currentPlayer;
- this.turn = turn;
- for (int i = 0; i < GRID_SIZE; i++) {
- for (int j = 0; j < GRID_SIZE; j++) {
- this.grid[i][j] = grid[i][j];
- }
- }
- }
-
- public void newGame() {
- for (int i = 0; i < GRID_SIZE; i++) {
- for (int j = 0; j < GRID_SIZE; j++) {
- grid[i][j] = FREE;
- }
- }
- // X start to play
- currentPlayer = PLAYER_X;
- turn = 0;
- }
-
- @Override
- public boolean isOver() {
- return hasWon(PLAYER_O) || hasWon(PLAYER_X) || turn == 9;
- }
-
- private boolean hasWon(int player) {
- return
- (player == grid[0][1] && player == grid[0][2] && player == grid[0][0])
- ||
- (player == grid[1][1] && player == grid[1][2] && player == grid[1][0])
- ||
- (player == grid[2][1] && player == grid[2][2] && player == grid[2][0])
- ||
- (player == grid[1][0] && player == grid[2][0] && player == grid[0][0])
- ||
- (player == grid[1][1] && player == grid[2][1] && player == grid[0][1])
- ||
- (player == grid[1][2] && player == grid[2][2] && player == grid[0][2])
- ||
- (player == grid[1][1] && player == grid[2][2] && player == grid[0][0])
- ||
- (player == grid[1][1] && player == grid[2][0] && player == grid[0][2]);
- }
-
- @Override
- public void makeMove(TicTacToeMove move) {
- grid[move.getX()][move.getY()] = currentPlayer;
- turn++;
- next();
- }
-
- @Override
- public void unmakeMove(TicTacToeMove move) {
- grid[move.getX()][move.getY()] = FREE;
- turn--;
- previous();
- }
-
- @Override
- public List getPossibleMoves() {
- List moves = new ArrayList<>(9);
- for (int i = 0; i < GRID_SIZE; i++) {
- for (int j = 0; j < GRID_SIZE; j++) {
- if (grid[i][j] == FREE) {
- moves.add(new TicTacToeMove(i, j, currentPlayer));
- }
- }
- }
- // moves can be sorted to optimize alpha-beta pruning
- // {1,1} is always the best move when available
- return moves;
- }
-
- @Override
- public double evaluate() {
- int eval = 0;
- if (hasWon(currentPlayer)) {
- // 2 for the win
- eval = 2;
- } else if (hasWon(3 - currentPlayer)) {
- // -2 for loosing
- eval = -2;
- } else if (grid[1][1] == currentPlayer) {
- // 1 for {1,1}
- eval = 1;
- } else if (grid[1][1] == 3 - currentPlayer) {
- // -1 for opponent {1,1}
- eval = -1;
- }
- return eval;
- }
-
- @Override
- public double maxEvaluateValue() {
- // evaluate return either -2, -1, 0, 1 or 2
- return 3;
- }
-
- @Override
- public void next() {
- currentPlayer = 3 - currentPlayer;
- }
-
- @Override
- public void previous() {
- currentPlayer = 3 - currentPlayer;
- }
-
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append(grid[0][0] == FREE ? " " : (grid[0][0] == PLAYER_O ? "O" : "X"));
- sb.append(grid[1][0] == FREE ? " " : (grid[1][0] == PLAYER_O ? "O" : "X"));
- sb.append(grid[2][0] == FREE ? " " : (grid[2][0] == PLAYER_O ? "O" : "X"));
- sb.append("\n");
- sb.append(grid[0][1] == FREE ? " " : (grid[0][1] == PLAYER_O ? "O" : "X"));
- sb.append(grid[1][1] == FREE ? " " : (grid[1][1] == PLAYER_O ? "O" : "X"));
- sb.append(grid[2][1] == FREE ? " " : (grid[2][1] == PLAYER_O ? "O" : "X"));
- sb.append("\n");
- sb.append(grid[0][2] == FREE ? " " : (grid[0][2] == PLAYER_O ? "O" : "X"));
- sb.append(grid[1][2] == FREE ? " " : (grid[1][2] == PLAYER_O ? "O" : "X"));
- sb.append(grid[2][2] == FREE ? " " : (grid[2][2] == PLAYER_O ? "O" : "X"));
- sb.append("\n");
- return sb.toString();
- }
-
- @Override
- public ParallelMinimax clone() {
- return new TicTacToeParallelMinimax(getAlgorithm(), grid, turn, currentPlayer);
- }
-
-}
diff --git a/minimax4j-sample/src/main/java/fr/avianey/minimax4j/sample/tictactoe/TicTacToeTranspositionMinimax.java b/minimax4j-sample/src/main/java/fr/avianey/minimax4j/sample/tictactoe/TicTacToeTranspositionMinimax.java
deleted file mode 100644
index c5da733..0000000
--- a/minimax4j-sample/src/main/java/fr/avianey/minimax4j/sample/tictactoe/TicTacToeTranspositionMinimax.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * This file is part of minimax4j.
- *
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2015 Antoine Vianey
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package fr.avianey.minimax4j.sample.tictactoe;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import fr.avianey.minimax4j.TranspositionMinimax;
-
-/**
- * Simple TicTacToe IA to showcase the API.
- *
- * @author antoine vianey
- */
-public class TicTacToeTranspositionMinimax extends TranspositionMinimax {
-
- static final int FREE = 0;
- static final int PLAYER_X = 1; // X : 01
- static final int PLAYER_O = 2; // O : 10
-
- private static final int GRID_SIZE = 3;
- private static final int MAX_TURN = GRID_SIZE * GRID_SIZE;
-
- /** The grid */
- private final int[][] grid;
-
- private int currentPlayer;
- private int turn = 0;
- private int hash = 0;
-
- public TicTacToeTranspositionMinimax(Algorithm algo) {
- super(algo);
- this.grid = new int[GRID_SIZE][GRID_SIZE];
- newGame();
- }
-
- public void newGame() {
- hash = 0;
- for (int i = 0; i < GRID_SIZE; i++) {
- for (int j = 0; j < GRID_SIZE; j++) {
- grid[i][j] = FREE;
- }
- }
- // X start to play
- currentPlayer = PLAYER_X;
- turn = 0;
- }
-
- @Override
- public boolean isOver() {
- return hasWon(PLAYER_O) || hasWon(PLAYER_X) || turn == 9;
- }
-
- private boolean hasWon(int player) {
- return
- (player == grid[0][1] && player == grid[0][2] && player == grid[0][0])
- ||
- (player == grid[1][1] && player == grid[1][2] && player == grid[1][0])
- ||
- (player == grid[2][1] && player == grid[2][2] && player == grid[2][0])
- ||
- (player == grid[1][0] && player == grid[2][0] && player == grid[0][0])
- ||
- (player == grid[1][1] && player == grid[2][1] && player == grid[0][1])
- ||
- (player == grid[1][2] && player == grid[2][2] && player == grid[0][2])
- ||
- (player == grid[1][1] && player == grid[2][2] && player == grid[0][0])
- ||
- (player == grid[1][1] && player == grid[2][0] && player == grid[0][2]);
- }
-
- @Override
- public void makeMove(TicTacToeMove move) {
- grid[move.getX()][move.getY()] = move.getPlayer();
- hash = hash ^ (move.getPlayer() << ((move.getX() + GRID_SIZE * move.getY()) * 2));
- turn++;
- next();
- }
-
- @Override
- public void unmakeMove(TicTacToeMove move) {
- grid[move.getX()][move.getY()] = FREE;
- hash = hash ^ (move.getPlayer() << ((move.getX() + GRID_SIZE * move.getY()) * 2));
- turn--;
- previous();
- }
-
- @Override
- public List getPossibleMoves() {
- List moves = new ArrayList<>(9);
- for (int i = 0; i < GRID_SIZE; i++) {
- for (int j = 0; j < GRID_SIZE; j++) {
- if (grid[i][j] == FREE) {
- moves.add(new TicTacToeMove(i, j, currentPlayer));
- }
- }
- }
- // moves can be sorted to optimize alpha-beta pruning
- // {1,1} is always the best move when available
- return moves;
- }
-
- @Override
- public double evaluate() {
- int eval = 0;
- if (hasWon(currentPlayer)) {
- // 2 for the win
- eval = 2;
- } else if (hasWon(3 - currentPlayer)) {
- // -2 for loosing
- eval = -2;
- } else if (grid[1][1] == currentPlayer) {
- // 1 for {1,1}
- eval = 1;
- } else if (grid[1][1] == 3 - currentPlayer) {
- // -1 for opponent {1,1}
- eval = -1;
- }
- return eval;
- }
-
- @Override
- public double maxEvaluateValue() {
- // evaluate return either -2, -1, 0, 1 or 2
- return 3;
- }
-
- @Override
- public void next() {
- currentPlayer = 3 - currentPlayer;
- }
-
- @Override
- public void previous() {
- currentPlayer = 3 - currentPlayer;
- }
-
- /*===============================*
- * TRANSPOSITION TABLE BACKED IA *
- *===============================*/
-
- @Override
- public Integer getTransposition() {
- return hash;
- }
-
- @Override
- public Integer getGroup() {
- // as moves increase over turns
- // we don't need to keep transposition from previous turns
- return turn;
- }
-
- @Override
- public boolean clearGroupsAfterSearch() {
- // remove useless transposition after search
- // groups reflect turns and as players can't
- // go back on a move in the next turn,
- // transpositions from previous turns are useless
- return true;
- }
-
- @Override
- public TicTacToeMove getBestMove(int depth) {
- TicTacToeMove move = super.getBestMove(depth);
- // clear the content of the transposition table
- // unless it reached the max depth... if not
- // using a known transposition value will lead to a loss
- // of search depth as we will use the result of an evaluation
- // with a lower depth of prediction !
- // we may have used informations from the transposition table
- // to order available moves as an optimization for alpha-beta cut-off
- if (turn + depth < MAX_TURN) {
- // use with caution
- super.clearTranspositionTable();
- }
-// super.clearTranspositionTable();
- return move;
- }
-
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append(grid[0][0] == FREE ? " " : (grid[0][0] == PLAYER_O ? "O" : "X"));
- sb.append(grid[1][0] == FREE ? " " : (grid[1][0] == PLAYER_O ? "O" : "X"));
- sb.append(grid[2][0] == FREE ? " " : (grid[2][0] == PLAYER_O ? "O" : "X"));
- sb.append("\n");
- sb.append(grid[0][1] == FREE ? " " : (grid[0][1] == PLAYER_O ? "O" : "X"));
- sb.append(grid[1][1] == FREE ? " " : (grid[1][1] == PLAYER_O ? "O" : "X"));
- sb.append(grid[2][1] == FREE ? " " : (grid[2][1] == PLAYER_O ? "O" : "X"));
- sb.append("\n");
- sb.append(grid[0][2] == FREE ? " " : (grid[0][2] == PLAYER_O ? "O" : "X"));
- sb.append(grid[1][2] == FREE ? " " : (grid[1][2] == PLAYER_O ? "O" : "X"));
- sb.append(grid[2][2] == FREE ? " " : (grid[2][2] == PLAYER_O ? "O" : "X"));
- sb.append("\n");
- return sb.toString();
- }
-
-}
diff --git a/minimax4j/pom.xml b/minimax4j/pom.xml
deleted file mode 100644
index 7f9c314..0000000
--- a/minimax4j/pom.xml
+++ /dev/null
@@ -1,187 +0,0 @@
-
-
- 4.0.0
- minimax4j
- fr.avianey
- minimax4j
- jar
- 1.0.1-SNAPSHOT
-
- Minimax4j is a pure java implementation of the IA algorithm.
- It provides implementation of standard IA but also provides alpha-beta pruning, negamax or negascout.
- This project can be use to implement two-person zero-sum games of perfect information such as chess, reversi, connect four, ...
-
-
-
- Antoine Vianey
-
- developer
-
- http://avianey.github.com
-
-
-
-
- org.sonatype.oss
- oss-parent
- 7
-
-
-
-
- The MIT License
- https://opensource.org/licenses/MIT
- repo
-
-
-
-
- https://github.com/avianey/minimax4j
- scm:git:git@github.com/avianey/minimax4j.git
- scm:git:git://github.com/avianey/minimax4j.git
- HEAD
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-release-plugin
- 2.4.2
-
- forked-path
- false
- -Psonatype-oss-release
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-javadoc-plugin
- 2.9.1
-
-
- attach-javadocs
-
- jar
-
-
- ${javadoc.additionalparam}
-
-
-
-
-
- org.apache.maven.plugins
- maven-source-plugin
- 2.2.1
-
- ${project.build.directory}
- true
-
-
-
- attach-sources
-
- jar
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.1
-
- 1.8
- 1.8
-
-
-
- org.apache.maven.plugins
- maven-release-plugin
-
- false
-
-
-
-
-
-
-
- com.google.guava
- guava
- 18.0
- test
-
-
- fr.avianey
- bitboard4j
- 1.0.0
- test
-
-
- junit
- junit
- 4.12
- test
-
-
-
-
-
-
- release-sign-artifacts
-
-
- performRelease
- true
-
-
-
-
-
- org.apache.maven.plugins
- maven-gpg-plugin
- 1.4
-
-
- sign-artifacts
- verify
-
- sign
-
-
-
-
-
-
-
-
- sonatype-nexus-staging
- https://oss.sonatype.org/service/local/staging/deploy/maven2
-
-
-
-
- javadoc-8
-
- 1.8
-
-
- -Xdoclint:none
-
-
-
-
-
\ No newline at end of file
diff --git a/minimax4j/src/main/java/fr/avianey/minimax4j/IA.java b/minimax4j/src/main/java/fr/avianey/minimax4j/IA.java
deleted file mode 100644
index 4b3fb30..0000000
--- a/minimax4j/src/main/java/fr/avianey/minimax4j/IA.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * This file is part of minimax4j.
- *
- *
- * The MIT License (MIT)
-
- * Copyright (c) 2015 Antoine Vianey
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package fr.avianey.minimax4j;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * Base interface for minimax and derivated decision rules for two-person
- * zero-sum games of perfect information.
- * Extend this class to implement IA for several games, such as :
- *
- *
Chess
- *
Reversi
- *
Checkers
- *
Go
- *
Connect Four
- *
Tic Tac Toe
- *
...
- *
- *
- * @author antoine vianey
- *
- * @param Implementation of the Move interface to use
- */
-public interface IA {
-
- /**
- * Get {@link Move} static evaluations at the given search depth
- * This methods iterates over {@link #getPossibleMoves()} to evaluate each.
- * @param depth The search depth (must be > 0)
- * @return The list of possible moves in descending evaluation order (best first)
- * @see #evaluate()
- */
- default List getBestMoves(final int depth) {
- return this.getBestMoves(depth, getPossibleMoves());
- }
-
- /**
- * Get {@link Move} static evaluations at the given search depth
- * This methods iterates over provided ordered moves to evaluate each and maximize cutoff.
- * @param depth The search depth (must be > 0)
- * @param possibleMoves The list of possible moves
- * @return The list of possible moves in descending evaluation order (best first)
- * @see #evaluate()
- */
- List getBestMoves(final int depth, Iterable possibleMoves);
-
- /**
- * Tell weather or not the game is over.
- * @return
- * True if the game is over
- */
- boolean isOver();
-
- /**
- * Play the given move and modify the state of the game.
- * This function MUST set correctly the turn of the next player
- * ... by calling the next() method for example.
- * @param move
- * The move to play
- * @see #next()
- */
- void makeMove(M move);
-
- /**
- * Undo the given move and restore the state of the game.
- * This function MUST restore correctly the turn of the previous player
- * ... by calling the previous() method for example.
- * @param move
- * The move to cancel
- * @see #previous()
- */
- void unmakeMove(M move);
-
- /**
- * List every valid moves for the current player.
- * "Improvement (of the alpha beta pruning) can be achieved without
- * sacrificing accuracy, by using ordering heuristics to search parts
- * of the tree that are likely to force alpha-beta cutoffs early."
- * - Alpha-beta pruning on Wikipedia
- * @return
- * The list of the current player possible moves
- */
- Iterable getPossibleMoves();
-
- /**
- * Evaluate the state of the game for the current player after a move.
- * The greatest the value is, the better the position of the current player is.
- * @return
- * The evaluation of the position for the current player
- * @see #maxEvaluateValue()
- */
- double evaluate();
-
- /**
- * The absolute maximal value for the evaluate function.
- * This value must not be equal to a possible return value of the evaluation function.
- * @return
- * The non inclusive maximal value
- * @see #evaluate()
- */
- double maxEvaluateValue();
-
- /**
- * Change current turn to the next player.
- * This method must not be used in conjunction with the makeMove() method.
- * Use it to implement a pass functionality.
- * @see #makeMove(Move)
- */
- void next();
-
- /**
- * Change current turn to the previous player.
- * This method must not be used in conjunction with the unmakeMove() method.
- * Use it to implement an undo functionality.
- * @see #unmakeMove(Move)
- */
- void previous();
-
-}
diff --git a/minimax4j/src/main/java/fr/avianey/minimax4j/IADecorator.java b/minimax4j/src/main/java/fr/avianey/minimax4j/IADecorator.java
deleted file mode 100644
index 7936b91..0000000
--- a/minimax4j/src/main/java/fr/avianey/minimax4j/IADecorator.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * This file is part of minimax4j.
- *
- *
- * The MIT License (MIT)
-
- * Copyright (c) 2015 Antoine Vianey
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package fr.avianey.minimax4j;
-
-import java.util.List;
-
-public abstract class IADecorator implements IA {
-
- protected final IA ia;
-
- public IADecorator(IA ia) {
- this.ia = ia;
- }
-
- @Override
- public List getBestMoves(int depth) {
- return ia.getBestMoves(depth);
- }
-
- @Override
- public boolean isOver() {
- return ia.isOver();
- }
-
- @Override
- public void makeMove(M move) {
- ia.makeMove(move);
- }
-
- @Override
- public void unmakeMove(M move) {
- ia.unmakeMove(move);
- }
-
- @Override
- public Iterable getPossibleMoves() {
- return ia.getPossibleMoves();
- }
-
- @Override
- public double evaluate() {
- return ia.evaluate();
- }
-
- @Override
- public double maxEvaluateValue() {
- return ia.maxEvaluateValue();
- }
-
- @Override
- public void next() {
- ia.next();
- }
-
- @Override
- public void previous() {
- ia.previous();
- }
-}
diff --git a/minimax4j/src/main/java/fr/avianey/minimax4j/IAUtils.java b/minimax4j/src/main/java/fr/avianey/minimax4j/IAUtils.java
deleted file mode 100644
index 51df854..0000000
--- a/minimax4j/src/main/java/fr/avianey/minimax4j/IAUtils.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package fr.avianey.minimax4j;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-public final class IAUtils {
-
- private IAUtils() {}
-
- public static List iterableToSortedList(Iterable iterable) {
- if (iterable instanceof Collection) {
- return new ArrayList<>((Collection) iterable);
- }
- List list = new ArrayList<>();
- for (M m : iterable) {
- list.add(m);
- }
- return list;
- }
-
-}
diff --git a/minimax4j/src/main/java/fr/avianey/minimax4j/Move.java b/minimax4j/src/main/java/fr/avianey/minimax4j/Move.java
deleted file mode 100644
index 76bab22..0000000
--- a/minimax4j/src/main/java/fr/avianey/minimax4j/Move.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * This file is part of minimax4j.
- *
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2015 Antoine Vianey
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package fr.avianey.minimax4j;
-
-import static java.lang.Double.isNaN;
-import static java.lang.Math.signum;
-
-/**
- *
- * Implement this interface to describe a Move in your game.
- * A typical implementation for a Chess game would be :
- *
- *
The color of the piece
- *
The type of the piece (king, queen, pawn, ...)
- *
The position before the move
- *
The position after the move
- *
- * Additional information might be necessary to implement the abstract {@link IA#unmakeMove(Move)} method of the {@link IA} class :
- *
- *
Taken pieces
- *
...
- *
- *
- * @author antoine vianey
- * @see IA#unmakeMove(Move)
- * @see IA#makeMove(Move)
- *
- */
-public abstract class Move implements Comparable {
-
- public double value = Double.NaN;
-
- @Override
- public int compareTo(Move move) {
- if (isNaN(value) && isNaN(move.value)) {
- return 0;
- } else if (isNaN(value)) {
- return -1;
- } else if (isNaN(move.value)) {
- return 1;
- }
- return (int) signum(move.value - value);
- }
-
-}
diff --git a/minimax4j/src/main/java/fr/avianey/minimax4j/impl/AlphaBeta.java b/minimax4j/src/main/java/fr/avianey/minimax4j/impl/AlphaBeta.java
deleted file mode 100644
index 12289f4..0000000
--- a/minimax4j/src/main/java/fr/avianey/minimax4j/impl/AlphaBeta.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * This file is part of minimax4j.
- *
- *
- * The MIT License (MIT)
-
- * Copyright (c) 2015 Antoine Vianey
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package fr.avianey.minimax4j.impl;
-
-import fr.avianey.minimax4j.IA;
-import fr.avianey.minimax4j.Move;
-
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-import static fr.avianey.minimax4j.IAUtils.iterableToSortedList;
-
-/**
- * AlphaBeta based implementation.
- *
- *
- * function alphabeta(node, depth, α, β, maximizingPlayer)
- * if depth = 0 or node is a terminal node
- * return the heuristic value of node
- * if maximizingPlayer
- * for each child of node
- * α := max(α, alphabeta(child, depth - 1, α, β, FALSE))
- * if β <= α
- * break (* β cut-off *)
- * return a
- * else
- * for each child of node
- * β := min(β, alphabeta(child, depth - 1, α, β, TRUE))
- * if β <= α
- * break (* α cut-off *)
- * return β
- *
- *
- * Initial call for maximizing player
- *
alphabeta(origin, depth, -8, +8, TRUE)
- *
- * @author antoine vianey
- *
- * @param Implementation of the Move interface to use
- * @deprecated For testing and documentation purpose only, the preferred way to implement IA is to use {@link Negamax}.
- */
-@Deprecated
-public abstract class AlphaBeta implements IA {
-
- @Override
- public List getBestMoves(final int depth, Iterable possibleMoves) {
- if (depth <= 0) {
- throw new IllegalArgumentException("Search depth MUST be > 0");
- }
- List orderedMoves = iterableToSortedList(possibleMoves);
- alphabeta(orderedMoves, depth, 1, -maxEvaluateValue(), maxEvaluateValue());
- Collections.sort(orderedMoves);
- return orderedMoves;
- }
-
- private double alphabeta(final Iterable initialMoves, final int depth, final int who, double alpha, double beta) {
- if (depth == 0 || isOver()) {
- return who * evaluate();
- }
- double score;
- Iterator moves = (initialMoves != null ? initialMoves : getPossibleMoves()).iterator();
- if (!moves.hasNext()) {
- next();
- score = alphabetaScore(depth, who, alpha, beta);
- previous();
- return score;
- }
- if (who > 0) {
- while (moves.hasNext()) {
- M move = moves.next();
- makeMove(move);
- score = alphabetaScore(depth, who, alpha, beta);
- unmakeMove(move);
- if (initialMoves != null) {
- move.value = score;
- }
- if (score > alpha) {
- alpha = score;
- if (alpha >= beta) {
- break;
- }
- }
- }
- return alpha;
- } else {
- while (moves.hasNext()) {
- M move = moves.next();
- makeMove(move);
- score = alphabetaScore(depth, who, alpha, beta);
- unmakeMove(move);
- if (initialMoves != null) {
- move.value = score;
- }
- if (score < beta) {
- beta = score;
- if (alpha >= beta) {
- break;
- }
- }
- }
- return beta;
- }
- }
-
- protected double alphabetaScore(final int depth, final int who, final double alpha, final double beta) {
- return alphabeta(null, depth - 1, -who, alpha, beta);
- }
-
-}
diff --git a/minimax4j/src/main/java/fr/avianey/minimax4j/impl/Minimax.java b/minimax4j/src/main/java/fr/avianey/minimax4j/impl/Minimax.java
deleted file mode 100644
index 2ef05ca..0000000
--- a/minimax4j/src/main/java/fr/avianey/minimax4j/impl/Minimax.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * This file is part of minimax4j.
- *
- *
- * The MIT License (MIT)
-
- * Copyright (c) 2015 Antoine Vianey
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package fr.avianey.minimax4j.impl;
-
-import fr.avianey.minimax4j.IA;
-import fr.avianey.minimax4j.Move;
-
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-import static fr.avianey.minimax4j.IAUtils.iterableToSortedList;
-
-/**
- * Minimax based implementation.
- *
- *
- * function minimax(node, depth, maximizingPlayer)
- * if depth = 0 or node is a terminal node
- * return the heuristic value of node
- * if maximizingPlayer
- * bestValue := -∞
- * for each child of node
- * val := minimax(child, depth - 1, FALSE)
- * bestValue := max(bestValue, val)
- * return bestValue
- * else
- * bestValue := +∞
- * for each child of node
- * val := minimax(child, depth - 1, TRUE)
- * bestValue := min(bestValue, val)
- * return bestValue
- *
- *
- * Initial call for maximizing player
- *
minimax(origin, depth, TRUE)
- *
- * @author antoine vianey
- *
- * @param Implementation of the Move interface to use
- * @deprecated For testing and documentation purpose only, the preferred way to implement IA is to use {@link Negamax}.
- */
-@Deprecated
-public abstract class Minimax implements IA {
-
- @Override
- public List getBestMoves(final int depth, Iterable possibleMoves) {
- if (depth <= 0) {
- throw new IllegalArgumentException("Search depth MUST be > 0");
- }
- List orderedMoves = iterableToSortedList(possibleMoves);
- minimax(orderedMoves, depth, 1);
- Collections.sort(orderedMoves);
- return orderedMoves;
- }
-
- private double minimax(Iterable initialMoves, final int depth, final int who) {
- if (depth == 0 || isOver()) {
- return who * evaluate();
- }
- Iterator moves = (initialMoves != null ? initialMoves : getPossibleMoves()).iterator();
- if (!moves.hasNext()) {
- next();
- double score = minimaxScore(depth, who);
- previous();
- return score;
- }
- if (who > 0) {
- // max
- double score;
- double bestScore = -maxEvaluateValue();
- while (moves.hasNext()) {
- M move = moves.next();
- makeMove(move);
- score = minimaxScore(depth, who);
- unmakeMove(move);
- if (initialMoves != null) {
- move.value = score;
- }
- if (score > bestScore) {
- bestScore = score;
- }
- }
- return bestScore;
- } else {
- // min
- double score;
- double bestScore = maxEvaluateValue();
- while (moves.hasNext()) {
- M move = moves.next();
- makeMove(move);
- score = minimaxScore(depth, who);
- unmakeMove(move);
- if (initialMoves != null) {
- move.value = score;
- }
- if (score < bestScore) {
- bestScore = score;
- }
- }
- return bestScore;
- }
- }
-
- protected double minimaxScore(final int depth, final int who) {
- return minimax(null, depth - 1, -who);
- }
-
-}
diff --git a/minimax4j/src/main/java/fr/avianey/minimax4j/impl/Negamax.java b/minimax4j/src/main/java/fr/avianey/minimax4j/impl/Negamax.java
deleted file mode 100644
index 22a6088..0000000
--- a/minimax4j/src/main/java/fr/avianey/minimax4j/impl/Negamax.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * This file is part of minimax4j.
- *
- *
- * The MIT License (MIT)
-
- * Copyright (c) 2015 Antoine Vianey
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package fr.avianey.minimax4j.impl;
-
-import fr.avianey.minimax4j.IA;
-import fr.avianey.minimax4j.Move;
-
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-import static fr.avianey.minimax4j.IAUtils.iterableToSortedList;
-
-/**
- * Negamax based implementation.
- *
- *
- * function negamax(node, depth, color)
- * if depth = 0 or node is a terminal node
- * return color * the heuristic value of node
- * bestValue := -∞
- * foreach child of node
- * val := -negamax(child, depth - 1, -color)
- * bestValue := max( bestValue, val )
- * return bestValue
- *
- *
- * This implementation use alpha-beta cut-offs.
- *
- * @author antoine vianey
- *
- * @param Implementation of the Move interface to use
- */
-public abstract class Negamax implements IA {
-
- public List getBestMoves(final int depth, Iterable possibleMoves) {
- if (depth <= 0) {
- throw new IllegalArgumentException("Search depth MUST be > 0");
- }
- List orderedMoves = iterableToSortedList(possibleMoves);
- negamax(orderedMoves, depth, -maxEvaluateValue(), maxEvaluateValue());
- Collections.sort(orderedMoves);
- return orderedMoves;
- }
-
- protected double negamax(Iterable initialMoves, final int depth, double alpha, double beta) {
- if (depth == 0 || isOver()) {
- return evaluate();
- }
- Iterator moves = (initialMoves != null ? initialMoves : getPossibleMoves()).iterator();
- if (!moves.hasNext()) {
- next();
- double score = -negamax(null, depth - 1, -beta, -alpha);
- previous();
- return score;
- }
- double score;
- while (moves.hasNext()) {
- M move = moves.next();
- makeMove(move);
- score = -negamax(null, depth - 1, -beta, -alpha);
- unmakeMove(move);
- if (initialMoves != null) {
- move.value = score;
- }
- if (score > alpha) {
- alpha = score;
- if (alpha >= beta) {
- break;
- }
- }
- }
- return alpha;
- }
-
-}
diff --git a/minimax4j/src/main/java/fr/avianey/minimax4j/impl/ParallelNegamax.java b/minimax4j/src/main/java/fr/avianey/minimax4j/impl/ParallelNegamax.java
deleted file mode 100644
index dcbb9ab..0000000
--- a/minimax4j/src/main/java/fr/avianey/minimax4j/impl/ParallelNegamax.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * This file is part of minimax4j.
- *
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2015 Antoine Vianey
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package fr.avianey.minimax4j.impl;
-
-import fr.avianey.minimax4j.IA;
-import fr.avianey.minimax4j.Move;
-
-import java.util.*;
-import java.util.concurrent.ForkJoinPool;
-import java.util.concurrent.RecursiveTask;
-
-import static fr.avianey.minimax4j.IAUtils.iterableToSortedList;
-import static java.lang.Runtime.getRuntime;
-
-/**
- * A {@link IA} implementation that distribute the tree exploration across processors.
- *
- * @param Implementation of the Move interface to use
- * @author antoine vianey
- */
-public abstract class ParallelNegamax implements IA, Cloneable {
-
- private ForkJoinPool pool;
-
- /**
- * Creates a new ParallelNegamax using {@link Runtime#availableProcessors()} for parallelism.
- */
- public ParallelNegamax() {
- this(getRuntime().availableProcessors());
- }
-
- /**
- * Creates a new ParallelNegamax using the given parallelism.
- * @param parallelism how many workers should be used for computation
- */
- public ParallelNegamax(int parallelism) {
- if (parallelism <= 0) {
- throw new IllegalArgumentException(this.getClass().getSimpleName() + " MUST use at least one processor.");
- }
- this.pool = new ForkJoinPool(parallelism);
- }
-
- /**
- * Creates a new IA with the same parallelism as the given instance.
- * This constructor SHOULD be used when creating clones as it skip {@link ForkJoinPool} configuration.
- * @param from
- */
- protected ParallelNegamax(ParallelNegamax from) {
- this(from.pool.getParallelism());
- }
-
- /**
- * Get the best {@link Move} for the given search depth
- * This method SHOULD be called from one thread at the time.
- * @param depth The search depth (must be > 0)
- * @return The best possible move
- */
- public List getBestMoves(final int depth, Iterable possibleMoves) {
- if (depth <= 0) {
- throw new IllegalArgumentException("Search depth MUST be > 0");
- }
- List orderedMoves = iterableToSortedList(possibleMoves);
- pool.invoke(new NegamaxAction<>(this, orderedMoves, null, depth, -maxEvaluateValue(), maxEvaluateValue()));
- Collections.sort(orderedMoves);
- return orderedMoves;
- }
-
- @Override
- public abstract ParallelNegamax clone();
-
- private static final class NegamaxAction extends RecursiveTask {
-
- private static final long serialVersionUID = 1L;
-
- private final List initialMoves;
- private final ParallelNegamax minimax;
- private final M move;
- private final int depth;
- private final double alpha;
- private final double beta;
-
- NegamaxAction(ParallelNegamax minimax, List initialMoves, M move, int depth, double alpha, double beta) {
- this.initialMoves = initialMoves;
- this.move = move;
- this.depth = depth;
- this.minimax = minimax;
- this.alpha = alpha;
- this.beta = beta;
- }
-
- @Override
- protected Double compute() {
- return negamax(initialMoves, depth, alpha, beta);
- }
-
- private double negamax(final Iterable initialMoves, final int depth, double alpha, double beta) {
- if (depth == 0 || minimax.isOver()) {
- return minimax.evaluate();
- }
- Iterator moves = (initialMoves != null ? initialMoves : minimax.getPossibleMoves()).iterator();
- if (moves.hasNext()) {
- // young brother wait
- // reduce alpha beta window
- // assume its the best possible move
- M move = moves.next();
- minimax.makeMove(move);
- double score = -negamax(null, depth - 1, -beta, -alpha);
- minimax.unmakeMove(move);
- if (initialMoves != null) {
- move.value = score;
- }
- if (score > alpha) {
- alpha = score;
- if (alpha >= beta) {
- // cutoff
- return alpha;
- }
- }
- if (moves.hasNext()) {
- Collection> tasks = new LinkedList<>();
- do {
- // create sub tree exploration tasks
- move = moves.next();
- ParallelNegamax clone = minimax.clone();
- clone.makeMove(move);
- tasks.add(new NegamaxAction<>(clone, null, move, depth - 1, -beta, -alpha));
- } while (moves.hasNext());
- // dispatch tasks across workers
- // and wait for completion...
- invokeAll(tasks);
- // await termination of all brothers
- // once all done alpha == best score
- for (NegamaxAction task : tasks) {
- score = -task.getRawResult();
- if (initialMoves != null) {
- task.move.value = score;
- }
- if (score > alpha) {
- alpha = score;
- if (alpha >= beta) {
- // task lead to a cutoff...
- // we don't care of other brothers
- break;
- }
- }
- }
- }
- } else {
- minimax.next();
- alpha = -negamax(null, depth - 1, -beta, -alpha);
- minimax.previous();
- }
- // sub tree done !
- return alpha;
- }
-
- }
-
-}
diff --git a/minimax4j/src/main/java/fr/avianey/minimax4j/impl/TranspositionNegamax.java b/minimax4j/src/main/java/fr/avianey/minimax4j/impl/TranspositionNegamax.java
deleted file mode 100644
index 1e2f1b4..0000000
--- a/minimax4j/src/main/java/fr/avianey/minimax4j/impl/TranspositionNegamax.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * This file is part of minimax4j.
- *
- *
- * The MIT License (MIT)
-
- * Copyright (c) 2015 Antoine Vianey
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package fr.avianey.minimax4j.impl;
-
-import fr.avianey.minimax4j.Move;
-
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.*;
-
-import static fr.avianey.minimax4j.IAUtils.iterableToSortedList;
-
-/**
- * Negamax based with transposition table implementation.
- *
- * @author antoine vianey
- *
- * @param Implementation of the Move interface to use
- * @param The key used for the transposition table
- * @param An optional {@link Comparable} use to group transpositions
- */
-public abstract class TranspositionNegamax extends Negamax {
-
- protected static final int FLAG_EXACT = 0;
- protected static final int FLAG_UPPERBOUND = 1;
- protected static final int FLAG_LOWERBOUND = 2;
-
- protected static class Transposition {
- private final double value;
- private final int depth;
- private final int flag;
- private final K key;
-
- protected Transposition(double value, int depth, int flag, K key) {
- this.value = value;
- this.depth = depth;
- this.flag = flag;
- this.key = key;
- }
- }
-
- public interface TranspositionTableFactory {
- Map> newTranspositionTable();
- }
-
- private final transient TreeMap>> transpositionTableMap;
- private final transient TranspositionTableFactory transpositionTableFactory;
-
- public TranspositionNegamax() {
- this(new TranspositionTableFactory() {
- @Override
- public Map> newTranspositionTable() {
- return new HashMap<>();
- }
- });
- }
-
- public TranspositionNegamax(final int initialCapacity) {
- this(new TranspositionTableFactory() {
- @Override
- public Map> newTranspositionTable() {
- return new HashMap<>(initialCapacity);
- }
- });
- }
-
- public TranspositionNegamax(final int initialCapacity, final float loadFactor) {
- this(new TranspositionTableFactory() {
- @Override
- public Map> newTranspositionTable() {
- return new HashMap<>(initialCapacity, loadFactor);
- }
- });
- }
-
- public TranspositionNegamax(TranspositionTableFactory transpositionTableFactory) {
- super();
- this.transpositionTableFactory = transpositionTableFactory;
- this.transpositionTableMap = initTranspositionTableMap();
- }
-
-
- /**
- * Initialize the map of transposition table classified by groups.
- * @return
- * A {@link TreeMap} storing transposition tables by group
- */
- @SuppressWarnings("unchecked")
- private TreeMap>> initTranspositionTableMap() {
- Type t = getClass().getGenericSuperclass();
- // search for the Group class within class hierarchy
- while (!(t instanceof ParameterizedType
- && TranspositionNegamax.class.getSimpleName().equals(
- ((Class>) ((ParameterizedType) t).getRawType()).getSimpleName()))) {
- t = ((Class>) t).getGenericSuperclass();
- }
- Class cls = (Class) ((ParameterizedType) t).getActualTypeArguments()[2];
- if (Comparable.class.isAssignableFrom(cls)) {
- // the transposition Group type is Comparable
- return new TreeMap<>();
- } else if (cls.isAssignableFrom(Void.class)) {
- // no transposition Group required
- // use everything-is-equal Comparator
- return new TreeMap<>(new Comparator() {
- @Override
- public int compare(G o1, G o2) {
- return 0;
- }
- });
- } else {
- throw new IllegalArgumentException("The transposition group type : " + cls.getSimpleName() + " is neither Void nor implement the java.lang.Comparable interface.");
- }
- }
-
- private void clearGroups(G currentGroup) {
- if (currentGroup != null) {
- // free memory :
- // evict unnecessary transpositions
- transpositionTableMap.headMap(currentGroup).clear();
- }
- }
-
- /**
- * Reset the content of the transposition table.
- * The preferred way to free memory is to use the grouping functionality.
- *
- * @see #getGroup()
- */
- public final void clearTranspositions() {
- transpositionTableMap.clear();
- }
-
- /**
- * Returns the current configuration key.
- * Implementation MUST override the {@link #hashCode()} and {@link #equals(Object)} methods.
- * A Zobrist hashing could be use to provide
- * the hash value of the transposition key. Equality between key will be used to check for collision when
- * different configurations map to the same hash value.
- *
- *
{@link #hashCode()}
- *
- * Should be tuned to adjust the number of entry in the transposition table as well as its memory footprint.
- * Increasing the number of possible hashCode values will allow more transpositions and consume more memory.
- *
- *
{@link #equals(Object)}
- *
- * Might be tuned to avoid using an invalid transposition du to collisions in the transposition table.
- *
- *
- * Use {@link #saveTransposition(Object, Transposition, double, int, int)} to implement replacement strategy.
- *
- * @see #saveTransposition(Object, Transposition, double, int, int)
- * @return
- * The key representing the current configuration.
- * MUST be non null and preferably immutable.
- */
- public abstract K getTranspositionKey();
-
- /**
- * Represent the group in which the current transposition belong.
- * Groups can be use to lower the number of transposition stored in memory :
- *
- *
Reversi
- *
Transpositions can be grouped by number of discs on board
- *
Chess
- *
Transpositions can be grouped by number of left pieces of each color on the board
- *
Connect Four
- *
Transpositions can be grouped by number of dropped discs
- *
- * Groups MUST be ordered such as when the current configuration hash belong to group
- * G1, transpositions that belongs to groups G < G1 can be removed... If you don't want to
- * handle groups, let G be {@link Void} and return null.
- *
- * @return
- * The group for the current position
- */
- public abstract G getGroup();
-
- /**
- * Save the transposition for the current position using a default strategy:
- *
- *
existing transposition is null
- *
existing transposition depth is lower than the remaining depth
- *
- * Override this method to implement your own replacement strategy using additional criteria such as ancient,
- *
- * @param key the transposition key for the current configuration
- * @param transposition the existing transposition for the given key hash (or null if no transposition exists)
- * @param score the evaluation for the given depth
- * @param depth the depth of the searched subtree (aka remaining depth)
- * @param flag type of evaluation {@link #FLAG_EXACT}, {@link #FLAG_LOWERBOUND}, {@link #FLAG_UPPERBOUND}
- */
- protected void saveTransposition(final K key, final Transposition transposition, final double score, final int depth, final int flag) {
- if (transposition == null || transposition.depth <= depth) {
- getTranspositionTable().put(key.hashCode(), new Transposition(score, depth, flag, key));
- }
- }
-
- private Map> getTranspositionTable() {
- Map> transpositionTable = transpositionTableMap.get(getGroup());
- if (transpositionTable == null) {
- transpositionTable = transpositionTableFactory.newTranspositionTable();
- transpositionTableMap.put(getGroup(), transpositionTable);
- }
- return transpositionTable;
- }
-
- @Override
- public List getBestMoves(final int depth, Iterable possibleMoves) {
- if (depth <= 0) {
- throw new IllegalArgumentException("Search depth MUST be > 0");
- }
- List orderedMoves = iterableToSortedList(possibleMoves);
- super.negamax(orderedMoves, depth, -maxEvaluateValue(), maxEvaluateValue());
- // clear useless groups
- clearGroups(getGroup());
- Collections.sort(orderedMoves);
- return orderedMoves;
- }
-
- @Override
- protected double negamax(final Iterable possibleMoves, final int depth, final double alpha, final double beta) {
- double a = alpha;
- double b = beta;
- K key = getTranspositionKey();
- Transposition transposition = getTranspositionTable().get(key.hashCode());
- if (transposition != null && depth <= transposition.depth && key.equals(transposition.key)) {
- switch (transposition.flag) {
- case FLAG_EXACT:
- // transposition has a deeper or equal search depth
- // we can stop here as we already know the value
- // returned by the evaluation function
- return transposition.value;
- case FLAG_UPPERBOUND:
- if (transposition.value < beta) {
- b = transposition.value;
- }
- break;
- case FLAG_LOWERBOUND:
- if (transposition.value > alpha) {
- a = transposition.value;
- }
- break;
- }
- if (a >= b) {
- return transposition.value;
- }
- }
-
- double score = super.negamax(possibleMoves, depth, a, b);
-
- if (score <= a) {
- saveTransposition(key, transposition, score, depth, FLAG_UPPERBOUND);
- } else if (score >= beta) {
- saveTransposition(key, transposition, score, depth, FLAG_LOWERBOUND);
- } else {
- saveTransposition(key, transposition, score, depth, FLAG_EXACT);
- }
-
- return score;
- }
-
-}
diff --git a/minimax4j/src/test/java/fr/avianey/minimax4j/BestMoveTest.java b/minimax4j/src/test/java/fr/avianey/minimax4j/BestMoveTest.java
deleted file mode 100644
index b3c69e3..0000000
--- a/minimax4j/src/test/java/fr/avianey/minimax4j/BestMoveTest.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * This file is part of minimax4j.
- *
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2015 Antoine Vianey
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package fr.avianey.minimax4j;
-
-import fr.avianey.minimax4j.ia.*;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-import java.util.Arrays;
-import java.util.Collection;
-
-import static org.junit.Assert.assertEquals;
-
-@RunWith(Parameterized.class)
-public class BestMoveTest {
-
- private final int depth;
- private final IA IA;
-
- public BestMoveTest(int depth, IA IA) {
- this.depth = depth;
- this.IA = IA;
- }
-
- @Parameters
- public static Collection