diff --git a/bin/coursework/Animation.class b/bin/coursework/Animation.class
index c2bb568060dfc33acfe2ac65225322cbbea49b6d..4d61f7b250ee2567433b3817e00f91bddb71c632 100644
Binary files a/bin/coursework/Animation.class and b/bin/coursework/Animation.class differ
diff --git a/bin/coursework/Cage.class b/bin/coursework/Cage.class
index 052d4186f6d4b83626024f7aaf7222bdaceaa13a..4e07610a39165c13072741687aa69b631c7d6493 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 bade47a38ad4369566460ba344b569c3d12da6f3..1dcc198f9f50cec7a6778bde2872599103f25065 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 8027a7087fee2b670d9c16a28a14d56c83fb11eb..f2191bde75af2628511e506635f2c9a30ca52de6 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 5b83beb2a97814918f935971184bb5dd7dce3c19..91322a5f64f24da6b9668f57097e6994f74b2337 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
index f3e9c9b44a6cbc4b6d9d43a10d722dd4c9a9a174..c1f8c7df3862f7d63960105732c11aa952e0845f 100644
--- a/src/coursework/Animation.java
+++ b/src/coursework/Animation.java
@@ -11,6 +11,7 @@ import javafx.util.Duration;
 
 public class Animation {
 
+	private int N;
 	private VBox[] gridBoxes;
 	private String[] colors = {"#FF0000", "#FF7F00", "#FFFF00", "#00FF00", "#00FFFF", "#0000FF", "#462370", "#7F00FF", "rgba(255,0,0,0)"};
 	private Integer[] indexArray;
@@ -21,6 +22,7 @@ public class Animation {
 
 	public Animation() {
 		gridBoxes = Main.getGridBoxes();
+		N = Main.getN();
 	}
 	
 	public void go() {
@@ -30,7 +32,7 @@ public class Animation {
 			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) {
+						if (indexArray[index - j] >= 0 && indexArray[index] - j <= N*N) {
 							gridBoxes[indexArray[index - j]].setStyle("-fx-background-color:"+colors[j]+";");
 						}
 					}
@@ -44,15 +46,15 @@ public class Animation {
 				count++;
 			}
 			if (count == 9) {
-				if (Main.N % 2 == 0  && colorIndex % 2 == 0 && colorIndex < 23 ) {
+				if (N % 2 == 0  && colorIndex % 2 == 0 && colorIndex < 23 ) {
 					//even
-					int maxCentre = Main.N / 2;
+					int maxCentre = 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 topLeft = (minCentre * N) + minCentre;
+					int topRight = (minCentre * N) + maxCentre;
+					int botLeft = (maxCentre * N) + minCentre;
+					int botRight = (maxCentre * N + maxCentre);
 					int[] gridIndicies = { topLeft, topRight, botLeft, botRight };
 					
 					if (colorIndex/2 < colors.length) {
@@ -60,37 +62,37 @@ public class Animation {
 							gridBoxes[gridIndex].setStyle("-fx-background-color:"+colors[colorIndex/2]+";");
 						}
 					}
-					if (colorIndex/2 - 1 > 0 && colorIndex/2 < colors.length + 1 && Main.N > 2) {						
-						int[] ringCombinations1 = {1, Main.N + 1, Main.N};
+					if (colorIndex/2 - 1 > 0 && colorIndex/2 < colors.length + 1 && N > 2) {						
+						int[] ringCombinations1 = {1, N + 1, N};
 						for (int ringVal : ringCombinations1) {
 							gridBoxes[botRight + ringVal].setStyle("-fx-background-color:"+colors[colorIndex/2 - 1]+";");
 							gridBoxes[topLeft - ringVal].setStyle("-fx-background-color:"+colors[colorIndex/2 - 1]+";");
 						}
-						int[] ringCombinations2 = {- 1, Main.N - 1, Main.N};
+						int[] ringCombinations2 = {- 1, N - 1, N};
 						for (int ringVal : ringCombinations2) {
 							gridBoxes[botLeft + ringVal].setStyle("-fx-background-color:"+colors[colorIndex/2 - 1]+";");
 							gridBoxes[topRight - ringVal].setStyle("-fx-background-color:"+colors[colorIndex/2 - 1]+";");
 						}
 					}
-					if (colorIndex/2 - 2 > 0 && colorIndex/2 < colors.length + 2 && Main.N > 4) {
-						int[] ringCombinations1 = {2, Main.N + 2, 2*Main.N + 2, 2*Main.N + 1, 2*Main.N};
+					if (colorIndex/2 - 2 > 0 && colorIndex/2 < colors.length + 2 && N > 4) {
+						int[] ringCombinations1 = {2, N + 2, 2*N + 2, 2*N + 1, 2*N};
 						for (int ringVal : ringCombinations1) {
 							gridBoxes[botRight + ringVal].setStyle("-fx-background-color:"+colors[colorIndex/2 - 2]+";");
 							gridBoxes[topLeft - ringVal].setStyle("-fx-background-color:"+colors[colorIndex/2 - 2]+";");
 						}
-						int[] ringCombinations2 = {- 2, Main.N - 2, 2*Main.N - 2, 2*Main.N - 1, 2*Main.N};
+						int[] ringCombinations2 = {- 2, N - 2, 2*N - 2, 2*N - 1, 2*N};
 						for (int ringVal : ringCombinations2) {
 							gridBoxes[botLeft + ringVal].setStyle("-fx-background-color:"+colors[colorIndex/2 - 2]+";");
 							gridBoxes[topRight - ringVal].setStyle("-fx-background-color:"+colors[colorIndex/2 - 2]+";");
 						}
 					}
-					if (colorIndex/2 - 3 > 0 && colorIndex/2 < colors.length + 3 && Main.N > 6) {
-						int[] ringCombinations1 = {3, Main.N + 3, 2*Main.N + 3, 3*Main.N + 3, 3*Main.N + 2, 3*Main.N + 1, 3*Main.N};
+					if (colorIndex/2 - 3 > 0 && colorIndex/2 < colors.length + 3 && N > 6) {
+						int[] ringCombinations1 = {3, N + 3, 2*N + 3, 3*N + 3, 3*N + 2, 3*N + 1, 3*N};
 						for (int ringVal : ringCombinations1) {
 							gridBoxes[botRight + ringVal].setStyle("-fx-background-color:"+colors[colorIndex/2 - 3]+";");
 							gridBoxes[topLeft - ringVal].setStyle("-fx-background-color:"+colors[colorIndex/2 - 3]+";");
 						}
-						int[] ringCombinations2 = {- 3, Main.N - 3, 2*Main.N - 3, 3*Main.N - 3, 3*Main.N - 2, 3*Main.N - 1, 3*Main.N};
+						int[] ringCombinations2 = {- 3, N - 3, 2*N - 3, 3*N - 3, 3*N - 2, 3*N - 1, 3*N};
 						for (int ringVal : ringCombinations2) {
 							gridBoxes[botLeft + ringVal].setStyle("-fx-background-color:"+colors[colorIndex/2 - 3]+";");
 							gridBoxes[topRight - ringVal].setStyle("-fx-background-color:"+colors[colorIndex/2 - 3]+";");
@@ -100,29 +102,29 @@ public class Animation {
 				}
 				else if (colorIndex % 2 == 0) {
 					//odd 
-					int centrePoint = (Main.N - 1) / 2;
-					int centre = (centrePoint * Main.N) + centrePoint;
+					int centrePoint = (N - 1) / 2;
+					int centre = (centrePoint * N) + centrePoint;
 					
 					if (colorIndex/2 < colors.length) {
 						gridBoxes[centre].setStyle("-fx-background-color:"+colors[colorIndex/2]+";");
 					}
 					
 					if (colorIndex/2 - 1 > 0 && colorIndex/2 < colors.length + 1) {
-						int[] firstRing = {- 1 - Main.N, - Main.N, 1 - Main.N, - 1, + 1, - 1 + Main.N, Main.N, 1 + Main.N };
+						int[] firstRing = {- 1 - N, - N, 1 - N, - 1, + 1, - 1 + N, N, 1 + N };
 						for (int ringVal : firstRing) {
 							gridBoxes[centre + ringVal].setStyle("-fx-background-color:"+colors[colorIndex/2 - 1]+";");
 						}
 					}
-					if (colorIndex/2 - 2 > 0 && colorIndex/2 < colors.length + 2 && Main.N > 3) {
-						int[] secondRing = { -2*Main.N - 2, - 2*Main.N - 1, - 2*Main.N, - 2*Main.N + 1, - 2*Main.N + 2, - Main.N - 2, - Main.N + 2, 2, -2, Main.N - 2, Main.N + 2,
-								2*Main.N - 2, 2*Main.N - 1, 2*Main.N, 2*Main.N + 1, 2*Main.N + 2 };
+					if (colorIndex/2 - 2 > 0 && colorIndex/2 < colors.length + 2 && N > 3) {
+						int[] secondRing = { -2*N - 2, - 2*N - 1, - 2*N, - 2*N + 1, - 2*N + 2, - N - 2, - N + 2, 2, -2, N - 2, N + 2,
+								2*N - 2, 2*N - 1, 2*N, 2*N + 1, 2*N + 2 };
 						for (int ringVal : secondRing) {
 							gridBoxes[centre + ringVal].setStyle("-fx-background-color:"+colors[colorIndex/2 - 2]+";");
 						}
 					}
-					if (colorIndex/2 - 3 > 0 && colorIndex/2 < colors.length + 3 && Main.N > 5) {
-						int[] thirdRing = { -3*Main.N - 3, - 3*Main.N - 2, -3*Main.N - 1, - 3*Main.N, - 3*Main.N + 1, - 3*Main.N + 2, - 3*Main.N + 3, - Main.N - 3, - Main.N + 3, 3, -3, Main.N - 3,
-								Main.N + 3, 2*Main.N - 3, 2*Main.N + 3, -2*Main.N + 3, -2*Main.N - 3, 3*Main.N - 3, 3*Main.N - 2, 3*Main.N - 1, 3*Main.N, 3*Main.N + 1, 3*Main.N + 2, 3*Main.N + 3};
+					if (colorIndex/2 - 3 > 0 && colorIndex/2 < colors.length + 3 && N > 5) {
+						int[] thirdRing = { -3*N - 3, - 3*N - 2, -3*N - 1, - 3*N, - 3*N + 1, - 3*N + 2, - 3*N + 3, - N - 3, - N + 3, 3, -3, N - 3,
+								N + 3, 2*N - 3, 2*N + 3, -2*N + 3, -2*N - 3, 3*N - 3, 3*N - 2, 3*N - 1, 3*N, 3*N + 1, 3*N + 2, 3*N + 3};
 						for (int ringVal : thirdRing) {
 							gridBoxes[centre + ringVal].setStyle("-fx-background-color:"+colors[colorIndex/2 - 3]+";");
 						}
@@ -147,29 +149,29 @@ public class Animation {
 	}
 		
 	private void initialiseIndex() {
-		for (int i = 0; i < Main.N; i++) {
-			for (int j = 0; j < Main.N; j++) {
+		for (int i = 0; i < N; i++) {
+			for (int j = 0; j < N; j++) {
 				if (i % 2 == 0) {
-					indexList.add(i*Main.N + j);
+					indexList.add(i*N + j);
 				}
 				else {
-					indexList.add((i+1) * Main.N - 1 - j);
+					indexList.add((i+1) * N - 1 - j);
 				}
 			}
 		}
 		
-		if (getPrevious(indexList) % Main.N == 0) {
+		if (getPrevious(indexList) % N == 0) {
 			// even n
-			for (int j = 0; j < Main.N / 2; j++) {
-				moveUpDown(1, Main.N - 1);
+			for (int j = 0; j < N / 2; j++) {
+				moveUpDown(1, N - 1);
 				moveLeftRight(1, 1);
-				moveUpDown(-1, Main.N - 1);
-				if (j != Main.N/2 - 1) {
+				moveUpDown(-1, N - 1);
+				if (j != N/2 - 1) {
 					moveLeftRight(1, 1);
 				}
 			}
 			
-			int count = Main.N - 1;
+			int count = N - 1;
 			moveLeftRight(-1, count);
 			moveUpDown(1, count);
 			moveLeftRight(1, count);
@@ -186,15 +188,15 @@ public class Animation {
 		}
 		else {
 			// odd n
-			for (int j = 0; j < Main.N / 2; j++) {
-				moveUpDown(1, Main.N - 1);
+			for (int j = 0; j < N / 2; j++) {
+				moveUpDown(1, N - 1);
 				moveLeftRight(-1, 1);
-				moveUpDown(-1, Main.N - 1);
+				moveUpDown(-1, N - 1);
 				moveLeftRight(-1, 1);
 			}
-			moveUpDown(1, Main.N - 1);
+			moveUpDown(1, N - 1);
 			
-			int count = Main.N - 1;
+			int count = N - 1;
 			moveLeftRight(1, count);
 			moveUpDown(-1, count);
 			moveLeftRight(-1, count);
@@ -222,7 +224,7 @@ public class Animation {
 	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);
+			indexList.add(getPrevious(indexList) - N*value);
 		}
 	}
 	
diff --git a/src/coursework/Cage.java b/src/coursework/Cage.java
index b2d17836b0680fef3f38f5fe4627242b75976bf1..6d7ed6a16ebf18626d946d85d35315f73ac5774d 100644
--- a/src/coursework/Cage.java
+++ b/src/coursework/Cage.java
@@ -11,6 +11,7 @@ import javafx.scene.paint.Color;
 
 public class Cage {
 
+	private static int N;
 	private int[] squareIds;
 	private int value;
 	private String operator;
@@ -25,6 +26,7 @@ public class Cage {
 		this.gridSquares = Main.getGridSquares();
 		this.gridNumbers = Main.getGridNumbers();
 		this.cageLabels = Main.getCageLabels();
+		N = Main.getN();
 		buildCage();
 		setCageInfo();
 	}
@@ -150,16 +152,16 @@ public class Cage {
 					final double WIDTH = 2;
 					
 					if (rowDiff == -1 && colDiff == 0) {
-						gridSquares[aCoord[0]*Main.N + aCoord[1]].setRightStroke(WIDTH, Color.GREY);
+						gridSquares[aCoord[0]*N + aCoord[1]].setRightStroke(WIDTH, Color.GREY);
 					}
 					else if (rowDiff == 1 && colDiff == 0) {
-						gridSquares[aCoord[0]*Main.N + aCoord[1]].setLeftStroke(WIDTH, Color.GREY);
+						gridSquares[aCoord[0]*N + aCoord[1]].setLeftStroke(WIDTH, Color.GREY);
 					}
 					else if (rowDiff == 0 && colDiff == -1) {
-						gridSquares[aCoord[0]*Main.N + aCoord[1]].setBottomStroke(WIDTH, Color.GREY);
+						gridSquares[aCoord[0]*N + aCoord[1]].setBottomStroke(WIDTH, Color.GREY);
 					}
 					else if (rowDiff == 0 && colDiff == 1) {
-						gridSquares[aCoord[0]*Main.N + aCoord[1]].setTopStroke(WIDTH, Color.GREY);
+						gridSquares[aCoord[0]*N + aCoord[1]].setTopStroke(WIDTH, Color.GREY);
 					}
 				}
 			}
@@ -174,8 +176,8 @@ public class Cage {
 	}
 	
 	public static int[] idToCoord(int id) {
-		int row = id / Main.N;
-		int col = id % Main.N;
+		int row = id / N;
+		int col = id % N;
 		return new int[] {row, col};
 	}
 	
diff --git a/src/coursework/ConstraintsHandler.java b/src/coursework/ConstraintsHandler.java
index 989872b304379d9738fa2627dfe301081df63355..15940de690b36d17a30d556723c18decd200f44a 100644
--- a/src/coursework/ConstraintsHandler.java
+++ b/src/coursework/ConstraintsHandler.java
@@ -8,10 +8,11 @@ import javafx.scene.layout.VBox;
 
 public class ConstraintsHandler {
 
-	private TextField[] gridNumbers = new TextField[Main.N*Main.N];
-	private VBox[] gridBoxes = new VBox[Main.N*Main.N];
+	private static int N;
+	private TextField[] gridNumbers = new TextField[N*N];
+	private VBox[] gridBoxes = new VBox[N*N];
 	private List<Cage> gridCages = new ArrayList<Cage>();
-	private boolean[][] gridErrors = new boolean[Main.N*Main.N][3];
+	private boolean[][] gridErrors = new boolean[N*N][3];
 	private boolean constraintChecked = false;	
 	
 	public ConstraintsHandler() {}
@@ -21,6 +22,7 @@ public class ConstraintsHandler {
 		gridBoxes = Main.getGridBoxes();
 		gridCages = Main.getGridCages();
 		gridErrors = Main.getGridErrors();
+		N = Main.getN();
 	}
 	
 	public boolean checked() {
@@ -49,8 +51,8 @@ public class ConstraintsHandler {
 		boolean repeat = false;
 		HashSet<String> rowValues = new HashSet<String>();
 		String number;
-		for (int i = 0; i < Main.N; i++) {
-			number = gridNumbers[row*Main.N + i].getText();
+		for (int i = 0; i < N; i++) {
+			number = gridNumbers[row*N + i].getText();
 			if (rowValues.contains(number) && !number.equals("")) {
 				repeat = true;
 			}
@@ -74,8 +76,8 @@ public class ConstraintsHandler {
 		boolean repeat = false;
 		HashSet<String> colValues = new HashSet<String>();
 		String number;
-		for (int i = 0; i < Main.N; i++) {
-			number = gridNumbers[i*Main.N + col].getText();
+		for (int i = 0; i < N; i++) {
+			number = gridNumbers[i*N + col].getText();
 			if (colValues.contains(number) && !number.equals("")) {
 				repeat = true;
 			}
@@ -91,7 +93,7 @@ public class ConstraintsHandler {
 			Cage searchCage = null;
 			for (Cage cage : gridCages) {
 				for (int id : cage.getCageIds()) {
-					if (id == (row*Main.N + col)) {
+					if (id == (row*N + col)) {
 						searchCage = cage;
 						break;
 					}
@@ -106,31 +108,31 @@ public class ConstraintsHandler {
 	}
 	
 	private void clearRow(int row) {
-		for (int i = 0; i < Main.N; i++) {
-			gridErrors[row*Main.N + i][0] = false;		
+		for (int i = 0; i < N; i++) {
+			gridErrors[row*N + i][0] = false;		
 		}
 	}
 	
 	private void clearColumn(int col) {
-		for (int i = 0; i < Main.N; i++) {
-			gridErrors[i*Main.N + col][1] = false;
+		for (int i = 0; i < N; i++) {
+			gridErrors[i*N + col][1] = false;
 		}
 	}
 	
 	private void highlightRow(int row) {
-		for (int i = 0; i < Main.N; i++) {
-			gridErrors[row*Main.N + i][0] = true;
+		for (int i = 0; i < N; i++) {
+			gridErrors[row*N + i][0] = true;
 		}
 	}
 	
 	private void highlightColumn(int col) {
-		for (int i = 0; i < Main.N; i++) {
-			gridErrors[i*Main.N + col][1] = true;
+		for (int i = 0; i < N; i++) {
+			gridErrors[i*N + col][1] = true;
 		}
 	}
 	
 	public void highlightCells(boolean showMistakes) {
-		for (int i = 0; i < Main.N*Main.N; i++) {
+		for (int i = 0; i < N*N; i++) {
 			if ((gridErrors[i][0] || gridErrors[i][1] || gridErrors[i][2]) && showMistakes) {
 				gridBoxes[i].setStyle("-fx-background-color: rgba(255,0,0,0.5);");
 			}
diff --git a/src/coursework/GameState.java b/src/coursework/GameState.java
index 092aa5eaf00f4146a8594d214cb45320248222ff..e38448c177c9beece8c2c7915bb61879c36f5913 100644
--- a/src/coursework/GameState.java
+++ b/src/coursework/GameState.java
@@ -4,10 +4,12 @@ import javafx.scene.control.TextField;
 
 public class GameState {
 
+	private static int N;
 	private String[] gridValues;
 	
 	public GameState(String[] gridValues) {
 		this.gridValues = gridValues;
+		N = Main.getN();
 	}
 	
 	public String[] getGameState() {
@@ -15,7 +17,7 @@ public class GameState {
 	}
 	
 	public static String[] getCurrentGameState(TextField[] gridNumbers) {
-		String[] gridValues = new String[Main.N*Main.N];
+		String[] gridValues = new String[N*N];
 		for (int k = 0; k < gridValues.length; k++) {
 			gridValues[k] = gridNumbers[k].getText();
 		}
diff --git a/src/coursework/Main.java b/src/coursework/Main.java
index 70ac3b204c3effc53081848cf2e089449f5627f5..bc3a1da1ee868a31a3a5a37cadec6093a9d206d6 100644
--- a/src/coursework/Main.java
+++ b/src/coursework/Main.java
@@ -36,17 +36,17 @@ import javafx.stage.Stage;
 
 public class Main extends Application {
 	
-	final static public int N = 8;
+	private static int N;
 	
 	private Scene scene;
 	private Stage stage;
 	
-	private static Square[] gridSquares = new Square[N*N];
-	private static TextField[] gridNumbers = new TextField[N*N];
-	private static Label[] cageLabels = new Label[N*N];
-	private static VBox[] gridBoxes = new VBox[N*N];
-	private static List<Cage> gridCages = new ArrayList<Cage>();
-	private static boolean[][] gridErrors = new boolean[N*N][3];
+	private static Square[] gridSquares;
+	private static TextField[] gridNumbers;
+	private static Label[] cageLabels;
+	private static VBox[] gridBoxes;
+	private static List<Cage> gridCages;
+	private static boolean[][] gridErrors;
 	
 	private static boolean showMistakes = false;
 	private Pane previousPane = null;
@@ -63,6 +63,10 @@ public class Main extends Application {
 	private Button redoButton;
 	
 	//////////////////////////////////////////////////////////////////////////////////
+	public static int getN() {
+		return N;
+	}
+	
 	public static Square[] getGridSquares() {
 		return gridSquares;
 	}
@@ -607,7 +611,18 @@ public class Main extends Application {
 		stage.show();
 	}
 	
+	private static void initialiseVariables() {
+		gridSquares = new Square[N*N];
+		gridNumbers = new TextField[N*N];
+		cageLabels = new Label[N*N];
+		gridBoxes = new VBox[N*N];
+		gridCages = new ArrayList<Cage>();
+		gridErrors = new boolean[N*N][3];
+	}
+	
 	public static void main(String[] args) {
+		N = Integer.parseInt(args[0]);
+		initialiseVariables();
 		launch(args);
 	}