diff --git a/MavenChess/MavenChess/src/main/java/controller/Game.java b/MavenChess/MavenChess/src/main/java/controller/Game.java
index 7d3ef8f9f455a714bcbfdedd80a5ba4e236ee478..93f916bbd0790f6df1b0a8c7618fdfd93097d5d5 100644
--- a/MavenChess/MavenChess/src/main/java/controller/Game.java
+++ b/MavenChess/MavenChess/src/main/java/controller/Game.java
@@ -7,7 +7,7 @@ import java.util.ArrayList;
 
 public class Game {
     private int status;
-    public static final int WHITE_TURN = 1, BLACK_TURN = 2, GAME_OVER = 3;
+    public static final int WHITE_TURN = 1, BLACK_TURN = 2, WHITE_WON = 3, BLACK_WON = 4;
 
     public Game() {
         status = WHITE_TURN;
@@ -37,9 +37,9 @@ public class Game {
 
     public void nextTurn() {
         if(isWhiteTurn())
-            setStatus(Game.BLACK_TURN);
-        else if(isBlackTurn())
-            setStatus(Game.WHITE_TURN);
+            setStatus(BLACK_TURN);
+        else
+            setStatus(WHITE_TURN);
     }
 
     public void clickPiece(PieceView clickedPiece, Board board, BoardView boardView, CustomMaterial material, Custom3dModel model, Log log, HUD hud) {
@@ -58,7 +58,7 @@ public class Game {
             // clicking a piece will ask her available moves
             Position position = clickedPiece.getPosition();
             board.setSelected(position);
-            boardView.resetColor(material);
+            boardView.resetTileColorAll(material);
             boardView.setColor(material, position, CustomMaterial.SELECTED_TILE);
             ArrayList<Position> moves = board.getPiece(position).getAvailableMoves(board);
 
@@ -73,23 +73,15 @@ public class Game {
 
             // shows all available moves on the tiles, with colors, each tile-color having a meaning
             for (Position move : moves) {
-
                 if (board.isFree(move)) {
                     boardView.setColor(material, move, CustomMaterial.MOVABLE_TILE);
                     // test for "en passant"
-                    if (board.isPawn(position) || board.isNwap(position)) {
+                    if (board.isPawn(position)) {
                         Position enemy = new Position(move.getX(), position.getY());
                         boolean isEnPassant = false;
-                        if (board.isEnemy(enemy, position)) {
-                            if (board.isPawn(enemy)) {
-                                if (((Pawn) board.getPiece(enemy)).isEnPassant()) {
-                                    isEnPassant = true;
-                                }
-                            }
-                            if (board.isNwap(enemy)) {
-                                if (((Nwap) board.getPiece(enemy)).isEnPassant()) {
-                                    isEnPassant = true;
-                                }
+                        if (board.isEnemy(enemy, position) && board.isPawn(enemy)) {
+                            if (((Pawn) board.getPiece(enemy)).isEnPassant()) {
+                                isEnPassant = true;
                             }
                         }
                         if (isEnPassant) {
@@ -106,10 +98,22 @@ public class Game {
                     boardView.getPiece(move.getID()).setTargeted(material, CustomMaterial.SPECIAL_TILE);
                 }
                 // PROMOTION (attacking or not)
-                if ((board.isPawn(position) || board.isNwap(position)) && (move.getY() == 8 || move.getY() == 1)) {
+                if ((board.isPawn(position)) && (move.getY() == 8 || move.getY() == 1)) {
                     boardView.setColor(material, move, CustomMaterial.SPECIAL_TILE);
                 }
             }
+
+            // Prevent available moves that let the king in check state
+            ArrayList<Position> toPrevent = new ArrayList<>();
+            for (Position move : moves) {
+                boolean selfCheck = applyMoveAndCheckVerification(board, boardView, getStatus(), move);
+                if(selfCheck) {
+                    toPrevent.add(move); // Prevents the move
+                }
+            }
+            for (Position elem : toPrevent) {
+                boardView.resetTileColor(material, elem);
+            }
         }
     }
 
@@ -136,7 +140,7 @@ public class Game {
             }
             // --- ALL SPECIAL MOVES ---
             if(state == TileView.SPECIAL) {
-                if(board.isPawn(selected) || board.isNwap(selected)) {
+                if(board.isPawn(selected)) {
                     // --- PROMOTION ---
                     if(arrival.getY() == 8 || arrival.getY() == 1) {
                         // --- ATTACK (while doing promotion) ---
@@ -244,13 +248,154 @@ public class Game {
             }
 
         }
+
         // --- Resets board coloring, doing any action or not ---
-        boardView.resetColor(material);
+        boardView.resetTileColorAll(material);
+
         // updates game status
         if(moved) {
             nextTurn(); // change player turn
             log.save(board, boardView); // saves current board
             hud.rollbackShow(); // show rollback button (if not showed already)
+
+            // signals if there is a check !
+            boolean echec = checkVerification(board, getStatus()); // test the opponent check (turn just changed)
+            if(echec) {
+                if (isWhiteTurn()) {
+                    System.out.println("echec white");
+                }
+                if (isBlackTurn()) {
+                    System.out.println("echec black");
+                }
+            }
+        }
+    }
+
+    public boolean checkVerification(Board board, int color){
+        boolean isCheck = false;
+        for (int i = 0 ; i < 64 ; i++){
+            Piece p = board.getPiece(i);
+            if(p != null && p.getColor() != color) {
+                // get all moves
+                ArrayList<Position> moves = p.getAvailableMoves(board);
+                // if kamikaze adds explosion moves
+                if(p.getClass() == Kamikaze.class) {
+                    ArrayList<Position> explosions = ((Kamikaze) p).getExplosion();
+                    moves.addAll(explosions);
+                }
+                // if it kills the king of specified color, check !
+                for (Position move : moves) {
+                    if (board.isKing(move) && board.getPiece(move).getColor() == color) {
+                        isCheck = true;
+                    }
+                }
+            }
         }
+        return isCheck;
+    }
+
+    public boolean applyMoveAndCheckVerification(Board originalBoard, BoardView boardView, int color, Position emulatedMove) {
+
+        Board board = originalBoard.newInstanceCopy(); // create a copy, to do tests on it
+        board.setSelected(originalBoard.getSelected());
+        TileView clickedTile = boardView.getTile(emulatedMove.getID());
+
+        // --- EMULATES THE MOVEMENT -----------------------------------------------
+
+        // --- Analyses the clicked tile type, and executes related actions ---
+        int state = clickedTile.getState();
+        Position selected = board.getSelected();
+        Position arrival = clickedTile.getPosition();
+        if(state != TileView.NORMAL && state != TileView.SELECTED) {
+            // --- Resets enPassant ---
+            for(int j = 1 ; j <= 8 ; j++) {
+                for(int i = 1 ; i <= 8 ; i++) {
+                    Position p = new Position(i, j);
+                    if (board.isPawn(p)) {
+                        ((Pawn) board.getPiece(p)).setEnPassant(false);
+                    }
+                    if (board.isNwap(p)) {
+                        ((Nwap) board.getPiece(p)).setEnPassant(false);
+                    }
+                }
+            }
+            // --- ALL SPECIAL MOVES ---
+            if(state == TileView.SPECIAL) {
+                if(board.isPawn(selected)) {
+                    // --- PROMOTION ---
+                    if(arrival.getY() == 8 || arrival.getY() == 1) {
+                        // Promotion to Queen (by default, Queen for now)
+                        board.mutationOfSelectedPiece(Board.QUEEN);
+                        board.movePiece(selected, arrival);
+                    }
+                    // --- PRISE EN PASSANT ---
+                    else {
+                        Position enemy = new Position(arrival.getX(), selected.getY());
+                        board.killPiece(enemy.getID()); // because we don't move "on it", we need to kill it manually (model)
+                        Position enPassantArrival = new Position(arrival.getX(), selected.getY()+1);
+                        if(board.getSelectedPiece().getColor() == Piece.BLACK) {
+                            enPassantArrival.setY(selected.getY()-1);
+                        }
+                        board.movePiece(selected, enPassantArrival);
+                    }
+                }
+                // --- CASTLING (from king) ---
+                if(board.isKing(selected)) {
+                    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
+                    board.movePiece(arrival, selected); // move rook
+                }
+                // --- CASTLING (from rook) ---
+                else if(board.isRook(selected)) {
+                    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
+                    board.movePiece(selected, arrival); // move rook
+                }
+            }
+            // --- EXPLOSION MOVES ---
+            else if (state == TileView.EXPLOSION) {
+                for(int n = 0 ; n < 64 ; n++) {
+                    if(boardView.getTile(n).getState() == TileView.EXPLOSION) {
+                        if(boardView.getPiece(n) != null) {
+                            board.killPiece(n);
+                        }
+                    }
+                }
+            }
+            // --- STANDARD MOVES ---
+            else {
+                // --- ATTACK ---
+                if(state == TileView.ATTACK) {
+                    // --- MAGICIAN CHANGE ---
+                    if(board.isMagician(selected)) {
+                        Magician magician = (Magician) board.getPiece(selected);
+                        Piece enemy = board.getPiece(arrival);
+                        magician.steal(enemy); // muahaha
+                    }
+                }
+                // --- EN PASSANT activation ---
+                if(Math.abs(selected.getY() - arrival.getY()) == 2) {
+                    if(board.isPawn(selected)) {
+                        ((Pawn) board.getPiece(selected)).setEnPassant(true);
+                    }
+                    if(board.isNwap(selected)) {
+                        ((Nwap) board.getPiece(selected)).setEnPassant(true);
+                    }
+                }
+                // --- MOVE ---
+                board.movePiece(selected, arrival); // move piece
+            }
+        }
+        // --- END OF EMULATION -------------------------------------------------
+
+        return checkVerification(board, color); // we test the board after emulating a move
     }
 }
diff --git a/MavenChess/MavenChess/src/main/java/controller/Log.java b/MavenChess/MavenChess/src/main/java/controller/Log.java
index cf05e2a68f05e801c7b80552315cabdcba12d298..c4c240b6bc8c0f871287cc17b29e70d61b91a12b 100644
--- a/MavenChess/MavenChess/src/main/java/controller/Log.java
+++ b/MavenChess/MavenChess/src/main/java/controller/Log.java
@@ -19,14 +19,8 @@ public class Log {
     }
 
     public void save(Board board, BoardView boardView) {
-        Board copy = new Board();
-        for(int n = 0 ; n < 64 ; n++) {
-            // we make a NEW COPY, not just getting pointer !
-            Piece piece = board.getPiece(n);
-            if(piece != null) {
-                copy.setPiece(piece.newInstanceCopy());
-            }
-        }
+        // we make a NEW COPY, not just getting pointer !
+        Board copy = board.newInstanceCopy();
         int id = logPieces.size();
         logPieces.add(id, copy.getAllPieces());
         // for graveyards, we don't need a copy, because pieces aren't moving at all once inside, so there will be no issues
diff --git a/MavenChess/MavenChess/src/main/java/controller/Main.java b/MavenChess/MavenChess/src/main/java/controller/Main.java
index 692df0bfc59080f613b88ca70474bc03b7687c2d..5b5e304b642778573176f4ec79b8cf28b671eff8 100644
--- a/MavenChess/MavenChess/src/main/java/controller/Main.java
+++ b/MavenChess/MavenChess/src/main/java/controller/Main.java
@@ -3,8 +3,6 @@ package controller;
 import javafx.application.Application;
 import javafx.beans.value.ChangeListener;
 import javafx.scene.*;
-import javafx.scene.input.KeyCode;
-import javafx.scene.input.KeyEvent;
 import javafx.scene.input.MouseEvent;
 import javafx.scene.input.ScrollEvent;
 import javafx.scene.layout.AnchorPane;
@@ -12,7 +10,6 @@ import javafx.stage.Stage;
 import model.*;
 import view.*;
 
-import java.util.ArrayList;
 
 public class Main extends Application {
 
@@ -136,7 +133,7 @@ public class Main extends Application {
 
 		// event - rollback
 		hud.getRollback().addEventHandler(MouseEvent.MOUSE_CLICKED, event -> {
-			boardView.resetColor(material);
+			boardView.resetTileColorAll(material);
 			log.rollback(board, boardView, material, model, group3d, game, hud);
 		});
 
diff --git a/MavenChess/MavenChess/src/main/java/model/Board.java b/MavenChess/MavenChess/src/main/java/model/Board.java
index f8a24ae6b90b553fea8b66315953b0d8efe78293..00d23d1f034964d21508586607f3144fb83731af 100644
--- a/MavenChess/MavenChess/src/main/java/model/Board.java
+++ b/MavenChess/MavenChess/src/main/java/model/Board.java
@@ -209,4 +209,14 @@ public class Board {
 			pieces[i] = null;
 		}
 	}
+	public Board newInstanceCopy() {
+		Board copy = new Board();
+		for(int n = 0 ; n < 64 ; n++) {
+			Piece piece = getPiece(n);
+			if(piece != null) {
+				copy.setPiece(piece.newInstanceCopy());
+			}
+		}
+		return copy;
+	}
 }
diff --git a/MavenChess/MavenChess/src/main/java/model/Kamikaze.java b/MavenChess/MavenChess/src/main/java/model/Kamikaze.java
index 2dfd29b7581f6387fc0a4c3c156fa62102504a24..a3f0c9621166f5dd23b08e14105f7212caa5ef59 100644
--- a/MavenChess/MavenChess/src/main/java/model/Kamikaze.java
+++ b/MavenChess/MavenChess/src/main/java/model/Kamikaze.java
@@ -2,31 +2,12 @@ package model;
 
 import java.util.ArrayList;
 
-public class Kamikaze extends Pawn { // aka Trojan knight :P
+public class Kamikaze extends Knight { // aka Trojan knight :P
     public Kamikaze(Position p, int color) {
         super(p, color);
     }
 
-    @Override
-    public ArrayList<Position> getAvailableMoves(Board b) {
-
-        ArrayList<Position> moves = new ArrayList<>();
-        Position arrival;
-
-        // list of the 8 kamikaze-knight specific movements
-        int[] all_x = {1, 2, 2, 1, -1, -2, -2, -1};
-        int[] all_y = {2, 1, -1, -2, -2, -1, 1, 2};
-
-        for(int n = 0 ; n < all_x.length ; n++) { // for each direction
-            int x = all_x[n];
-            int y = all_y[n];
-            arrival = new Position(p.getX() + x, p.getY() + y);
-            if (b.isEnemy(arrival, p) || b.isFree(arrival)) {
-                moves.add(arrival);
-            }
-        }
-        return moves;
-    }
+    // getAvailableMoves is in Knight already
 
     public ArrayList<Position> getExplosion() {
 
diff --git a/MavenChess/MavenChess/src/main/java/model/Nwap.java b/MavenChess/MavenChess/src/main/java/model/Nwap.java
index f7732c348e9ba08167bf8fab8d49a431c2bb4a8b..f952b40e86108e9bcf9d35420de3008101e86015 100644
--- a/MavenChess/MavenChess/src/main/java/model/Nwap.java
+++ b/MavenChess/MavenChess/src/main/java/model/Nwap.java
@@ -13,71 +13,69 @@ public class Nwap extends Pawn {
     @Override
     public ArrayList<Position> getAvailableMoves(Board b) {
 
-
-        ArrayList<Position> moves = new ArrayList<Position>();
+        ArrayList<Position> moves = new ArrayList<>();
         Position arrival;
         Position arrival2;
 
         if(color == Piece.WHITE) { // black and white have an opposite direction behavior
 
-            if(!hasBeenMoved){
-
-                //	up left 2
-
-
-                //	up right 2
-
-            }
-            //	up left 1
+            // up left
             arrival = new Position(p.getX()-1, p.getY() +1);
             if(arrival.isCorrect() && b.isFree(arrival)) {
+                moves.add(arrival);
+                if(!hasBeenMoved) {
+                    arrival2 = new Position(p.getX() - 2, p.getY() + 2);
+                    if (arrival2.isCorrect() && b.isFree(arrival2)) {
+                        moves.add(arrival2);
+                    }
+                }
+            }
 
-                 arrival2 = new Position(p.getX()-2, p.getY() +2);
-                if(arrival2.isCorrect() && b.isFree(arrival2)) { moves.add(arrival2); }
-                moves.add(arrival); }
-
-
-            //	up right 1
+            // up right
             arrival = new Position(p.getX()+1, p.getY() +1);
             if(arrival.isCorrect() && b.isFree(arrival)) {
-                arrival2 = new Position(p.getX()+2, p.getY() +2);
-                if(arrival2.isCorrect() && b.isFree(arrival2)) { moves.add(arrival2); }
-                moves.add(arrival); }
+                moves.add(arrival);
+                if (!hasBeenMoved) {
+                    arrival2 = new Position(p.getX() + 2, p.getY() + 2);
+                    if (arrival2.isCorrect() && b.isFree(arrival2)) {
+                        moves.add(arrival2);
+                    }
+                }
+            }
 
+            // up attack
             arrival = new Position(p.getX(),p.getY()+1);
             if(b.isEnemy(arrival,p)) {moves.add(arrival);}
-
         }
         else {
 
-
-            if(!hasBeenMoved){
-
-
-
-
-            }
-            //	up left 1
+            // down left
             arrival = new Position(p.getX()-1, p.getY() -1);
             if(arrival.isCorrect() && b.isFree(arrival)) {
-                //	up left 2
-                arrival2 = new Position(p.getX()-2, p.getY() -2);
-                if(arrival2.isCorrect() && b.isFree(arrival2)) { moves.add(arrival2); }
-                moves.add(arrival); }
-
+                moves.add(arrival);
+                if (!hasBeenMoved) {
+                    arrival2 = new Position(p.getX() - 2, p.getY() - 2);
+                    if (arrival2.isCorrect() && b.isFree(arrival2)) {
+                        moves.add(arrival2);
+                    }
+                }
+            }
 
-            //	up left 1
+            // down right
             arrival = new Position(p.getX()+1, p.getY() -1);
             if(arrival.isCorrect() && b.isFree(arrival)) {
+                moves.add(arrival);
+                if (!hasBeenMoved) {
+                    arrival2 = new Position(p.getX() + 2, p.getY() - 2);
+                    if (arrival2.isCorrect() && b.isFree(arrival2)) {
+                        moves.add(arrival2);
+                    }
+                }
+            }
 
-                //	up left 2
-                arrival2 = new Position(p.getX()+2, p.getY() -2);
-                if(arrival2.isCorrect() && b.isFree(arrival2)) { moves.add(arrival2); }moves.add(arrival); }
-
-
+            // down attack
             arrival = new Position(p.getX(),p.getY()-1);
             if(b.isEnemy(arrival,p)) {moves.add(arrival);}
-
         }
         return moves;
     }
diff --git a/MavenChess/MavenChess/src/main/java/view/BoardView.java b/MavenChess/MavenChess/src/main/java/view/BoardView.java
index fcf0e986765193fed6bf68f3098d2e658fa5fe1e..92feb3de0c00229ce135e549e7b6b34dbc206d1e 100644
--- a/MavenChess/MavenChess/src/main/java/view/BoardView.java
+++ b/MavenChess/MavenChess/src/main/java/view/BoardView.java
@@ -6,8 +6,6 @@ import javafx.scene.shape.*;
 import model.*;
 import javafx.util.Duration;
 
-import java.util.ArrayList;
-
 public class BoardView {
 
 	public static final int BOARD_SIZE = 16, CENTERED_ORIGIN = -BOARD_SIZE*7/2, BOARD_HEIGHT = -5, GRAVEYARD_HEIGHT = -1;
@@ -46,7 +44,7 @@ public class BoardView {
 		blackGraveyard = new PieceView[16]; // 16 is maximum kills
 		whiteGraveyard = new PieceView[16];
 
-		resetColor(material); // init/reset the board squares with black and white
+		resetTileColorAll(material); // init/reset the board squares with black and white
 
 		// creates the board visual border
 		border = new Box[4];
@@ -179,23 +177,28 @@ public class BoardView {
 		piece.getObj().setTranslateY(GRAVEYARD_HEIGHT); // place at right height (Y axis) on table
 	}
 
-	public void resetColor(CustomMaterial material) {
+	public void resetTileColorAll(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
-				if((i + j) % 2 == 0) {
-					getTileObj(n).setMaterial(material.get(CustomMaterial.BLACK_TILE)); // (visually)
-				} else {
-					getTileObj(n).setMaterial(material.get(CustomMaterial.WHITE_TILE)); // (visually)
-				}
-				getTile(n).setState(TileView.NORMAL); // (on 'state' attribute)
-				if(getPiece(n) != null) {
-					getPiece(n).resetTargeted(material); // reset the 3d pieces color too (visual)
-				}
+				resetTileColor(material, new Position(i, j));
 			}
 		}
 	}
 
+	public void resetTileColor(CustomMaterial material, Position p) {
+		int i = p.getX(), j = p.getY(), n = p.getID();
+		// resets board with black and white - bottom left (first case) is black, then alternates
+		if((i + j) % 2 == 0) {
+			getTileObj(n).setMaterial(material.get(CustomMaterial.BLACK_TILE)); // (visually)
+		} else {
+			getTileObj(n).setMaterial(material.get(CustomMaterial.WHITE_TILE)); // (visually)
+		}
+		getTile(n).setState(TileView.NORMAL); // (on 'state' attribute)
+		if(getPiece(n) != null) {
+			getPiece(n).resetTargeted(material); // reset the 3d pieces color too (visual)
+		}
+	}
+
 	public void setColor(CustomMaterial material, Position position, int type) {
 		int id = position.getID();
 		// set the new color-type (visually)