diff --git a/bin/coursework/Cage.class b/bin/coursework/Cage.class
index c6c3ed15e75955038dd209362021099653822e4f..0d46fadf7157f06d6f76b9df718397930d2b3ef8 100644
Binary files a/bin/coursework/Cage.class and b/bin/coursework/Cage.class differ
diff --git a/bin/coursework/Main.class b/bin/coursework/Main.class
index a1011f22830a280134bd2237cb846b343e56df25..464a8a449899abc71b6193a9814592f925eb09f1 100644
Binary files a/bin/coursework/Main.class and b/bin/coursework/Main.class differ
diff --git a/bin/coursework/RandomGenerator.class b/bin/coursework/RandomGenerator.class
index 1f537e186719638b1e5d09d50f44faca09f7c2df..a8f01bdbc87bbb87844746bc98f29c1b24e0f285 100644
Binary files a/bin/coursework/RandomGenerator.class and b/bin/coursework/RandomGenerator.class differ
diff --git a/bin/coursework/Solver.class b/bin/coursework/Solver.class
new file mode 100644
index 0000000000000000000000000000000000000000..3f53a100d0f959129e4ecbda2c6aa57da6713928
Binary files /dev/null and b/bin/coursework/Solver.class differ
diff --git a/src/coursework/Cage.java b/src/coursework/Cage.java
index 190e102c0b1b9f41cd65ba272f37565021b3ecbb..a066052220bead607ba5b41b4e70fcd37ec34e8c 100644
--- a/src/coursework/Cage.java
+++ b/src/coursework/Cage.java
@@ -181,5 +181,13 @@ public class Cage {
 	public int[] getCageIds() {
 		return squareIds;
 	}
+	
+	public int getCageValue() {
+		return value;
+	}
+	
+	public String getCageOperator() {
+		return operator;
+	}
 
 }
