2021-01-27 11:49:49 +01:00
|
|
|
package othello;
|
|
|
|
|
2021-02-16 13:41:20 +01:00
|
|
|
import othello.players.Player;
|
2021-02-12 09:18:03 +01:00
|
|
|
|
2021-02-20 18:54:38 +01:00
|
|
|
import java.util.LinkedList;
|
|
|
|
import java.util.List;
|
|
|
|
|
2021-01-27 11:49:49 +01:00
|
|
|
public class State {
|
|
|
|
|
2021-02-20 18:54:38 +01:00
|
|
|
public static List<State> previousSituations = new LinkedList<>();
|
|
|
|
|
|
|
|
private final Player[][] board;
|
|
|
|
private final Player player1;
|
|
|
|
private final Player player2;
|
2021-02-16 13:41:20 +01:00
|
|
|
private Player currentPlayer;
|
2021-02-02 09:14:10 +01:00
|
|
|
private int n1;
|
|
|
|
private int n2;
|
2021-01-27 12:24:17 +01:00
|
|
|
|
2021-02-20 18:54:38 +01:00
|
|
|
public State(Player[][] board, Player p1, Player p2) {
|
2021-01-27 12:24:17 +01:00
|
|
|
this.board = board;
|
|
|
|
this.player1 = p1;
|
|
|
|
this.player2 = p2;
|
|
|
|
currentPlayer = p1;
|
2021-02-20 18:54:38 +01:00
|
|
|
this.n1 = 2;
|
|
|
|
this.n2 = 2;
|
2021-01-27 12:24:17 +01:00
|
|
|
}
|
|
|
|
|
2021-01-27 11:49:49 +01:00
|
|
|
public boolean isOver() {
|
2021-02-20 18:54:38 +01:00
|
|
|
return n1 == 0 || n2 == 0 || (getMove(player1).isEmpty() && getMove(player2).isEmpty());
|
|
|
|
}
|
|
|
|
|
|
|
|
public Player getPlayerById(int id) {
|
|
|
|
if(id == 1)
|
|
|
|
return player1;
|
|
|
|
else if(id == -1)
|
|
|
|
return player2;
|
|
|
|
throw new IllegalArgumentException("Invalid player id: " + id);
|
2021-01-27 11:49:49 +01:00
|
|
|
}
|
|
|
|
|
2021-02-20 18:54:38 +01:00
|
|
|
public LinkedList<Pair<Point, Point>> getMove(Player player) {
|
2021-02-10 12:01:51 +01:00
|
|
|
// Pair<Depart, Arrivee>
|
2021-02-20 18:54:38 +01:00
|
|
|
LinkedList<Pair<Point, Point>> moves = new LinkedList<>();
|
2021-01-27 16:55:50 +01:00
|
|
|
// Parcours du plateau de jeu
|
2021-02-10 12:01:51 +01:00
|
|
|
for (int y = 0; y < this.board.length; y++) {
|
|
|
|
for (int x = 0; x < this.board[y].length; x++) {
|
|
|
|
if (this.board[y][x] == player) {
|
2021-01-27 16:55:50 +01:00
|
|
|
// Recherche autour du pion du joueur courant
|
2021-02-10 12:26:47 +01:00
|
|
|
for (int deltaY = -1; deltaY < 2; deltaY++) {
|
|
|
|
for (int deltaX = -1; deltaX < 2; deltaX++) {
|
2021-02-12 09:57:05 +01:00
|
|
|
// La position du pion trouvée est exclue
|
|
|
|
// Si une place libre est trouvée elle est ajoutée à la liste des coups
|
2021-02-10 12:01:51 +01:00
|
|
|
try {
|
2021-02-20 18:54:38 +01:00
|
|
|
Point current = new Point(y, x);
|
2021-02-12 09:18:03 +01:00
|
|
|
if (this.board[y+deltaY][x+deltaX] == null) {
|
2021-02-20 18:54:38 +01:00
|
|
|
moves.add(new Pair<>(current, new Point(y + deltaY, x + deltaX)));
|
2021-02-10 12:26:47 +01:00
|
|
|
}
|
2021-02-20 18:54:38 +01:00
|
|
|
Point other = new Point(y + 2 * deltaY, x + 2 * deltaX);
|
|
|
|
if(this.board[other.getY()][other.getX()] == null && current.isJump(other))
|
|
|
|
moves.add(new Pair<>(current, other));
|
2021-02-10 12:01:51 +01:00
|
|
|
} catch(ArrayIndexOutOfBoundsException ignored) {}
|
2021-01-27 16:55:50 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return moves;
|
2021-01-27 11:49:49 +01:00
|
|
|
}
|
|
|
|
|
2021-02-16 13:41:20 +01:00
|
|
|
public int getScore(Player player) {
|
2021-02-20 18:54:38 +01:00
|
|
|
return player == player1 ? n1 : n2;
|
2021-01-27 11:49:49 +01:00
|
|
|
}
|
2021-02-12 09:38:18 +01:00
|
|
|
|
2021-02-16 13:41:20 +01:00
|
|
|
public Player getWinner() {
|
2021-02-12 09:38:18 +01:00
|
|
|
int scoreP1 = getScore(player1), scoreP2 = getScore(player2);
|
|
|
|
if(scoreP1 > scoreP2)
|
|
|
|
return player1;
|
|
|
|
else if(scoreP2 > scoreP1)
|
|
|
|
return player2;
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2021-02-20 18:54:38 +01:00
|
|
|
public State play(Pair<Point,Point> move) {
|
2021-02-10 11:21:33 +01:00
|
|
|
State copy = this.copy();
|
2021-02-20 18:54:38 +01:00
|
|
|
copy.board[move.getRight().getY()][move.getRight().getX()] = copy.getCurrentPlayer();
|
2021-02-12 09:57:05 +01:00
|
|
|
for(int i = -1; i < 2; i++){
|
|
|
|
for(int z = -1; z < 2; z++){
|
2021-02-02 09:14:10 +01:00
|
|
|
try {
|
2021-02-20 18:54:38 +01:00
|
|
|
if(copy.board[move.getRight().getY() + i][move.getRight().getX() + z] != copy.getCurrentPlayer()
|
|
|
|
&& !move.getLeft().isJump(move.getRight())){
|
|
|
|
copy.board[move.getRight().getY() + i][move.getRight().getX() + z] = copy.getCurrentPlayer();
|
2021-02-12 09:02:53 +01:00
|
|
|
}
|
2021-02-10 11:21:33 +01:00
|
|
|
} catch (IndexOutOfBoundsException ignored) {}
|
2021-02-02 09:14:10 +01:00
|
|
|
}
|
|
|
|
}
|
2021-02-20 18:54:38 +01:00
|
|
|
int ni = 0, nj = 0;
|
|
|
|
for(int i = 0; i < board.length; i++) {
|
|
|
|
for(int j = 0; j < board[i].length; j++) {
|
|
|
|
if(board[i][j] == player1){
|
|
|
|
ni++;
|
|
|
|
}
|
|
|
|
if(board[i][j] == player2){
|
|
|
|
nj++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
copy.n1 = ni;
|
|
|
|
copy.n2 = nj;
|
2021-02-10 11:21:33 +01:00
|
|
|
copy.switchPlayer();
|
|
|
|
return copy;
|
2021-01-27 11:49:49 +01:00
|
|
|
}
|
2021-02-16 13:41:20 +01:00
|
|
|
public Player getCurrentPlayer() {
|
2021-01-27 12:24:17 +01:00
|
|
|
return currentPlayer;
|
|
|
|
}
|
2021-01-27 11:49:49 +01:00
|
|
|
|
2021-02-16 13:41:20 +01:00
|
|
|
public void setCurrentPlayer(Player currentPlayer) {
|
2021-01-27 13:00:52 +01:00
|
|
|
this.currentPlayer = currentPlayer;
|
|
|
|
}
|
|
|
|
|
2021-02-10 11:21:33 +01:00
|
|
|
public State copy () {
|
2021-02-20 18:54:38 +01:00
|
|
|
State copy = new State(this.board, this.player1, this.player2);
|
2021-02-12 09:57:05 +01:00
|
|
|
for (int i = 0; i < this.board.length; i++) {
|
2021-02-20 18:54:38 +01:00
|
|
|
System.arraycopy(this.board[i], 0, copy.board[i], 0, this.board.length);
|
2021-01-27 13:00:52 +01:00
|
|
|
}
|
2021-02-12 09:57:05 +01:00
|
|
|
copy.setCurrentPlayer(this.currentPlayer);
|
2021-02-20 18:54:38 +01:00
|
|
|
copy.n1 = n1;
|
|
|
|
copy.n2 = n2;
|
2021-02-10 11:21:33 +01:00
|
|
|
return copy;
|
2021-01-27 13:00:52 +01:00
|
|
|
}
|
|
|
|
|
2021-02-10 12:01:51 +01:00
|
|
|
public void switchPlayer() {
|
2021-02-10 11:21:33 +01:00
|
|
|
setCurrentPlayer(getCurrentPlayer() == this.player1 ? player2 : player1);
|
2021-01-27 13:00:52 +01:00
|
|
|
}
|
|
|
|
|
2021-02-12 09:18:03 +01:00
|
|
|
/**
|
|
|
|
* TODO: display the current state of the board
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
2021-02-12 09:38:18 +01:00
|
|
|
StringBuilder str = new StringBuilder();
|
2021-02-20 18:54:38 +01:00
|
|
|
for (Player[] players : board) {
|
2021-02-12 09:38:18 +01:00
|
|
|
for (int x = 0; x < board.length; x++) {
|
2021-02-20 18:54:38 +01:00
|
|
|
if (players[x] == player1)
|
2021-02-12 09:38:18 +01:00
|
|
|
str.append("O");
|
2021-02-20 18:54:38 +01:00
|
|
|
else if (players[x] == player2)
|
2021-02-12 09:38:18 +01:00
|
|
|
str.append("X");
|
|
|
|
else
|
|
|
|
str.append(".");
|
|
|
|
str.append(" ");
|
|
|
|
}
|
|
|
|
str.append("\r\n");
|
|
|
|
}
|
|
|
|
return str.toString();
|
2021-02-12 09:18:03 +01:00
|
|
|
}
|
|
|
|
|
2021-01-27 11:49:49 +01:00
|
|
|
}
|