diff --git a/2x2.txt b/2x2.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a160185c2df92e92305178d0f72b5dda8c0744c8
--- /dev/null
+++ b/2x2.txt
@@ -0,0 +1,2 @@
+1 1
+5+ 2,3,4
\ No newline at end of file
diff --git a/3x3.txt b/3x3.txt
new file mode 100644
index 0000000000000000000000000000000000000000..012464937d16c14025f7339886f59cce3440a7be
--- /dev/null
+++ b/3x3.txt
@@ -0,0 +1,4 @@
+6x 1,4
+6+ 2,3,6
+3x 5,7,8
+2 9
\ No newline at end of file
diff --git a/4x4.txt b/4x4.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8786526d5a4a016490d15e5ce88ecf43f14e8173
--- /dev/null
+++ b/4x4.txt
@@ -0,0 +1,6 @@
+10+ 1,2,5
+4+ 3,7
+2÷ 4,8
+24x 6,10,11
+3x 9,13,14
+24x 12,15,16
\ No newline at end of file
diff --git a/4x4_divdiff.txt b/4x4_divdiff.txt
new file mode 100644
index 0000000000000000000000000000000000000000..4b8227d94525d03e0f38152bd39c3735326795f8
--- /dev/null
+++ b/4x4_divdiff.txt
@@ -0,0 +1,6 @@
+2 1
+72x 2,5,6,7
+2- 3,4,8
+2÷ 9,13,14
+3x 10,11
+24x 12,15,16
\ No newline at end of file
diff --git a/5x5.txt b/5x5.txt
new file mode 100644
index 0000000000000000000000000000000000000000..951031d2a080f52626dd8dbcfa449d19e58e9322
--- /dev/null
+++ b/5x5.txt
@@ -0,0 +1,10 @@
+9+ 1,6
+1- 2,7
+2- 3,4
+7+ 5,9,10,15
+4 8
+12x 11,16,17
+7+ 12,13
+9+ 14,18,19
+100x 20,24,25
+6+ 21,22,23
\ No newline at end of file
diff --git a/6x6.txt b/6x6.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9fb24595d59c25b1727e30f6f38f13dbf51b15e8
--- /dev/null
+++ b/6x6.txt
@@ -0,0 +1,15 @@
+48x 1,7,8,13
+11+ 2,3
+1- 4,5
+18x 6,12
+72x 9,15,16,21
+60x 10,11,17
+6x 14,20
+11+ 18,23,24
+7+ 19,25
+8x 22,27,28
+3 26
+13+ 29,34,35
+2÷ 30,36
+3 31
+9+ 32,33
\ No newline at end of file
diff --git a/7x7.txt b/7x7.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1cce2005cfbd3a09125b62d9465c5b5ad1d40565
--- /dev/null
+++ b/7x7.txt
@@ -0,0 +1,19 @@
+6x 1,2
+112x 3,9,10
+7 4
+18x 5,6,13
+13+ 7,14,21
+1- 8,15
+8+ 11,12
+18+ 16,22,23
+6+ 17,18,25
+3- 19,20
+20+ 24,30,31,32,38
+10+ 26,33,40
+4 27
+14+ 28,34,35
+10+ 29,36,37
+24x 39,45,46
+14+ 41,47,48
+12x 42,49
+7+ 43,44
\ No newline at end of file
diff --git a/8x8.txt b/8x8.txt
new file mode 100644
index 0000000000000000000000000000000000000000..31a103e70ec60587d3ee45a502196709cb6e4121
--- /dev/null
+++ b/8x8.txt
@@ -0,0 +1,24 @@
+8 1
+14x 2,10,11
+12x 3,4
+19+ 5,6,7,14
+2 8
+210x 9,17,18,25
+12x 12,19,20
+4 13
+480x 15,22,23,31
+192x 16,24,32
+432x 21,28,29,30,37
+12+ 26,27
+17+ 33,34,41
+70x 35,36,44
+8x 38,46
+10+ 39,40,48
+19+ 42,49,50,51
+8 43
+23+ 45,52,53,54
+2÷ 47,55
+35x 56,64
+3- 57,58
+14+ 59,60
+30x 61,62,63
diff --git a/__MACOSX/._2x2.txt b/__MACOSX/._2x2.txt
new file mode 100644
index 0000000000000000000000000000000000000000..42c46acfca90295772f380a3264d88bdf2e42cb0
Binary files /dev/null and b/__MACOSX/._2x2.txt differ
diff --git a/__MACOSX/._3x3.txt b/__MACOSX/._3x3.txt
new file mode 100644
index 0000000000000000000000000000000000000000..976d7f6e53b6a757e53b5b4952a34d6698f75863
Binary files /dev/null and b/__MACOSX/._3x3.txt differ
diff --git a/__MACOSX/._4x4.txt b/__MACOSX/._4x4.txt
new file mode 100644
index 0000000000000000000000000000000000000000..611c692c0f536f8ceea999f8ed3aeeecc69e2208
Binary files /dev/null and b/__MACOSX/._4x4.txt differ
diff --git a/__MACOSX/._4x4_divdiff.txt b/__MACOSX/._4x4_divdiff.txt
new file mode 100644
index 0000000000000000000000000000000000000000..68c0f7762cd46549970d8f898d057867dd145a99
Binary files /dev/null and b/__MACOSX/._4x4_divdiff.txt differ
diff --git a/__MACOSX/._5x5.txt b/__MACOSX/._5x5.txt
new file mode 100644
index 0000000000000000000000000000000000000000..363387bf316536769785f6e912114dec9e9a65b5
Binary files /dev/null and b/__MACOSX/._5x5.txt differ
diff --git a/__MACOSX/._6x6.txt b/__MACOSX/._6x6.txt
new file mode 100644
index 0000000000000000000000000000000000000000..31de9f1fb13e6e6a59b8a4dd8e39846abee3c039
Binary files /dev/null and b/__MACOSX/._6x6.txt differ
diff --git a/__MACOSX/._7x7.txt b/__MACOSX/._7x7.txt
new file mode 100644
index 0000000000000000000000000000000000000000..58a293503ed04e525ce76d5388b757152b36b595
Binary files /dev/null and b/__MACOSX/._7x7.txt differ
diff --git a/__MACOSX/._8x8.txt b/__MACOSX/._8x8.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e11d18f5c5c4ac57152a1a64e1fcca1c48663b56
Binary files /dev/null and b/__MACOSX/._8x8.txt differ
diff --git a/__MACOSX/._example.txt b/__MACOSX/._example.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d6d879cd142c9d26e6288a613b62f8fe7452201e
Binary files /dev/null and b/__MACOSX/._example.txt differ
diff --git a/bin/coursework/ConstraintsHandler.class b/bin/coursework/ConstraintsHandler.class
index 1dcc198f9f50cec7a6778bde2872599103f25065..7a534da6f3ea82d122bf6ef01a70e4d0fc5acff5 100644
Binary files a/bin/coursework/ConstraintsHandler.class and b/bin/coursework/ConstraintsHandler.class differ
diff --git a/bin/coursework/Main.class b/bin/coursework/Main.class
index ad335423a42f6e1153dad4b17f07b9fe36756ed1..027176c92ec43dbf9ae7bffae3c76c8e7c31dee8 100644
Binary files a/bin/coursework/Main.class and b/bin/coursework/Main.class differ
diff --git a/bin/coursework/Solver.class b/bin/coursework/Solver.class
deleted file mode 100644
index 3f53a100d0f959129e4ecbda2c6aa57da6713928..0000000000000000000000000000000000000000
Binary files a/bin/coursework/Solver.class and /dev/null differ
diff --git a/example.txt b/example.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6db4b916c980a4511611ff780330fba7f6c9114b
--- /dev/null
+++ b/example.txt
@@ -0,0 +1,15 @@
+11+ 1,7
+2÷ 2,3
+20x 4,10
+6x 5,6,12,18
+3- 8,9
+3÷ 11,17
+240x 13,14,19,20
+6x 15,16
+6x 21,27
+7+ 22,28,29
+30x 23,24
+6x 25,26
+9+ 30,36
+8+ 31,32,33
+2÷ 34,35
\ No newline at end of file
diff --git a/instructions.docx b/instructions.docx
new file mode 100644
index 0000000000000000000000000000000000000000..5522b0a58148cc3b040ad997a30b7500912f6c79
Binary files /dev/null and b/instructions.docx differ
diff --git a/src/coursework/ConstraintsHandler.java b/src/coursework/ConstraintsHandler.java
index 15940de690b36d17a30d556723c18decd200f44a..ba954505569fae9dfe71a0fef264a906c7289161 100644
--- a/src/coursework/ConstraintsHandler.java
+++ b/src/coursework/ConstraintsHandler.java
@@ -142,12 +142,12 @@ public class ConstraintsHandler {
 		}
 	}
 	
