diff --git a/OOP_2B1_Project/.classpath b/OOP_2B1_Project/.classpath new file mode 100644 index 0000000..52f234a --- /dev/null +++ b/OOP_2B1_Project/.classpath @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/OOP_2B1_Project/.gitignore b/OOP_2B1_Project/.gitignore new file mode 100644 index 0000000..ae3c172 --- /dev/null +++ b/OOP_2B1_Project/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/OOP_2B1_Project/.project b/OOP_2B1_Project/.project new file mode 100644 index 0000000..2f8a9e1 --- /dev/null +++ b/OOP_2B1_Project/.project @@ -0,0 +1,17 @@ + + + OOP_2B1_Project + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/OOP_2B1_Project/.settings/org.eclipse.core.resources.prefs b/OOP_2B1_Project/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/OOP_2B1_Project/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/OOP_2B1_Project/.settings/org.eclipse.jdt.core.prefs b/OOP_2B1_Project/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..6f94d6a --- /dev/null +++ b/OOP_2B1_Project/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=23 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=23 +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.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=23 diff --git a/OOP_2B1_Project/default.board b/OOP_2B1_Project/default.board new file mode 100644 index 0000000..8d83268 --- /dev/null +++ b/OOP_2B1_Project/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/OOP_2B1_Project/pieces.png b/OOP_2B1_Project/pieces.png new file mode 100644 index 0000000..01cc2f8 Binary files /dev/null and b/OOP_2B1_Project/pieces.png differ diff --git a/OOP_2B1_Project/src/Main.java b/OOP_2B1_Project/src/Main.java new file mode 100644 index 0000000..2ff297c --- /dev/null +++ b/OOP_2B1_Project/src/Main.java @@ -0,0 +1,22 @@ +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); + } + +} diff --git a/OOP_2B1_Project/src/backend/AutoPlayer.java b/OOP_2B1_Project/src/backend/AutoPlayer.java new file mode 100644 index 0000000..a48c0c2 --- /dev/null +++ b/OOP_2B1_Project/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/OOP_2B1_Project/src/backend/Board.java b/OOP_2B1_Project/src/backend/Board.java new file mode 100644 index 0000000..80eb9ac --- /dev/null +++ b/OOP_2B1_Project/src/backend/Board.java @@ -0,0 +1,180 @@ +package backend; + +import java.util.ArrayList; + +public class Board { + public int width; + public int height; + public ArrayList> board = new ArrayList<>(); + public boolean select = false; + public int xm; + public int ym; + public int turnNumber; + public boolean turnColor; + public Board(int colNum, int lineNum) { + this.width = colNum; + this.height = lineNum; + int rows = 8; + int cols = 8; + for (int i = 0; i < rows; i++) { + ArrayList row = new ArrayList<>(); + for (int j = 0; j < cols; j++) { + row.add(null); // Fill with null + } + this.board.add(row); + } + this.turnNumber = 0; + this.turnColor = true; + + } + + public int getWidth() { + return this.width; + } + + public int getHeight() { + return this.height; + } + + public int getTurnNumber() { + return this.turnNumber; + } + + public boolean isTurnWhite() { + return this.turnColor; + } + + public void setPiece(int x, int y, PieceType type, boolean isWhite) { + Piece piece = new Piece(x,y,type,isWhite); + board.get(y).set(x, piece); + } + + public void populateBoard() { + for (int x = 0; x < this.width;x++) { + for (int y = 0; y < this.height; y++) { + if (y ==1 || y == 6) { + if (y == 1) { + this.setPiece(x,y,PieceType.Pawn,false); + } + else if (y == 6) {this.setPiece(x,y,PieceType.Pawn,true);} + } + if (y == 0) { + boolean col = false; + if (x == 0 || x == 7) { + this.setPiece(x,y,PieceType.Rook,col); + } else if (x == 1 || x == 6) {this.setPiece(x,y,PieceType.Knight,col);} + else if (x == 2 || x == 5) {this.setPiece(x,y,PieceType.Bishop,col);} + else if (x == 3) {this.setPiece(x,y,PieceType.Queen,col);} + else if (x == 4) {this.setPiece(x,y,PieceType.King,col);} + } else if (y == 7) { + boolean col = true; + if (x == 0 || x == 7) { + this.setPiece(x,y,PieceType.Rook,col); + } else if (x == 1 || x == 6) {this.setPiece(x,y,PieceType.Knight,col);} + else if (x == 2 || x == 5) {this.setPiece(x,y,PieceType.Bishop,col);} + else if (x == 3) {this.setPiece(x,y,PieceType.Queen,col);} + else if (x == 4) {this.setPiece(x,y,PieceType.King,col);} + } + } + } + } + + public void cleanBoard() { + int rows = 8; + int cols = 8; + for (int i = 0; i < rows; i++) { + ArrayList row = new ArrayList<>(); + for (int j = 0; j < cols; j++) { + row.add(null); // Fill with null + } + this.board.add(row); + } + + } + + @Override + public String toString() { + return "Board [width=" + width + ", height=" + height + ", board=" + board + "]"; + } + + public ArrayList getPieces() { + ArrayList pieces = new ArrayList<>(); + for (ArrayList row : board) { + for (Piece piece : row) { + if (piece != null) { + pieces.add(piece); + } + } + } + return pieces; + } + + public Piece getPiece(int x, int y) { + return board.get(y).get(x); + } + + public void movePiece(int x, int y) { + Piece pieceToMove = this.board.get(this.ym).get(this.xm); + this.setPiece(x,y,pieceToMove.getType(),pieceToMove.isWhite()); + board.get(this.ym).set(this.xm,null); + } + + public void userTouch(int x, int y) { + if (this.select == false && board.get(y).get(x) != null) { + this.xm = x; + this.ym = y; + select = true; + } + else if (select == true && this.xm != x || this.ym != y){ + this.movePiece(x, y); + select = false; + this.turnNumber += 1; + // System.out.println(this.toString()); // Debug + this.turnColor = !this.turnColor; + } else { + select = false; + } + } + + public boolean isSelected(int x, int y) { + boolean S; + if (this.xm == x && this.ym == y) {S = true;} + else {S = false;} + return S; + } + + /* saving-loading feature :*/ + + public String[] toFileRep() { + //TODO + return null; + } + + public Board(String[] array) { + //TODO + + } + + /* The following methods require more work ! */ + + public boolean isHighlighted(int x, int y) { + //TODO + return false; + } + + public void undoLastMove() { + //TODO + + } + + public Board(Board board) { + //TODO + + } + + public void playMove(Move move) { + //TODO + + } + +} diff --git a/OOP_2B1_Project/src/backend/Game.java b/OOP_2B1_Project/src/backend/Game.java new file mode 100644 index 0000000..ce1421f --- /dev/null +++ b/OOP_2B1_Project/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(int x, int y, PieceType type, boolean isWhite) { + board.setPiece(x, y, type, isWhite); + } + + 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/OOP_2B1_Project/src/backend/Move.java b/OOP_2B1_Project/src/backend/Move.java new file mode 100644 index 0000000..7b9ff9b --- /dev/null +++ b/OOP_2B1_Project/src/backend/Move.java @@ -0,0 +1,5 @@ +package backend; + +public class Move { + +} diff --git a/OOP_2B1_Project/src/backend/Piece.java b/OOP_2B1_Project/src/backend/Piece.java new file mode 100644 index 0000000..08d5da1 --- /dev/null +++ b/OOP_2B1_Project/src/backend/Piece.java @@ -0,0 +1,35 @@ +package backend; + +public class Piece { + public int x; + public int y; + public PieceType type; + public 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 this.x; + } + + public int getY() { + return this.y; + } + + public PieceType getType() { + return this.type; + } + + public boolean isWhite() { + return this.isWhite; + } + @Override + public String toString() { + return "Piece [x=" + x + ", y=" + y + ", type=" + type + ", isWhite=" + isWhite + "]"; + } + +} diff --git a/OOP_2B1_Project/src/backend/PieceType.java b/OOP_2B1_Project/src/backend/PieceType.java new file mode 100644 index 0000000..b7b5304 --- /dev/null +++ b/OOP_2B1_Project/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/OOP_2B1_Project/src/backend/PossibleMovements.java b/OOP_2B1_Project/src/backend/PossibleMovements.java new file mode 100644 index 0000000..6ce007d --- /dev/null +++ b/OOP_2B1_Project/src/backend/PossibleMovements.java @@ -0,0 +1,47 @@ +package backend; + +import java.util.ArrayList; + +public class PossibleMovements { + ArrayList> board; + Piece pieceToMove; + PieceType type; + int x; + int y; + boolean turnColor; + public PossibleMovements(ArrayList> board, int x, int y,boolean turnColor) { + this.board = board; + this.pieceToMove = board.get(y).get(x); + this.type = pieceToMove.getType(); + this.x = x; + this.y = y; + this.turnColor = turnColor; + } + public ArrayList> PM(){ + ArrayList> possibleMoves = new ArrayList<>(); + int rows = 8; + int cols = 8; + for (int i = 0; i < rows; i++) { + ArrayList row = new ArrayList<>(); + for (int j = 0; j < cols; j++) { + row.add(false); // Fill with false + } + possibleMoves.add(row); + } + if (turnColor) { + if (type == PieceType.Pawn) { + if (x == 0) { + if (board.get(y).get(x+1) != null) { + possibleMoves.get(y).set(x+1, true); + } + } + if (x==7) { + if (board.get(y).get(x-1) != null) { + possibleMoves.get(y).set(x-1, true); + } + } + for (int xi = 1; xi<7;i++) { + } + } + } +} diff --git a/OOP_2B1_Project/src/windowInterface/JPanelChessBoard.java b/OOP_2B1_Project/src/windowInterface/JPanelChessBoard.java new file mode 100644 index 0000000..84e95b2 --- /dev/null +++ b/OOP_2B1_Project/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(x, y, selectedPieceType, selectedPieceIsWhite); + 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"); + } + +}