diff --git a/bin/coursework/Animation.class b/bin/coursework/Animation.class
new file mode 100644
index 0000000000000000000000000000000000000000..ea9fd11221e9b362801b9cf1f759bb0931b3b95c
Binary files /dev/null and b/bin/coursework/Animation.class differ
diff --git a/bin/coursework/Cage.class b/bin/coursework/Cage.class
index 70a114efa9b35343e040b2214c124d1c0de03eb7..f93cf6cd92afb4721aa5581143ec6bcac4afbf0f 100644
Binary files a/bin/coursework/Cage.class and b/bin/coursework/Cage.class differ
diff --git a/bin/coursework/ConstraintsHandler.class b/bin/coursework/ConstraintsHandler.class
index d80f886ace8cb45794c9249a022cb37de2a66d45..0a68b66c3ee4a187021e0e0b1082d8babf7d6818 100644
Binary files a/bin/coursework/ConstraintsHandler.class and b/bin/coursework/ConstraintsHandler.class differ
diff --git a/bin/coursework/GameState.class b/bin/coursework/GameState.class
index 7da95ce3340cd26d28aaa90c45379d71f8c06b7d..05a8e904dce51e954e51bf717fb058b235294275 100644
Binary files a/bin/coursework/GameState.class and b/bin/coursework/GameState.class differ
diff --git a/bin/coursework/Main.class b/bin/coursework/Main.class
index eebd54f556d3480d151a72b3fd5448dad7431061..0bac322ce29c478d59d85bef452194620b73f727 100644
Binary files a/bin/coursework/Main.class and b/bin/coursework/Main.class differ
diff --git a/src/coursework/Animation.java b/src/coursework/Animation.java
new file mode 100644
index 0000000000000000000000000000000000000000..cdf17e1f032b4ae690e853df85ef2799cb7b7ff2
--- /dev/null
+++ b/src/coursework/Animation.java
@@ -0,0 +1,184 @@
+package coursework;
+
+import javafx.animation.Timeline;
+import java.util.ArrayList;
+import java.util.List;
+import javafx.animation.KeyFrame;
+import javafx.scene.layout.VBox;
+import javafx.util.Duration;
+
+public class Animation {
+
+	private VBox[] gridBoxes;
+	private String[] colors = {"#FF0000", "#FF7F00", "#FFFF00", "#00FF00", "#00FFFF", "#0000FF", "#3F00FF", "#7F00FF", "rgba(255,0,0,0)"};
+	private Integer[] indexArray;
+	private List<Integer> indexList = new ArrayList<Integer>();
+	private int index = 0;
+	private int count = 1;
+	private int colorIndex = 0;
+
+	public Animation() {
+		gridBoxes = Main.getGridBoxes();
+	}
+	
+	public void go() {
+		initialiseIndex();
+		Timeline timeline = new Timeline();
+		KeyFrame keyframe = new KeyFrame(Duration.seconds(0.1), e -> {
+			if (index != indexArray.length) {
+				for (int j = 0; j < colors.length; j++) {
+					if (index - j >= 0) {
+						if (indexArray[index - j] >= 0 && indexArray[index] - j <= Main.N*Main.N) {
+							gridBoxes[indexArray[index - j]].setStyle("-fx-background-color:"+colors[j]+";");
+						}
+					}
+				}
+				index++;
+			}
+			if (index == indexArray.length && count < 9) {
+				for (int i = 0; i < colors.length - count; i++) {
+					gridBoxes[indexArray[indexArray.length - i - 1]].setStyle("-fx-background-color:"+colors[i+count]+";");
+				}
+				count++;
+			}
+			if (count == 9) {
+				if (Main.N % 2 == 0) {
+					//even
+					int maxCentre = Main.N / 2;
+					int minCentre = maxCentre - 1;
+					
+					int topLeft = (minCentre * Main.N) + minCentre;
+					int topRight = (minCentre * Main.N) + maxCentre;
+					int botLeft = (maxCentre * Main.N) + minCentre;
+					int botRight = (maxCentre * Main.N + maxCentre);
+					int[] gridIndicies = { topLeft, topRight, botLeft, botRight };
+					
+					if (colorIndex < colors.length) {
+						for (int gridIndex : gridIndicies) {
+							gridBoxes[gridIndex].setStyle("-fx-background-color:"+colors[colorIndex]+";");
+						}
+					}
+					if (colorIndex - 1 > 0 && colorIndex < colors.length + 1) {
+						gridBoxes[topLeft - 1].setStyle("-fx-background-color:"+colors[colorIndex - 1]+";");
+						gridBoxes[topLeft - Main.N].setStyle("-fx-background-color:"+colors[colorIndex - 1]+";");
+						gridBoxes[topLeft - Main.N - 1].setStyle("-fx-background-color:"+colors[colorIndex - 1]+";");
+						
+						gridBoxes[topRight + 1].setStyle("-fx-background-color:"+colors[colorIndex - 1]+";");
+						gridBoxes[topRight - Main.N].setStyle("-fx-background-color:"+colors[colorIndex - 1]+";");
+						gridBoxes[topRight - Main.N + 1].setStyle("-fx-background-color:"+colors[colorIndex - 1]+";");
+						
+						gridBoxes[botLeft - 1].setStyle("-fx-background-color:"+colors[colorIndex - 1]+";");
+						gridBoxes[botLeft + Main.N].setStyle("-fx-background-color:"+colors[colorIndex - 1]+";");
+						gridBoxes[botLeft + Main.N - 1].setStyle("-fx-background-color:"+colors[colorIndex - 1]+";");
+						
+						gridBoxes[botRight + 1].setStyle("-fx-background-color:"+colors[colorIndex - 1]+";");
+						gridBoxes[botRight + Main.N].setStyle("-fx-background-color:"+colors[colorIndex - 1]+";");
+						gridBoxes[botRight + Main.N + 1].setStyle("-fx-background-color:"+colors[colorIndex - 1]+";");
+					}
+					
+
+					
+				}
+				else {
+					//odd 
+					int centre = Main.N - 1 / 2;
+					
+					gridBoxes[centre * Main.N + centre].setStyle("-fx-background-color:"+colors[colorIndex]+";");
+				}
+				colorIndex++;
+			}
+			
+		});
+		timeline.getKeyFrames().add(keyframe);
+		timeline.setCycleCount(indexArray.length + 20);
+		timeline.play();
+		
+	}
+	
+	private void initialiseIndex() {
+		for (int i = 0; i < Main.N; i++) {
+			for (int j = 0; j < Main.N; j++) {
+				if (i % 2 == 0) {
+					indexList.add(i*Main.N + j);
+				}
+				else {
+					indexList.add((i+1) * Main.N - 1 - j);
+				}
+			}
+		}
+		
+		if (getPrevious(indexList) % Main.N == 0) {
+			// even n
+			for (int j = 0; j < Main.N / 2; j++) {
+				moveUpDown(1, Main.N - 1);
+				moveLeftRight(1, 1);
+				moveUpDown(-1, Main.N - 1);
+				if (j != Main.N/2 - 1) {
+					moveLeftRight(1, 1);
+				}
+			}
+			
+			int count = Main.N - 1;
+			moveLeftRight(-1, count);
+			moveUpDown(1, count);
+			moveLeftRight(1, count);
+			count--;
+			
+			while (count > 0) {
+				moveUpDown(-1, count);
+				moveLeftRight(-1, count);
+				count--;
+				moveUpDown(1, count );
+				moveLeftRight(1, count);
+				count--;
+			}
+		}
+		else {
+			// odd n
+			for (int j = 0; j < Main.N / 2; j++) {
+				moveUpDown(1, Main.N - 1);
+				moveLeftRight(-1, 1);
+				moveUpDown(-1, Main.N - 1);
+				moveLeftRight(-1, 1);
+			}
+			moveUpDown(1, Main.N - 1);
+			
+			int count = Main.N - 1;
+			moveLeftRight(1, count);
+			moveUpDown(-1, count);
+			moveLeftRight(-1, count);
+			
+			while (count > 3) {
+				count--;
+				moveUpDown(1, count);
+				moveLeftRight(1, count);
+				count--;
+				moveUpDown(-1, count);
+				moveLeftRight(-1, count);
+			}
+			count--;
+			moveUpDown(1, count);
+			moveLeftRight(1, count);
+		}		
+		
+		indexArray = indexList.toArray(new Integer[indexList.size()]);
+	}
+	
+	private Integer getPrevious(List<Integer> indexList) {
+		return indexList.get(indexList.size() - 1);
+	}
+	
+	private void moveUpDown(int value, int n) {
+		// value == 1 to move up, value == -1 to move down
+		for (int i  = 0; i < n; i++) {
+			indexList.add(getPrevious(indexList) - Main.N*value);
+		}
+	}
+	
+	private void moveLeftRight(int value, int n) {
+		// value == 1, move right, value == -1 move left
+		for (int i  = 0; i < n; i++) {
+			indexList.add(getPrevious(indexList) + value);
+		}
+	}
+}
diff --git a/src/coursework/ConstraintsHandler.java b/src/coursework/ConstraintsHandler.java
index be5667258d9cecb55d0ab14649c137a4f7ca9725..989872b304379d9738fa2627dfe301081df63355 100644
--- a/src/coursework/ConstraintsHandler.java
+++ b/src/coursework/ConstraintsHandler.java
@@ -12,7 +12,7 @@ public class ConstraintsHandler {
 	private VBox[] gridBoxes = new VBox[Main.N*Main.N];
 	private List<Cage> gridCages = new ArrayList<Cage>();
 	private boolean[][] gridErrors = new boolean[Main.N*Main.N][3];
-	
+	private boolean constraintChecked = false;	
 	
 	public ConstraintsHandler() {}
 	
@@ -23,7 +23,12 @@ public class ConstraintsHandler {
 		gridErrors = Main.getGridErrors();
 	}
 	
+	public boolean checked() {
+		return constraintChecked;
+	}
+	
 	public void checkConstraints(int col, int row, boolean showMistakes) {
+		constraintChecked = true;
 		updateData();
 		columnConstraint(row, col);
 		rowConstraint(row, col);
@@ -136,16 +141,17 @@ public class ConstraintsHandler {
 	}
 	
 	public void checkWinCondition() {
+		updateData();
 		if (checkCellsFull() && checkConstraintErrors()) {
-			// win condition fulfilled
-			// animation and pop up
-			System.out.println("You won");
+			Animation animation = new Animation();
+			animation.go();
 		}
 	}
 	
 	private boolean checkCellsFull() {
+		System.out.println("");
 		for (TextField textField : gridNumbers) {
-			if (!textField.getText().equals("")) {
+			if (textField.getText().equals("")) {
 				return false;
 			}
 		}
diff --git a/src/coursework/Main.java b/src/coursework/Main.java
index 3416de1a951f792bb230dafa7a20866ea2c94eeb..9c8ff2fc07cda09e28392ba7e34623683e2570c9 100644
--- a/src/coursework/Main.java
+++ b/src/coursework/Main.java
@@ -19,6 +19,7 @@ import javafx.scene.control.Button;
 import javafx.scene.control.ButtonType;
 import javafx.scene.control.CheckBox;
 import javafx.scene.control.Label;
+import javafx.scene.control.TextArea;
 import javafx.scene.control.TextField;
 import javafx.scene.image.Image;
 import javafx.scene.image.ImageView;
@@ -30,12 +31,12 @@ import javafx.scene.layout.VBox;
 import javafx.scene.paint.Color;
 import javafx.scene.shape.Rectangle;
 import javafx.stage.FileChooser;
+import javafx.stage.Modality;
 import javafx.stage.Stage;
 
 public class Main extends Application {
 	
-	final static public int N = 5;
-	final private double GRID_PERCENTAGE = 0.75;
+	final static public int N = 6;
 	
 	private Scene scene;
 	private Stage stage;
@@ -48,7 +49,6 @@ public class Main extends Application {
 	private static boolean[][] gridErrors = new boolean[N*N][3];
 	
 	private static boolean showMistakes = false;
-	private boolean isWider;
 	private Pane previousPane = null;
 	private Square previousSquare = null;
 	private boolean clearing = false;
@@ -86,18 +86,19 @@ public class Main extends Application {
 	public static boolean[][] getGridErrors() {
 		return gridErrors;
 	}
-	//////////////////////////////////////////////////////////////////////////////////
-	
-	private GridPane setupGrid() {
+	//
+	////////////////////////////////////////////////////////////////////////////////
+	private GridPane setupGrid(int width, int height) {
 		GridPane gridPane = new GridPane();
 		gridPane.setAlignment(Pos.CENTER);
-		double size = (scene.getWidth() * GRID_PERCENTAGE) / N;
-
+		double value = width < height ? width : height;	
+		double size = value / N;
 		for (int i = 0; i < N; i++) {
 			for (int j = 0; j < N; j++) {
 				gridPane = addToGridPane(gridPane, size, i, j);
 			}
 		}
+		
 		return gridPane;
 	}
 	
@@ -182,29 +183,13 @@ public class Main extends Application {
 			loadFileButtonClickEvent();
 		});
 		
-		return topHBox;
-	}
-	
-	private void createNewCage(String line) {
-		String[] splitLine = line.split(" ");
-		String[] shiftedIds = splitLine[1].split(",");
-		int[] ids = new int[shiftedIds.length];
-		for (int i = 0; i < shiftedIds.length; i++) {
-			ids[i] = Integer.parseInt(shiftedIds[i]) - 1;
-		}
-		
-		if (splitLine[0].contains("÷")) {
-			splitLine[0] = splitLine[0].replace("÷", "�");
-		}
-		
-		int value = Integer.parseInt(splitLine[0].substring(0, splitLine[0].length()- 1));
-		String operator = splitLine[0].substring(splitLine[0].length() - 1);
+		loadGameTextInputButton.setOnAction(e -> {
+			loadTextButtonClickEvent();
+		});
 		
-		Cage cage = new Cage(ids, value, operator);
-		gridCages.add(cage);
+		return topHBox;
 	}
 	
-	
 	private void updateGameState(GameState gameState) {
 		String[] gameValues = gameState.getGameState();
 		for (int i = 0; i < gridNumbers.length; i++) {
@@ -239,34 +224,43 @@ public class Main extends Application {
 	
 	private VBox setupNumbersVBox() {
 		VBox vbox = new VBox();
+		Button balanceButtonTop = new Button("");
+		balanceButtonTop.setPrefWidth(111);
+		balanceButtonTop.setVisible(false);
+		Button balanceButtonBottom = new Button("");
+		balanceButtonBottom.setPrefWidth(111);
+		balanceButtonBottom.setVisible(false);
+		vbox.getChildren().add(balanceButtonTop);
 		for (int i = 1; i <= N; i++)  {
 			Button button = new Button(i + "");
-			double cellWidth = gridSquares[0].getRectangle().getWidth() / 2;
-			double fontSize = cellWidth * 0.4;
+			final double WIDTH = 50;
 			
-			button.setPrefSize(cellWidth, cellWidth);
-			button.setMaxSize(150, 150);
-			button.setStyle("-fx-font-size:"+fontSize+"pt");
+			button.setPrefSize(WIDTH, WIDTH);
+			button.setMaxSize(WIDTH, WIDTH);
+			button.setStyle("-fx-font-size:"+18+"pt");
 			button.setOnAction(e -> {
 				numbersButtonClickEvent(button);
 			});
 			vbox.getChildren().add(button);
 		}
+		vbox.getChildren().add(balanceButtonBottom);
 		vbox.setSpacing(10);
-		vbox.setAlignment(Pos.CENTER);
+		vbox.setAlignment(Pos.CENTER_LEFT);
 		return vbox;
 	}
 	
 	private VBox setupFontSizeHBox() {
 		VBox vbox = new VBox();	
-		vbox.getChildren().addAll(setupButton("Tiny", 10), setupButton("Small", 14), setupButton("Medium", 18), setupButton("Large", 22), setupButton("Huge", 26));
-		vbox.setSpacing(10);
+		vbox.getChildren().addAll(setupButton("Tiny", 10, 71), setupButton("Small", 14, 81), setupButton("Medium", 18, 91), setupButton("Large", 22, 101), setupButton("Huge", 26, 111));
+		vbox.setSpacing(15);
 		vbox.setAlignment(Pos.CENTER);
 		return vbox;
 	}
 	
-	private Button setupButton(String name, int size) {
+	private Button setupButton(String name, int size, int width) {
 		Button button = new Button(name);
+		button.setMinWidth(width);
+		button.setPrefWidth(width);
 		button.setStyle("-fx-font-size:" + size + "px;");
 		button.setOnAction(e -> {
 			changeFontSizeEvent(size);
@@ -274,6 +268,59 @@ public class Main extends Application {
 		return button;
 	}
 	
+	private void createNewCage(String line) {
+		String[] splitLine = line.split(" ");
+		String[] shiftedIds = splitLine[1].split(",");
+		int[] ids = new int[shiftedIds.length];
+		
+		for (int i = 0; i < shiftedIds.length; i++) {
+			ids[i] = Integer.parseInt(shiftedIds[i]) - 1;
+		}
+		
+		if (splitLine[0].contains("÷") || splitLine[0].contains("/")) {
+			splitLine[0] = splitLine[0].replace("÷", "�");
+		}
+		
+		int value = Integer.parseInt(splitLine[0].substring(0, splitLine[0].length()- 1));
+		String operator = splitLine[0].substring(splitLine[0].length() - 1);
+		
+		Cage cage = new Cage(ids, value, operator);
+		gridCages.add(cage);
+	}
+	
+	
+	private void clearGridAlert() {
+		clearing = true;
+		Alert alert = new Alert(AlertType.CONFIRMATION);
+		alert.setContentText("Are you sure you wish to clear the board?");
+		alert.setTitle("Clearing Board.");
+		alert.showAndWait().ifPresent(type -> {
+			if (type == ButtonType.OK) {
+				clearGridData();
+				undoStack.push(new GameState(GameState.getCurrentGameState(gridNumbers)));
+			}
+		});;
+		clearing = false;
+	}
+	
+	private void clearEmptyGridAlert() {
+		Alert alert = new Alert(AlertType.WARNING);
+		alert.setContentText("Nothing to clear on the board.");
+		alert.setTitle("Empty Board");
+		alert.showAndWait();
+	}
+	
+	private void clearGridData() {
+		for (TextField textField : gridNumbers) {
+			textField.setText("");
+		}
+		for (int i = 0; i < N*N; i++) {
+			for (int j = 0; j < 3; j++) {
+				gridErrors[i][j] = false;
+			}
+		}
+	}
+	
 	///////////////////////////////////////////////////////////
 	private void loadFileButtonClickEvent() {
 		try {
@@ -294,9 +341,51 @@ public class Main extends Application {
 		}
 	}
 	
+	private void loadTextButtonClickEvent() {
+		Stage popupStage = new Stage();
+		popupStage.initModality(Modality.APPLICATION_MODAL);
+		popupStage.initOwner(stage);
+		
+		VBox vbox = new VBox();
+		vbox.setPadding(new Insets(10));
+		vbox.setSpacing(10);
+		
+		HBox hbox = new HBox();
+		hbox.setSpacing(162);
+		
+		TextArea textArea = new TextArea();
+		Button cancelButton = new Button("Cancel");
+		cancelButton.setAlignment(Pos.TOP_LEFT);
+		cancelButton.setOnAction(e -> {
+			popupStage.hide();
+		});
+		Button loadButton = new Button("Load");
+		loadButton.setAlignment(Pos.TOP_RIGHT);
+		loadButton.setOnAction(e -> {
+			String[] lines = textArea.getText().split("\n");
+			for (String line : lines) {
+				if (!line.equals(null) && !line.equals("")) {
+					createNewCage(line);
+				}
+			}
+			popupStage.hide();
+		});
+		
+		hbox.getChildren().addAll(cancelButton, loadButton);
+		vbox.getChildren().addAll(textArea, hbox);
+		
+		popupStage.setScene(new Scene(vbox, 300, 300));
+		popupStage.show();
+	}
+	
 	private void showMistakesCheckEvent(CheckBox showMistakesCheck) {
+		if (!constraints.checked()) {
+			constraints.checkConstraints(0, 0, false);
+		}
 		showMistakes = showMistakesCheck.isSelected();
 		constraints.highlightCells(showMistakes);
+		Animation animation = new Animation();
+		animation.go();
 	}
 	
 	private void undoButtonClickEvent() {
@@ -351,8 +440,7 @@ public class Main extends Application {
 	private void stageWidthResizeEvent(Stage stage, GridPane gridPane) {
 		stage.widthProperty().addListener((obs, oldVal, newVal) -> {
 			if (newVal.doubleValue() < stage.getHeight())  {
-				isWider = false;
-				resizeGrid(gridPane.getLayoutX(), gridPane.getLayoutY(), gridPane.getWidth());
+				resizeGrid();
 			}
 		});
 	}
@@ -360,20 +448,21 @@ public class Main extends Application {
 	private void stageHeightResizeEvent(Stage stage, GridPane gridPane) {
 		stage.heightProperty().addListener((obs, oldVal, newVal) -> {
 			if (newVal.doubleValue() < stage.getWidth())  {
-				isWider = true;
-				resizeGrid(gridPane.getLayoutX(), gridPane.getLayoutY(), gridPane.getWidth());
+				resizeGrid();
 			}
 		});
 	}
 	
-	public void resizeGrid(double gridX, double gridY, double gridWidth) {
-		double newValue = isWider ? scene.getHeight() : scene.getWidth();
+	public void resizeGrid() {
+		double width = scene.getWidth() - 200;
+		double height = scene.getHeight() - 150;
+		double newValue = height < width ? height : width;
 		for (int i = 0; i < N; i++) {
 			for (int j = 0; j < N; j++) {
 				Rectangle rectangle = gridSquares[i*N + j].getRectangle();
-				rectangle.setWidth(newValue * GRID_PERCENTAGE / N);
-				rectangle.setHeight(newValue * GRID_PERCENTAGE  / N);
-				gridSquares[i*N + j].resizeLines(newValue * GRID_PERCENTAGE / N);
+				rectangle.setWidth(newValue / N);
+				rectangle.setHeight(newValue / N);
+				gridSquares[i*N + j].resizeLines(newValue / N);
 			}
 		}
 	}
@@ -417,25 +506,10 @@ public class Main extends Application {
 	private void clearButtonClickEvent(Button clearButton) {		
 		clearButton.setOnAction(e -> {
 			if (!lastOperationClear()) {
-				clearing = true;
-				Alert alert = new Alert(AlertType.CONFIRMATION);
-				alert.setContentText("Are you sure you wish to clear the board?");
-				alert.setTitle("Clearing Board.");
-				alert.showAndWait().ifPresent(type -> {
-					if (type == ButtonType.OK) {
-						for (TextField textField : gridNumbers) {
-							textField.setText("");
-						}
-						undoStack.push(new GameState(GameState.getCurrentGameState(gridNumbers)));
-					}
-				});;
-				clearing = false;
+				clearGridAlert();
 			}
 			else {
-				Alert alert = new Alert(AlertType.WARNING);
-				alert.setContentText("Nothing to clear on the board.");
-				alert.setTitle("Empty Board");
-				alert.showAndWait();
+				clearEmptyGridAlert();
 			}
 		});
 	}
@@ -467,12 +541,17 @@ public class Main extends Application {
 	@Override
 	public void start(Stage stage) throws Exception {
 		VBox vBox = new VBox();
-		scene = new Scene(vBox,500+50*N,500+50*N);
+		int width = 400 + 80 * N;
+		int height = 275 + 80 * N;
+		
+		scene = new Scene(vBox, width, height);
+		stage.setWidth(width);
+		stage.setHeight(height);
 		vBox.setSpacing(10);
 		vBox.setPadding(new Insets(20));
 		vBox.setAlignment(Pos.CENTER);
 		
-		GridPane gridPane = setupGrid();
+		GridPane gridPane = setupGrid(width - 200, height - 150);
 		undoStack.push(new GameState(GameState.getCurrentGameState(gridNumbers)));
 		
 		fontSize = 18;
@@ -484,6 +563,7 @@ public class Main extends Application {
 		HBox gridHBox = new HBox();
 		gridHBox.getChildren().addAll(fontSizeVBox, gridPane, numbersVBox);
 		gridHBox.setSpacing(20);
+		gridHBox.setAlignment(Pos.CENTER);
 		
 		HBox bottomHBox = setupBottomHBox();
 		
@@ -492,8 +572,8 @@ public class Main extends Application {
 		stageWidthResizeEvent(stage, gridPane);
 		stageHeightResizeEvent(stage, gridPane);
 		
-		stage.setMinWidth(500 + 50*N);
-		stage.setMinHeight(500 + 50*N);
+		stage.setMinWidth(width + 50);
+		stage.setMinHeight(height + 50);
 		stage.setScene(scene);
 		stage.setTitle("Mathdoku");
 		stage.show();