-	public void checkWinCondition() {
+	public boolean checkWinCondition() {
 		updateData();
 		if (checkCellsFull() && checkConstraintErrors()) {
-			Animation animation = new Animation();
-			animation.go();
+			return true;
 		}
+		return false;
 	}
 	
 	private boolean checkCellsFull() {
diff --git a/src/coursework/Main.java b/src/coursework/Main.java
index cbb2058f6cd7f649a7fd736bc0ea2ca6ed129dd6..21e2436f399655f00a2fa495fd24aead754ed7f9 100644
--- a/src/coursework/Main.java
+++ b/src/coursework/Main.java
@@ -22,12 +22,10 @@ import javafx.scene.control.ButtonType;
 import javafx.scene.control.CheckBox;
 import javafx.scene.control.Label;
 import javafx.scene.control.RadioButton;
-import javafx.scene.control.Slider;
 import javafx.scene.control.TextArea;
 import javafx.scene.control.TextField;
 import javafx.scene.control.ToggleGroup;
 import javafx.scene.input.MouseEvent;
-import javafx.scene.layout.BorderPane;
 import javafx.scene.layout.GridPane;
 import javafx.scene.layout.HBox;
 import javafx.scene.layout.Pane;
@@ -58,10 +56,10 @@ public class Main extends Application {
 	private static boolean clearing = false;
 	private static boolean undoing = false;
 	private int fontSize;
-	private ConstraintsHandler constraints = new ConstraintsHandler();
+	private static ConstraintsHandler constraints;
 	
-	private Stack<GameState> undoStack = new Stack<GameState>();
-	private Stack<GameState> redoStack = new Stack<GameState>();
+	private static Stack<GameState> undoStack;
+	private static Stack<GameState> redoStack;
 	
 	private Button undoButton;
 	private Button redoButton;
@@ -96,7 +94,7 @@ public class Main extends Application {
 	}
 	//
 	////////////////////////////////////////////////////////////////////////////////
-	private GridPane setupGrid(int width, int height) {
+	private GridPane setupGrid(double width, double height) {
 		GridPane gridPane = new GridPane();
 		gridPane.setAlignment(Pos.CENTER);
 		double value = width < height ? width : height;	
@@ -172,36 +170,38 @@ public class Main extends Application {
 
 	private HBox setupTopHBox() {
 		HBox topHBox = new HBox();
-		topHBox.setAlignment(Pos.BOTTOM_CENTER);
-		topHBox.setSpacing(10);
+		topHBox.setAlignment(Pos.BOTTOM_LEFT);
+		topHBox.setSpacing(6);
 		
 		Button loadGameFileButton = new Button("Load Game - File");
-		CheckBox showMistakesCheck = new CheckBox("Show mistakes");
-		showMistakesCheck.setMinWidth(showMistakesCheck.getPrefWidth());
-		if (showMistakes) {
-			showMistakesCheck.setSelected(true);
-		}
+		loadGameFileButton.setPrefWidth(140);
+		loadGameFileButton.setPrefHeight(30);
+		loadGameFileButton.setStyle("-fx-font-size:14px;");
+		
 		Button loadGameTextInputButton = new Button("Load Game - Text");
-		loadGameFileButton.setPrefWidth(120);
+		loadGameTextInputButton.setStyle("-fx-font-size:14px;");
 		loadGameTextInputButton.setPrefWidth(loadGameFileButton.getPrefWidth());
+		loadGameTextInputButton.setPrefHeight(loadGameFileButton.getPrefHeight());
 		
-		Button generateRandomGameButton = new Button("Generate Random\nGame");
-		generateRandomGameButton.setPrefWidth(loadGameFileButton.getPrefWidth());
-		generateRandomGameButton.setPrefHeight(60);
-		generateRandomGameButton.setStyle("-fx-text-alignment:center;");
+		Button generateRandomGameButton = new Button("Generate\nRandom Game");
+		generateRandomGameButton.setPrefWidth(loadGameFileButton.getPrefWidth() - 20);
+		generateRandomGameButton.setPrefHeight((loadGameFileButton.getPrefHeight() * 2) + 5);
+		generateRandomGameButton.setStyle("-fx-text-alignment:center; -fx-font-size:14px;");
 		
 		VBox leftVBox = new VBox();
 		leftVBox.setSpacing(5);
+		leftVBox.setAlignment(Pos.BOTTOM_CENTER);
 		leftVBox.getChildren().addAll(loadGameFileButton, loadGameTextInputButton);
 		
-//		VBox rightVBox = new VBox();
-//		rightVBox.setSpacing(5);
-//		rightVBox.getChildren().addAll(, generateRandomGameButton);
-//		
-		topHBox.getChildren().addAll(leftVBox, showMistakesCheck, generateRandomGameButton);
+		Button changeFontSizeButton = new Button("Font\nSize");
+		changeFontSizeButton.setStyle("-fx-font-size:14px; -fx-text-alignment: center;");
+		changeFontSizeButton.setPrefHeight((loadGameFileButton.getPrefHeight() * 2) + 5);
+		changeFontSizeButton.setPrefWidth(60);
 		
-		showMistakesCheck.selectedProperty().addListener((obs, oldVal, newVal) -> {
-			showMistakesCheckEvent(showMistakesCheck);
+		topHBox.getChildren().addAll(leftVBox, generateRandomGameButton, changeFontSizeButton);
+		
+		changeFontSizeButton.setOnAction(e -> {
+			changeFontSizePopup();
 		});
 		
 		loadGameFileButton.setOnAction(e -> {
@@ -226,7 +226,11 @@ public class Main extends Application {
 		}
 	}
 	
-	private HBox setupBottomHBox() {
+	private VBox setupBottomHBox() {
+		VBox vbox = new VBox();
+		vbox.setAlignment(Pos.CENTER);
+		vbox.setSpacing(10);
+		
 		HBox bottomHBox = new HBox();
 		bottomHBox.setSpacing(10);
 		bottomHBox.setAlignment(Pos.TOP_CENTER);
@@ -234,7 +238,9 @@ public class Main extends Application {
 //		undoButton = new Button("", new ImageView(new Image("file:Images/undo_icon.png")));
 //		redoButton = new Button("", new ImageView(new Image("file:Images/redo_icon.png")));
 		undoButton = new Button("Undo");
+		undoButton.setStyle("-fx-font-size:14px;");
 		redoButton = new Button("Redo");
+		redoButton.setStyle("-fx-font-size:14px;");
 		Button clearButton = new Button("Clear");
 		undoButton.setOnAction(e -> {
 			undoButtonClickEvent();
@@ -245,81 +251,151 @@ public class Main extends Application {
 		
 		undoButton.setDisable(true);
 		redoButton.setDisable(true);
-		clearButton.setPrefSize(100, 36);
-		undoButton.setPrefSize(80, 36);
-		redoButton.setPrefSize(80, 36);
+		clearButton.setStyle("-fx-font-size:14px;");
+		clearButton.setPrefWidth(100);
 		clearButtonClickEvent(clearButton);
 		
 		bottomHBox.getChildren().addAll(undoButton, clearButton, redoButton);
-		return bottomHBox;
+		
+		CheckBox showMistakesCheck = new CheckBox("Show mistakes");
+		showMistakesCheck.setMinWidth(showMistakesCheck.getPrefWidth());
+		showMistakesCheck.setStyle("-fx-font-size:14px;");
+		if (showMistakes) {
+			showMistakesCheck.setSelected(true);
+		}
+		
+		showMistakesCheck.selectedProperty().addListener((obs, oldVal, newVal) -> {
+			showMistakesCheckEvent(showMistakesCheck);
+		});
+		
+		vbox.getChildren().addAll(bottomHBox, showMistakesCheck);
+		
+		return vbox;
 	}
 	
 	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);
+//		Button balanceButtonTop = new Button("");
+//		balanceButtonTop.setPrefWidth(111);
+//		balanceButtonTop.setMinWidth(111);
+//		balanceButtonTop.setVisible(false);
+//		Button balanceButtonBottom = new Button("");
+//		balanceButtonBottom.setPrefWidth(111);
+//		balanceButtonBottom.setMinWidth(111);
+//		balanceButtonBottom.setVisible(false);
+		//vbox.getChildren().add(balanceButtonTop);
 		for (int i = 1; i <= N; i++)  {
 			Button button = new Button(i + "");
 			final double WIDTH = 50;
 			
 			button.setPrefSize(WIDTH, WIDTH);
 			button.setMaxSize(WIDTH, WIDTH);
-			button.setStyle("-fx-font-size:"+18+"pt");
+			button.setStyle("-fx-font-size:"+14+"pt");
 			button.setOnAction(e -> {
 				numbersButtonClickEvent(button);
 			});
 			vbox.getChildren().add(button);
 		}
-		vbox.getChildren().add(balanceButtonBottom);
-		vbox.setSpacing(10);
+		//vbox.getChildren().add(balanceButtonBottom);
+		vbox.setSpacing(5);
 		vbox.setAlignment(Pos.CENTER_LEFT);
-		vbox.setPadding(new Insets(10));
+		vbox.setPadding(new Insets(0));
 		return vbox;
 	}
 	
-	private VBox setupFontSizeHBox() {
-		VBox vbox = new VBox();	
-		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);
+	
+	private void changeFontSizePopup() {
+		Stage popupStage = new Stage();
+		popupStage.initModality(Modality.APPLICATION_MODAL);
+		popupStage.initOwner(stage);
+		
+		VBox vbox = new VBox();
+		
+		HBox hbox = new HBox();	
+		hbox.getChildren().addAll(
+				setupButton("Tiny", 10, 75, popupStage),
+				setupButton("Small", 14, 85, popupStage),
+				setupButton("Medium", 18, 95, popupStage),
+				setupButton("Large", 22, 105, popupStage),
+				setupButton("Huge", 26, 115, popupStage));
+		hbox.setSpacing(10);
+		hbox.setAlignment(Pos.CENTER);
+		
+		Label headingLabel = new Label("Select font size:");
+		headingLabel.setStyle("-fx-font-size: 18px;");
+		
 		vbox.setAlignment(Pos.CENTER);
-		vbox.setPadding(new Insets(10));
-		return vbox;
+		vbox.getChildren().addAll(headingLabel, hbox);
+		
+		
+		popupStage.setScene(new Scene(vbox, 550, 110));
+		popupStage.setTitle("Change font size");
+		popupStage.show();
 	}
 	
-	private Button setupButton(String name, int size, int width) {
+	private Button setupButton(String name, int size, int width, Stage popupStage) {
 		Button button = new Button(name);
 		button.setMinWidth(width);
 		button.setPrefWidth(width);
-		button.setStyle("-fx-font-size:" + size + "px;");
 		button.setOnAction(e -> {
-			changeFontSizeEvent(size);
+			changeFontSizeEvent(size, popupStage);
 		});
+		if (fontSize == size) {
+			button.setStyle("-fx-font-size:" + size + "px; -fx-background-color: #99ddff; -fx-border-color: grey; fx-border-width: 1px; -fx-border-radius:3px;");
+		}
+		else {
+			button.setStyle("-fx-font-size:" + size + "px;");
+		}
 		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.length < 2) {
+			Alert alert = new Alert(AlertType.WARNING);
+			alert.setContentText("The puzzle you have attempted to load is not in the correct format, please try again.");
+			alert.setTitle("Incorrect Format");
+			alert.showAndWait();
+			return;
 		}
 		
-		if (splitLine[0].contains("÷") || splitLine[0].contains("/")) {
-			splitLine[0] = splitLine[0].replace("÷", "�");
-		}
+		int[] ids;
+		int value;
+		String operator;
 		
-		int value = Integer.parseInt(splitLine[0].substring(0, splitLine[0].length()- 1));
-		String operator = splitLine[0].substring(splitLine[0].length() - 1);
+		if (splitLine[1].contains(",")) {
+			String[] shiftedIds = splitLine[1].split(",");
+			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("÷", "�");
+			}
+			
+			value = Integer.parseInt(splitLine[0].substring(0, splitLine[0].length()- 1));
+			operator = splitLine[0].substring(splitLine[0].length() - 1);
+		}
+		else {
+			ids = new int[1];
+			ids[0] = Integer.parseInt(splitLine[1]) - 1;
+			value = Integer.parseInt(splitLine[0]);
+			operator = "";
+		}
 		
 		Cage cage = new Cage(ids, value, operator);
 		gridCages.add(cage);
+		
+		System.out.print(value + operator + " ");
+		for (int i = 0; i < ids.length; i++) {
+			System.out.print(ids[i] + 1);
+			if (i < ids.length - 1) {
+				System.out.print(",");
+			}
+		}
+		System.out.print("\n");
 	}
 	
 	
@@ -354,22 +430,7 @@ public class Main extends Application {
 			}
 		}
 	}
-	
-	private Slider setupSlider() {
-		Slider slider = new Slider(2,8,1);
-		slider.setPrefWidth(150);
-		slider.setMaxWidth(150);
-		slider.setShowTickLabels(true);
-		slider.setShowTickMarks(true);
-		slider.setMinorTickCount(0);
-		slider.setMajorTickUnit(1);
-		slider.setBlockIncrement(1);
-		slider.setSnapToTicks(true);
-		slider.setValue(N);
-		slider.setPadding(new Insets(10, 0, 0, 0));
-		return slider;
-	}
-	
+		
 	///////////////////////////////////////////////////////////
 	private void generateRandomGameEvent() {
 		Stage popupStage = new Stage();
@@ -381,10 +442,10 @@ public class Main extends Application {
 		vbox.setAlignment(Pos.TOP_CENTER);
 		
 		HBox hboxBottom = new HBox();
-		hboxBottom.setSpacing(86);
+		hboxBottom.setSpacing(100);
 		hboxBottom.setPadding(new Insets(10));
 		
-		Slider slider = setupSlider();
+		TextField textField = new TextField();		
 		
 		Button generateButton = new Button("Generate");
 		generateButton.setAlignment(Pos.TOP_RIGHT);
@@ -395,7 +456,7 @@ public class Main extends Application {
 			popupStage.hide();
 		});
 		
-		HBox hboxTop = new HBox(new Label("Size (NxN):"), slider);
+		HBox hboxTop = new HBox(new Label("Size (NxN):"), textField);
 		hboxTop.setSpacing(3);
 		hboxTop.setAlignment(Pos.CENTER);
 		
@@ -414,30 +475,51 @@ public class Main extends Application {
 		hboxMiddle.getChildren().addAll(new Label("Difficulty:"), radioVBox);
 		
 		hboxBottom.getChildren().addAll(cancelButton, generateButton);
+		hboxBottom.setAlignment(Pos.CENTER);
 		vbox.getChildren().addAll(hboxTop, hboxMiddle, hboxBottom);
+		vbox.setAlignment(Pos.CENTER);
 		
 		generateButton.setOnAction(e -> {
-			popupStage.close();
-			N = (int) slider.getValue();
-			resetGrid();
-			int difficulty;
-			if (easy.isSelected()) {
-				difficulty = 1;
+			int textFieldValue = - 1;
+			try {
+				textFieldValue = Integer.parseInt(textField.getText());
 			}
-			else if (medium.isSelected()) {
-				difficulty = 2;
+			catch (NumberFormatException ex) {
+				Alert alert = new Alert(AlertType.WARNING);
+				alert.setContentText("The value for the board size to generate a puzzel is not valid, please try again.");
+				alert.setTitle("File Not Found");
+				alert.showAndWait();
 			}
-			else if (hard.isSelected()) {
-				difficulty = 3;
+			if (textFieldValue > 0 && textFieldValue <= 10) {
+				N = textFieldValue;
+				popupStage.close();
+				resetGrid();
+				int difficulty;
+				if (easy.isSelected()) {
+					difficulty = 1;
+				}
+				else if (medium.isSelected()) {
+					difficulty = 2;
+				}
+				else if (hard.isSelected()) {
+					difficulty = 3;
+				}
+				else {
+					difficulty = 2;
+				}
+				RandomGenerator rg = new RandomGenerator(N, difficulty);
+				gridCages = rg.generate();
 			}
-			else {
-				difficulty = 2;
+			if (textFieldValue > 10) {
+				Alert alert = new Alert(AlertType.INFORMATION);
+				alert.setContentText("The maximum size is 10.");
+				alert.setTitle("Size Too Large");
+				alert.showAndWait();
 			}
-			RandomGenerator rg = new RandomGenerator(N, difficulty);
-			gridCages = rg.generate();	
 		});
-		
-		popupStage.setScene(new Scene(vbox, 240, 170));
+		popupStage.setMinHeight(200);
+		popupStage.setMinWidth(255);
+		popupStage.setScene(new Scene(vbox, 240, 160));
 		popupStage.show();
 	}
 	
@@ -452,34 +534,66 @@ public class Main extends Application {
 			List<String> fileLines = file.lines().collect(Collectors.toList());
 			int max = -1;
 			for (String line : fileLines) {
-				String[] rightHalfLine = line.split(" ")[1].split(",");
-				int[] lineIds = new int[rightHalfLine.length];
-				for (int i = 0; i < lineIds.length; i++) {
-					lineIds[i] = Integer.parseInt(rightHalfLine[i]);
-					if (lineIds[i] > max) {
-						max = lineIds[i];
+				if (line.split(" ")[1].contains(",")) {
+					String[] rightHalfLine = line.split(" ")[1].split(",");
+					int[] lineIds = new int[rightHalfLine.length];
+					for (int i = 0; i < lineIds.length; i++) {
+						lineIds[i] = Integer.parseInt(rightHalfLine[i]);
+						if (lineIds[i] > max) {
+							max = lineIds[i];
+						}
+					}
+				}
+				else {
+					int value = Integer.parseInt(line.split(" ")[1]);
+					if (value > max) {
+						max = value;
 					}
 				}
 			}
 			
-			if (Math.sqrt(max) != N) {
+			if (Math.sqrt(max) != N && Math.sqrt(max) <= 10) {
 				N = (int) Math.sqrt(max);
 				resetGrid();
 			}
 			
-			
-			for (String line : fileLines) {
-				createNewCage(line);
+			if (Math.sqrt(max) > 10) {
+				Alert alert = new Alert(AlertType.INFORMATION);
+				alert.setContentText("The maximum size is 10.");
+				alert.setTitle("Size Too Large");
+				alert.showAndWait();
+			}
+			else {
+				for (String line : fileLines) {
+					createNewCage(line);
+				}
+				file.close();
 			}
-			file.close();
 		}
 		catch (FileNotFoundException e1) {
-			e1.printStackTrace();
+			Alert alert = new Alert(AlertType.WARNING);
+			alert.setContentText("The file you have selected cannot be found, please try again.");
+			alert.setTitle("File Not Found");
+			alert.showAndWait();
 		}
 		catch (IOException e2) {
-			e2.printStackTrace();
+			Alert alert = new Alert(AlertType.WARNING);
+			alert.setContentText("An error has occured when loading the file, please try again.");
+			alert.setTitle("File Loading Error");
+			alert.showAndWait();
+		}
+		catch (NullPointerException e3) {
+			Alert alert = new Alert(AlertType.WARNING);
+			alert.setContentText("You have not selected a file, please try again.");
+			alert.setTitle("No File Selected");
+			alert.showAndWait();
+		}
+		catch (NumberFormatException e4) {
+			Alert alert = new Alert(AlertType.WARNING);
+			alert.setContentText("The file you have selected is not in the correct format of a Mathdoku puzzle, please try again.");
+			alert.setTitle("Incorrect File Format");
+			alert.showAndWait();
 		}
-		catch (NullPointerException e3) {}
 		
 	}
 	
@@ -493,15 +607,13 @@ public class Main extends Application {
 		vbox.setSpacing(5);
 		
 		HBox hboxBottom = new HBox();
-		hboxBottom.setSpacing(163);
+		hboxBottom.setSpacing(186);
 		
 		
 		HBox hboxTop = new HBox();
 		hboxTop.setSpacing(5);
 		hboxTop.setAlignment(Pos.CENTER);
 		
-		Slider slider = setupSlider();
-		
 		TextArea textArea = new TextArea();
 		Button cancelButton = new Button("Cancel");
 		cancelButton.setAlignment(Pos.TOP_LEFT);
@@ -511,25 +623,63 @@ public class Main extends Application {
 		Button loadButton = new Button("Load");
 		loadButton.setAlignment(Pos.TOP_RIGHT);
 		loadButton.setOnAction(e -> {
-			if ((int) slider.getValue() != N) {
-				N = (int) slider.getValue();
-				resetGrid();
-			}
-			String[] lines = textArea.getText().split("\n");
-			for (String line : lines) {
-				if (!line.equals(null) && !line.equals("")) {
-					createNewCage(line);
+			try {
+				String[] lines = textArea.getText().split("\n");
+				int max = -1;
+				for (String line : lines) {
+					if (line.split(" ")[1].contains(",")) {
+						String[] rightHalfLine = line.split(" ")[1].split(",");
+						int[] lineIds = new int[rightHalfLine.length];
+						for (int i = 0; i < lineIds.length; i++) {
+							lineIds[i] = Integer.parseInt(rightHalfLine[i]);
+							if (lineIds[i] > max) {
+								max = lineIds[i];
+							}
+						}
+					}
+					else {
+						int value = Integer.parseInt(line.split(" ")[1]);
+						if (value > max) {
+							max = value;
+						}
+					}
+				}
+				
+				if (Math.sqrt(max) != N && Math.sqrt(max) <= 10) {
+					N = (int) Math.sqrt(max);
+					resetGrid();
+				}
+				
+				if (Math.sqrt(max) > 10) {
+					Alert alert = new Alert(AlertType.INFORMATION);
+					alert.setContentText("The maximum size is 10.");
+					alert.setTitle("Size Too Large");
+					alert.showAndWait();
+				}
+				else {
+					for (String line : lines) {
+						if (!line.equals(null) && !line.equals("")) {
+							createNewCage(line);
+						}
+					}
+					popupStage.hide();
 				}
 			}
-			popupStage.hide();
+			catch (NumberFormatException e4) {
+				Alert alert = new Alert(AlertType.WARNING);
+				alert.setContentText("The file you have selected is not in the correct format of a Mathdoku puzzle, please try again.");
+				alert.setTitle("Incorrect File Format");
+				alert.showAndWait();
+				popupStage.hide();
+			}
 		});
 		
-		Label sizeLabel = new Label("Size (NxN):");
-		hboxTop.getChildren().addAll(sizeLabel, slider);
 		hboxBottom.getChildren().addAll(cancelButton, loadButton);
-		vbox.getChildren().addAll(hboxTop, textArea, hboxBottom);
+		vbox.getChildren().addAll(textArea, hboxBottom);
 		
-		popupStage.setScene(new Scene(vbox, 300, 300));
+		popupStage.setScene(new Scene(vbox, 300, 200));
+		popupStage.setMinHeight(220);
+		popupStage.setMinWidth(300);
 		popupStage.show();
 	}
 	
@@ -568,7 +718,7 @@ public class Main extends Application {
 		}
 	}
 	
-	private void numbersButtonClickEvent(Button button) {
+	private void numbersButtonClickEvent(Button button) {	
 		if (previousSquare != null) {
 			for (int i = 0; i < gridSquares.length; i++) {
 				if (previousSquare.equals(gridSquares[i])) {
@@ -578,7 +728,7 @@ public class Main extends Application {
 		}
 	}
 	
-	private void changeFontSizeEvent(int size) {
+	private void changeFontSizeEvent(int size, Stage popupStage) {
 		fontSize = size;
 		for (TextField textField : gridNumbers) {
 			textField.setStyle("-fx-focus-color: transparent; -fx-text-box-border: transparent;"
@@ -588,11 +738,14 @@ public class Main extends Application {
 		for (Label label : cageLabels) {
 			label.setStyle("-fx-font-size:" + size*0.9 + ";");
 		}
+		if (popupStage != null) {
+			popupStage.close();
+		}
 	}
 	
 	private void stageWidthResizeEvent(Stage stage, GridPane gridPane) {
 		stage.widthProperty().addListener((obs, oldVal, newVal) -> {
-			if (newVal.doubleValue() < stage.getHeight())  {
+			if (newVal.doubleValue() - 0 < stage.getHeight())  {
 				resizeGrid();
 			}
 		});
@@ -600,16 +753,16 @@ public class Main extends Application {
 	
 	private void stageHeightResizeEvent(Stage stage, GridPane gridPane) {
 		stage.heightProperty().addListener((obs, oldVal, newVal) -> {
-			if (newVal.doubleValue() < stage.getWidth())  {
+			if (newVal.doubleValue() < stage.getWidth() - 0)  {
 				resizeGrid();
 			}
 		});
 	}
 	
 	public void resizeGrid() {
-		double width = scene.getWidth() - 200;
-		double height = scene.getHeight() - 150;
-		double newValue = height < width ? height : width;
+		double width = scene.getWidth() - 170;
+		double height = scene.getHeight() - 170;
+		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();
@@ -700,7 +853,10 @@ public class Main extends Application {
 			}
 		}
 		constraints.checkConstraints(j, i, showMistakes);;
-		constraints.checkWinCondition();
+		if (constraints.checkWinCondition()) {
+			Animation animation = new Animation();
+			animation.go();
+		}
 	}
 	
 	private boolean lastOperationClear() {
@@ -719,37 +875,40 @@ public class Main extends Application {
 	@Override
 	public void start(Stage primaryStage) throws Exception {
 		stage = primaryStage;
-		BorderPane borderPane = new BorderPane();
-		int width = 350 + 80 * N;
-		int height = 275 + 80 * N;
-		
-		scene = new Scene(borderPane, width, height);
-		stage.setWidth(width);
-		stage.setHeight(height);
-		borderPane.setPadding(new Insets(20));
 		
-		GridPane gridPane = setupGrid(width - 200, height - 175);
-		undoStack.push(new GameState(GameState.getCurrentGameState(gridNumbers)));
+		GridPane gridPane = new GridPane();
+		int size = N*80;
+		int extraWidth = 170;
+		int extraHeight = 170;
 		
-		fontSize = 18;
-		changeFontSizeEvent(fontSize);
+		scene = new Scene(gridPane, size, size);
+		stage.setWidth(size + extraWidth);
+		stage.setHeight(size + extraHeight);
+		gridPane.setPadding(new Insets(20));
 		
 		HBox topHBox = setupTopHBox();
-		VBox fontSizeVBox = setupFontSizeHBox();
 		VBox numbersVBox = setupNumbersVBox();
-		HBox bottomHBox = setupBottomHBox();
+		VBox bottomHBox = setupBottomHBox();
+		GridPane puzzleGrid = setupGrid(size, size);
+		undoStack.push(new GameState(GameState.getCurrentGameState(gridNumbers)));
+		
+		fontSize = 18;
+		changeFontSizeEvent(fontSize, null);
 		
-		borderPane.setTop(topHBox);
-		borderPane.setLeft(fontSizeVBox);
-		borderPane.setRight(numbersVBox);
-		borderPane.setBottom(bottomHBox);
-		borderPane.setCenter(gridPane);
+		gridPane.add(topHBox, 0, 0, 2, 1);
+		gridPane.add(puzzleGrid, 0, 1);
+		gridPane.add(numbersVBox, 1, 1);
+		gridPane.add(bottomHBox, 0, 2);
 		
-		stageWidthResizeEvent(stage, gridPane);
-		stageHeightResizeEvent(stage, gridPane);
+		gridPane.setVgap(10);
+		gridPane.setHgap(10);
+		gridPane.setAlignment(Pos.CENTER);
+			
+		stageWidthResizeEvent(stage, puzzleGrid);
+		stageHeightResizeEvent(stage, puzzleGrid);
 		
-		stage.setMinWidth(width + 50);
-		stage.setMinHeight(height + 50);
+		stage.setMinWidth(size + extraWidth + 50);
+		stage.setMinHeight(size + extraHeight + 50);
 		stage.setScene(scene);
 		stage.setTitle("Mathdoku");
 		stage.show();
@@ -759,38 +918,48 @@ public class Main extends Application {
 	private void resetGrid() {
 		stage.close();
 		initialiseVariables();
-		BorderPane borderPane = new BorderPane();;
-		int width = 350 + 80 * N;
-		int height = 275 + 80 * N;
+		GridPane gridPane = new GridPane();;
 		
-		Stage newStage = new Stage();
-		Scene newScene = new Scene(borderPane, width, height);
-		newStage.setWidth(width);
-		newStage.setHeight(height);
-		borderPane.setPadding(new Insets(20));
+		int size = N*80;
+		int extraWidth = 170;
+		int extraHeight = 170;
 		
-		GridPane gridPane = setupGrid(width - 200, height - 175);
-		undoStack.push(new GameState(GameState.getCurrentGameState(gridNumbers)));
+		if (N*80 + extraHeight + 50 > 1000) {
+			System.out.println("Here");
+			size = (1000 - extraHeight);
+		}
 		
-		fontSize = 18;
-		changeFontSizeEvent(fontSize);
+		Stage newStage = new Stage();
+		Scene newScene = new Scene(gridPane, size + extraWidth, size + extraHeight);
+		newStage.setWidth(size + extraWidth + 50);
+		newStage.setHeight(size + extraHeight + 50);
+		gridPane.setPadding(new Insets(20));
 		
 		HBox topHBox = setupTopHBox();
-		VBox fontSizeVBox = setupFontSizeHBox();
 		VBox numbersVBox = setupNumbersVBox();
-		HBox bottomHBox = setupBottomHBox();
+		VBox bottomHBox = setupBottomHBox();
+		GridPane puzzleGrid = setupGrid(size, size);
+		undoStack.push(new GameState(GameState.getCurrentGameState(gridNumbers)));
+
+		fontSize = 18;
+		changeFontSizeEvent(fontSize, null);
+		
+		gridPane.add(topHBox, 0, 0, 2, 1);
+		gridPane.add(puzzleGrid, 0, 1);
+		gridPane.add(numbersVBox, 1, 1);
+		gridPane.add(bottomHBox, 0, 2);
 		
-		borderPane.setTop(topHBox);
-		borderPane.setLeft(fontSizeVBox);
-		borderPane.setRight(numbersVBox);
-		borderPane.setBottom(bottomHBox);
-		borderPane.setCenter(gridPane);
+		gridPane.setVgap(10);
+		gridPane.setHgap(10);
+		gridPane.setAlignment(Pos.CENTER);
 		
-		stageWidthResizeEvent(stage, gridPane);
-		stageHeightResizeEvent(stage, gridPane);
+		stageWidthResizeEvent(stage, puzzleGrid);
+		stageHeightResizeEvent(stage, puzzleGrid);
 		
-		newStage.setMinWidth(width + 50);
-		newStage.setMinHeight(height + 50);
+		newStage.setMinWidth(size + extraWidth + 50);
+		newStage.setMinHeight(size + extraHeight + 50);
+		newStage.setMaxHeight(1000);
+		newStage.setMaxWidth(1200);
 		newStage.setScene(newScene);
 		newStage.setTitle("Mathdoku");
 		newStage.show();
@@ -810,6 +979,9 @@ public class Main extends Application {
 		previousSquare = null;
 		clearing = false;
 		undoing = false;
+		undoStack = new Stack<GameState>();
+		redoStack = new Stack<GameState>();
+		constraints = new ConstraintsHandler();
 	}
 	
 	public static void main(String[] args) {
diff --git a/src/coursework/RandomGenerator.java b/src/coursework/RandomGenerator.java
index 7cda69ebd543949d71d4f200bb85769e0f4dbeee..6bc89c91a9f612799af81a069ca263a55387844d 100644
--- a/src/coursework/RandomGenerator.java
+++ b/src/coursework/RandomGenerator.java
@@ -411,14 +411,4 @@ public class RandomGenerator {
 		grid = temp;
 	}
 
-//	private void output() {
-//		for (int i = 0; i < N; i++) {
-//			for (int j = 0; j < N; j++) {
-//				System.out.print(grid[i][j] + " ");
-//			}
-//			System.out.print("\n");
-//		}
-//		System.out.print("\n");
-//	}
-
 }
\ No newline at end of file
diff --git a/src/coursework/Solver.java b/src/coursework/Solver.java
deleted file mode 100644
index 58b843f9e47fbdcddccce64e0e322a7954f0edb9..0000000000000000000000000000000000000000
--- a/src/coursework/Solver.java
+++ /dev/null
@@ -1,137 +0,0 @@
-package coursework;
-
-import java.util.List;
-
-public class Solver {
-
-	private int N;
-	private int[][] gridValues;	// -1 = not possible | 1 = possible | 2 = definite
-	private List<Cage> gridCages;
-	
-	public Solver(int N, List<Cage> gridCages) {
-		this.N = N;
-		this.gridCages = gridCages;
-		gridValues = new int[N*N][N];
-	}
-
-	public void solvePuzzel() {
-		setDefaultValues();
-		output();
-		checkCageValues();
-	}
-	
-	private void setDefaultValues() {
-		for (int i = 0; i < N*N; i++) {
-			for (int j = 0; j < N; j++) {
-				gridValues[i][j] = 1;	// sets all values to possible
-			}
-		}
-	}
-	
-	private void checkCageValues() {
-		for (Cage cage : gridCages) {
-			int cageValue = cage.getCageValue();
-			int length = cage.getCageIds().length;
-			
-			if (length == 1) {
-				gridValues[cage.getCageIds()[0]][cageValue - 1] = 2;
-				removePossibleValue(cage.getCageIds()[0], cageValue);
-			}
-			else {
-				String operator = cage.getCageOperator();
-				int counter = 1;
-				switch (operator) {
-				case "+":
-					int[] possibleValues = new int[length];
-					for (int i = 0; i < length; i++) {
-						possibleValues[i] = 1;
-					}
-					
-					while (valuesMultiplied(possibleValues) < Math.pow(N, length)) {
-						if (sumOfValues(possibleValues, cageValue)) {
-							for (int possibleVal : possibleValues) {
-								for (int id : cage.getCageIds()) {
-									gridValues[id][possibleVal - 1] = 1;
-								}
-							}
-						}
-						
-						
-						for (int j = 1; j <= counter; j++) {
-							
-							if (possibleValues[possibleValues.length - counter] == N) {
-								possibleValues[possibleValues.length - counter] = 0;
-								possibleValues[possibleValues.length - 2] += 1;
-								counter += 1;
-							}
-						
-						}
-
-						
-						
-
-					}
-
-					break;
-				case "-":
-					
-					break;
-				case "x":
-					
-					break;
-				case "�":
-				
-					break;
-				}
-			}
-		}
-	}
-	
-	private boolean sumOfValues(int[] values, int cageValue) {
-		int sum = 0;
-		for (int value : values) {
-			sum += value;
-		}
-		return sum == cageValue;
-	}
-	
-	private int valuesMultiplied(int[] values) {
-		int result = 1;
-		for (int value : values) {
-			result *= value;
-		}
-		return result;
-	}
-	
-	private void removePossibleValue(int id, int cageValue) {
-		int row = (int) id / N;
-		int col = id % N;
-		
-		for (int i = 0; i < N; i++) {
-			if (i != col)
-				gridValues[row*N + i][cageValue - 1] = -1;
-		}
-		for (int i = 0; i < N; i++) {
-			if (i != row)
-				gridValues[i*N + col][cageValue - 1] = -1;
-		}
-		for (int i = 0; i < N; i++) {
-			if (i != cageValue - 1)
-				gridValues[id][i] = -1;
-		}
-	}
-	
-	private void output() {
-		for (int i = 0; i < N; i++) {
-			for (int j = 0; j < N; j++) {
-				System.out.print("[");
-				for (int k = 0; k < N; k++) {
-					System.out.print(gridValues[i*N + j][k]);
-					System.out.print(",");
-				}
-				System.out.print("], ");
-			}
-			System.out.print("\n");
-		}
-	}
-}