Part 1
This commit is contained in:
parent
ea13ad02fe
commit
f81c49d27c
|
|
@ -1,99 +1,315 @@
|
||||||
|
|
||||||
package backend;
|
package backend;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Stack;
|
||||||
|
|
||||||
public class Board {
|
public class Board {
|
||||||
|
|
||||||
|
private int width, height;
|
||||||
|
private ArrayList<Piece> pieces;
|
||||||
|
private int turnNumber;
|
||||||
|
private boolean isWhiteTurn;
|
||||||
|
private Integer selectedX, selectedY;
|
||||||
|
private ArrayList<int[]> highlightedSquares = new ArrayList<>();
|
||||||
|
private Stack<Move> moveHistory = new Stack<>();
|
||||||
|
|
||||||
public Board(int colNum, int lineNum) {
|
public Board(int colNum, int lineNum) {
|
||||||
//TODO add constructor
|
this.width = colNum;
|
||||||
|
this.height = lineNum;
|
||||||
|
this.turnNumber = 0;
|
||||||
|
this.isWhiteTurn = true;
|
||||||
|
this.pieces = new ArrayList<>();
|
||||||
|
this.selectedX = null;
|
||||||
|
this.selectedY = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getWidth() {
|
public int getWidth() {
|
||||||
//TODO
|
return width;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getHeight() {
|
public int getHeight() {
|
||||||
//TODO
|
return height;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTurnNumber() {
|
public int getTurnNumber() {
|
||||||
//TODO
|
return turnNumber;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTurnWhite() {
|
public boolean isTurnWhite() {
|
||||||
//TODO
|
return isWhiteTurn;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPiece(boolean isWhite, PieceType type, int x, int y) {
|
public void setPiece(boolean isWhite, PieceType type, int x, int y) {
|
||||||
//TODO
|
removePieceAt(x, y);
|
||||||
|
pieces.add(new Piece(x, y, isWhite, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void populateBoard() {
|
public void populateBoard() {
|
||||||
//TODO
|
PieceType[] backRow = {
|
||||||
|
PieceType.Rook, PieceType.Knight, PieceType.Bishop, PieceType.Queen,
|
||||||
|
PieceType.King, PieceType.Bishop, PieceType.Knight, PieceType.Rook
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int x = 0; x < width; x++) {
|
||||||
|
pieces.add(new Piece(x, 1, false, PieceType.Pawn)); // Black pawns
|
||||||
|
pieces.add(new Piece(x, 6, true, PieceType.Pawn)); // White pawns
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int x = 0; x < width; x++) {
|
||||||
|
pieces.add(new Piece(x, 0, false, backRow[x])); // Black back row
|
||||||
|
pieces.add(new Piece(x, 7, true, backRow[x])); // White back row
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cleanBoard() {
|
public void cleanBoard() {
|
||||||
//TODO
|
pieces.clear();
|
||||||
|
turnNumber = 0;
|
||||||
|
isWhiteTurn = true;
|
||||||
|
selectedX = null;
|
||||||
|
selectedY = null;
|
||||||
|
highlightedSquares.clear();
|
||||||
|
moveHistory.clear();
|
||||||
}
|
}
|
||||||
|
//create the board
|
||||||
public String toString() {
|
public String toString() {
|
||||||
//TODO
|
StringBuilder sb = new StringBuilder();
|
||||||
return "";
|
for (int y = 0; y < height; y++) {
|
||||||
|
for (int x = 0; x < width; x++) {
|
||||||
|
Piece p = getPieceAt(x, y);
|
||||||
|
if (p != null) {
|
||||||
|
sb.append(p.isWhite() ? "W" : "B");
|
||||||
|
sb.append(p.getType().getSummary());
|
||||||
|
} else {
|
||||||
|
sb.append("- ");
|
||||||
|
}
|
||||||
|
sb.append(" ");
|
||||||
|
}
|
||||||
|
sb.append("\n");
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArrayList<Piece> getPieces() {
|
public ArrayList<Piece> getPieces() {
|
||||||
ArrayList<Piece> pieces = new ArrayList<>();
|
return new ArrayList<>(pieces);
|
||||||
//TODO
|
|
||||||
|
|
||||||
return pieces;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void userTouch(int x, int y) {
|
public void userTouch(int x, int y) {
|
||||||
//TODO
|
Piece clickedPiece = getPieceAt(x, y);
|
||||||
|
|
||||||
|
// No selection yet
|
||||||
|
if (selectedX == null || selectedY == null) {
|
||||||
|
if (clickedPiece != null && clickedPiece.isWhite() == isWhiteTurn) {
|
||||||
|
selectedX = x;
|
||||||
|
selectedY = y;
|
||||||
|
highlightedSquares = computeLegalMoves(clickedPiece);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Click again to unselect
|
||||||
|
if (selectedX == x && selectedY == y) {
|
||||||
|
selectedX = null;
|
||||||
|
selectedY = null;
|
||||||
|
highlightedSquares.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to move
|
||||||
|
for (int[] move : highlightedSquares) {
|
||||||
|
if (move[0] == x && move[1] == y) {
|
||||||
|
Piece selectedPiece = getPieceAt(selectedX, selectedY);
|
||||||
|
Piece captured = getPieceAt(x, y);
|
||||||
|
|
||||||
|
// Store move for undo
|
||||||
|
Move m = new Move(
|
||||||
|
selectedX, selectedY, x, y,
|
||||||
|
selectedPiece.isWhite(), selectedPiece.getType(), captured
|
||||||
|
);
|
||||||
|
moveHistory.push(m);
|
||||||
|
|
||||||
|
removePieceAt(x, y); // capture
|
||||||
|
removePieceAt(selectedX, selectedY);
|
||||||
|
pieces.add(new Piece(x, y, selectedPiece.isWhite(), selectedPiece.getType()));
|
||||||
|
|
||||||
|
turnNumber++;
|
||||||
|
isWhiteTurn = !isWhiteTurn;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedX = null;
|
||||||
|
selectedY = null;
|
||||||
|
highlightedSquares.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSelected(int x, int y) {
|
public boolean isSelected(int x, int y) {
|
||||||
//TODO
|
return selectedX != null && selectedY != null && selectedX == x && selectedY == y;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* saving-loading feature :*/
|
|
||||||
|
|
||||||
public String[] toFileRep() {
|
public String[] toFileRep() {
|
||||||
//TODO
|
// TODO: Part 3 - Save
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Board(String[] array) {
|
public Board(String[] array) {
|
||||||
//TODO
|
// TODO: Part 3 - Load
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The following methods require more work ! */
|
|
||||||
|
|
||||||
public boolean isHighlighted(int x, int y) {
|
public boolean isHighlighted(int x, int y) {
|
||||||
//TODO
|
for (int[] move : highlightedSquares) {
|
||||||
|
if (move[0] == x && move[1] == y) return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void undoLastMove() {
|
public void undoLastMove() {
|
||||||
//TODO
|
if (moveHistory.isEmpty()) return;
|
||||||
|
|
||||||
|
Move lastMove = moveHistory.pop();
|
||||||
|
|
||||||
|
// Remove moved piece from destination
|
||||||
|
removePieceAt(lastMove.getToX(), lastMove.getToY());
|
||||||
|
|
||||||
|
// Restore original piece
|
||||||
|
pieces.add(new Piece(
|
||||||
|
lastMove.getFromX(),
|
||||||
|
lastMove.getFromY(),
|
||||||
|
lastMove.isWhite(),
|
||||||
|
lastMove.getType()
|
||||||
|
));
|
||||||
|
|
||||||
|
// Restore captured piece, if any
|
||||||
|
if (lastMove.getCapturedPiece() != null) {
|
||||||
|
Piece p = lastMove.getCapturedPiece();
|
||||||
|
pieces.add(new Piece(p.getX(), p.getY(), p.isWhite(), p.getType()));
|
||||||
|
}
|
||||||
|
|
||||||
|
turnNumber--;
|
||||||
|
isWhiteTurn = !isWhiteTurn;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Board(Board board) {
|
public Board(Board board) {
|
||||||
//TODO
|
// TODO: Part 4 - Clone
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void playMove(Move move) {
|
public void playMove(Move move) {
|
||||||
//TODO
|
// TODO: Part 4 - AutoPlayer
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== Helper Methods ==========
|
||||||
|
|
||||||
|
private void removePieceAt(int x, int y) {
|
||||||
|
pieces.removeIf(p -> p.getX() == x && p.getY() == y);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Piece getPieceAt(int x, int y) {
|
||||||
|
for (Piece p : pieces) {
|
||||||
|
if (p.getX() == x && p.getY() == y) return p;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayList<int[]> computeLegalMoves(Piece piece) {
|
||||||
|
ArrayList<int[]> moves = new ArrayList<>();
|
||||||
|
int x = piece.getX();
|
||||||
|
int y = piece.getY();
|
||||||
|
boolean isWhite = piece.isWhite();
|
||||||
|
|
||||||
|
switch (piece.getType()) {
|
||||||
|
case Pawn:
|
||||||
|
int dir = isWhite ? -1 : 1;
|
||||||
|
int startRow = isWhite ? 6 : 1;
|
||||||
|
|
||||||
|
if (getPieceAt(x, y + dir) == null) {
|
||||||
|
moves.add(new int[]{x, y + dir});
|
||||||
|
if (y == startRow && getPieceAt(x, y + 2 * dir) == null) {
|
||||||
|
moves.add(new int[]{x, y + 2 * dir});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int dx = -1; dx <= 1; dx += 2) {
|
||||||
|
int nx = x + dx;
|
||||||
|
int ny = y + dir;
|
||||||
|
if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
|
||||||
|
Piece target = getPieceAt(nx, ny);
|
||||||
|
if (target != null && target.isWhite() != isWhite) {
|
||||||
|
moves.add(new int[]{nx, ny});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Rook:
|
||||||
|
addSlidingMoves(moves, x, y, isWhite, new int[][]{{1,0},{-1,0},{0,1},{0,-1}});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Bishop:
|
||||||
|
addSlidingMoves(moves, x, y, isWhite, new int[][]{{1,1},{1,-1},{-1,1},{-1,-1}});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Queen:
|
||||||
|
addSlidingMoves(moves, x, y, isWhite, new int[][]{
|
||||||
|
{1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Knight:
|
||||||
|
int[][] knightMoves = {
|
||||||
|
{x+1, y+2}, {x+1, y-2}, {x-1, y+2}, {x-1, y-2},
|
||||||
|
{x+2, y+1}, {x+2, y-1}, {x-2, y+1}, {x-2, y-1}
|
||||||
|
};
|
||||||
|
for (int[] move : knightMoves) {
|
||||||
|
int nx = move[0];
|
||||||
|
int ny = move[1];
|
||||||
|
if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
|
||||||
|
Piece target = getPieceAt(nx, ny);
|
||||||
|
if (target == null || target.isWhite() != isWhite) {
|
||||||
|
moves.add(new int[]{nx, ny});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case King:
|
||||||
|
for (int dx = -1; dx <= 1; dx++) {
|
||||||
|
for (int dy = -1; dy <= 1; dy++) {
|
||||||
|
if (dx == 0 && dy == 0) continue;
|
||||||
|
int nx = x + dx;
|
||||||
|
int ny = y + dy;
|
||||||
|
if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
|
||||||
|
Piece target = getPieceAt(nx, ny);
|
||||||
|
if (target == null || target.isWhite() != isWhite) {
|
||||||
|
moves.add(new int[]{nx, ny});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return moves;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addSlidingMoves(ArrayList<int[]> moves, int x, int y, boolean isWhite, int[][] directions) {
|
||||||
|
for (int[] dir : directions) {
|
||||||
|
for (int i = 1; i < 8; i++) {
|
||||||
|
int nx = x + dir[0] * i;
|
||||||
|
int ny = y + dir[1] * i;
|
||||||
|
if (nx < 0 || nx >= width || ny < 0 || ny >= height) break;
|
||||||
|
Piece target = getPieceAt(nx, ny);
|
||||||
|
if (target == null) {
|
||||||
|
moves.add(new int[]{nx, ny});
|
||||||
|
} else {
|
||||||
|
if (target.isWhite() != isWhite) {
|
||||||
|
moves.add(new int[]{nx, ny});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,55 @@
|
||||||
package backend;
|
package backend;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class Move {
|
public class Move {
|
||||||
|
|
||||||
|
private int fromX, fromY;
|
||||||
|
|
||||||
|
private int toX, toY;
|
||||||
|
|
||||||
|
private boolean isWhite;
|
||||||
|
|
||||||
|
private PieceType type;
|
||||||
|
|
||||||
|
private Piece capturedPiece;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public Move(int fromX, int fromY, int toX, int toY, boolean isWhite, PieceType type, Piece capturedPiece) {
|
||||||
|
|
||||||
|
this.fromX = fromX;
|
||||||
|
|
||||||
|
this.fromY = fromY;
|
||||||
|
|
||||||
|
this.toX = toX;
|
||||||
|
|
||||||
|
this.toY = toY;
|
||||||
|
|
||||||
|
this.isWhite = isWhite;
|
||||||
|
|
||||||
|
this.type = type;
|
||||||
|
|
||||||
|
this.capturedPiece = capturedPiece;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
|
||||||
|
public int getFromX() { return fromX; }
|
||||||
|
|
||||||
|
public int getFromY() { return fromY; }
|
||||||
|
|
||||||
|
public int getToX() { return toX; }
|
||||||
|
|
||||||
|
public int getToY() { return toY; }
|
||||||
|
|
||||||
|
public boolean isWhite() { return isWhite; }
|
||||||
|
|
||||||
|
public PieceType getType() { return type; }
|
||||||
|
|
||||||
|
public Piece getCapturedPiece() { return capturedPiece; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,21 +1,61 @@
|
||||||
package backend;
|
package backend;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class Piece {
|
public class Piece {
|
||||||
|
|
||||||
public int getX() {
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
|
|
||||||
|
private int x, y;
|
||||||
|
|
||||||
|
private boolean isWhite;
|
||||||
|
|
||||||
|
private PieceType type;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public Piece(int x, int y, boolean isWhite, PieceType type) {
|
||||||
|
|
||||||
|
this.x = x;
|
||||||
|
|
||||||
|
this.y = y;
|
||||||
|
|
||||||
|
this.isWhite = isWhite;
|
||||||
|
|
||||||
|
this.type = type;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public int getX() {
|
||||||
|
|
||||||
|
return x;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public int getY() {
|
public int getY() {
|
||||||
return 0;
|
|
||||||
|
return y;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PieceType getType() {
|
public PieceType getType() {
|
||||||
return null;
|
|
||||||
|
return type;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public boolean isWhite() {
|
public boolean isWhite() {
|
||||||
return false;
|
|
||||||
|
return isWhite;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue