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"); - } - } -}