diff --git a/MavenChess/MavenChess/src/main/java/controller/Main.java b/MavenChess/MavenChess/src/main/java/controller/Main.java index 0637b74e9c8be4a513ebed53156ba4369da52178..0725fe2e02b4988cbafdb1d17fca499228cf5bd2 100644 --- a/MavenChess/MavenChess/src/main/java/controller/Main.java +++ b/MavenChess/MavenChess/src/main/java/controller/Main.java @@ -65,7 +65,7 @@ public class Main extends Application { // event - click on (visual) "colored tiles" to move the selected piece there for(int n = 0 ; n < 64 ; n++) { TileView tile = boardView.getTile(n); - tile.getObj().addEventHandler(MouseEvent.MOUSE_CLICKED, event -> boardView.clickTile(material, tile, board)); + tile.getObj().addEventHandler(MouseEvent.MOUSE_CLICKED, event -> boardView.clickTile(material, model, tile, board)); } // start -------------------------------------------------------------- diff --git a/MavenChess/MavenChess/src/main/java/model/Board.java b/MavenChess/MavenChess/src/main/java/model/Board.java index 7a0e8388ff9bc85dd3d7c33d2a1af305a13e484b..6abb93133170b82c65ce4215ed3d848b60695810 100644 --- a/MavenChess/MavenChess/src/main/java/model/Board.java +++ b/MavenChess/MavenChess/src/main/java/model/Board.java @@ -18,14 +18,12 @@ public class Board { int y; for(int color = Piece.WHITE ; color == Piece.WHITE || color == Piece.BLACK ; color++) { // placement of pawns - if(color == Piece.WHITE) { y = 2; } - else { y = 7; } + if(color == Piece.WHITE) { y = 2; } else { y = 7; } for(int x = A ; x <= H ; x++) { createPiece(x, y, color, PAWN); // fills line 2 and line 7 with pawns } // placement of rook, knight, bishop, queen, king - line 1 and line 8 - if(color == Piece.WHITE) { y = 1; } - else { y = 8; } + if(color == Piece.WHITE) { y = 1; } else { y = 8; } createPiece(A, y, color, ROOK); createPiece(B, y, color, KNIGHT); createPiece(C, y, color, BISHOP); @@ -48,6 +46,7 @@ public class Board { public Piece getPiece(int id) { return pieces[id]; } + public void createPiece(int x, int y, int color, int type) { Position p = new Position(x, y); switch(type) { @@ -64,8 +63,12 @@ public class Board { return selected; } + public Piece getSelectedPiece() { + return getPiece(selected.getID()); + } + public void setSelected(Position p) { - selected = p; + selected = new Position(p.getX(), p.getY()); // creates a new copy, to avoid using reference } public void movePiece(Position origin, Position arrival) { @@ -75,6 +78,16 @@ public class Board { pieces[origin.getID()] = null; // removes the origin ID piece on the pieces list } + public void mutationOfSelectedPiece(int type) { + int color = getSelectedPiece().getColor(); + switch(type) { + case ROOK -> setPiece(new Rook(selected, color)); + case KNIGHT -> setPiece(new Knight(selected, color)); + case BISHOP -> setPiece(new Bishop(selected, color)); + default -> setPiece(new Queen(selected, color)); + } + } + public boolean isFree(Position p) { return (p.isCorrect() && getPiece(p) == null); @@ -85,6 +98,7 @@ public class Board { && !isFree(arrival) && getPiece(arrival).getColor() != getPiece(origin).getColor() ); } + public boolean isKing(Position p) { return (p.isCorrect() && !isFree(p) diff --git a/MavenChess/MavenChess/src/main/java/model/Piece.java b/MavenChess/MavenChess/src/main/java/model/Piece.java index d26f9f4b4151a7e3e8c2cead5982e465b740dc6b..4053281d513f4780e70d2318fc5cbc4ad517c3a8 100644 --- a/MavenChess/MavenChess/src/main/java/model/Piece.java +++ b/MavenChess/MavenChess/src/main/java/model/Piece.java @@ -34,7 +34,7 @@ public abstract class Piece { } public void setPosition(Position p) { - this.p = p; + this.p = new Position(p.getX(), p.getY()); // creates a new copy, to avoid using reference hasBeenMoved = true; } } diff --git a/MavenChess/MavenChess/src/main/java/view/BoardView.java b/MavenChess/MavenChess/src/main/java/view/BoardView.java index a0579b8ace412dfc44feea95506d28872c9acce8..978fecff192b1e833f9345b1050d4309376cd9a1 100644 --- a/MavenChess/MavenChess/src/main/java/view/BoardView.java +++ b/MavenChess/MavenChess/src/main/java/view/BoardView.java @@ -2,14 +2,7 @@ package view; import javafx.scene.Group; import javafx.scene.shape.*; -import model.Board; -import model.Rook; -import model.Knight; -import model.Bishop; -import model.Queen; -import model.King; -import model.Piece; -import model.Position; +import model.*; import java.util.ArrayList; @@ -52,28 +45,31 @@ public class BoardView { white_death_count = 0; } - public void updatePiece(Position position) { // updates the piece(i, j), visually, to the right position - int id = position.getID(); - if(getPiece(id) != null) { - getPieceObj(id).setTranslateX((position.getX()-1) * BOARD_SIZE + CENTERED_ORIGIN); - getPieceObj(id).setTranslateZ((position.getY()-1) * BOARD_SIZE + CENTERED_ORIGIN); - } + public TileView getTile(int id) { + return tiles[id]; } - public void updateGraveyardPiece(PieceView piece) { // updates position (visual) of a dead piece - int x = piece.getPosition().getX(); - int y = piece.getPosition().getY(); - if(x == Position.WHITE_GRAVEYARD) { - piece.getObj().setTranslateX(-2 * BOARD_SIZE + CENTERED_ORIGIN); - piece.getObj().setTranslateZ(y * BOARD_SIZE*0.65f - BOARD_SIZE*4); - } else { // x == Position.BLACK_GRAVEYARD - piece.getObj().setTranslateX(9 * BOARD_SIZE + CENTERED_ORIGIN); - piece.getObj().setTranslateZ(-y * BOARD_SIZE*0.65f + BOARD_SIZE*4); - } - piece.getObj().setTranslateY(GRAVEYARD_HEIGHT); // place at right height (Y axis) on table + public Box getTileObj(int id) { + return tiles[id].getObj(); } - public void createTile(Position position) { + public void setTile(TileView tile) { + tiles[tile.getPosition().getID()] = tile; + } + + public PieceView getPiece(int id) { + return pieces[id]; + } + + public MeshView getPieceObj(int id) { + return pieces[id].getObj(); + } + + public void setPiece(PieceView piece) { + pieces[piece.getPosition().getID()] = piece; + } + + private void createTile(Position position) { // creates a tile and with the right size and position Box box = new Box(BOARD_SIZE, (double) BOARD_SIZE / 2, BOARD_SIZE); box.setTranslateX((position.getX()-1) * BOARD_SIZE + CENTERED_ORIGIN); @@ -106,31 +102,28 @@ public class BoardView { updatePiece(position); } - public TileView getTile(int id) { - return tiles[id]; - } - - public Box getTileObj(int id) { - return tiles[id].getObj(); - } - - public void setTile(TileView tile) { - tiles[tile.getPosition().getID()] = tile; - } - - public PieceView getPiece(int id) { - return pieces[id]; - } - - public MeshView getPieceObj(int id) { - return pieces[id].getObj(); + private void updatePiece(Position position) { // updates the piece(i, j), visually, to the right position + int id = position.getID(); + if(getPiece(id) != null) { + getPieceObj(id).setTranslateX((position.getX()-1) * BOARD_SIZE + CENTERED_ORIGIN); + getPieceObj(id).setTranslateZ((position.getY()-1) * BOARD_SIZE + CENTERED_ORIGIN); + } } - public void setPiece(PieceView piece) { - pieces[piece.getPosition().getID()] = piece; + private void updateGraveyardPiece(PieceView piece) { // updates position (visual) of a dead piece + int x = piece.getPosition().getX(); + int y = piece.getPosition().getY(); + if(x == Position.WHITE_GRAVEYARD) { + piece.getObj().setTranslateX(-2 * BOARD_SIZE + CENTERED_ORIGIN); + piece.getObj().setTranslateZ(y * BOARD_SIZE*0.65f - BOARD_SIZE*4); + } else { // x == Position.BLACK_GRAVEYARD + piece.getObj().setTranslateX(9 * BOARD_SIZE + CENTERED_ORIGIN); + piece.getObj().setTranslateZ(-y * BOARD_SIZE*0.65f + BOARD_SIZE*4); + } + piece.getObj().setTranslateY(GRAVEYARD_HEIGHT); // place at right height (Y axis) on table } - public void resetColor(CustomMaterial material) { + private void resetColor(CustomMaterial material) { for(int n = 0, j = 1 ; j <= 8 ; j++) { for (int i = 1; i <= 8; i++, n++) { // resets board with black and white - bottom left (first case) is black, then alternates @@ -144,7 +137,7 @@ public class BoardView { } } - public void setColor(CustomMaterial material, Position position, int type) { + private void setColor(CustomMaterial material, Position position, int type) { int id = position.getID(); // set the new color-type (visually) getTileObj(id).setMaterial(material.get(type)); @@ -159,48 +152,101 @@ public class BoardView { } public void clickPiece(CustomMaterial material, PieceView clickedPiece, Board board) { + // clicking a piece will ask her available moves Position position = clickedPiece.getPosition(); board.setSelected(position); resetColor(material); setColor(material, position, CustomMaterial.SELECTED_TILE); ArrayList<Position> moves = board.getPiece(position).getAvailableMoves(board); + + // shows all available moves on the tiles, with colors, each tile-color having a meaning for (Position move : moves) { if(board.isFree(move)) { setColor(material, move, CustomMaterial.MOVABLE_TILE); } else if(board.isEnemy(move, position)) { setColor(material, move, CustomMaterial.ATTACK_TILE); } else { - setColor(material, move, CustomMaterial.SPECIAL_TILE); + setColor(material, move, CustomMaterial.SPECIAL_TILE); // any special move } - // promotion + // PROMOTION (attacking or not) if(board.isPawn(position) && (move.getY() == 8 || move.getY() == 1)) { setColor(material, move, CustomMaterial.SPECIAL_TILE); } } } - public void clickTile(CustomMaterial material, TileView clickedTile, Board board) { + public void clickTile(CustomMaterial material, Custom3dModel model, TileView clickedTile, Board board) { int state = clickedTile.getState(); Position selected = board.getSelected(); Position arrival = clickedTile.getPosition(); if(state != TileView.NORMAL && state != TileView.SELECTED) { - if(state == TileView.ATTACK) { - killPiece(getPiece(arrival.getID())); - } + // --- ALL SPECIAL MOVES --- if(state == TileView.SPECIAL) { - // promotion can be done while attacking too - if(!board.isFree(arrival)) { - killPiece(getPiece(arrival.getID())); + if(board.isPawn(selected)) { + // --- PROMOTION --- + if(arrival.getY() == 8 || arrival.getY() == 1) { + // --- ATTACK (while doing promotion) --- + if (!board.isFree(arrival)) { + killPiece(arrival); // place piece on graveyard (visual) + } + // Promotion to Queen (by default, Queen for now) + board.mutationOfSelectedPiece(Board.QUEEN); // (on model) + mutationPiece(model, selected, Custom3dModel.QUEEN); // (on view) + } + // --- PRISE EN PASSANT --- + else { + // PRE : if it's not a promotion, then it's "prise en passant", because of pawn rules + // we don't need to test y-position + } + } + // --- CASTLING (from king) --- + if(board.isKing(selected)) { + // PRE (1) : the arrival piece CAN ONLY BE ROOK, because of king rules + // PRE (2) : we don't need to test if rook !hasBeenMoved(), because of king rules + // PRE (3) : we don't need to test if king !hasBeenMoved(), because of king rules + int x = Board.D; // king x arrival, for west-rook + if(arrival.getX() == Board.H) { + x = Board.F; // king x arrival, for east-rook + } + Position kingArrival = new Position(x, selected.getY()); + board.movePiece(selected, kingArrival); // move king (on model) + movePiece(selected, kingArrival); // move king (on 3d view) + board.movePiece(arrival, selected); // move rook (on model) + movePiece(arrival, selected); // move rook (on 3d view) + } + // --- CASTLING (from rook) --- + else if(board.isRook(selected)) { + // PRE (1) : the arrival piece CAN ONLY BE KING, because of rook rules + // PRE (2) : we don't need to test if king !hasBeenMoved(), because of rook rules + // PRE (3) : we don't need to test if rook !hasBeenMoved(), because of rook rules + int x = Board.D; // king x arrival, for west-rook + if (selected.getX() == Board.H) { + x = Board.F; // king x arrival, for east-rook + } + Position kingArrival = new Position(x, arrival.getY()); + board.movePiece(arrival, kingArrival); // move king (on model) + movePiece(arrival, kingArrival); // move king (on 3d view) + board.movePiece(selected, arrival); // move rook (on model) + movePiece(selected, arrival); // move rook (on 3d view) + } + } + // --- STANDARD MOVES --- + else { + // --- ATTACK --- + if(state == TileView.ATTACK) { + killPiece(arrival); // place piece on graveyard (visual) } - // promotion + rook , to implement + // --- MOVE --- + board.movePiece(selected, arrival); // move piece (on model) + movePiece(selected, arrival); // move piece (on 3d view) } - board.movePiece(selected, arrival); // move piece (on model) - movePiece(selected, arrival); // move piece (on 3d view) - resetColor(material); + } + // --- Resets board coloring, doing any action or not --- + resetColor(material); } - public void movePiece(Position origin, Position arrival) { + private void movePiece(Position origin, Position arrival) { PieceView piece = getPiece(origin.getID()); piece.setPosition(arrival); // changes position to arrival setPiece(piece); // copies the piece from origin ID to arrival ID @@ -208,7 +254,8 @@ public class BoardView { updatePiece(arrival); // updates 3d model position (visual) } - public void killPiece(PieceView piece) { // graveyards are specified as negative x + private void killPiece(Position p) { // graveyards are specified as negative x + PieceView piece = getPiece(p.getID()); if(piece.getColor() == Piece.WHITE){ white_death_count++; piece.setPosition(new Position(Position.WHITE_GRAVEYARD, white_death_count)); @@ -219,6 +266,13 @@ public class BoardView { updateGraveyardPiece(piece); } + private void mutationPiece(Custom3dModel model, Position selected, int type) { + // for view side, we can't "overwrite" the piece, we need to "edit" it, + // otherwise the old 3d model would stay on the scene + MeshView obj = getPieceObj(selected.getID()); + obj.setMesh(model.get(type)); + } + public void addAllToScene(Group group) { for(int n = 0 ; n < 64 ; n++) { if(getTile(n) != null) { diff --git a/MavenChess/MavenChess/src/main/java/view/CustomMaterial.java b/MavenChess/MavenChess/src/main/java/view/CustomMaterial.java index 0302968fa94f2293407f7cbfec7db1eecdf92b31..8a31a0209658c41f93c73b1257df2483653eb62a 100644 --- a/MavenChess/MavenChess/src/main/java/view/CustomMaterial.java +++ b/MavenChess/MavenChess/src/main/java/view/CustomMaterial.java @@ -15,9 +15,9 @@ public class CustomMaterial { public CustomMaterial() { material = new PhongMaterial[MATERIAL_LENGTH]; material[BLACK] = new PhongMaterial(); - material[BLACK].setDiffuseColor(Color.BLACK); + material[BLACK].setDiffuseColor(Color.rgb(20,20,20)); material[WHITE] = new PhongMaterial(); - material[WHITE].setDiffuseColor(Color.WHITE); + material[WHITE].setDiffuseColor(Color.rgb(240,240,240)); material[SELECTED_TILE] = new PhongMaterial(); material[SELECTED_TILE].setDiffuseColor(Color.rgb(50,200,100)); material[MOVABLE_TILE] = new PhongMaterial(); diff --git a/MavenChess/MavenChess/src/main/java/view/PieceView.java b/MavenChess/MavenChess/src/main/java/view/PieceView.java index 2652f21a46eefb27fb28e91558d085982cc20601..3e6cb142a55b6566408e2ff9a4a2244295e211bc 100644 --- a/MavenChess/MavenChess/src/main/java/view/PieceView.java +++ b/MavenChess/MavenChess/src/main/java/view/PieceView.java @@ -27,7 +27,7 @@ public class PieceView { } public void setPosition(Position arrival) { - position = arrival; + position = new Position(arrival.getX(), arrival.getY()); // creates a new copy, to avoid using reference } public int getColor() { diff --git a/MavenChess/MavenChess/target/classes/controller/Main.class b/MavenChess/MavenChess/target/classes/controller/Main.class index 1021ecf5800bb5235d0702489ee5928b761d82ea..26a5078555bb03c979e9421431ca6b3186969f9e 100644 Binary files a/MavenChess/MavenChess/target/classes/controller/Main.class and b/MavenChess/MavenChess/target/classes/controller/Main.class differ diff --git a/MavenChess/MavenChess/target/classes/model/Board.class b/MavenChess/MavenChess/target/classes/model/Board.class index 1407815545854fd1dd5a89e16d2f19e127a9ecb9..68dda59d7a6c6d20e35581e29bb7e67234456bc5 100644 Binary files a/MavenChess/MavenChess/target/classes/model/Board.class and b/MavenChess/MavenChess/target/classes/model/Board.class differ diff --git a/MavenChess/MavenChess/target/classes/model/Piece.class b/MavenChess/MavenChess/target/classes/model/Piece.class index c70cfe3367e1cb27e247905ca4d730e0342c589f..5ea10cd77ba3e51ecf0a9c9952be710ffc479667 100644 Binary files a/MavenChess/MavenChess/target/classes/model/Piece.class and b/MavenChess/MavenChess/target/classes/model/Piece.class differ diff --git a/MavenChess/MavenChess/target/classes/view/BoardView.class b/MavenChess/MavenChess/target/classes/view/BoardView.class index 658950bedb33ff474e89419b3e918501d22fd96f..4e3204d077c098470e984565f8b0fada87995e72 100644 Binary files a/MavenChess/MavenChess/target/classes/view/BoardView.class and b/MavenChess/MavenChess/target/classes/view/BoardView.class differ diff --git a/MavenChess/MavenChess/target/classes/view/CustomMaterial.class b/MavenChess/MavenChess/target/classes/view/CustomMaterial.class index 716c4af3b9b45177c2e298edd4a74ae7fb2c8078..06ac3d5e95495a07bff9fe1ddba2c69a20ed8c70 100644 Binary files a/MavenChess/MavenChess/target/classes/view/CustomMaterial.class and b/MavenChess/MavenChess/target/classes/view/CustomMaterial.class differ diff --git a/MavenChess/MavenChess/target/classes/view/PieceView.class b/MavenChess/MavenChess/target/classes/view/PieceView.class index 3c6a4b6876b721f6d4664abc0a04f078c07ac0ac..861779ea1eb44cd71c28a9393b6864abf3cf04a9 100644 Binary files a/MavenChess/MavenChess/target/classes/view/PieceView.class and b/MavenChess/MavenChess/target/classes/view/PieceView.class differ