\ No newline at end of file
diff --git a/src/coursework/Main.java b/src/coursework/Main.java
index fb366a6df0e250a7edb1b7aa36f58ffd2034b779..c9b219c41255d85057c0c131ff6191af9ba9bf28 100644
--- a/src/coursework/Main.java
+++ b/src/coursework/Main.java
@@ -179,27 +179,26 @@ public class Main extends Application {
 		
 		Button loadGameFileButton = new Button("Load Game - File");
 		CheckBox showMistakesCheck = new CheckBox("Show mistakes");
+		showMistakesCheck.setMinWidth(showMistakesCheck.getPrefWidth());
 		if (showMistakes) {
 			showMistakesCheck.setSelected(true);
 		}
 		Button loadGameTextInputButton = new Button("Load Game - Text");
-		loadGameFileButton.setPrefWidth(200);
+		loadGameFileButton.setPrefWidth(150);
 		loadGameTextInputButton.setPrefWidth(loadGameFileButton.getPrefWidth());
 		
 		Button generateRandomGameButton = new Button("Generate Random Game");
 		generateRandomGameButton.setPrefWidth(loadGameFileButton.getPrefWidth());
-		Button solveGridButton = new Button("Solve Current Grid");
-		solveGridButton.setPrefWidth(loadGameFileButton.getPrefWidth());
 		
 		VBox leftVBox = new VBox();
 		leftVBox.setSpacing(5);
 		leftVBox.getChildren().addAll(loadGameFileButton, loadGameTextInputButton);
 		
-		VBox rightVBox = new VBox();
-		rightVBox.setSpacing(5);
-		rightVBox.getChildren().addAll(generateRandomGameButton, solveGridButton);
-		
-		topHBox.getChildren().addAll(leftVBox, showMistakesCheck, rightVBox);
+//		VBox rightVBox = new VBox();
+//		rightVBox.setSpacing(5);
+//		rightVBox.getChildren().addAll(, generateRandomGameButton);
+//		
+		topHBox.getChildren().addAll(leftVBox, showMistakesCheck, generateRandomGameButton);
 		
 		showMistakesCheck.selectedProperty().addListener((obs, oldVal, newVal) -> {
 			showMistakesCheckEvent(showMistakesCheck);
@@ -232,8 +231,10 @@ public class Main extends Application {
 		bottomHBox.setSpacing(10);
 		bottomHBox.setAlignment(Pos.TOP_CENTER);
 		
-		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("", 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");
+		redoButton = new Button("Redo");
 		Button clearButton = new Button("Clear");
 		undoButton.setOnAction(e -> {
 			undoButtonClickEvent();
@@ -244,8 +245,9 @@ public class Main extends Application {
 		
 		undoButton.setDisable(true);
 		redoButton.setDisable(true);
-		clearButton.setPrefHeight(36);
-		clearButton.setPrefWidth(120);
+		clearButton.setPrefSize(100, 36);
+		undoButton.setPrefSize(80, 36);
+		redoButton.setPrefSize(80, 36);
 		clearButtonClickEvent(clearButton);
 		
 		bottomHBox.getChildren().addAll(undoButton, clearButton, redoButton);
@@ -276,6 +278,7 @@ public class Main extends Application {
 		vbox.getChildren().add(balanceButtonBottom);
 		vbox.setSpacing(10);
 		vbox.setAlignment(Pos.CENTER_LEFT);
+		vbox.setPadding(new Insets(0, 0, 0, 0));
 		return vbox;
 	}
 	
@@ -366,22 +369,27 @@ public class Main extends Application {
 		return slider;
 	}
 	
-	private HBox setupRadioHBox() {
-		HBox hboxMiddle = new HBox();
-		ToggleGroup tg = new ToggleGroup();
-		RadioButton easy = new RadioButton("Easy");
-		easy.setToggleGroup(tg);
-		RadioButton medium = new RadioButton("Medium");
-		medium.setToggleGroup(tg);
-		RadioButton hard = new RadioButton("Hard");
-		hard.setToggleGroup(tg);
-		hboxMiddle.setAlignment(Pos.CENTER);
-		hboxMiddle.setSpacing(10);
-		VBox radioVBox = new VBox(easy, medium, hard);
-		radioVBox.setSpacing(5);
-		hboxMiddle.getChildren().addAll(new Label("Difficulty:"), radioVBox);
-		
-		return hboxMiddle;
+//	private HBox setupRadioHBox() {
+//		HBox hboxMiddle = new HBox();
+//		ToggleGroup tg = new ToggleGroup();
+//		RadioButton easy = new RadioButton("Easy");
+//		easy.setToggleGroup(tg);
+//		RadioButton medium = new RadioButton("Medium");
+//		medium.setToggleGroup(tg);
+//		RadioButton hard = new RadioButton("Hard");
+//		hard.setToggleGroup(tg);
+//		hboxMiddle.setAlignment(Pos.CENTER);
+//		hboxMiddle.setSpacing(10);
+//		VBox radioVBox = new VBox(easy, medium, hard);
+//		radioVBox.setSpacing(5);
+//		hboxMiddle.getChildren().addAll(new Label("Difficulty:"), radioVBox);
+//		
+//		return hboxMiddle;
+//	}
+	
+	private void solveGrid() {
+		Solver solver = new Solver(N, gridCages);
+		solver.solvePuzzel();
 	}
 	
 	///////////////////////////////////////////////////////////
@@ -402,13 +410,6 @@ public class Main extends Application {
 		
 		Button generateButton = new Button("Generate");
 		generateButton.setAlignment(Pos.TOP_RIGHT);
-		generateButton.setOnAction(e -> {
-			popupStage.close();
-			N = (int) slider.getValue();
-			resetGrid();
-			RandomGenerator rg = new RandomGenerator(N);
-			gridCages = rg.generate();	
-		});
 		
 		Button cancelButton = new Button("Cancel");
 		cancelButton.setAlignment(Pos.TOP_LEFT);
@@ -420,8 +421,43 @@ public class Main extends Application {
 		hboxTop.setSpacing(3);
 		hboxTop.setAlignment(Pos.CENTER);
 		
+		HBox hboxMiddle = new HBox();
+		ToggleGroup tg = new ToggleGroup();
+		RadioButton easy = new RadioButton("Easy");
+		easy.setToggleGroup(tg);
+		RadioButton medium = new RadioButton("Medium");
+		medium.setToggleGroup(tg);
+		RadioButton hard = new RadioButton("Hard");
+		hard.setToggleGroup(tg);
+		hboxMiddle.setAlignment(Pos.CENTER);
+		hboxMiddle.setSpacing(10);
+		VBox radioVBox = new VBox(easy, medium, hard);
+		radioVBox.setSpacing(5);
+		hboxMiddle.getChildren().addAll(new Label("Difficulty:"), radioVBox);
+		
 		hboxBottom.getChildren().addAll(cancelButton, generateButton);
-		vbox.getChildren().addAll(hboxTop, setupRadioHBox(), hboxBottom);
+		vbox.getChildren().addAll(hboxTop, hboxMiddle, hboxBottom);
+		
+		generateButton.setOnAction(e -> {
+			popupStage.close();
+			N = (int) slider.getValue();
+			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();	
+		});
 		
 		popupStage.setScene(new Scene(vbox, 250, 250));
 		popupStage.show();
@@ -706,7 +742,7 @@ public class Main extends Application {
 	public void start(Stage primaryStage) throws Exception {
 		stage = primaryStage;
 		VBox vBox = new VBox();
-		int width = 400 + 80 * N;
+		int width = 350 + 80 * N;
 		int height = 275 + 80 * N;
 		
 		scene = new Scene(vBox, width, height);
@@ -779,18 +815,18 @@ public class Main extends Application {
 		stage.close();
 		initialiseVariables();
 		VBox vBox = new VBox();
-		int width = 300 + 80 * N;
-		int height = 300 + 80 * N;
+		int width = 350 + 80 * N;
+		int height = 275 + 80 * N;
 		
-		Stage stage = new Stage();
+		Stage newStage = new Stage();
 		Scene newScene = new Scene(vBox, width, height);
-		stage.setWidth(width);
-		stage.setHeight(height);
+		newStage.setWidth(width);
+		newStage.setHeight(height);
 		vBox.setSpacing(5);
 		vBox.setPadding(new Insets(20));
 		vBox.setAlignment(Pos.CENTER);
 		
-		GridPane gridPane = setupGrid(width - 200, height - 120);
+		GridPane gridPane = setupGrid(width - 200, height - 175);
 		undoStack.push(new GameState(GameState.getCurrentGameState(gridNumbers)));
 		
 		fontSize = 18;
@@ -811,13 +847,13 @@ public class Main extends Application {
 		stageWidthResizeEvent(stage, gridPane);
 		stageHeightResizeEvent(stage, gridPane);
 		
-		stage.setMinWidth(width + 50);
-		stage.setMinHeight(height + 50);
-		stage.setScene(newScene);
-		stage.setTitle("Mathdoku");
-		stage.show();
+		newStage.setMinWidth(width + 50);
+		newStage.setMinHeight(height + 50);
+		newStage.setScene(newScene);
+		newStage.setTitle("Mathdoku");
+		newStage.show();
 		scene = newScene;
-		this.stage = stage;
+		stage = newStage;
 
 	}
 	
diff --git a/src/coursework/RandomGenerator.java b/src/coursework/RandomGenerator.java
index fcd6a00ca20bb175efa835724c5c90afed50c58b..8eddff0922c525e9367db1983f509b4af33bd710 100644
--- a/src/coursework/RandomGenerator.java
+++ b/src/coursework/RandomGenerator.java
@@ -12,12 +12,13 @@ public class RandomGenerator {
 
 	private int N;
 	private int[][] grid;
+	private int difficult;	// 1 = easy | 2 = medium | 3 = hard	
 	
 	private List<Integer> uncagedGrids = new ArrayList<Integer>();
 	private List<Integer> possibleMoves = new ArrayList<Integer>();
 	private List<Cage> gridCages = new ArrayList<Cage>();
 	
-	public RandomGenerator(int N) {
+	public RandomGenerator(int N, int difficulty) {
 		this.N = N;
 		grid = new int[N][N];
 	}
@@ -160,7 +161,7 @@ public class RandomGenerator {
 				cageOperator = keySet.get(random.nextInt(keySet.size()));
 				cageValue = possibleValues.get(cageOperator);
 			}
-			else {;
+			else {
 				int row = cageIds[0] / N;
 				int col = cageIds[0] % N;
 				cageValue = grid[row][col];
diff --git a/src/coursework/Solver.java b/src/coursework/Solver.java
new file mode 100644
index 0000000000000000000000000000000000000000..58b843f9e47fbdcddccce64e0e322a7954f0edb9
--- /dev/null
+++ b/src/coursework/Solver.java
@@ -0,0 +1,137 @@
+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");
+		}
+	}
+}