287 lines
7.7 KiB
Java
287 lines
7.7 KiB
Java
package backend;
|
||
|
||
import java.util.ArrayList;
|
||
|
||
public class Board {
|
||
|
||
private int width;
|
||
private int height;
|
||
private int turnNumber = 0;
|
||
private int selectedX = -1;
|
||
private int selectedY = -1;
|
||
private ArrayList<Piece> pieces = new ArrayList<>();
|
||
private ArrayList<int[]> highlightedSquares = new ArrayList<>();
|
||
private ArrayList<Move> moveHistory = new ArrayList<>();
|
||
|
||
|
||
|
||
|
||
|
||
public Board(int colNum, int lineNum) {
|
||
this.width = colNum;
|
||
this.height = lineNum;
|
||
}
|
||
|
||
public int getWidth() {
|
||
return width;
|
||
}
|
||
|
||
public int getHeight() {
|
||
return height;
|
||
}
|
||
|
||
public int getTurnNumber() {
|
||
return turnNumber;
|
||
}
|
||
|
||
public boolean isTurnWhite() {
|
||
return (turnNumber % 2 == 0);
|
||
}
|
||
|
||
public void setPiece(boolean isWhite, PieceType type, int x, int y) {
|
||
Piece piece = new Piece(type, isWhite, x, y);
|
||
pieces.add(piece);
|
||
}
|
||
|
||
public void populateBoard() {
|
||
cleanBoard(); // on vide d'abord le plateau
|
||
|
||
// Pions
|
||
for (int i = 0; i < 8; i++) {
|
||
setPiece(true, PieceType.Pawn, i, 6); // Blancs
|
||
setPiece(false, PieceType.Pawn, i, 1); // Noirs
|
||
}
|
||
|
||
// Pi<50>ces noires
|
||
setPiece(false, PieceType.Rook, 0, 0);
|
||
setPiece(false, PieceType.Knight, 1, 0);
|
||
setPiece(false, PieceType.Bishop, 2, 0);
|
||
setPiece(false, PieceType.Queen, 4, 0);
|
||
setPiece(false, PieceType.King, 3, 0);
|
||
setPiece(false, PieceType.Bishop, 5, 0);
|
||
setPiece(false, PieceType.Knight, 6, 0);
|
||
setPiece(false, PieceType.Rook, 7, 0);
|
||
|
||
// Pi<50>ces blanches
|
||
setPiece(true, PieceType.Rook, 0, 7);
|
||
setPiece(true, PieceType.Knight, 1, 7);
|
||
setPiece(true, PieceType.Bishop, 2, 7);
|
||
setPiece(true, PieceType.Queen, 4, 7);
|
||
setPiece(true, PieceType.King, 3, 7);
|
||
setPiece(true, PieceType.Bishop, 5, 7);
|
||
setPiece(true, PieceType.Knight, 6, 7);
|
||
setPiece(true, PieceType.Rook, 7, 7);
|
||
}
|
||
|
||
public void cleanBoard() {
|
||
pieces.clear();
|
||
}
|
||
|
||
public String toString() {
|
||
StringBuilder sb = new StringBuilder();
|
||
for (Piece p : pieces) {
|
||
sb.append(p.getType()).append(" ")
|
||
.append(p.isWhite() ? "white" : "black")
|
||
.append(" at (").append(p.getX()).append(", ").append(p.getY()).append(")\n");
|
||
}
|
||
return sb.toString();
|
||
}
|
||
|
||
|
||
public ArrayList<Piece> getPieces() {
|
||
return pieces;
|
||
}
|
||
|
||
|
||
public void userTouch(int x, int y) {
|
||
Piece clickedPiece = getPieceAt(x, y);
|
||
|
||
// Aucune s<>lection active
|
||
if (selectedX == -1 && selectedY == -1) {
|
||
if (clickedPiece != null && clickedPiece.isWhite() == isTurnWhite()) {
|
||
// S<>lection de la pi<70>ce
|
||
selectedX = x;
|
||
selectedY = y;
|
||
|
||
// Calcul des d<>placements valides
|
||
highlightedSquares = Move.getPossibleMoves(this, clickedPiece);
|
||
}
|
||
}
|
||
|
||
// Une pi<70>ce est d<>j<EFBFBD> s<>lectionn<6E>e
|
||
else {
|
||
// Si on clique <20> nouveau sur la case s<>lectionn<6E>e on annule
|
||
if (x == selectedX && y == selectedY) {
|
||
selectedX = -1;
|
||
selectedY = -1;
|
||
highlightedSquares.clear();
|
||
}
|
||
|
||
// Sinon on tente de bouger la pi<70>ce s<>lectionn<6E>e vers (x, y)
|
||
else {
|
||
Piece selectedPiece = getPieceAt(selectedX, selectedY);
|
||
|
||
if (selectedPiece != null && selectedPiece.isWhite() == isTurnWhite()) {
|
||
// Est-ce une destination valide ?
|
||
boolean valid = false;
|
||
for (int[] move : highlightedSquares) {
|
||
if (move[0] == x && move[1] == y) {
|
||
valid = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (valid) {
|
||
Piece destPiece = getPieceAt(x, y);
|
||
|
||
// Enregistrer le coup dans l'historique
|
||
Move move = new Move(selectedPiece, selectedX, selectedY, x, y, destPiece);
|
||
moveHistory.add(move);
|
||
|
||
// Appliquer le d<>placement
|
||
pieces.remove(selectedPiece);
|
||
if (destPiece != null) pieces.remove(destPiece);
|
||
pieces.add(new Piece(selectedPiece.getType(), selectedPiece.isWhite(), x, y));
|
||
|
||
turnNumber++;
|
||
}
|
||
|
||
// Dans tous les cas, on d<>s<EFBFBD>lectionne
|
||
selectedX = -1;
|
||
selectedY = -1;
|
||
highlightedSquares.clear();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
public boolean isSelected(int x, int y) {
|
||
return x == selectedX && y == selectedY;
|
||
}
|
||
|
||
|
||
|
||
/* saving-loading feature :*/
|
||
|
||
public String[] toFileRep() {
|
||
String[] lines = new String[height + 1];
|
||
|
||
for (int y = 0; y < height; y++) {
|
||
StringBuilder row = new StringBuilder();
|
||
for (int x = 0; x < width; x++) {
|
||
Piece p = getPieceAt(x, y);
|
||
if (p != null) {
|
||
row.append(p.isWhite() ? "W" : "B").append(p.getType().getSummary());
|
||
}
|
||
row.append(x < width - 1 ? "," : "");
|
||
}
|
||
lines[y] = row.toString();
|
||
}
|
||
|
||
// Derni<6E>re ligne : couleur du joueur actif
|
||
lines[height] = isTurnWhite() ? "W" : "B";
|
||
|
||
return lines;
|
||
}
|
||
|
||
public Board(String[] array) {
|
||
this.width = 8;
|
||
this.height = 8;
|
||
this.pieces = new ArrayList<>();
|
||
this.highlightedSquares = new ArrayList<>();
|
||
this.selectedX = -1;
|
||
this.selectedY = -1;
|
||
|
||
for (int y = 0; y < height; y++) {
|
||
String[] cells = array[y].split(",", -1);
|
||
for (int x = 0; x < cells.length; x++) {
|
||
String cell = cells[x];
|
||
if (cell.length() == 2) {
|
||
boolean isWhite = cell.charAt(0) == 'W';
|
||
PieceType type = PieceType.fromSummary(cell.charAt(1));
|
||
setPiece(isWhite, type, x, y);
|
||
}
|
||
}
|
||
}
|
||
|
||
// Ligne 9 : couleur du joueur actif
|
||
this.turnNumber = array[height].equals("W") ? 0 : 1;
|
||
}
|
||
|
||
/* The following methods require more work ! */
|
||
|
||
public boolean isHighlighted(int x, int y) {
|
||
for (int[] pos : highlightedSquares) {
|
||
if (pos[0] == x && pos[1] == y) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
|
||
public void undoLastMove() {
|
||
if (moveHistory.isEmpty()) return;
|
||
|
||
Move last = moveHistory.remove(moveHistory.size() - 1);
|
||
|
||
// Supprimer la pi<70>ce d<>plac<61>e
|
||
Piece current = getPieceAt(last.getToX(), last.getToY());
|
||
if (current != null) {
|
||
pieces.remove(current);
|
||
}
|
||
|
||
// Restaurer la pi<70>ce d<>plac<61>e
|
||
pieces.add(new Piece(
|
||
last.getMovedPiece().getType(),
|
||
last.getMovedPiece().isWhite(),
|
||
last.getFromX(), last.getFromY()
|
||
));
|
||
|
||
// R<>ins<6E>rer la pi<70>ce captur<75>e si besoin
|
||
if (last.getCapturedPiece() != null) {
|
||
Piece c = last.getCapturedPiece();
|
||
pieces.add(new Piece(c.getType(), c.isWhite(), c.getX(), c.getY()));
|
||
}
|
||
|
||
turnNumber--;
|
||
}
|
||
|
||
public Board(Board board) {
|
||
//TODO
|
||
|
||
}
|
||
|
||
public void playMove(Move move) {
|
||
if (move == null) return;
|
||
|
||
// Remove the moved piece from its old position
|
||
Piece from = move.getMovedPiece();
|
||
pieces.removeIf(p -> p.getX() == from.getX() && p.getY() == from.getY());
|
||
|
||
// Remove captured piece if any
|
||
if (move.getCapturedPiece() != null) {
|
||
Piece captured = move.getCapturedPiece();
|
||
pieces.removeIf(p -> p.getX() == captured.getX() && p.getY() == captured.getY());
|
||
}
|
||
|
||
// Add moved piece in new position
|
||
pieces.add(new Piece(from.getType(), from.isWhite(), move.getToX(), move.getToY()));
|
||
|
||
moveHistory.add(move);
|
||
turnNumber++;
|
||
}
|
||
|
||
public Piece getPieceAt(int x, int y) {
|
||
for (Piece p : pieces) {
|
||
if (p.getX() == x && p.getY() == y) {
|
||
return p;
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
}
|