From 202195d035e99c9b2715408f565e25ecd811bdfc Mon Sep 17 00:00:00 2001
From: Nimrod Abramovich <grumpydormin@gmail.com>
Date: Wed, 11 Mar 2020 10:10:33 +0000
Subject: [PATCH] moved constraint handling to new class

---
 bin/coursework/Constraints.class | Bin 0 -> 4358 bytes
 bin/coursework/Main.class        | Bin 24854 -> 22761 bytes
 src/coursework/Constraints.java  | 138 ++++++++++++++++++++++
 src/coursework/Main.java         | 192 ++++++++-----------------------
 4 files changed, 184 insertions(+), 146 deletions(-)
 create mode 100644 bin/coursework/Constraints.class
 create mode 100644 src/coursework/Constraints.java

diff --git a/bin/coursework/Constraints.class b/bin/coursework/Constraints.class
new file mode 100644
index 0000000000000000000000000000000000000000..3c70c8fb30b14d6a2391e0f208b022abb821ebc1
GIT binary patch
literal 4358
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
FCICBTMJoUR

literal 0
HcmV?d00001

diff --git a/bin/coursework/Main.class b/bin/coursework/Main.class
index 3d978104687481173a895a9c50c1b4e9b64dec3b..4ff668e892537ec5df1044acc4cfbe5cf09b0d2b 100644
GIT binary patch
literal 22761
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
VlFXURX)JOMlFaPPj4bjDk^sRvIw}AF

literal 24854
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

diff --git a/src/coursework/Constraints.java b/src/coursework/Constraints.java
new file mode 100644
index 0000000..eafc645
--- /dev/null
+++ b/src/coursework/Constraints.java
@@ -0,0 +1,138 @@
+package coursework;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import javafx.scene.control.TextField;
+import javafx.scene.layout.VBox;
+
+public class Constraints {
+
+	private TextField[] gridNumbers = new TextField[Main.N*Main.N];
+	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];
+	
+	
+	public Constraints() {}
+	
+	private void updateData() {
+		gridNumbers = Main.getGridNumbers();
+		gridBoxes = Main.getGridBoxes();
+		gridCages = Main.getGridCages();
+		gridErrors = Main.getGridErrors();
+	}
+	
+	public void checkConstraints(int col, int row, boolean showMistakes) {
+		updateData();
+		columnConstraint(row, col);
+		rowConstraint(row, col);
+		cageConstraint(row, col);
+		highlightCells(showMistakes);
+	}
+
+	private void rowConstraint(int row, int col) {
+		if (!doesRowRepeat(row)) {
+			clearRow(row);
+		}
+		else {
+			highlightRow(row);
+		}
+	}
+	
+	private boolean doesRowRepeat(int row) {
+		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();
+			if (rowValues.contains(number) && !number.equals("")) {
+				repeat = true;
+			}
+			else {
+				rowValues.add(number);
+			}
+		}
+		return repeat;
+	}
+	
+	private void columnConstraint(int row, int col) {	
+		if (!doesColumnRepeat(col)) {
+			clearColumn(col);
+		}
+		else {
+			highlightColumn(col);
+		}
+	}
+	
+	private boolean doesColumnRepeat(int col) {
+		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();
+			if (colValues.contains(number) && !number.equals("")) {
+				repeat = true;
+			}
+			else {
+				colValues.add(number);
+			}
+		}
+		return repeat;
+	}
+		
+	private void cageConstraint(int row, int col) {
+		if (gridCages.size() > 0) {
+			Cage searchCage = null;
+			for (Cage cage : gridCages) {
+				for (int id : cage.getCageIds()) {
+					if (id == (row*Main.N + col)) {
+						searchCage = cage;
+						break;
+					}
+				}
+			}
+			
+			boolean validCageValues = searchCage.checkCageValues();
+			for (int id : searchCage.getCageIds()) {
+				gridErrors[id][2] = validCageValues;
+			}
+		}
+	}
+	
+	private void clearRow(int row) {
+		for (int i = 0; i < Main.N; i++) {
+			gridErrors[row*Main.N + i][0] = false;		
+		}
+	}
+	
+	private void clearColumn(int col) {
+		for (int i = 0; i < Main.N; i++) {
+			gridErrors[i*Main.N + col][1] = false;
+		}
+	}
+	
+	private void highlightRow(int row) {
+		for (int i = 0; i < Main.N; i++) {
+			gridErrors[row*Main.N + i][0] = true;
+		}
+	}
+	
+	private void highlightColumn(int col) {
+		for (int i = 0; i < Main.N; i++) {
+			gridErrors[i*Main.N + col][1] = true;
+		}
+	}
+	
+	public void highlightCells(boolean showMistakes) {
+		for (int i = 0; i < Main.N*Main.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);");
+			}
+			else {
+				gridBoxes[i].setStyle("-fx-background-color: rgba(255,0,0,0);");
+			}
+		}
+	}
+	
+}
diff --git a/src/coursework/Main.java b/src/coursework/Main.java
index 35d0332..86f2cb4 100644
--- a/src/coursework/Main.java
+++ b/src/coursework/Main.java
@@ -6,17 +6,12 @@ import java.io.FileNotFoundException;
 import java.io.FileReader;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Stack;
