From c032e3023c4078e3232252e44afb7849c75b6395 Mon Sep 17 00:00:00 2001 From: jefei Date: Wed, 14 May 2025 10:17:08 +0200 Subject: [PATCH] Hello we are terribly sorry since we did not push but me and ahmed live together and we have been working on it daily. Again we are terribly sorry but up until now this is what we have --- default.board | 9 + pieces.png | Bin 0 -> 954 bytes src/Main.java | 19 +- src/backend/AutoPlayer.java | 17 ++ src/backend/Board.java | 303 ++++++++++++++++++++++ src/backend/Game.java | 110 ++++++++ src/backend/Move.java | 5 + src/backend/Piece.java | 42 +++ src/backend/PieceType.java | 28 ++ src/backend/Test_1.java | 5 + src/windowInterface/JPanelChessBoard.java | 196 ++++++++++++++ src/windowInterface/MyInterface.java | 269 +++++++++++++++++++ 12 files changed, 1002 insertions(+), 1 deletion(-) create mode 100644 default.board create mode 100644 pieces.png create mode 100644 src/backend/AutoPlayer.java create mode 100644 src/backend/Board.java create mode 100644 src/backend/Game.java create mode 100644 src/backend/Move.java create mode 100644 src/backend/Piece.java create mode 100644 src/backend/PieceType.java create mode 100644 src/backend/Test_1.java create mode 100644 src/windowInterface/JPanelChessBoard.java create mode 100644 src/windowInterface/MyInterface.java diff --git a/default.board b/default.board new file mode 100644 index 0000000..8d83268 --- /dev/null +++ b/default.board @@ -0,0 +1,9 @@ +BR,BN,BB,BQ,BK,BB,BN,BR +BP,BP,BP,BP,BP,BP,BP,BP + , , , , , , , + , , , , , , , + , , , , , , , + , , , , , , , +WP,WP,WP,WP,WP,WP,WP,WP +WR,WN,WB,WQ,WK,WB,WN,WR +W diff --git a/pieces.png b/pieces.png new file mode 100644 index 0000000000000000000000000000000000000000..01cc2f8e0723c40907fcafb30d2044adb1dbd2ff GIT binary patch literal 954 zcmV;r14aCaP)Px&bV)=(RA_n93+CyBv1*&Oq{|ll?3Z58QD>Akp8lm*j5papY>-F z_|!G7(E+F0t>l*zXgEm&ZX>9f!1N&qw-hUoZ8N-SbSxaZQZ4>gfJ_4KfM-5!RAwmJ zMI2yF^HZ4sCXebFxEx$X2W8v9$LS)4Z@xqo@XOd44k-syX8#}){C6-GEbrN>nHrbpkZqDvUnK2wjy?t@5Rq@NFzyDK7;PhNe%$nS?gU#z?WPf0 z=Bh{9D_%50EY8Tmu^pC9C;6oj)D`T4XjaOO$^;XQ5ZQ&5aq|iC@qZ7s^`d)qG970lGuj~I+H*dh?h7i*(5ku$?%p{z4<&P9=274 zgXq}=KDD{39dO#*N`5DSnpAR7{v54Ix!65KGqwpIS0_1l@pkYLe#J+}w~8l>Q`XTg{0sZ)wNvYW cJN8}q0;pW6z5*s-O#lD@07*qoM6N<$g2Ji5hX4Qo literal 0 HcmV?d00001 diff --git a/src/Main.java b/src/Main.java index 3503159..ce07336 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,4 +1,21 @@ +import backend.Board; +import backend.Move; +import backend.Piece; +import backend.PieceType; +import windowInterface.MyInterface; + public class Main { -} + + public static void main(String[] args) { + // testing : + Board testBoard = new Board(8, 8); + testBoard.populateBoard(); + System.out.println(testBoard.toString()); + + // launches graphical interface : + MyInterface mjf = new MyInterface(); + mjf.setVisible(true); + } +} \ No newline at end of file diff --git a/src/backend/AutoPlayer.java b/src/backend/AutoPlayer.java new file mode 100644 index 0000000..a988a22 --- /dev/null +++ b/src/backend/AutoPlayer.java @@ -0,0 +1,17 @@ +package backend; + +public class AutoPlayer { + + + /** + * returns the best Move to try on provided board for active player + * @param board + * @return + */ + public Move computeBestMove(Board board) { + + return null; + } + + +} diff --git a/src/backend/Board.java b/src/backend/Board.java new file mode 100644 index 0000000..594d56b --- /dev/null +++ b/src/backend/Board.java @@ -0,0 +1,303 @@ +package backend; + +import java.util.ArrayList; + +public class Board { + private int width; + private int height; + private ArrayList pieces; + private int turnNumber; + private boolean isTurnWhite; + private int selectedX, selectedY; + private ArrayList highlightedSquares; + + public Board(int colNum, int lineNum) { + this.width = colNum; + this.height = lineNum; + this.pieces = new ArrayList<>(); + this.turnNumber = 0; + this.isTurnWhite = true; + this.selectedX = -1; + this.selectedY = -1; + this.highlightedSquares = new ArrayList<>(); + + } + + public int getWidth() { + return this.width; + } + + public int getHeight() { + return this.height; + } + + public int getTurnNumber() { + return this.turnNumber; + } + + public boolean isTurnWhite() { + return this.isTurnWhite; + } + + public void setPiece(boolean isWhite, PieceType type, int x, int y) { + pieces.removeIf(p -> p.getX() == x && p.getY() == y); // Remove any piece already at position + pieces.add(new Piece(x, y, type, isWhite)); + } + + public void populateBoard() { + cleanBoard(); + + setPiece(false, PieceType.Rook, 0, 0); + setPiece(false, PieceType.Knight, 1, 0); + setPiece(false, PieceType.Bishop, 2, 0); + setPiece(false, PieceType.Queen, 3, 0); + setPiece(false, PieceType.King, 4, 0); + setPiece(false, PieceType.Bishop, 5, 0); + setPiece(false, PieceType.Knight, 6, 0); + setPiece(false, PieceType.Rook, 7, 0); + + for (int x = 0; x < width; x++) { + setPiece(false, PieceType.Pawn, x, 1); + } + + for (int x = 0; x < width; x++) { + setPiece(true, PieceType.Pawn, x, 6); + } + + setPiece(true, PieceType.Rook, 0, 7); + setPiece(true, PieceType.Knight, 1, 7); + setPiece(true, PieceType.Bishop, 2, 7); + setPiece(true, PieceType.Queen, 3, 7); + setPiece(true, PieceType.King, 4, 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 (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 getPieces() { + return pieces; + } + + public void userTouch(int x, int y) { + Piece selectedPiece = getPieceAt(selectedX, selectedY); + + if (selectedPiece == null) { + Piece piece = getPieceAt(x, y); + if (piece != null && piece.isWhite() == isTurnWhite) { + selectedX = x; + selectedY = y; + highlightedSquares = getValidMoves(piece); // compute highlights normally + } + } else { + if (x == selectedX && y == selectedY) { + selectedX = -1; + selectedY = -1; + highlightedSquares.clear(); + } else { + Piece destinationPiece = getPieceAt(x, y); + selectedPiece.setX(x); + selectedPiece.setY(y); + + if (destinationPiece != null && destinationPiece.isWhite() != selectedPiece.isWhite()) { + pieces.remove(destinationPiece); + } + + turnNumber++; + isTurnWhite = !isTurnWhite; + + selectedX = -1; + selectedY = -1; + highlightedSquares.clear(); + } + } + } + + public boolean isSelected(int x, int y) { + return x == selectedX && y == selectedY; + } + + public boolean isHighlighted(int x, int y) { + for (int[] pos : highlightedSquares) { + if (pos[0] == x && pos[1] == y){ + return true; + } + } + return false; + } + private ArrayList getValidMoves(Piece piece) { + ArrayList moves = new ArrayList<>(); + int x = piece.getX(); + int y = piece.getY(); + boolean isWhite = piece.isWhite(); + PieceType type = piece.getType(); + + if (type == PieceType.Pawn) { + int dir = isWhite ? -1 : 1; + if (getPieceAt(x, y + dir) == null) { + moves.add(new int[]{x, y + dir}); + } + // Capture left + if (getPieceAt(x - 1, y + dir) != null && getPieceAt(x - 1, y + dir).isWhite() != isWhite) { + moves.add(new int[]{x - 1, y + dir}); + } + // Capture right + if (getPieceAt(x + 1, y + dir) != null && getPieceAt(x + 1, y + dir).isWhite() != isWhite) { + moves.add(new int[]{x + 1, y + dir}); + } + } else if (type == PieceType.Rook) { + addLineMoves(moves, x, y, 1, 0, isWhite); + addLineMoves(moves, x, y, -1, 0, isWhite); + addLineMoves(moves, x, y, 0, 1, isWhite); + addLineMoves(moves, x, y, 0, -1, isWhite); + } else if (type == PieceType.Bishop) { + addLineMoves(moves, x, y, 1, 1, isWhite); + addLineMoves(moves, x, y, -1, 1, isWhite); + addLineMoves(moves, x, y, 1, -1, isWhite); + addLineMoves(moves, x, y, -1, -1, isWhite); + } else if (type == PieceType.Queen) { + addLineMoves(moves, x, y, 1, 0, isWhite); + addLineMoves(moves, x, y, -1, 0, isWhite); + addLineMoves(moves, x, y, 0, 1, isWhite); + addLineMoves(moves, x, y, 0, -1, isWhite); + addLineMoves(moves, x, y, 1, 1, isWhite); + addLineMoves(moves, x, y, -1, 1, isWhite); + addLineMoves(moves, x, y, 1, -1, isWhite); + addLineMoves(moves, x, y, -1, -1, isWhite); + } else if (type == PieceType.Knight) { + int[][] knightMoves = { + {2, 1}, {1, 2}, {-1, 2}, {-2, 1}, + {-2, -1}, {-1, -2}, {1, -2}, {2, -1} + }; + for (int[] d : knightMoves) { + int nx = x + d[0]; + int ny = y + d[1]; + if (isInsideBoard(nx, ny)) { + Piece p = getPieceAt(nx, ny); + if (p == null || p.isWhite() != isWhite) { + moves.add(new int[]{nx, ny}); + } + } + } + } else if (type == PieceType.King) { + for (int dx = -1; dx <= 1; dx++) { + for (int dy = -1; dy <= 1; dy++) { + if (dx != 0 || dy != 0) { + int nx = x + dx; + int ny = y + dy; + if (isInsideBoard(nx, ny)) { + Piece p = getPieceAt(nx, ny); + if (p == null || p.isWhite() != isWhite) { + moves.add(new int[]{nx, ny}); + } + } + } + } + } + } + if (type == PieceType.Pawn) { + int dir = isWhite ? -1 : 1; + + if (isInsideBoard(x, y + dir) && getPieceAt(x, y + dir) == null) { + moves.add(new int[]{x, y + dir}); + + if ((isWhite && y == 6) || (!isWhite && y == 1)) { + if (isInsideBoard(x, y + 2 * dir) && getPieceAt(x, y + 2 * dir) == null) { + moves.add(new int[]{x, y + 2 * dir}); + } + } + } + + + if (isInsideBoard(x - 1, y + dir)) { + Piece captureLeft = getPieceAt(x - 1, y + dir); + if (captureLeft != null && captureLeft.isWhite() != isWhite) { + moves.add(new int[]{x - 1, y + dir}); + } + } + + + if (isInsideBoard(x + 1, y + dir)) { + Piece captureRight = getPieceAt(x + 1, y + dir); + if (captureRight != null && captureRight.isWhite() != isWhite) { + moves.add(new int[]{x + 1, y + dir}); + } + } + } + + return moves; + } + + private void addLineMoves(ArrayList moves, int x, int y, int dx, int dy, boolean isWhite) { + int nx = x + dx; + int ny = y + dy; + while (isInsideBoard(nx, ny)) { + 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; + } + nx += dx; + ny += dy; + } + } + + private boolean isInsideBoard(int x, int y) { + return (x >= 0 && x < width && y >= 0 && y < height); + } + + public void undoLastMove() { + + } + + public String[] toFileRep() { + + return null; + } + + public Board(String[] array) { + + } + + public Board(Board board) { + + } + + public void playMove(Move move) { + + } + + private Piece getPieceAt(int x, int y) { + for (Piece p : pieces) { + if (p.getX() == x && p.getY() == y) { + return p; + } + } + return null; + } +} diff --git a/src/backend/Game.java b/src/backend/Game.java new file mode 100644 index 0000000..4c64f70 --- /dev/null +++ b/src/backend/Game.java @@ -0,0 +1,110 @@ +package backend; + +import windowInterface.MyInterface; + +public class Game extends Thread { + + private AutoPlayer aiPlayer; + private Board board; + + private MyInterface mjf; + private int COL_NUM = 8; + private int LINE_NUM = 8; + 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(); + } + + public int getWidth() { + return board.getWidth(); + } + + public int getHeight() { + return board.getHeight(); + } + + public void run() { + while(true) { + aiPlayerTurn(); + mjf.update(board.getTurnNumber(), board.isTurnWhite()); + try { + Thread.sleep(loopDelay); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + private boolean isAITurn() { + 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(!isAITurn()) { + board.userTouch(x, y); + } + + } + + public void setPiece(boolean isWhite, PieceType type, int x, int y) { + board.setPiece(isWhite, type, 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 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]; + } + +} diff --git a/src/backend/Move.java b/src/backend/Move.java new file mode 100644 index 0000000..5f64282 --- /dev/null +++ b/src/backend/Move.java @@ -0,0 +1,5 @@ +package backend; + +public class Move { + +} diff --git a/src/backend/Piece.java b/src/backend/Piece.java new file mode 100644 index 0000000..0069582 --- /dev/null +++ b/src/backend/Piece.java @@ -0,0 +1,42 @@ +package backend; + +/** + * Represents a chess piece with its position, type and color. + */ +public class Piece { + private int x; + private int y; + private PieceType type; + private boolean isWhite; + + public Piece(int x, int y, PieceType type, boolean isWhite) { + this.x = x; + this.y = y; + this.type = type; + this.isWhite = isWhite; + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + + public PieceType getType() { + return type; + } + + public boolean isWhite() { + return isWhite; + } + + public void setX(int x) { + this.x = x; + } + + public void setY(int y) { + this.y = y; + } +} diff --git a/src/backend/PieceType.java b/src/backend/PieceType.java new file mode 100644 index 0000000..baceab1 --- /dev/null +++ b/src/backend/PieceType.java @@ -0,0 +1,28 @@ +package backend; + +public enum PieceType { + Pawn, Rook, Knight, Bishop, Queen, King; + + public String getSummary() { + if(this == PieceType.Knight) { + return "N"; + } + return this.name().substring(0, 1); + } + + public static PieceType fromSummary(char c) { + if(c=='P') { + return PieceType.Pawn; + }else if(c=='N') { + return PieceType.Knight; + }else if(c=='B') { + return PieceType.Bishop; + }else if(c=='R') { + return PieceType.Rook; + }else if(c=='K') { + return PieceType.King; + } + return PieceType.Queen; + } + +} diff --git a/src/backend/Test_1.java b/src/backend/Test_1.java new file mode 100644 index 0000000..239f87c --- /dev/null +++ b/src/backend/Test_1.java @@ -0,0 +1,5 @@ +package backend; + +public class Test_1 { + +} diff --git a/src/windowInterface/JPanelChessBoard.java b/src/windowInterface/JPanelChessBoard.java new file mode 100644 index 0000000..78a68de --- /dev/null +++ b/src/windowInterface/JPanelChessBoard.java @@ -0,0 +1,196 @@ +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.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; +import javax.swing.JPanel; + +import backend.Game; +import backend.Piece; +import backend.PieceType; + +public class JPanelChessBoard extends JPanel { + + private static final long serialVersionUID = 1L; + private Game myGame; + private MyInterface interfaceGlobal; + private BufferedImage spriteSheet; + private int PIECE_WIDTH = 16; //in spritesheet + private int PIECE_HEIGHT = 16; //in spritesheet + private int MARGIN = 6; + + private boolean pieceSelectorMode; + private boolean selectedPieceIsWhite; + private PieceType selectedPieceType; + private boolean pieceAdderMode; + + 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; + 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()); + pieceSelectorMode = false; + } else { + if(myGame == null) { + interfaceGlobal.instantiateSimu(); + } + int x = (me.getX()*myGame.getWidth())/getWidth(); + int y = (me.getY()*myGame.getHeight())/getHeight(); + if(pieceAdderMode) { + //TODO + myGame.setPiece(selectedPieceIsWhite,selectedPieceType, x, y); + pieceAdderMode = false; + } else { + myGame.clickCoords(x,y); + } + } + repaint(); + } + }); + } + + + public void setGame(Game simu) { + myGame = simu; + } + + @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(); + + g.setColor(Color.white); + for(int x=0; x lines = new LinkedList(); + 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(); + } + } + + public void clicSaveToFileButton() { + String fileName=SelectFile(); + if (fileName.length()>0) { + String[] content = game.getFileRepresentation(); + writeFile(fileName, content); + } + } + + 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(); + } + } + + 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(); + } + + public void eraseLabels() { + this.setStepBanner("Turn : X"); + } + +}