From 276b3df94c8eb0e479f9a4d5f75fa2db35de5c3f Mon Sep 17 00:00:00 2001 From: tmp1u19 <tmp1u19@soton.ac.uk> Date: Sun, 12 Apr 2020 15:11:52 +0300 Subject: [PATCH] Animation implemented: cells change colors randomly --- Cage.java | 19 ++++++++--- Cell.java | 48 +++++++++++++++++--------- GameScene.java | 73 +++++++++++++++++++++++++++++++++------ Handler.java | 74 +++++++++++++++++++++++++++++++--------- Window.java | 92 ++++++++++++++++++++++++++++++++++++++++++-------- 5 files changed, 245 insertions(+), 61 deletions(-) diff --git a/Cage.java b/Cage.java index 7158531..0a98e9b 100644 --- a/Cage.java +++ b/Cage.java @@ -1,3 +1,4 @@ + import java.util.ArrayList; public class Cage { @@ -24,6 +25,8 @@ public class Cage { cell = new Cell(n, i, j); } + cell.setCellNumber(cellNumber); + cells.add(cell); } @@ -44,10 +47,6 @@ public class Cage { this.label = label; } - public String getLabel() { - return label; - } - public char getSymbol() { return symbol; } @@ -103,10 +102,20 @@ public class Cage { public boolean isCompleted() { for(Cell cell : getCells()) { - if(!cell.isNumeric(cell.getTextField().getText())) { + if(!isNumeric(cell.getTextField().getText())) { return false; } } return true; } + + public boolean isNumeric(String x) { + try { + Integer.parseInt(x); + } catch (NumberFormatException e) { + return false; + } + return true; + } } + diff --git a/Cell.java b/Cell.java index 8ee6022..9d98c1a 100644 --- a/Cell.java +++ b/Cell.java @@ -4,12 +4,15 @@ import javafx.scene.control.TextField; import javafx.scene.layout.*; import javafx.scene.text.Font; import javafx.scene.control.*; +import javafx.scene.text.FontWeight; public class Cell extends Pane { private TextField input; private int i; private int j; + private int cellNumber; + private Label l; public Cell(int n, int i, int j) { @@ -17,39 +20,30 @@ public class Cell extends Pane { this.j = j; input = new TextField(); - setPrefSize(400/n, 400/n); - setStyle("- fx-background-color: transparent;"); - input.setStyle("-fx-text-box-border: transparent; -fx-background-color: transparent;" + - "-fx-font-weight: bold;"); + input.setStyle("-fx-text-box-border: transparent; -fx-background-color: transparent;"); + input.setFont(Font.font("Verdana", FontWeight.BOLD, 20)); input.setAlignment(Pos.CENTER); - input.setFont(Font.font(20)); - input.setPrefWidth(400/n); - input.setPrefHeight(400/n); getChildren().addAll(input); } public void setLabel(String label) { - Label l = new Label(label); + l = new Label(label); l.setPadding(new Insets(5)); l.setAlignment(Pos.TOP_LEFT); getChildren().add(l); } + public Label getLabel() { + return l; + } + public TextField getTextField() { return input; } - public boolean isNumeric(String text) { - try { - Integer.parseInt(text); - return true; - } catch(Exception e) { - return false; - } - } public int getRow() { return i; } @@ -77,4 +71,26 @@ public class Cell extends Pane { } return false; } + + public boolean isAdjacent(Cage cage) { + for(Cell cell : cage.getCells()) { + if((cell.getCellNumber() == getCellNumber() - 1 || + cell.getCellNumber() == getCellNumber() + 1 || + cell.getCellNumber() == getCellNumber() - 8 || + cell.getCellNumber() == getCellNumber() + 8) && + cell.getCellNumber() != getCellNumber()) { + return true; + } + } + return false; + } + + public void setCellNumber(int cellNumber) { + this.cellNumber = cellNumber; + } + + public int getCellNumber() { + return cellNumber; + } } + diff --git a/GameScene.java b/GameScene.java index 1bfce62..ffd89a1 100644 --- a/GameScene.java +++ b/GameScene.java @@ -18,8 +18,8 @@ import java.util.ArrayList; public class GameScene extends Application { - boolean sizeSelected = false; private ArrayList<Cage> cages = new ArrayList<Cage>(); + private Window window = new Window(); public static void main(String[] args) { launch(args); @@ -29,7 +29,6 @@ public class GameScene extends Application { public void start(Stage stage) { FileChooser fileChooser = new FileChooser(); - Window window = new Window(); VBox root = new VBox(20); root.setPrefSize(800, 700); root.setAlignment(Pos.TOP_CENTER); @@ -63,7 +62,8 @@ public class GameScene extends Application { buttons.setAlignment(Pos.TOP_CENTER); Button play = new Button("Play"); - play.setStyle("-fx-font-size: 20px; -fx-font-weight:bold;"); + play.setStyle("-fx-font-size: 20px; -fx-font-weight:bold; -fx-background-color: MediumSeaGreen;" + + "-fx-border-color: black; -fx-border-width: 4 4 4 4;"); play.setDisable(true); Label size = new Label("Choose size: "); @@ -101,7 +101,7 @@ public class GameScene extends Application { @Override public void changed(ObservableValue<? extends String> observableValue, String oldValue, String newValue) { - sizeSelected = true; + size.setDisable(true); input.setDisable(false); cbInput.setDisable(false); @@ -114,6 +114,8 @@ public class GameScene extends Application { int n = Character.getNumericValue(cbSize.getSelectionModel().getSelectedItem().toString().charAt(0)); + //play.setDisable(false); + if(newValue.equals("file")) { if(cbSize.getSelectionModel().getSelectedItem() != null) { @@ -122,18 +124,19 @@ public class GameScene extends Application { if(file != null) { try { - openFile(file, n); + openFile(file, n, play); } catch (IOException e) { e.printStackTrace(); } + } else { + play.setDisable(true); } } } else if(newValue.equals("text area")) { - directInput(n); + directInput(n, play); } input.setDisable(true); - play.setDisable(false); } }); @@ -166,7 +169,7 @@ public class GameScene extends Application { stage.setResizable(false); } - public void openFile(File file, int n) throws IOException { + public boolean openFile(File file, int n, Button play) throws IOException { BufferedReader buffer = new BufferedReader(new FileReader(file.getPath())); @@ -199,9 +202,58 @@ public class GameScene extends Application { cages.add(cage); line = buffer.readLine(); } + + try { + if(!checkUniqueCells(n)) { + cages = new ArrayList<Cage>(); + play.setDisable(true); + window.inputError("The cells are not part of exactly " + + "one cage.").showAndWait(); + return false; + } + } catch (ArrayIndexOutOfBoundsException e) { + cages = new ArrayList<Cage>(); + play.setDisable(true); + window.inputError("Some cells don't belong to the bord").showAndWait(); + return false; + } + + play.setDisable(false); + return true; } - public void directInput(int n) { + public boolean checkUniqueCells(int n) throws IOException { + + int[] verify = new int[n*n + 1]; + + for(Cage cage : cages) { + for(Cell cell : cage.getCells()) { + verify[cell.getCellNumber()] += 1; + } + } + + for(int i = 1; i <= n*n; i ++) { + if(verify[i] != 1) { + return false; + } + } + + return true; + } + + public boolean checkAdjacent() { + + for(Cage cage : cages) { + for(Cell cell : cage.getCells()) { + if(!cell.isAdjacent(cage)) { + return false; + } + } + } + return true; + } + + public void directInput(int n, Button play) { VBox root = new VBox(10); root.setPadding(new Insets(20)); @@ -223,6 +275,7 @@ public class GameScene extends Application { Scene scene = new Scene(root); Stage stage = new Stage(); stage.setScene(scene); + play.setDisable(true); ok.setOnAction(new EventHandler<ActionEvent>() { @Override @@ -238,7 +291,7 @@ public class GameScene extends Application { } try { - openFile(file, n); + openFile(file, n, play); } catch (IOException e) { e.printStackTrace(); } diff --git a/Handler.java b/Handler.java index c9d0fd8..975b2c7 100644 --- a/Handler.java +++ b/Handler.java @@ -1,3 +1,4 @@ +import javafx.animation.*; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.event.ActionEvent; @@ -13,9 +14,11 @@ import javafx.scene.layout.BackgroundFill; import javafx.scene.layout.CornerRadii; import javafx.scene.layout.GridPane; import javafx.scene.paint.Color; +import javafx.scene.text.Font; +import javafx.scene.text.FontWeight; +import javafx.util.Duration; import java.util.ArrayList; -import java.util.Collections; public class Handler { @@ -78,7 +81,7 @@ public class Handler { } if(verify() && verifyCages()) { - window.win("Congratulations!", "You won the game!"); + win(); } else { window.win("Too bad...", "You lost the game"); } @@ -137,13 +140,30 @@ public class Handler { }); } + public void changeFont(Button button, int number) { + button.setOnAction(new EventHandler<ActionEvent>() { + @Override + public void handle(ActionEvent actionEvent) { + for(Cage cage : cages) { + for(Cell cell : cage.getCells()) { + + cell.getTextField().setStyle("-fx-text-box-border: transparent; " + + "-fx-background-color: transparent;"); + cell.getTextField().setFont(Font.font("Verdana", FontWeight.BOLD, number)); + } + cage.getCells().get(0).getLabel().setFont(Font.font(number - 10)); + } + } + }); + } + public void addActions(GridPane grid, Button undo) { for(Node cell : grid.getChildren()) { ((Cell) cell).getTextField().textProperty().addListener(new ChangeListener<String>() { @Override public void changed(ObservableValue<? extends String> observableValue, String s, String t1) { - if(((Cell) cell).isNumeric(((Cell) cell).getTextField().getText())) { + if(isNumeric(((Cell) cell).getTextField().getText())) { Element e = new Element(((Cell) cell).getRow(), ((Cell) cell).getColumn(), Integer.parseInt(((Cell) cell).getTextField().getText())); undoStack.push(e); @@ -173,7 +193,7 @@ public class Handler { public void changed(ObservableValue<? extends String> observableValue, String oldValue, String newValue) { - if (cell.isNumeric(newValue)) { + if (isNumeric(newValue)) { if (Integer.parseInt(newValue) > n || Integer.parseInt(newValue) == 0) { cell.getTextField().setText(oldValue); } else { @@ -210,20 +230,16 @@ public class Handler { public void drawGrid(GridPane grid) { for(Cage cage : cages) { - cage.getCells().get(0).setStyle("-fx-border-color: black; -fx-border-width: 2 2 2 2;"); - for(Cell cell : cage.getCells()) { - if(cell != cage.getCells().get(0)) { - if(cell.hasLeftNeighbour(cage) && cell.hasUpNeighbour(cage)) { - cell.setStyle("-fx-border-color: black; -fx-border-width: 0 2 2 0;"); - } else if(cell.hasLeftNeighbour(cage)) { - cell.setStyle("-fx-border-color: black; -fx-border-width: 2 2 2 0;"); - } else if(cell.hasUpNeighbour(cage)) { - cell.setStyle("-fx-border-color: black; -fx-border-width: 0 2 2 2;"); - } else { - cell.setStyle("-fx-border-color: black; -fx-border-width: 2 2 2 2;"); - } + if(cell.hasLeftNeighbour(cage) && cell.hasUpNeighbour(cage)) { + cell.setStyle("-fx-border-color: black; -fx-border-width: 0 4 4 0;"); + } else if(cell.hasLeftNeighbour(cage)) { + cell.setStyle("-fx-border-color: black; -fx-border-width: 4 4 4 0;"); + } else if(cell.hasUpNeighbour(cage)) { + cell.setStyle("-fx-border-color: black; -fx-border-width: 0 4 4 4;"); + } else { + cell.setStyle("-fx-border-color: black; -fx-border-width: 4 4 4 4;"); } doubleClick(cell); @@ -436,6 +452,23 @@ public class Handler { } } + public void win() { + Timeline timeline = new Timeline(new KeyFrame(Duration.millis(100), new EventHandler<ActionEvent>() { + @Override + public void handle(ActionEvent actionEvent) { + for(Cage cage : cages) { + for(Cell cell : cage.getCells()) { + cell.setBackground(new Background(new BackgroundFill(Color.color(Math.random(), Math.random(), + Math.random()), CornerRadii.EMPTY, Insets.EMPTY))); + } + } + } + })); + + timeline.setCycleCount(Transition.INDEFINITE); + timeline.play(); + } + public Cell getCell(GridPane grid, int i, int j) { for(Node cell : grid.getChildren()) { if(((Cell) cell).getRow() == i && ((Cell) cell).getColumn() == j) { @@ -452,5 +485,14 @@ public class Handler { public void setN(int n) { this.n = n; } + + public boolean isNumeric(String x) { + try { + Integer.parseInt(x); + } catch (NumberFormatException e) { + return false; + } + return true; + } } diff --git a/Window.java b/Window.java index c6033b1..a7a5656 100644 --- a/Window.java +++ b/Window.java @@ -11,11 +11,8 @@ import javafx.scene.text.Font; import javafx.stage.Modality; import javafx.stage.Stage; import javafx.stage.StageStyle; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; import java.util.ArrayList; +import java.util.TimerTask; public class Window { @@ -131,6 +128,15 @@ public class Window { return alert; } + public Alert inputError(String comment) { + Alert alert = new Alert(Alert.AlertType.ERROR); + alert.setTitle("Error"); + alert.setHeaderText("Input error"); + alert.setContentText(comment); + + return alert; + } + public Stage mathdokuStage(int n, ArrayList<Cage> cages) { this.n = n; @@ -138,6 +144,12 @@ public class Window { Handler handler = new Handler(n, cages); handler.setN(n); Stage stage = new Stage(); + TimerTask task= new TimerTask() { + @Override + public void run() { + + } + }; VBox root = new VBox(5); root.setAlignment(Pos.CENTER); @@ -146,17 +158,26 @@ public class Window { HBox buttons = new HBox(); buttons.setAlignment(Pos.CENTER); - HBox sizes = new HBox(5); - sizes.setAlignment(Pos.CENTER); - GridPane grid = new GridPane(); grid.setAlignment(Pos.CENTER); - grid.setPadding(new Insets(20)); + grid.setStyle("-fx-border-color: black; -fx-border-width: 4 4 4 4;"); Button undo = new Button("Undo"); Button redo = new Button("Redo"); Button help = new Button("Enable Help"); Button clear = new Button("Clear"); + Button hint = new Button("Hint"); + + undo.setStyle("-fx-font-size: 20px; -fx-font-weight:bold; -fx-background-color: MediumSeaGreen;" + + "-fx-border-color: black; -fx-border-width: 4 4 4 4;"); + redo.setStyle("-fx-font-size: 20px; -fx-font-weight:bold; -fx-background-color: MediumSeaGreen;" + + "-fx-border-color: black; -fx-border-width: 4 4 4 4;"); + help.setStyle("-fx-font-size: 20px; -fx-font-weight:bold; -fx-background-color: MediumSeaGreen;" + + "-fx-border-color: black; -fx-border-width: 4 4 4 4;"); + clear.setStyle("-fx-font-size: 20px; -fx-font-weight:bold; -fx-background-color: MediumSeaGreen;" + + "-fx-border-color: black; -fx-border-width: 4 4 4 4;"); + hint.setStyle("-fx-font-size: 20px; -fx-font-weight:bold; -fx-background-color: MediumSeaGreen;" + + "-fx-border-color: black; -fx-border-width: 4 4 4 4;"); undo.setDisable(true); redo.setDisable(true); @@ -166,31 +187,74 @@ public class Window { handler.undoAction(undo, redo, grid); handler.redoAction(redo, grid); - buttons.getChildren().addAll(undo, redo, help, clear); + buttons.getChildren().addAll(undo, redo, help, clear, hint); handler.drawGrid(grid); - handler.addActions(grid, undo); + Button small = new Button("Small"); + Button medium = new Button("Medium"); + Button large = new Button("Large"); + + small.setStyle("-fx-font-size: 20px; -fx-font-weight:bold; -fx-background-color: MediumSeaGreen;" + + " -fx-border-color: black; -fx-border-width: 4 4 4 4;"); + medium.setStyle("-fx-font-size: 20px; -fx-font-weight:bold; -fx-background-color: MediumSeaGreen; " + + "-fx-border-color: black; -fx-border-width: 4 4 4 4;"); + large.setStyle("-fx-font-size: 20px; -fx-font-weight:bold; -fx-background-color: MediumSeaGreen; " + + "-fx-border-color: black; -fx-border-width: 4 4 4 4;"); + + HBox sizes = new HBox(5); + sizes.setAlignment(Pos.CENTER); + + sizes.getChildren().addAll(small, medium, large); + Label note = new Label("Double click the space provided for text in cell"); Button submit = new Button("Submit"); + note.setStyle("-fx-font-size: 15px; -fx-font-weight:bold;"); + submit.setStyle("-fx-font-size: 20px; -fx-font-weight:bold; -fx-background-color: MediumSeaGreen; " + + "-fx-border-color: black; -fx-border-width: 4 4 4 4;"); + + handler.changeFont(small, 20); + handler.changeFont(medium, 30); + handler.changeFont(large, 40); handler.submitButton(submit); root.getChildren().addAll(buttons, grid, sizes, note, submit); + root.widthProperty().addListener((obs, oldVal, newVal) -> { + grid.setMaxWidth((Double) newVal - 100); + for(Cage cage : cages) { + for(Cell cell : cage.getCells()) { + cell.setPrefWidth((Double) newVal - 100); + cell.getTextField().setPrefSize(cell.getWidth(), cell.getHeight()); + } + } + }); + + root.heightProperty().addListener((obs, oldVal, newVal) -> { + grid.setMaxHeight((Double) newVal - 100); + for(Cage cage : cages) { + for(Cell cell : cage.getCells()) { + cell.setPrefHeight((Double) newVal- 100); + cell.getTextField().setPrefSize(cell.getWidth(), cell.getHeight()); + } + } + }); + Scene scene = new Scene(root); stage.setScene(scene); stage.setTitle("Mathdoku"); stage.initStyle(StageStyle.DECORATED); - stage.setX(800); - stage.setY(300); + stage.setX(700); + stage.setY(200); - stage.setMinHeight(600); - stage.setMinWidth(500); + stage.setMinHeight(700); + stage.setMinWidth(700); return stage; } } + -- GitLab