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