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