-import java.util.Vector;
-
 import javafx.application.*;
-import javafx.event.EventHandler;
 import javafx.geometry.Insets;
 import javafx.geometry.Pos;
 import javafx.scene.Group;
-import javafx.scene.Node;
 import javafx.scene.Scene;
 import javafx.scene.control.Alert;
 import javafx.scene.control.Alert.AlertType;
@@ -28,19 +23,12 @@ import javafx.scene.control.TextField;
 import javafx.scene.image.Image;
 import javafx.scene.image.ImageView;
 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;
 import javafx.scene.layout.VBox;
 import javafx.scene.paint.Color;
-import javafx.scene.shape.HLineTo;
-import javafx.scene.shape.Line;
-import javafx.scene.shape.LineTo;
-import javafx.scene.shape.MoveTo;
-import javafx.scene.shape.Path;
 import javafx.scene.shape.Rectangle;
-import javafx.scene.shape.VLineTo;
 import javafx.stage.FileChooser;
 import javafx.stage.Stage;
 
@@ -52,21 +40,21 @@ public class Main extends Application {
 	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 boolean[][] highlightedError = new boolean[N*N][3];
-	private VBox[] gridBoxes = new VBox[N*N];
-	private List<Cage> gridCages = new ArrayList<Cage>();
+	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 boolean showMistakes = false;
 	private boolean isWider;
 	private Pane previousPane = null;
 	private Square previousSquare = null;
 	private boolean clearing = false;
 	private boolean undoing = false;
-	private boolean showMistakes = false;
 	private int fontSize;
+	private Constraints constraints = new Constraints();
 	
 	private Stack<GameState> undoStack = new Stack<GameState>();
 	private Stack<GameState> redoStack = new Stack<GameState>();
@@ -74,6 +62,31 @@ public class Main extends Application {
 	private Button undoButton;
 	private Button redoButton;
 	
+	
+	public static Square[] getGridSquares() {
+		return gridSquares;
+	}
+	
+	public static TextField[] getGridNumbers() {
+		return gridNumbers;
+	}
+	
+	public static Label[] getCageLabels() {
+		return cageLabels;
+	}
+	
+	public static VBox[] getGridBoxes() {
+		return gridBoxes;
+	}
+	
+	public static List<Cage> getGridCages() {
+		return gridCages;
+	}
+	
+	public static boolean[][] getGridErrors() {
+		return gridErrors;
+	}
+	
 	private GridPane setupGrid() {
 		GridPane gridPane = new GridPane();
 		gridPane.setAlignment(Pos.CENTER);
@@ -104,20 +117,24 @@ public class Main extends Application {
 		gridPane.add(vbox, j, i);
 		
 		textField.textProperty().addListener((observable, oldValue, newValue) -> {
-			if (!clearing && !undoing) {
-				undoStack.push(new GameState(GameState.getCurrentGameState(gridNumbers)));
-				if (undoButton.isDisabled()) {
-					undoButton.setDisable(false);
-				}
-			}
-			checkConstraints(j, i);
-			checkWinCondition();
+			textFieldClickEvent(i, j);
 		});
 		
 		square.getRectangle().toFront();
 		return gridPane;
 	}
 	
+	private void textFieldClickEvent(int i, int j) {
+		if (!clearing && !undoing) {
+			undoStack.push(new GameState(GameState.getCurrentGameState(gridNumbers)));
+			if (undoButton.isDisabled()) {
+				undoButton.setDisable(false);
+			}
+		}
+		constraints.checkConstraints(j, i, showMistakes);;
+		checkWinCondition();
+	}
+	
 	private void checkWinCondition() {
 		if (checkCellsFull() && checkConstraintErrors()) {
 			// win condition fulfilled
@@ -136,7 +153,7 @@ public class Main extends Application {
 	}
 	
 	private boolean checkConstraintErrors() {
-		for (boolean[] cellErrors : highlightedError) {
+		for (boolean[] cellErrors : gridErrors) {
 			for (boolean errorVal : cellErrors) {
 				if (errorVal) {
 					return false;
@@ -146,111 +163,6 @@ public class Main extends Application {
 		return true;
 	}
 	
-	private void checkConstraints(int col, int row) {
-		columnConstraint(row, col);
-		rowConstraint(row, col);
-		cageConstraint(row, col);
-		highlightCells();
-	}
-
-	private void rowConstraint(int row, int col) {
-		boolean repeat = false;
-		HashSet<String> rowValues = new HashSet<String>();
-		String number;
-		for (int i = 0; i < N; i++) {
-			number = gridNumbers[row*N + i].getText();
-			if (rowValues.contains(number) && !number.equals("")) {
-				repeat = true;
-			}
-			else {
-				rowValues.add(number);
-			}
-		}
-		
-		if (!repeat) {
-			clearRow(row);
-		}
-		else {
-			highlightRow(row);
-		}
-	}
-	
-	private void columnConstraint(int row, int col) {
-		boolean repeat = false;
-		HashSet<String> colValues = new HashSet<String>();
-		String number;
-		for (int i = 0; i < N; i++) {
-			number = gridNumbers[i*N + col].getText();
-			if (colValues.contains(number) && !number.equals("")) {
-				repeat = true;
-			}
-			else {
-				colValues.add(number);
-			}
-		}
-		
-		if (!repeat) {
-			clearColumn(col);
-		}
-		else {
-			highlightColumn(col);
-		}
-	}
-		
-	private void cageConstraint(int row, int col) {
-		if (gridCages.size() > 0) {
-			Cage searchCage = null;
-			for (Cage cage : gridCages) {
-				for (int id : cage.getCageIds()) {
-					if (id == (row*N + col)) {
-						searchCage = cage;
-						break;
-					}
-				}
-			}
-			
-			boolean validCageValues = searchCage.checkCageValues();
-			for (int id : searchCage.getCageIds()) {
-				highlightedError[id][2] = validCageValues;
-			}
-		}
-	}
-	
-	private void clearRow(int row) {
-		for (int i = 0; i < N; i++) {
-			highlightedError[row*N + i][0] = false;		
-		}
-	}
-	
-	private void clearColumn(int col) {
-		for (int i = 0; i < N; i++) {
-			highlightedError[i*N + col][1] = false;
-		}
-	}
-	
-	private void highlightRow(int row) {
-		for (int i = 0; i < N; i++) {
-			highlightedError[row*N + i][0] = true;
-		}
-	}
-	
-	private void highlightColumn(int col) {
-		for (int i = 0; i < N; i++) {
-			highlightedError[i*N + col][1] = true;
-		}
-	}
-	
-	private void highlightCells() {
-		for (int i = 0; i < N*N; i++) {
-			if ((highlightedError[i][0] || highlightedError[i][1] || highlightedError[i][2]) && showMistakes) {
-				gridBoxes[i].setStyle("-fx-background-color: rgba(255,0,0,0.5);");
-			}
-			else {
-				gridBoxes[i].setStyle("-fx-background-color: rgba(255,0,0,0);");
-			}
-		}
-	}
-	
 	private VBox setupGridVBox(Square square, int i, int j) {
 		VBox vbox = new VBox();
 		Label cageInfoLabel = new Label("");
@@ -302,7 +214,7 @@ public class Main extends Application {
 		
 		showMistakesCheck.selectedProperty().addListener((obs, oldVal, newVal) -> {
 			showMistakes = showMistakesCheck.isSelected();
-			highlightCells();
+			constraints.highlightCells(showMistakes);
 		});
 		
 		loadGameFileButton.setOnAction(e -> {
@@ -402,14 +314,14 @@ public class Main extends Application {
 		gridBoxes[i*N + j].addEventHandler(MouseEvent.MOUSE_CLICKED, e -> {
 			if (previousPane != null) {
 				int previousIndex = getIndexOf(previousPane);
-				if ((highlightedError[previousIndex][0] || highlightedError[previousIndex][1] || highlightedError[previousIndex][2]) && showMistakes) {
+				if ((gridErrors[previousIndex][0] || gridErrors[previousIndex][1] || gridErrors[previousIndex][2]) && showMistakes) {
 					previousPane.setStyle("-fx-background-color: rgba(255,0,20,0.5); -fx-border-width: 0px;");
 				}
 				else {
 					previousPane.setStyle("-fx-background-color: rgba(255,0,20,0); -fx-border-width: 0px;");
 				}
 			}
-			if ((highlightedError[i*N + j][0] || highlightedError[i*N + j][1] || highlightedError[i*N + j][2]) && showMistakes) {
+			if ((gridErrors[i*N + j][0] || gridErrors[i*N + j][1] || gridErrors[i*N + j][2]) && showMistakes) {
 				gridBoxes[i*N + j].setStyle("-fx-border-color: #2309FB; -fx-border-width: 2px; -fx-background-color: rgba(255,0,0,0.3);");
 			}
 			else {
@@ -584,18 +496,6 @@ public class Main extends Application {
 		}
 	}
 	
-	public static Square[] getGridSquares() {
-		return gridSquares;
-	}
-	
-	public static Label[] getCageLabels() {
-		return cageLabels;
-	}
-	
-	public static TextField[] getGridNumbers() {
-		return gridNumbers;
-	}
-	
 	@Override
 	public void start(Stage stage) throws Exception {
 		VBox vBox = new VBox();
-- 
GitLab