trial
This commit is contained in:
parent
955fa918db
commit
5e4ffefdbf
|
|
@ -1,5 +1,6 @@
|
|||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
|
|
@ -7,6 +8,8 @@ org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
|||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
|
||||
org.eclipse.jdt.core.compiler.release=enabled
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
|
|
|
|||
|
|
@ -1,17 +1,36 @@
|
|||
package backend;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public class AutoPlayer {
|
||||
private final Random rnd = new Random();
|
||||
|
||||
/**
|
||||
* Picks a random legal move for the active player.
|
||||
*/
|
||||
private int valueOf(PieceType t) {
|
||||
switch (t) {
|
||||
case Pawn: return 1;
|
||||
case Knight:
|
||||
case Bishop: return 3;
|
||||
case Rook: return 5;
|
||||
case Queen: return 9;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/** Greedy‐capture AI with random tie‐break */
|
||||
public Move computeBestMove(Board board) {
|
||||
ArrayList<Move> moves = board.generateLegalMoves();
|
||||
List<Move> moves = ChessRules.generateLegalMoves(board, board.isTurnWhite());
|
||||
if (moves.isEmpty()) return null;
|
||||
return moves.get(rnd.nextInt(moves.size()));
|
||||
|
||||
int bestScore = Integer.MIN_VALUE;
|
||||
Move best = null;
|
||||
for (Move m : moves) {
|
||||
int score = (m.getCapturedPiece()==null ? 0 : valueOf(m.getCapturedPiece().getType()));
|
||||
if (score > bestScore || (score==bestScore && rnd.nextBoolean())) {
|
||||
bestScore = score;
|
||||
best = m;
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ public class Board {
|
|||
private boolean canCastleWK = true, canCastleWQ = true;
|
||||
private boolean canCastleBK = true, canCastleBQ = true;
|
||||
|
||||
/** Empty board */
|
||||
public Board(int colNum, int lineNum) {
|
||||
this.width = colNum;
|
||||
this.height = lineNum;
|
||||
|
|
@ -24,6 +25,7 @@ public class Board {
|
|||
this.pieces = new ArrayList<>();
|
||||
}
|
||||
|
||||
/** Load from file */
|
||||
public Board(String[] array) {
|
||||
this(array[0].split(",").length, array.length - 1);
|
||||
this.isWhiteTurn = array[height].equals("W");
|
||||
|
|
@ -40,6 +42,7 @@ public class Board {
|
|||
}
|
||||
}
|
||||
|
||||
/** Deep copy */
|
||||
public Board(Board other) {
|
||||
this(other.width, other.height);
|
||||
this.turnNumber = other.turnNumber;
|
||||
|
|
@ -49,27 +52,28 @@ public class Board {
|
|||
this.canCastleBK = other.canCastleBK;
|
||||
this.canCastleBQ = other.canCastleBQ;
|
||||
this.pieces = new ArrayList<>();
|
||||
for (Piece p : other.pieces) {
|
||||
for (Piece p : other.pieces)
|
||||
this.pieces.add(new Piece(p.getX(), p.getY(), p.isWhite(), p.getType()));
|
||||
}
|
||||
}
|
||||
|
||||
// Accessors
|
||||
public int getWidth() { return width; }
|
||||
public int getHeight() { return height; }
|
||||
public int getTurnNumber() { return turnNumber; }
|
||||
public boolean isTurnWhite(){ return isWhiteTurn; }
|
||||
|
||||
/** Standard setup */
|
||||
public void populateBoard() {
|
||||
PieceType[] back = {
|
||||
PieceType.Rook, PieceType.Knight, PieceType.Bishop, PieceType.Queen,
|
||||
PieceType.King, PieceType.Bishop, PieceType.Knight, PieceType.Rook
|
||||
};
|
||||
// black pawns + back
|
||||
// black
|
||||
for (int x = 0; x < width; x++) {
|
||||
pieces.add(new Piece(x,1,false,PieceType.Pawn));
|
||||
pieces.add(new Piece(x,0,false,back[x]));
|
||||
}
|
||||
// white pawns + back
|
||||
// white
|
||||
for (int x = 0; x < width; x++) {
|
||||
pieces.add(new Piece(x,6,true,PieceType.Pawn));
|
||||
pieces.add(new Piece(x,7,true,back[x]));
|
||||
|
|
@ -77,6 +81,7 @@ public class Board {
|
|||
canCastleWK = canCastleWQ = canCastleBK = canCastleBQ = true;
|
||||
}
|
||||
|
||||
/** Clear everything */
|
||||
public void cleanBoard() {
|
||||
pieces.clear();
|
||||
moveHistory.clear();
|
||||
|
|
@ -86,15 +91,12 @@ public class Board {
|
|||
canCastleWK = canCastleWQ = canCastleBK = canCastleBQ = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
@Override public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
Piece p = getPieceAt(x,y);
|
||||
sb.append(p == null
|
||||
? ".."
|
||||
: (p.isWhite() ? "W" : "B") + p.getType().getSummary());
|
||||
sb.append(p==null?"..":(p.isWhite()?"W":"B")+p.getType().getSummary());
|
||||
if (x<width-1) sb.append(",");
|
||||
}
|
||||
sb.append("\n");
|
||||
|
|
@ -109,9 +111,7 @@ public class Board {
|
|||
StringBuilder row = new StringBuilder();
|
||||
for (int x = 0; x < width; x++) {
|
||||
Piece p = getPieceAt(x,y);
|
||||
row.append(p == null
|
||||
? ".."
|
||||
: (p.isWhite() ? "W" : "B") + p.getType().getSummary());
|
||||
row.append(p==null?"..":(p.isWhite()?"W":"B")+p.getType().getSummary());
|
||||
if (x<width-1) row.append(",");
|
||||
}
|
||||
out[y] = row.toString();
|
||||
|
|
@ -120,21 +120,17 @@ public class Board {
|
|||
return out;
|
||||
}
|
||||
|
||||
public ArrayList<Piece> getPieces() {
|
||||
return new ArrayList<>(pieces);
|
||||
}
|
||||
|
||||
public ArrayList<Piece> getPieces() { return new ArrayList<>(pieces); }
|
||||
public void setPiece(boolean w, PieceType t, int x, int y) {
|
||||
removePieceAt(x,y);
|
||||
pieces.add(new Piece(x,y,w,t));
|
||||
removePieceAt(x,y); pieces.add(new Piece(x,y,w,t));
|
||||
}
|
||||
|
||||
/** User click → select/move */
|
||||
public void userTouch(int x, int y) {
|
||||
Piece clicked = getPieceAt(x,y);
|
||||
if (selectedX==null) {
|
||||
if (clicked!=null && clicked.isWhite()==isWhiteTurn) {
|
||||
selectedX = x;
|
||||
selectedY = y;
|
||||
selectedX=x; selectedY=y;
|
||||
highlightedSquares = computeLegalMoves(clicked);
|
||||
}
|
||||
return;
|
||||
|
|
@ -148,8 +144,7 @@ public class Board {
|
|||
if (mv[0]==x && mv[1]==y) {
|
||||
Piece sel = getPieceAt(selectedX, selectedY);
|
||||
Piece cap = getPieceAt(x,y);
|
||||
|
||||
// en passant detection
|
||||
// en passant
|
||||
if (cap==null && sel.getType()==PieceType.Pawn && x!=selectedX) {
|
||||
int dir = sel.isWhite()? -1:1;
|
||||
Move last = moveHistory.isEmpty()?null:moveHistory.peek();
|
||||
|
|
@ -164,7 +159,6 @@ public class Board {
|
|||
cap = behind;
|
||||
}
|
||||
}
|
||||
|
||||
Move m = new Move(
|
||||
selectedX, selectedY,
|
||||
x, y,
|
||||
|
|
@ -182,37 +176,32 @@ public class Board {
|
|||
public boolean isSelected(int x,int y) {
|
||||
return selectedX!=null && selectedX==x && selectedY==y;
|
||||
}
|
||||
|
||||
public boolean isHighlighted(int x,int y) {
|
||||
for (int[] mv : highlightedSquares) {
|
||||
for (int[] mv: highlightedSquares)
|
||||
if (mv[0]==x && mv[1]==y) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Execute a move (incl. castle & en passant) */
|
||||
public void playMove(Move m) {
|
||||
if (m==null) return;
|
||||
|
||||
// castling rook reposition
|
||||
// castling rook
|
||||
if (m.getType()==PieceType.King && Math.abs(m.getToX()-m.getFromX())==2) {
|
||||
int y = m.isWhite()?7:0;
|
||||
if (m.getToX()-m.getFromX()==2) {
|
||||
removePieceAt(7, y);
|
||||
pieces.add(new Piece(5, y, m.isWhite(), PieceType.Rook));
|
||||
removePieceAt(7,y); pieces.add(new Piece(5,y,m.isWhite(),PieceType.Rook));
|
||||
} else {
|
||||
removePieceAt(0, y);
|
||||
pieces.add(new Piece(3, y, m.isWhite(), PieceType.Rook));
|
||||
removePieceAt(0,y); pieces.add(new Piece(3,y,m.isWhite(),PieceType.Rook));
|
||||
}
|
||||
}
|
||||
|
||||
// normal or en passant capture
|
||||
// normal or en passant cap
|
||||
if (m.getCapturedPiece()!=null) {
|
||||
removePieceAt(
|
||||
m.getCapturedPiece().getX(),
|
||||
m.getCapturedPiece().getY()
|
||||
);
|
||||
}
|
||||
// update opponent's castling rights if rook was captured
|
||||
// update opponent castling rights if rook was captured
|
||||
if (m.getCapturedPiece()!=null && m.getCapturedPiece().getType()==PieceType.Rook) {
|
||||
Piece cap=m.getCapturedPiece();
|
||||
if (cap.isWhite()) {
|
||||
|
|
@ -223,13 +212,9 @@ public class Board {
|
|||
if (cap.getX()==7 && cap.getY()==0) canCastleBK=false;
|
||||
}
|
||||
}
|
||||
|
||||
// move the piece
|
||||
removePieceAt(m.getFromX(),m.getFromY());
|
||||
pieces.add(new Piece(
|
||||
m.getToX(), m.getToY(),
|
||||
m.isWhite(), m.getType()
|
||||
));
|
||||
pieces.add(new Piece(m.getToX(),m.getToY(),m.isWhite(),m.getType()));
|
||||
|
||||
// moving piece castling rights
|
||||
if (m.getType()==PieceType.King) {
|
||||
|
|
@ -251,43 +236,33 @@ public class Board {
|
|||
isWhiteTurn = !isWhiteTurn;
|
||||
}
|
||||
|
||||
/** Undo last */
|
||||
public void undoLastMove() {
|
||||
if (moveHistory.isEmpty()) return;
|
||||
Move m = moveHistory.pop();
|
||||
|
||||
// undo castling rook move
|
||||
// undo castling
|
||||
if (m.getType()==PieceType.King && Math.abs(m.getToX()-m.getFromX())==2) {
|
||||
int y = m.isWhite()?7:0;
|
||||
if (m.getToX()-m.getFromX()==2) {
|
||||
removePieceAt(5, y);
|
||||
pieces.add(new Piece(7, y, m.isWhite(), PieceType.Rook));
|
||||
removePieceAt(5,y); pieces.add(new Piece(7,y,m.isWhite(),PieceType.Rook));
|
||||
} else {
|
||||
removePieceAt(3, y);
|
||||
pieces.add(new Piece(0, y, m.isWhite(), PieceType.Rook));
|
||||
removePieceAt(3,y); pieces.add(new Piece(0,y,m.isWhite(),PieceType.Rook));
|
||||
}
|
||||
}
|
||||
|
||||
// move piece back
|
||||
// move the king/piece back
|
||||
removePieceAt(m.getToX(),m.getToY());
|
||||
pieces.add(new Piece(
|
||||
m.getFromX(), m.getFromY(),
|
||||
m.isWhite(), m.getType()
|
||||
));
|
||||
|
||||
pieces.add(new Piece(m.getFromX(),m.getFromY(),m.isWhite(),m.getType()));
|
||||
// restore capture
|
||||
if (m.getCapturedPiece()!=null) {
|
||||
Piece c=m.getCapturedPiece();
|
||||
pieces.add(new Piece(
|
||||
c.getX(), c.getY(),
|
||||
c.isWhite(), c.getType()
|
||||
));
|
||||
pieces.add(new Piece(c.getX(),c.getY(),c.isWhite(),c.getType()));
|
||||
}
|
||||
|
||||
turnNumber--;
|
||||
isWhiteTurn = !isWhiteTurn;
|
||||
// note: castling rights are not fully restored in this simple undo
|
||||
// note: castling rights not fully restored here
|
||||
}
|
||||
|
||||
/** Pseudo-legal moves for side to move */
|
||||
public ArrayList<Move> generateLegalMoves() {
|
||||
ArrayList<Move> all = new ArrayList<>();
|
||||
for (Piece p : pieces) {
|
||||
|
|
@ -306,11 +281,46 @@ public class Board {
|
|||
return all;
|
||||
}
|
||||
|
||||
// --- New attack-detection helpers ---
|
||||
private boolean attacksSquare(Piece p, int targetX, int targetY) {
|
||||
/** Is that color’s king under attack? */
|
||||
public boolean isInCheck(boolean color) {
|
||||
int kx=-1, ky=-1;
|
||||
for (Piece p:pieces) {
|
||||
if (p.getType()==PieceType.King && p.isWhite()==color) {
|
||||
kx=p.getX(); ky=p.getY(); break;
|
||||
}
|
||||
}
|
||||
if (kx<0) throw new IllegalStateException("No king for " + color);
|
||||
return isSquareAttacked(kx,ky,!color);
|
||||
}
|
||||
|
||||
/** True legal moves for `color` (filter out self-check) */
|
||||
public ArrayList<Move> generateLegalMoves(boolean color) {
|
||||
Board copy = new Board(this);
|
||||
copy.isWhiteTurn = color;
|
||||
ArrayList<Move> pseudo = copy.generateLegalMoves();
|
||||
ArrayList<Move> legal = new ArrayList<>();
|
||||
for (Move m : pseudo) {
|
||||
copy.playMove(m);
|
||||
if (!copy.isInCheck(color)) legal.add(m);
|
||||
copy.undoLastMove();
|
||||
}
|
||||
return legal;
|
||||
}
|
||||
|
||||
/** Square attacked by given side? */
|
||||
public boolean isSquareAttacked(int x,int y,boolean byWhite) {
|
||||
for (Piece p:pieces)
|
||||
if (p.isWhite()==byWhite && attacksSquare(p,x,y))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// ─── Private helpers ────────────────────────────────────────────
|
||||
|
||||
private boolean attacksSquare(Piece p,int tx,int ty) {
|
||||
int x=p.getX(), y=p.getY();
|
||||
boolean w=p.isWhite();
|
||||
int dx = targetX - x, dy = targetY - y;
|
||||
int dx=tx-x, dy=ty-y;
|
||||
switch(p.getType()) {
|
||||
case Pawn:
|
||||
int dir = w?-1:1;
|
||||
|
|
@ -320,13 +330,13 @@ public class Board {
|
|||
|| (Math.abs(dx)==2&&Math.abs(dy)==1);
|
||||
case Bishop:
|
||||
if (Math.abs(dx)!=Math.abs(dy)) return false;
|
||||
return clearPath(x, y, targetX, targetY);
|
||||
return clearPath(x,y,tx,ty);
|
||||
case Rook:
|
||||
if (dx!=0&&dy!=0) return false;
|
||||
return clearPath(x, y, targetX, targetY);
|
||||
return clearPath(x,y,tx,ty);
|
||||
case Queen:
|
||||
if (dx==0||dy==0||Math.abs(dx)==Math.abs(dy))
|
||||
return clearPath(x, y, targetX, targetY);
|
||||
return clearPath(x,y,tx,ty);
|
||||
return false;
|
||||
case King:
|
||||
return Math.max(Math.abs(dx),Math.abs(dy))==1;
|
||||
|
|
@ -336,33 +346,24 @@ public class Board {
|
|||
}
|
||||
|
||||
private boolean clearPath(int x1,int y1,int x2,int y2) {
|
||||
int stepX = Integer.signum(x2 - x1);
|
||||
int stepY = Integer.signum(y2 - y1);
|
||||
int cx = x1 + stepX, cy = y1 + stepY;
|
||||
int sx=Integer.signum(x2-x1), sy=Integer.signum(y2-y1);
|
||||
int cx=x1+sx, cy=y1+sy;
|
||||
while (cx!=x2||cy!=y2) {
|
||||
if (getPieceAt(cx,cy)!=null) return false;
|
||||
cx += stepX; cy += stepY;
|
||||
cx+=sx; cy+=sy;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isSquareAttacked(int x, int y, boolean byWhite) {
|
||||
for (Piece p : pieces) {
|
||||
if (p.isWhite() == byWhite && attacksSquare(p, x, y))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// --- Original helpers ---
|
||||
private Piece getPieceAt(int x,int y) {
|
||||
for (Piece p : pieces)
|
||||
if (p.getX() == x && p.getY() == y) return p;
|
||||
for (Piece p:pieces) if (p.getX()==x&&p.getY()==y) return p;
|
||||
return null;
|
||||
}
|
||||
|
||||
private void removePieceAt(int x,int y) {
|
||||
pieces.removeIf(p->p.getX()==x&&p.getY()==y);
|
||||
}
|
||||
|
||||
private boolean in(int x,int y) {
|
||||
return x>=0&&x<width&&y>=0&&y<height;
|
||||
}
|
||||
|
|
@ -373,9 +374,8 @@ public class Board {
|
|||
int nx=x+d[0]*i, ny=y+d[1]*i;
|
||||
if (!in(nx,ny)) break;
|
||||
Piece t = getPieceAt(nx,ny);
|
||||
if (t == null) {
|
||||
out.add(new int[]{nx, ny});
|
||||
} else {
|
||||
if (t==null) out.add(new int[]{nx,ny});
|
||||
else {
|
||||
if (t.isWhite()!=w) out.add(new int[]{nx,ny});
|
||||
break;
|
||||
}
|
||||
|
|
@ -392,17 +392,14 @@ public class Board {
|
|||
int dir = w?-1:1, sr = w?6:1;
|
||||
if (in(x,y+dir)&&getPieceAt(x,y+dir)==null) {
|
||||
out.add(new int[]{x,y+dir});
|
||||
if (y == sr && getPieceAt(x, y + 2*dir) == null) {
|
||||
if (y==sr&&getPieceAt(x,y+2*dir)==null)
|
||||
out.add(new int[]{x,y+2*dir});
|
||||
}
|
||||
}
|
||||
for (int dx : new int[]{-1,1}) {
|
||||
int nx=x+dx, ny=y+dir;
|
||||
if (in(nx,ny)) {
|
||||
Piece t=getPieceAt(nx,ny);
|
||||
if (t != null && t.isWhite() != w) {
|
||||
out.add(new int[]{nx, ny});
|
||||
}
|
||||
if (t!=null&&t.isWhite()!=w) out.add(new int[]{nx,ny});
|
||||
}
|
||||
}
|
||||
if (!moveHistory.isEmpty()) {
|
||||
|
|
@ -410,8 +407,7 @@ public class Board {
|
|||
if (last.getType()==PieceType.Pawn
|
||||
&&Math.abs(last.getFromY()-last.getToY())==2
|
||||
&&last.getToY()==y
|
||||
&& Math.abs(last.getToX() - x) == 1
|
||||
) {
|
||||
&&Math.abs(last.getToX()-x)==1) {
|
||||
int ex=last.getToX(), ey=y+dir;
|
||||
if (in(ex,ey)&&getPieceAt(ex,ey)==null)
|
||||
out.add(new int[]{ex,ey});
|
||||
|
|
@ -427,17 +423,15 @@ public class Board {
|
|||
case Queen:
|
||||
slide(out,x,y,w,new int[][]{
|
||||
{1,0},{-1,0},{0,1},{0,-1},
|
||||
{1,1},{1,-1},{-1,1},{-1,-1}
|
||||
});
|
||||
{1,1},{1,-1},{-1,1},{-1,-1}});
|
||||
break;
|
||||
case Knight:
|
||||
int[][] knightMoves = {{1,2},{1,-2},{-1,2},{-1,-2},{2,1},{2,-1},{-2,1},{-2,-1}};
|
||||
for (int[] m : knightMoves) {
|
||||
int[][] km={{1,2},{1,-2},{-1,2},{-1,-2},{2,1},{2,-1},{-2,1},{-2,-1}};
|
||||
for (int[] m:km) {
|
||||
int nx=x+m[0], ny=y+m[1];
|
||||
if (in(nx,ny)) {
|
||||
Piece t=getPieceAt(nx,ny);
|
||||
if (t == null || t.isWhite() != w)
|
||||
out.add(new int[]{nx, ny});
|
||||
if (t==null||t.isWhite()!=w) out.add(new int[]{nx,ny});
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -448,8 +442,7 @@ public class Board {
|
|||
int nx=x+dx, ny=y+dy;
|
||||
if (in(nx,ny)){
|
||||
Piece t=getPieceAt(nx,ny);
|
||||
if (t == null || t.isWhite() != w)
|
||||
out.add(new int[]{nx, ny});
|
||||
if (t==null||t.isWhite()!=w) out.add(new int[]{nx,ny});
|
||||
}
|
||||
}
|
||||
boolean opp=!w;
|
||||
|
|
@ -477,4 +470,12 @@ public class Board {
|
|||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
public Move getLastMove() {
|
||||
return moveHistory.isEmpty() ? null : moveHistory.peek();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package backend;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ChessRules {
|
||||
|
||||
public static boolean isInCheck(Board board, boolean color) {
|
||||
return board.isInCheck(color);
|
||||
}
|
||||
|
||||
public static List<Move> generateLegalMoves(Board board, boolean color) {
|
||||
return board.generateLegalMoves(color);
|
||||
}
|
||||
|
||||
public static boolean isCheckmate(Board board, boolean color) {
|
||||
List<Move> legal = board.generateLegalMoves(color);
|
||||
return legal.isEmpty() && board.isInCheck(color);
|
||||
}
|
||||
|
||||
public static boolean isStalemate(Board board, boolean color) {
|
||||
List<Move> legal = board.generateLegalMoves(color);
|
||||
return legal.isEmpty() && !board.isInCheck(color);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,115 +1,111 @@
|
|||
package backend;
|
||||
|
||||
import windowInterface.MyInterface;
|
||||
import java.util.List;
|
||||
|
||||
public class Game extends Thread {
|
||||
|
||||
private AutoPlayer aiPlayer;
|
||||
private final AutoPlayer aiPlayer;
|
||||
private Board board;
|
||||
|
||||
private MyInterface mjf;
|
||||
private int COL_NUM = 8;
|
||||
private int LINE_NUM = 8;
|
||||
private final MyInterface mjf;
|
||||
private final boolean[] activationAIFlags = new boolean[2];
|
||||
private boolean gameOver = false;
|
||||
private int whiteCaptures = 0, blackCaptures = 0;
|
||||
private int loopDelay = 250;
|
||||
boolean[] activationAIFlags;
|
||||
|
||||
public Game(MyInterface mjfParam) {
|
||||
mjf = mjfParam;
|
||||
board = new Board(COL_NUM, LINE_NUM);
|
||||
loopDelay = 250;
|
||||
LINE_NUM = 8;
|
||||
COL_NUM = 8;
|
||||
activationAIFlags = new boolean[2];
|
||||
aiPlayer = new AutoPlayer();
|
||||
this.mjf = mjfParam;
|
||||
this.board = new Board(8, 8);
|
||||
this.aiPlayer = new AutoPlayer();
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return board.getWidth();
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return board.getHeight();
|
||||
}
|
||||
public int getWidth() { return board.getWidth(); }
|
||||
public int getHeight() { return board.getHeight(); }
|
||||
public int getWhiteCaptures() { return whiteCaptures; }
|
||||
public int getBlackCaptures() { return blackCaptures; }
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while(true) {
|
||||
aiPlayerTurn();
|
||||
mjf.update(board.getTurnNumber(), board.isTurnWhite());
|
||||
try {
|
||||
Thread.sleep(loopDelay);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
while (!gameOver) {
|
||||
if (isAITurn()) {
|
||||
Move m = aiPlayer.computeBestMove(new Board(board));
|
||||
board.playMove(m);
|
||||
recordCapture(m);
|
||||
checkGameEnd();
|
||||
}
|
||||
mjf.update(board.getTurnNumber(), board.isTurnWhite());
|
||||
try { Thread.sleep(loopDelay); }
|
||||
catch (InterruptedException e) { e.printStackTrace(); }
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAITurn() {
|
||||
// [1] = white, [0] = black
|
||||
return activationAIFlags[ board.isTurnWhite()?1:0 ];
|
||||
}
|
||||
|
||||
private void aiPlayerTurn() {
|
||||
if(isAITurn()) {
|
||||
board.playMove(aiPlayer.computeBestMove(new Board(board)));
|
||||
}
|
||||
}
|
||||
|
||||
public void clickCoords(int x, int y) {
|
||||
int width = this.getWidth();
|
||||
int height = this.getHeight();
|
||||
if(0>x || 0>y || x>width || y>height) {
|
||||
System.out.println("Click out of bounds");
|
||||
return;
|
||||
}
|
||||
if (gameOver) return;
|
||||
if (x<0||y<0||x>=getWidth()||y>=getHeight()) return;
|
||||
if (!isAITurn()) {
|
||||
board.userTouch(x,y);
|
||||
// lastMove not returned, but board.moveHistory.peek() is it:
|
||||
Move last = board.getLastMove();
|
||||
recordCapture(last);
|
||||
checkGameEnd();
|
||||
}
|
||||
}
|
||||
|
||||
private void recordCapture(Move m) {
|
||||
if (m!=null && m.getCapturedPiece()!=null) {
|
||||
if (m.isWhite()) whiteCaptures++;
|
||||
else blackCaptures++;
|
||||
}
|
||||
}
|
||||
|
||||
public void setPiece(boolean isWhite, PieceType type, int x, int y) {
|
||||
board.setPiece(isWhite, type, x, y);
|
||||
/** check for end‐of‐game and notify GUI */
|
||||
private void checkGameEnd() {
|
||||
boolean sideToMove = board.isTurnWhite();
|
||||
List<Move> replies = ChessRules.generateLegalMoves(board, sideToMove);
|
||||
if (replies.isEmpty()) {
|
||||
String msg;
|
||||
if (ChessRules.isCheckmate(board, sideToMove)) {
|
||||
msg = (sideToMove?"White":"Black")
|
||||
+ " is checkmated. "
|
||||
+ (!sideToMove?"White":"Black")
|
||||
+ " wins!";
|
||||
} else {
|
||||
msg = "Stalemate—draw.";
|
||||
}
|
||||
System.out.println(msg);
|
||||
mjf.gameOver(msg);
|
||||
gameOver = true;
|
||||
}
|
||||
}
|
||||
|
||||
// --- existing API below ---
|
||||
|
||||
public void setPiece(boolean w, PieceType t, int x, int y) {
|
||||
board.setPiece(w,t,x,y);
|
||||
}
|
||||
public String[] getFileRepresentation() {
|
||||
return board.toFileRep();
|
||||
}
|
||||
|
||||
public void setLoopDelay(int delay) {
|
||||
this.loopDelay = delay;
|
||||
}
|
||||
|
||||
public void setDefaultSetup() {
|
||||
board.cleanBoard();
|
||||
board.populateBoard();
|
||||
}
|
||||
|
||||
public void setBoard(String[] array) {
|
||||
board = new Board(array);
|
||||
}
|
||||
|
||||
public Iterable<Piece> getPieces() {
|
||||
return board.getPieces();
|
||||
}
|
||||
|
||||
public boolean isSelected(int x, int y) {
|
||||
return board.isSelected(x, y);
|
||||
}
|
||||
|
||||
public boolean isHighlighted(int x, int y) {
|
||||
return board.isHighlighted(x, y);
|
||||
}
|
||||
|
||||
public void undoLastMove() {
|
||||
board.undoLastMove();
|
||||
}
|
||||
|
||||
public void toggleAI(boolean isWhite) {
|
||||
this.activationAIFlags[isWhite?1:0] = !this.activationAIFlags[isWhite?1:0];
|
||||
}
|
||||
|
||||
public void setLoopDelay(int d) { loopDelay = d; }
|
||||
public void setDefaultSetup() { board.cleanBoard(); board.populateBoard(); }
|
||||
public void setBoard(String[] a){ board = new Board(a); }
|
||||
public Iterable<Piece> getPieces() { return board.getPieces(); }
|
||||
public boolean isSelected(int x,int y) { return board.isSelected(x,y); }
|
||||
public boolean isHighlighted(int x,int y){ return board.isHighlighted(x,y); }
|
||||
public void undoLastMove() { board.undoLastMove(); }
|
||||
public void toggleAI(boolean w) { activationAIFlags[w?1:0] = !activationAIFlags[w?1:0]; }
|
||||
public Board getBoard() { return board; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,67 +1,44 @@
|
|||
package windowInterface;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.*;
|
||||
|
||||
import backend.Game;
|
||||
import backend.Piece;
|
||||
import backend.PieceType;
|
||||
import backend.*;
|
||||
|
||||
public class JPanelChessBoard extends JPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Game myGame;
|
||||
private MyInterface interfaceGlobal;
|
||||
private final MyInterface interfaceGlobal;
|
||||
private BufferedImage spriteSheet;
|
||||
private int PIECE_WIDTH = 16; //in spritesheet
|
||||
private int PIECE_HEIGHT = 16; //in spritesheet
|
||||
private int MARGIN = 6;
|
||||
private final int PIECE_W=16, PIECE_H=16, M=6;
|
||||
|
||||
private boolean pieceSelectorMode;
|
||||
private boolean selectedPieceIsWhite;
|
||||
private PieceType selectedPieceType;
|
||||
private boolean pieceAdderMode;
|
||||
private boolean pieceSelectorMode=false, pieceAdderMode=false;
|
||||
private boolean selIsWhite=true; private PieceType selType=PieceType.Pawn;
|
||||
|
||||
public JPanelChessBoard(MyInterface itf) {
|
||||
super();
|
||||
myGame = null;
|
||||
interfaceGlobal = itf;
|
||||
selectedPieceIsWhite = true;
|
||||
selectedPieceType = PieceType.Pawn;
|
||||
pieceSelectorMode = false;
|
||||
try {
|
||||
spriteSheet = ImageIO.read(new File("pieces.png"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
pieceSelectorMode = false;
|
||||
pieceAdderMode = false;
|
||||
super(); interfaceGlobal=itf;
|
||||
try { spriteSheet=ImageIO.read(new File("pieces.png")); }
|
||||
catch(Exception e){ e.printStackTrace(); }
|
||||
addMouseListener(new MouseAdapter(){
|
||||
public void mousePressed(MouseEvent me){
|
||||
// System.out.println(me);
|
||||
if(pieceSelectorMode){
|
||||
int x = Math.round(me.getX()/cellWidth());
|
||||
selectedPieceType = PieceType.values()[5-x];
|
||||
selectedPieceIsWhite = (me.getY() > cellHeight());
|
||||
int x=(int)(me.getX()/cellW()), y=(int)(me.getY()/cellH());
|
||||
selType = PieceType.values()[5-x];
|
||||
selIsWhite = y>1;
|
||||
pieceSelectorMode=false;
|
||||
} else {
|
||||
if(myGame == null) {
|
||||
interfaceGlobal.instantiateSimu();
|
||||
}
|
||||
int x = (me.getX()*myGame.getWidth())/getWidth();
|
||||
int y = (me.getY()*myGame.getHeight())/getHeight();
|
||||
if(myGame==null) interfaceGlobal.instantiateSimu();
|
||||
int x=(me.getX()*myGame.getWidth())/getWidth(),
|
||||
y=(me.getY()*myGame.getHeight())/getHeight();
|
||||
if(pieceAdderMode){
|
||||
//TODO
|
||||
myGame.setPiece(selectedPieceIsWhite,selectedPieceType, x, y);
|
||||
myGame.setPiece(selIsWhite,selType,x,y);
|
||||
pieceAdderMode=false;
|
||||
} else {
|
||||
myGame.clickCoords(x,y);
|
||||
|
|
@ -72,125 +49,64 @@ public class JPanelChessBoard extends JPanel {
|
|||
});
|
||||
}
|
||||
|
||||
public void setGame(Game g){ myGame=g; }
|
||||
|
||||
public void setGame(Game simu) {
|
||||
myGame = simu;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
@Override protected void paintComponent(Graphics g){
|
||||
super.paintComponent(g);
|
||||
this.setBackground(Color.black);
|
||||
if(pieceSelectorMode) {
|
||||
g.drawImage(
|
||||
spriteSheet,
|
||||
0,
|
||||
0,
|
||||
Math.round(5*cellWidth()),
|
||||
Math.round(2*cellHeight()),
|
||||
null
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (myGame != null) {
|
||||
// Draw Interface from state of simulator
|
||||
float cellWidth = cellWidth();
|
||||
float cellHeight = cellHeight();
|
||||
if (myGame==null) return;
|
||||
|
||||
g.setColor(Color.white);
|
||||
// compute legal highlights
|
||||
int selX=-1, selY=-1;
|
||||
for(int xx=0;xx<myGame.getWidth();xx++) for(int yy=0;yy<myGame.getHeight();yy++)
|
||||
if(myGame.isSelected(xx,yy)){ selX=xx; selY=yy; break;}
|
||||
Set<Point> legalH = new HashSet<>();
|
||||
if(selX>=0){
|
||||
List<Move> lm = ChessRules.generateLegalMoves(
|
||||
myGame.getBoard(), myGame.getBoard().isTurnWhite()
|
||||
);
|
||||
for(Move m:lm) if(m.getFromX()==selX&&m.getFromY()==selY)
|
||||
legalH.add(new Point(m.getToX(),m.getToY()));
|
||||
}
|
||||
|
||||
float w=cellW(), h=cellH();
|
||||
for(int x=0;x<myGame.getWidth();x++){
|
||||
for(int y=0;y<myGame.getHeight();y++){
|
||||
boolean isSelect = myGame.isSelected(x,y);
|
||||
boolean isHighlight = myGame.isHighlighted(x,y);
|
||||
if(isSelect) {
|
||||
g.setColor(Color.blue);
|
||||
boolean isSel= myGame.isSelected(x,y),
|
||||
isHl = legalH.contains(new Point(x,y));
|
||||
if (isSel) g.setColor(Color.PINK);
|
||||
else if(isHl) g.setColor(Color.GREEN);
|
||||
else g.setColor((x+y)%2==0?Color.WHITE:Color.RED);
|
||||
g.fillRect((int)(x*w),(int)(y*h),(int)w,(int)h);
|
||||
}
|
||||
if(isHighlight) {
|
||||
g.setColor(Color.yellow);
|
||||
}
|
||||
if((x+y)%2==1 || isSelect || isHighlight) {
|
||||
g.fillRect(
|
||||
Math.round(x*cellWidth),
|
||||
Math.round(y*cellHeight),
|
||||
Math.round(cellWidth),
|
||||
Math.round(cellHeight)
|
||||
g.setColor(Color.GRAY);
|
||||
for(int x=0;x<=myGame.getWidth();x++)
|
||||
g.drawLine((int)(x*w),0,(int)(x*w),getHeight());
|
||||
for(int y=0;y<=myGame.getHeight();y++)
|
||||
g.drawLine(0,(int)(y*h),getWidth(),(int)(y*h));
|
||||
|
||||
// draw pieces
|
||||
for(Piece p: myGame.getPieces()) drawPiece(g,p);
|
||||
}
|
||||
|
||||
private void drawPiece(Graphics g, Piece p){
|
||||
Image sub = spriteSheet.getSubimage(
|
||||
spriteIndex(p.getType())*PIECE_W,
|
||||
p.isWhite()?PIECE_H:0,
|
||||
PIECE_W,PIECE_H
|
||||
);
|
||||
}
|
||||
if(isHighlight || isSelect) {
|
||||
g.setColor(Color.white);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
g.setColor(Color.gray);
|
||||
for(int x=0; x<myGame.getWidth();x++) {
|
||||
int graphX = Math.round(x*cellWidth);
|
||||
g.drawLine(graphX, 0, graphX, this.getHeight());
|
||||
}
|
||||
for (int y=0; y<myGame.getHeight(); y++) {
|
||||
int graphY = Math.round(y*cellHeight);
|
||||
g.drawLine(0, graphY, this.getWidth(), graphY);
|
||||
}
|
||||
|
||||
for (Piece piece : myGame.getPieces()) {
|
||||
drawPiece(g,piece);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void drawPiece(Graphics g, Piece piece) {
|
||||
g.drawImage(
|
||||
getChessPieceImageFromType(piece.getType(), piece.isWhite()),
|
||||
MARGIN+(xCoordFromGame(piece.getX())),
|
||||
MARGIN+(yCoordFromGame(piece.getY())),
|
||||
null
|
||||
sub.getScaledInstance((int)(cellW()-2*M),(int)(cellH()-2*M),0),
|
||||
(int)(p.getX()*cellW())+M, (int)(p.getY()*cellH())+M, null
|
||||
);
|
||||
}
|
||||
|
||||
private int spriteIndex(PieceType t){ return 5 - t.ordinal(); }
|
||||
private float cellW(){ return getWidth()/(float)myGame.getWidth(); }
|
||||
private float cellH(){ return getHeight()/(float)myGame.getHeight(); }
|
||||
|
||||
private Image getChessPieceImageFromType(PieceType type, boolean isWhite) {
|
||||
int x = spriteSheetPositionOfPieceType(type)*PIECE_WIDTH;
|
||||
int y = PIECE_HEIGHT * (isWhite?1:0);
|
||||
Image subImage = spriteSheet.getSubimage(x, y, PIECE_WIDTH, PIECE_HEIGHT);
|
||||
return subImage.getScaledInstance(
|
||||
Math.round(cellWidth())-2*MARGIN,
|
||||
Math.round(cellHeight())-2*MARGIN, 0
|
||||
);
|
||||
}
|
||||
|
||||
private int spriteSheetPositionOfPieceType(PieceType type) {
|
||||
return 5-type.ordinal();
|
||||
}
|
||||
|
||||
private float cellWidth() {
|
||||
return (float) this.getWidth()/ (float)myGame.getWidth();
|
||||
}
|
||||
private float cellHeight() {
|
||||
return (float)this.getHeight()/ (float)myGame.getHeight();
|
||||
}
|
||||
private int xCoordFromGame(int x) {
|
||||
return Math.round(x*cellWidth());
|
||||
}
|
||||
private int yCoordFromGame(int y) {
|
||||
return Math.round(y*cellHeight());
|
||||
}
|
||||
|
||||
public void togglePieceSelector() {
|
||||
pieceSelectorMode = ! pieceSelectorMode;
|
||||
}
|
||||
|
||||
public void toggleAdderMode() {
|
||||
pieceAdderMode = ! pieceAdderMode;
|
||||
}
|
||||
|
||||
public boolean isPieceSelectorMode() {
|
||||
return pieceSelectorMode;
|
||||
}
|
||||
|
||||
|
||||
public boolean isPieceAdderMode() {
|
||||
return pieceAdderMode;
|
||||
}
|
||||
|
||||
public void togglePieceSelector(){ pieceSelectorMode = !pieceSelectorMode; }
|
||||
public void toggleAdderMode() { pieceAdderMode = !pieceAdderMode; }
|
||||
public boolean isPieceSelectorMode(){ return pieceSelectorMode; }
|
||||
public boolean isPieceAdderMode() { return pieceAdderMode; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,153 +1,73 @@
|
|||
package windowInterface;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridLayout;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import backend.Game;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JLabel;
|
||||
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.awt.event.ActionEvent;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.AbstractListModel;
|
||||
import javax.swing.JToggleButton;
|
||||
import javax.swing.JRadioButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.*;
|
||||
import backend.Game;
|
||||
|
||||
public class MyInterface extends JFrame {
|
||||
|
||||
private static final long serialVersionUID = -6840815447618468846L;
|
||||
private JPanel contentPane;
|
||||
private JLabel turnLabel;
|
||||
private JLabel borderLabel;
|
||||
private JLabel speedLabel;
|
||||
private static final long serialVersionUID = 1L;
|
||||
private JPanelChessBoard panelDraw;
|
||||
private Game game;
|
||||
private JLabel actionLabel;
|
||||
private JCheckBox chckbxBlackAI;
|
||||
private JCheckBox chckbxWhiteAI;
|
||||
private JLabel turnLabel, actionLabel, whiteCapLabel, blackCapLabel;
|
||||
|
||||
/**
|
||||
* Create the frame.
|
||||
*/
|
||||
public MyInterface(){
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
setBounds(10, 10, 650, 650);
|
||||
contentPane = new JPanel();
|
||||
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||
contentPane.setLayout(new BorderLayout(0, 0));
|
||||
setContentPane(contentPane);
|
||||
super("Chess");
|
||||
setDefaultCloseOperation(EXIT_ON_CLOSE);
|
||||
setBounds(100,100,700,700);
|
||||
JPanel top = new JPanel();
|
||||
getContentPane().add(top,BorderLayout.NORTH);
|
||||
|
||||
JPanel panelTop = new JPanel();
|
||||
contentPane.add(panelTop, BorderLayout.NORTH);
|
||||
JPanel panelRight = new JPanel();
|
||||
contentPane.add(panelRight, BorderLayout.EAST);
|
||||
panelRight.setLayout(new GridLayout(4,1));
|
||||
actionLabel = new JLabel("Waiting to start");
|
||||
top.add(actionLabel);
|
||||
|
||||
JButton start = new JButton("Start/Restart");
|
||||
start.addActionListener(e->clicButtonStart());
|
||||
top.add(start);
|
||||
|
||||
actionLabel = new JLabel("Waiting For Start");
|
||||
panelTop.add(actionLabel);
|
||||
turnLabel = new JLabel("Turn: 0");
|
||||
top.add(turnLabel);
|
||||
|
||||
JButton btnGo = new JButton("Start/Restart");
|
||||
btnGo.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
clicButtonStart();
|
||||
}
|
||||
});
|
||||
panelTop.add(btnGo);
|
||||
whiteCapLabel = new JLabel("W captures: 0");
|
||||
top.add(whiteCapLabel);
|
||||
blackCapLabel = new JLabel("B captures: 0");
|
||||
top.add(blackCapLabel);
|
||||
|
||||
turnLabel = new JLabel("Turn : X");
|
||||
panelTop.add(turnLabel);
|
||||
JCheckBox wAI = new JCheckBox("White AI");
|
||||
wAI.addActionListener(e->clicAIToggle(true));
|
||||
top.add(wAI);
|
||||
JCheckBox bAI = new JCheckBox("Black AI");
|
||||
bAI.addActionListener(e->clicAIToggle(false));
|
||||
top.add(bAI);
|
||||
|
||||
JButton btnLoad = new JButton("Load File");
|
||||
btnLoad.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
clicLoadFileButton();
|
||||
}
|
||||
});
|
||||
panelRight.add(btnLoad);
|
||||
|
||||
JButton btnSave = new JButton("Save To File");
|
||||
btnSave.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
clicSaveToFileButton();
|
||||
}
|
||||
});
|
||||
panelRight.add(btnSave);
|
||||
|
||||
JButton btnAdder = new JButton("Add Piece");
|
||||
btnAdder.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
clickButtonAdder();
|
||||
}
|
||||
});
|
||||
panelRight.add(btnAdder);
|
||||
|
||||
JButton btnPieceSelector = new JButton("Piece Select");
|
||||
btnPieceSelector.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
clickButtonSelector();
|
||||
}
|
||||
});
|
||||
panelRight.add(btnPieceSelector);
|
||||
|
||||
JButton btnUndo = new JButton("Undo");
|
||||
btnUndo.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
clicUndoButton();
|
||||
}
|
||||
|
||||
});
|
||||
panelTop.add(btnUndo);
|
||||
|
||||
chckbxWhiteAI = new JCheckBox("WhiteAI");
|
||||
chckbxWhiteAI.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
clicAIToggle(true);
|
||||
}
|
||||
|
||||
});
|
||||
panelTop.add(chckbxWhiteAI);
|
||||
|
||||
chckbxBlackAI = new JCheckBox("BlackAI");
|
||||
chckbxBlackAI.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
clicAIToggle(false);
|
||||
}
|
||||
|
||||
});
|
||||
panelTop.add(chckbxBlackAI);
|
||||
JButton undo = new JButton("Undo");
|
||||
undo.addActionListener(e->game.undoLastMove());
|
||||
top.add(undo);
|
||||
|
||||
panelDraw = new JPanelChessBoard(this);
|
||||
contentPane.add(panelDraw, BorderLayout.CENTER);
|
||||
}
|
||||
getContentPane().add(panelDraw,BorderLayout.CENTER);
|
||||
|
||||
public void setStepBanner(String s) {
|
||||
turnLabel.setText(s);
|
||||
}
|
||||
JPanel right = new JPanel(new GridLayout(4,1));
|
||||
getContentPane().add(right,BorderLayout.EAST);
|
||||
|
||||
public void setBorderBanner(String s) {
|
||||
borderLabel.setText(s);
|
||||
}
|
||||
JButton load = new JButton("Load File");
|
||||
load.addActionListener(e->clicLoadFileButton());
|
||||
right.add(load);
|
||||
|
||||
public JPanelChessBoard getPanelDessin() {
|
||||
return panelDraw;
|
||||
JButton save = new JButton("Save To File");
|
||||
save.addActionListener(e->clicSaveToFileButton());
|
||||
right.add(save);
|
||||
|
||||
JButton adder = new JButton("Add Piece");
|
||||
adder.addActionListener(e->panelDraw.toggleAdderMode());
|
||||
right.add(adder);
|
||||
|
||||
JButton selP = new JButton("Piece Select");
|
||||
selP.addActionListener(e->panelDraw.togglePieceSelector());
|
||||
right.add(selP);
|
||||
}
|
||||
|
||||
public void instantiateSimu(){
|
||||
|
|
@ -159,111 +79,55 @@ public class MyInterface extends JFrame {
|
|||
}
|
||||
|
||||
public void clicButtonStart(){
|
||||
this.instantiateSimu();
|
||||
instantiateSimu();
|
||||
game.setDefaultSetup();
|
||||
}
|
||||
|
||||
public void clickButtonAdder() {
|
||||
panelDraw.toggleAdderMode();
|
||||
}
|
||||
public void clickButtonSelector() {
|
||||
panelDraw.togglePieceSelector();
|
||||
}
|
||||
|
||||
private void clicUndoButton() {
|
||||
if(game == null) {
|
||||
System.out.println("error : can't undo while no game present");
|
||||
} else {
|
||||
game.undoLastMove();
|
||||
}
|
||||
|
||||
}
|
||||
public void clicAIToggle(boolean isWhite){
|
||||
if(game == null) {
|
||||
System.out.println("error : can't activate AI while no game present");
|
||||
if(isWhite) {
|
||||
chckbxWhiteAI.setSelected(false);
|
||||
}else {
|
||||
chckbxBlackAI.setSelected(false);
|
||||
}
|
||||
} else {
|
||||
game.toggleAI(isWhite);
|
||||
}
|
||||
if (game!=null) game.toggleAI(isWhite);
|
||||
}
|
||||
|
||||
public void clicLoadFileButton(){
|
||||
Game loadedSim = new Game(this);
|
||||
String fileName=SelectFile();
|
||||
LinkedList<String> lines = new LinkedList<String>();
|
||||
if (fileName.length()>0) {
|
||||
try {
|
||||
BufferedReader fileContent = new BufferedReader(new FileReader(fileName));
|
||||
String line = fileContent.readLine();
|
||||
int colorID = 0;
|
||||
while (line != null) {
|
||||
lines.add(line);
|
||||
line = fileContent.readLine();
|
||||
}
|
||||
loadedSim.setBoard(Arrays.stream(lines.toArray()).map(Object::toString).toArray(String[]::new));
|
||||
fileContent.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
game = loadedSim;
|
||||
panelDraw.setGame(game);
|
||||
this.repaint();
|
||||
}
|
||||
instantiateSimu();
|
||||
String f = selectFile();
|
||||
if (f.isEmpty()) return;
|
||||
LinkedList<String> lines = new LinkedList<>();
|
||||
try(BufferedReader r = new BufferedReader(new FileReader(f))){
|
||||
String L;
|
||||
while((L=r.readLine())!=null) lines.add(L);
|
||||
}catch(Exception e){ e.printStackTrace(); }
|
||||
game.setBoard(lines.toArray(new String[0]));
|
||||
panelDraw.repaint();
|
||||
}
|
||||
|
||||
public void clicSaveToFileButton(){
|
||||
String fileName=SelectFile();
|
||||
if (fileName.length()>0) {
|
||||
String[] content = game.getFileRepresentation();
|
||||
writeFile(fileName, content);
|
||||
}
|
||||
String f = selectFile();
|
||||
if (f.isEmpty()||game==null) return;
|
||||
String[] out = game.getFileRepresentation();
|
||||
try(PrintWriter w=new PrintWriter(new FileWriter(f))){
|
||||
for(String row:out) w.println(row);
|
||||
}catch(Exception e){e.printStackTrace();}
|
||||
}
|
||||
|
||||
public String SelectFile() {
|
||||
String s;
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
chooser.setCurrentDirectory(new java.io.File("."));
|
||||
chooser.setDialogTitle("Choose a file");
|
||||
chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
|
||||
chooser.setAcceptAllFileFilterUsed(true);
|
||||
if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
|
||||
s=chooser.getSelectedFile().toString();
|
||||
} else {
|
||||
System.out.println("No Selection ");
|
||||
s="";
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
public void writeFile(String fileName, String[] content) {
|
||||
FileWriter csvWriter;
|
||||
try {
|
||||
csvWriter = new FileWriter(fileName);
|
||||
for (String row : content) {
|
||||
csvWriter.append(row);
|
||||
csvWriter.append("\n");
|
||||
}
|
||||
csvWriter.flush();
|
||||
csvWriter.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
private String selectFile(){
|
||||
JFileChooser C=new JFileChooser();
|
||||
if(C.showOpenDialog(this)==JFileChooser.APPROVE_OPTION)
|
||||
return C.getSelectedFile().toString();
|
||||
return "";
|
||||
}
|
||||
|
||||
public void update(int turnCount, boolean turnIsWhite){
|
||||
turnLabel.setText("Turn : "+turnCount+", "+(turnIsWhite?"White":"Black"));
|
||||
actionLabel.setText(panelDraw.isPieceAdderMode()?"Adding Piece":
|
||||
(panelDraw.isPieceSelectorMode()?"Selecting Piece to Add":
|
||||
"Playing"));
|
||||
this.repaint();
|
||||
panelDraw.isPieceSelectorMode()?"Selecting Piece":"Playing");
|
||||
whiteCapLabel.setText("W captures: "+game.getWhiteCaptures());
|
||||
blackCapLabel.setText("B captures: "+game.getBlackCaptures());
|
||||
panelDraw.repaint();
|
||||
}
|
||||
|
||||
public void eraseLabels() {
|
||||
this.setStepBanner("Turn : X");
|
||||
public void gameOver(String message){
|
||||
JOptionPane.showMessageDialog(
|
||||
this, message, "Game Over", JOptionPane.INFORMATION_MESSAGE
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue