diff --git a/bin/coursework/Constraints.class b/bin/coursework/Constraints.class new file mode 100644 index 0000000000000000000000000000000000000000..3c70c8fb30b14d6a2391e0f208b022abb821ebc1 Binary files /dev/null and b/bin/coursework/Constraints.class differ diff --git a/bin/coursework/Main.class b/bin/coursework/Main.class index 3d978104687481173a895a9c50c1b4e9b64dec3b..4ff668e892537ec5df1044acc4cfbe5cf09b0d2b 100644 Binary files a/bin/coursework/Main.class and b/bin/coursework/Main.class differ diff --git a/src/coursework/Constraints.java b/src/coursework/Constraints.java new file mode 100644 index 0000000000000000000000000000000000000000..eafc64554cdba995ad051d130dcab3b76d8fef32 --- /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 35d0332f9ce560bf5fd770704cfa63c64e12b973..86f2cb407ccb964ceb35dccce626bb0d8df096b5 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();