diff --git a/bin/coursework/Cage.class b/bin/coursework/Cage.class index 4e07610a39165c13072741687aa69b631c7d6493..c6c3ed15e75955038dd209362021099653822e4f 100644 Binary files a/bin/coursework/Cage.class and b/bin/coursework/Cage.class differ diff --git a/bin/coursework/GameState.class b/bin/coursework/GameState.class index f2191bde75af2628511e506635f2c9a30ca52de6..23910ba3317c7a6b95925d3dac5eff34796fc869 100644 Binary files a/bin/coursework/GameState.class and b/bin/coursework/GameState.class differ diff --git a/bin/coursework/Main.class b/bin/coursework/Main.class index 91322a5f64f24da6b9668f57097e6994f74b2337..e11864fcd4a0c4e5737bfec1dfeeafb4b2b6f0e2 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 3ffd12084d130765e78aa78c13730b35777c3487..1f537e186719638b1e5d09d50f44faca09f7c2df 100644 Binary files a/bin/coursework/RandomGenerator.class and b/bin/coursework/RandomGenerator.class differ diff --git a/src/coursework/Cage.java b/src/coursework/Cage.java index 6d7ed6a16ebf18626d946d85d35315f73ac5774d..190e102c0b1b9f41cd65ba272f37565021b3ecbb 100644 --- a/src/coursework/Cage.java +++ b/src/coursework/Cage.java @@ -80,13 +80,12 @@ public class Cage { } } Collections.sort(sortedCageValues, Collections.reverseOrder()); + int cageVal = sortedCageValues.get(0); - - for (int value : sortedCageValues) { - if (value != cageVal) { - cageVal -= value; - } + for (int i = 1; i < sortedCageValues.size(); i++) { + cageVal -= sortedCageValues.get(i); } + if (cageVal == value) { return false; } @@ -107,12 +106,10 @@ public class Cage { } } Collections.sort(sortedCageValues, Collections.reverseOrder()); - int cageVal = sortedCageValues.get(0); - for (int value : sortedCageValues) { - if (value != cageVal) { - cageVal /= value; - } + int cageVal = sortedCageValues.get(0); + for (int i = 1; i < sortedCageValues.size(); i++) { + cageVal /= sortedCageValues.get(i); } if (cageVal == value) { diff --git a/src/coursework/GameState.java b/src/coursework/GameState.java index e38448c177c9beece8c2c7915bb61879c36f5913..c86ae4625b78ba7faa197861af37896e58ff943a 100644 --- a/src/coursework/GameState.java +++ b/src/coursework/GameState.java @@ -17,6 +17,7 @@ public class GameState { } public static String[] getCurrentGameState(TextField[] gridNumbers) { + N = Main.getN(); String[] gridValues = new String[N*N]; for (int k = 0; k < gridValues.length; k++) { gridValues[k] = gridNumbers[k].getText(); diff --git a/src/coursework/Main.java b/src/coursework/Main.java index bc3a1da1ee868a31a3a5a37cadec6093a9d206d6..39d33515271a439637387e6578f1b70a0c0e7395 100644 --- a/src/coursework/Main.java +++ b/src/coursework/Main.java @@ -19,8 +19,11 @@ import javafx.scene.control.Button; 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.image.Image; import javafx.scene.image.ImageView; import javafx.scene.input.MouseEvent; @@ -49,10 +52,10 @@ public class Main extends Application { private static boolean[][] gridErrors; private static boolean showMistakes = false; - private Pane previousPane = null; - private Square previousSquare = null; - private boolean clearing = false; - private boolean undoing = false; + private static Pane previousPane = null; + private static Square previousSquare = null; + private static boolean clearing = false; + private static boolean undoing = false; private int fontSize; private ConstraintsHandler constraints = new ConstraintsHandler(); @@ -173,11 +176,27 @@ public class Main extends Application { Button loadGameFileButton = new Button("Load game - file"); CheckBox showMistakesCheck = new CheckBox("Show mistakes"); + if (showMistakes) { + showMistakesCheck.setSelected(true); + } Button loadGameTextInputButton = new Button("Load game - text input"); loadGameFileButton.setPrefWidth(200); loadGameTextInputButton.setPrefWidth(loadGameFileButton.getPrefWidth()); - topHBox.getChildren().addAll(loadGameFileButton, showMistakesCheck, loadGameTextInputButton); + 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); showMistakesCheck.selectedProperty().addListener((obs, oldVal, newVal) -> { showMistakesCheckEvent(showMistakesCheck); @@ -191,6 +210,10 @@ public class Main extends Application { loadTextButtonClickEvent(); }); + generateRandomGameButton.setOnAction(e -> { + generateRandomGameEvent(); + }); + return topHBox; } @@ -326,6 +349,77 @@ public class Main extends Application { } /////////////////////////////////////////////////////////// + private void generateRandomGameEvent() { + // new popup selecting difficultly and n + Stage popupStage = new Stage(); + popupStage.initModality(Modality.APPLICATION_MODAL); + popupStage.initOwner(stage); + + VBox vbox = new VBox(); + vbox.setSpacing(5); + vbox.setAlignment(Pos.TOP_CENTER); + + HBox hboxBottom = new HBox(); + hboxBottom.setSpacing(86); + hboxBottom.setPadding(new Insets(10)); + + 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)); + + 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); + + Button generateButton = new Button("Generate"); + generateButton.setAlignment(Pos.TOP_RIGHT); + generateButton.setOnAction(e -> { + popupStage.close(); + if ((int) slider.getValue() != N) { + N = (int) slider.getValue(); + resetGrid(); + } + RandomGenerator rg = new RandomGenerator(N); + gridCages = rg.generate(); + }); + + Button cancelButton = new Button("Cancel"); + cancelButton.setAlignment(Pos.TOP_LEFT); + cancelButton.setOnAction(e -> { + popupStage.hide(); + }); + + HBox hboxTop = new HBox(new Label("Size (NxN):"), slider); + hboxTop.setSpacing(3); + hboxTop.setAlignment(Pos.CENTER); + + + + hboxBottom.getChildren().addAll(cancelButton, generateButton); + vbox.getChildren().addAll(hboxTop, hboxMiddle, hboxBottom); + + popupStage.setScene(new Scene(vbox, 250, 250)); + popupStage.show(); + } + private void loadFileButtonClickEvent() { try { FileChooser fileChooser = new FileChooser(); @@ -541,7 +635,8 @@ public class Main extends Application { //////////////////////////////////////////////////////// @Override - public void start(Stage stage) throws Exception { + public void start(Stage primaryStage) throws Exception { + stage = primaryStage; VBox vBox = new VBox(); int width = 400 + 80 * N; int height = 275 + 80 * N; @@ -549,11 +644,11 @@ public class Main extends Application { scene = new Scene(vBox, width, height); stage.setWidth(width); stage.setHeight(height); - vBox.setSpacing(10); + vBox.setSpacing(5); vBox.setPadding(new Insets(20)); vBox.setAlignment(Pos.CENTER); - GridPane gridPane = setupGrid(width - 200, height - 150); + GridPane gridPane = setupGrid(width - 200, height - 175); undoStack.push(new GameState(GameState.getCurrentGameState(gridNumbers))); fontSize = 18; @@ -564,7 +659,7 @@ public class Main extends Application { VBox numbersVBox = setupNumbersVBox(); HBox gridHBox = new HBox(); gridHBox.getChildren().addAll(fontSizeVBox, gridPane, numbersVBox); - gridHBox.setSpacing(20); + gridHBox.setSpacing(10); gridHBox.setAlignment(Pos.CENTER); HBox bottomHBox = setupBottomHBox(); @@ -609,6 +704,53 @@ public class Main extends Application { stage.setScene(scene); stage.setTitle("Mathdoku"); stage.show(); + + } + + private void resetGrid() { + stage.close(); + initialiseVariables(); + VBox vBox = new VBox(); + int width = 300 + 80 * N; + int height = 300 + 80 * N; + + Stage stage = new Stage(); + Scene newScene = new Scene(vBox, width, height); + stage.setWidth(width); + stage.setHeight(height); + vBox.setSpacing(5); + vBox.setPadding(new Insets(20)); + vBox.setAlignment(Pos.CENTER); + + GridPane gridPane = setupGrid(width - 200, height - 120); + undoStack.push(new GameState(GameState.getCurrentGameState(gridNumbers))); + + fontSize = 18; + changeFontSizeEvent(fontSize); + HBox topHBox = setupTopHBox(); + + VBox fontSizeVBox = setupFontSizeHBox(); + VBox numbersVBox = setupNumbersVBox(); + HBox gridHBox = new HBox(); + gridHBox.getChildren().addAll(fontSizeVBox, gridPane, numbersVBox); + gridHBox.setSpacing(10); + gridHBox.setAlignment(Pos.CENTER); + + HBox bottomHBox = setupBottomHBox(); + + vBox.getChildren().addAll(topHBox, gridHBox, bottomHBox); + + stageWidthResizeEvent(stage, gridPane); + stageHeightResizeEvent(stage, gridPane); + + stage.setMinWidth(width + 50); + stage.setMinHeight(height + 50); + stage.setScene(newScene); + stage.setTitle("Mathdoku"); + stage.show(); + scene = newScene; + this.stage = stage; + } private static void initialiseVariables() { @@ -618,10 +760,14 @@ public class Main extends Application { gridBoxes = new VBox[N*N]; gridCages = new ArrayList<Cage>(); gridErrors = new boolean[N*N][3]; + previousPane = null; + previousSquare = null; + clearing = false; + undoing = false; } public static void main(String[] args) { - N = Integer.parseInt(args[0]); + N = 4; initialiseVariables(); launch(args); } diff --git a/src/coursework/RandomGenerator.java b/src/coursework/RandomGenerator.java index d0d26ac4cef6414c796c5c2599f317d2be61d41b..fcd6a00ca20bb175efa835724c5c90afed50c58b 100644 --- a/src/coursework/RandomGenerator.java +++ b/src/coursework/RandomGenerator.java @@ -1,29 +1,35 @@ package coursework; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Random; public class RandomGenerator { - private static int N = 6; - private static int[][] grid = new int[N][N]; + private int N; + private int[][] grid; - private static List<Integer> uncagedGrids = new ArrayList<Integer>(); - private static List<Integer> possibleMoves; + private List<Integer> uncagedGrids = new ArrayList<Integer>(); + private List<Integer> possibleMoves = new ArrayList<Integer>(); + private List<Cage> gridCages = new ArrayList<Cage>(); - public static void main(String[] args) { - generate(); + public RandomGenerator(int N) { + this.N = N; + grid = new int[N][N]; } - private static void generate() { + public List<Cage> generate() { generateGridValues(); shuffleGridValues(); generateCages(); + return gridCages; } - private static void generateCages() { + private void generateCages() { Random random = new Random(); addAllGrids(); while (uncagedGrids.size() > 0) { @@ -102,16 +108,78 @@ public class RandomGenerator { uncagedGrids.remove(uncagedGrids.indexOf(id)); } } + + int cageValue; + String cageOperator; + List<Integer> cageValues = new ArrayList<Integer>(); + HashSet<Integer> hashSetIds = new HashSet<Integer>(); + for (int cageId : cageIds) { + hashSetIds.add(cageId); + } + + if (hashSetIds.size() > 1) { + for (int cageId : hashSetIds) { + int row = cageId / N; + int col = cageId % N; + cageValues.add(grid[row][col]); + } + Collections.sort(cageValues, Collections.reverseOrder()); + + Map<String, Integer> possibleValues = new HashMap<String, Integer>(); + + int additionResult = 0; + for (int value : cageValues) { + additionResult += value; + } + possibleValues.put("+", additionResult); + + int subtractionResult = cageValues.get(0); + for (int i = 1; i < cageValues.size(); i++) { + subtractionResult -= cageValues.get(i); + } + if (subtractionResult > 0) { + possibleValues.put("-", subtractionResult); + } + + int multiplicationResult = 1; + for (int value : cageValues) { + multiplicationResult *= value; + } + possibleValues.put("x", multiplicationResult); + + float divisionResult = cageValues.get(0); + for (int i = 1; i < cageValues.size(); i++) { + divisionResult /= cageValues.get(i); + } + if (divisionResult == (int) divisionResult) { + possibleValues.put("�", (int) divisionResult); + } + + + List<String> keySet = new ArrayList<String>(possibleValues.keySet()); + cageOperator = keySet.get(random.nextInt(keySet.size())); + cageValue = possibleValues.get(cageOperator); + } + else {; + int row = cageIds[0] / N; + int col = cageIds[0] % N; + cageValue = grid[row][col]; + cageOperator = ""; + } - String operator = "+"; - int value = 0; + int[] finalCageIds = new int[hashSetIds.size()]; + int counter = 0; + for (int cageId : hashSetIds) { + finalCageIds[counter] = cageId; + counter++; + } - //Cage cage = new Cage(cageIds, value, operator); + gridCages.add(new Cage(cageIds, cageValue, cageOperator)); } } - private static void centre(int id) { + private void centre(int id) { if (!uncagedGrids.contains(id + N)) possibleMoves.remove(possibleMoves.indexOf(id + N)); if (!uncagedGrids.contains(id - N)) @@ -122,7 +190,7 @@ public class RandomGenerator { possibleMoves.remove(possibleMoves.indexOf(id - 1)); } - private static void topLeftCorner(int id) { + private void topLeftCorner(int id) { possibleMoves.remove(possibleMoves.indexOf(id - 1)); possibleMoves.remove(possibleMoves.indexOf(id - N)); if (!uncagedGrids.contains(id + 1)) @@ -131,7 +199,7 @@ public class RandomGenerator { possibleMoves.remove(possibleMoves.indexOf(id + N)); } - private static void topRightCorner(int id) { + private void topRightCorner(int id) { possibleMoves.remove(possibleMoves.indexOf(id - N)); possibleMoves.remove(possibleMoves.indexOf(id + 1)); if (!uncagedGrids.contains(id - 1)) @@ -140,7 +208,7 @@ public class RandomGenerator { possibleMoves.remove(possibleMoves.indexOf(id + N)); } - private static void bottomRightCorner(int id) { + private void bottomRightCorner(int id) { possibleMoves.remove(possibleMoves.indexOf(id + N)); possibleMoves.remove(possibleMoves.indexOf(id + 1)); if (!uncagedGrids.contains(id - 1)) @@ -149,7 +217,7 @@ public class RandomGenerator { possibleMoves.remove(possibleMoves.indexOf(id - N)); } - private static void bottomLeftCorner(int id) { + private void bottomLeftCorner(int id) { possibleMoves.remove(possibleMoves.indexOf(id + N)); possibleMoves.remove(possibleMoves.indexOf(id - 1)); if (!uncagedGrids.contains(id + 1)) @@ -158,7 +226,7 @@ public class RandomGenerator { possibleMoves.remove(possibleMoves.indexOf(id - N)); } - private static void leftEdge(int id) { + private void leftEdge(int id) { possibleMoves.remove(possibleMoves.indexOf(id - 1)); if (!uncagedGrids.contains(id + N)) possibleMoves.remove(possibleMoves.indexOf(id + N)); @@ -168,7 +236,7 @@ public class RandomGenerator { possibleMoves.remove(possibleMoves.indexOf(id + 1)); } - private static void topEdge(int id) { + private void topEdge(int id) { possibleMoves.remove(possibleMoves.indexOf(id - N)); if (!uncagedGrids.contains(id + N)) possibleMoves.remove(possibleMoves.indexOf(id + N)); @@ -178,7 +246,7 @@ public class RandomGenerator { possibleMoves.remove(possibleMoves.indexOf(id - 1)); } - private static void rightEdge(int id) { + private void rightEdge(int id) { possibleMoves.remove(possibleMoves.indexOf(id + 1)); if (!uncagedGrids.contains(id - N)) possibleMoves.remove(possibleMoves.indexOf(id - N)); @@ -188,7 +256,7 @@ public class RandomGenerator { possibleMoves.remove(possibleMoves.indexOf(id - 1)); } - private static void bottomEdge(int id) { + private void bottomEdge(int id) { possibleMoves.remove(possibleMoves.indexOf(id + N)); if (!uncagedGrids.contains(id - N)) possibleMoves.remove(possibleMoves.indexOf(id - N)); @@ -198,13 +266,13 @@ public class RandomGenerator { possibleMoves.remove(possibleMoves.indexOf(id + 1)); } - private static void addAllGrids() { + private void addAllGrids() { for (int i = 0; i < N*N; i++) { uncagedGrids.add(i); } } - private static int isEdgeGrid(int gridId) { + private int isEdgeGrid(int gridId) { if (gridId % N == 0) // left edge return 0; if (gridId % N == N - 1) // right edge @@ -216,7 +284,7 @@ public class RandomGenerator { return -1; // not an edge grid } - private static int isCornerGrid(int gridId) { + private int isCornerGrid(int gridId) { if ((int) gridId / N == 0 && gridId % N == 0) // top left corner return 0; if ((int) gridId / N == N - 1 && gridId % N == N - 1) // bottom right corner @@ -228,7 +296,7 @@ public class RandomGenerator { return -1; // not a corner } - private static void generateGridValues() { + private void generateGridValues() { int counter = 1; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { @@ -245,7 +313,7 @@ public class RandomGenerator { } } - private static void shuffleGridValues() { + private void shuffleGridValues() { Random random = new Random(); for (int i = 0; i < 15; i++) { int[] colsSwap = new int[2]; @@ -266,11 +334,11 @@ public class RandomGenerator { } } - private static int[] generateValues(Random random) { + private int[] generateValues(Random random) { return new int[] { random.nextInt(N), random.nextInt(N) }; } - private static void swapColumns(int colA, int colB) { + private void swapColumns(int colA, int colB) { int[][] columns = new int[N][2]; for (int i = 0; i < N; i++) { columns[i][0] = grid[i][colA]; @@ -282,7 +350,7 @@ public class RandomGenerator { } } - private static void swapRows(int rowA, int rowB) { + private void swapRows(int rowA, int rowB) { int[][] rows = new int[N][2]; for (int i = 0; i < N; i++) { rows[i][0] = grid[rowA][i]; @@ -294,7 +362,7 @@ public class RandomGenerator { } } - private static void transpose() { + private void transpose() { int[][] temp = new int[N][N]; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { @@ -304,7 +372,7 @@ public class RandomGenerator { grid = temp; } - private static void output() { + private void output() { for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { System.out.print(grid[i][j] + " ");