From 202195d035e99c9b2715408f565e25ecd811bdfc Mon Sep 17 00:00:00 2001 From: Nimrod Abramovich <grumpydormin@gmail.com> Date: Wed, 11 Mar 2020 10:10:33 +0000 Subject: [PATCH] moved constraint handling to new class --- bin/coursework/Constraints.class | Bin 0 -> 4358 bytes bin/coursework/Main.class | Bin 24854 -> 22761 bytes src/coursework/Constraints.java | 138 ++++++++++++++++++++++ src/coursework/Main.java | 192 ++++++++----------------------- 4 files changed, 184 insertions(+), 146 deletions(-) create mode 100644 bin/coursework/Constraints.class create mode 100644 src/coursework/Constraints.java diff --git a/bin/coursework/Constraints.class b/bin/coursework/Constraints.class new file mode 100644 index 0000000000000000000000000000000000000000..3c70c8fb30b14d6a2391e0f208b022abb821ebc1 GIT binary patch literal 4358 zcmX^0Z`VEs1_l#`&Fl<Jj0|GQ`K3k0spa`a+4|1;dBr6~iJ5sN#q10$j0^%<iDilU zIf;4c`u<5-smUdb4BY8OnJIpyxk;%-#f%J!(LNw0X%+g#$*Fm%`pNluB}Mr;`XQ+m zC2pCiIVskR44fbxPWct7#f%KnXzFtkEAvZB^uwI;D_|;}6VpK|1;7UDmzHGa==)?A zmw=>$Gt=`DOG=AU85xw(q-}hVy^)xnYHerD$iM}%+O?=CALLf%=;$a$1~!|_yv!0i zMh0dL%`ip=7U%qwR4xW)24Nlseg*+{22n-^Is9JYWME_v=V4%FU}I;HWMq&)QH|sw zkUD7|26hGxb_Q8S24Rpoh<_Z5iV`b9p5kJVVGstXQ{Z9XWZ+_F-~(}#c^G&Z_!t@Z zeKPY>AweCIn3R*s$ROmCpPZNzmROVt;zI>lN-{Ew85tx{LI4qwpkOF1NJ%V7bxABq z<YLfb&|zoLW@O+;3NYWq%sd_jT?Rcy2EO#v5_jY%R@Tr&i!{tg2AOKW!(hl@#K^z{ zH2@mpvKZQtg2)=A(S(P=l)((45t;ymG&IrT7_8cYhryD;ijjdAY7H!QSv54l@hgy= zk(!*1l#m%2*fcynqcp>~7#JDsco;Mo1VAhY9tKASCq@Q=<ouk{+&qK^Mg~?5Pfv() z7aj&zkRslq{Bnc}kal+-1`m)7Uvgr4Dyozh4}&*@4<iF#MrL|OPG)*WiF0aBPB9|` zi$)YE$uTGA=P)ubdNMLF7v+~TGVl~<<d^$q7MCPugAzVt6v+Hw9)=KxP(}vcl>F4< zp#1Wn)PmH+5|A05nqURtJPZ*Gk&Fx+$vLTsML{5gSTvx{j^<&A0m<>eT>zHn4K7Jc z&h||#04E%FhImE>K}4eTNG#3>PA%bLh+`1uVh~|S;$cW;NMU4PPfslYWoJeP5m=0X z3xwd3qRhN>YmoXh9)@&=43Jy$^GXsk^NJZ6L^U9h2UZFxJFGRMI2f`R85p=2av1X1 z8FEp|7l?5@4EZ2~*is8i6LX3|W*71>6oG`86H`(c8Q6-T;lNpxUmlj2Qwj<(VTe`W zq5|p*YeojPJa8ce$~0h4f?Wc!#hQ_UF_V!&3^g}Z7Nmj$hLJ%X(?A=D5V9e5)}V;0 z;bEu+MU((2qMX5L2@+Qz$$B1!22ezBgChwd3leYQVQ2=4^TQ(uBFD(UnVg>k@fSBk z8$$;>Lpvh_AK3k1?|}*p9)?baE=C5H;>@a4a53fyQrg4A(96)r$iR_Vl3J8ll3&Eg zAO?#suvSl~xHUJ!1cpiM3=<g{gb)V9WO*1SGfZJ*V986ZC_#^LXf(1jOhYX_KpB>c zVJgE69)_6=vp}V8Y6(cpGX<RJHKRR2R?gvJn9DGak%2uUvDgo6I<p2SDNkisz{9W* zB*PEMx{2wjkPu*G;3`f{EK1G*8OF#Uh*H3Tig-o_7EtzMWMIlnVPxPhOU%hk0jY&( zXJ=T!$iNis$-%ISkwHT@twJ{`F*!TED8Do>MK?J=C%?!_p(s5mQNzg8RL1}W^-MLb zxfmoE*6=W_Wmw0^z)_r95?oRVDtS@TGc*-xhH)@#U}R7u#%N7YF&vy<T9lmXmI*RY z08wZZ>w)5dL6L!xfti7UfrWtyRJkxPFff5C4=~Ni07^F8U^Wi}6R3V*U|`^7U<6fK z42%qd3=9m}49pCS3=9mqTH6_fv;<W4GKg$t5CbzLwlYX*?PidP+|D4kl|f!hK!xon zgCf&b2BnQ)BUKm}7^E237#J7?8CV#&8F(3Z7{nNO859}#7<3o}8B`e<7<eFtGpI4B zgY{@I2tX|kXJ7)$$!hIj&;(hzgFzo;;SL64kYzg<%uy^7V_;=qU=U$oXAouJV-RBy zWe{hOVUR$wL>6iZBZD=A4b+kf24)5p1_lNht?dl9S~Akx8SKHNGnjPKlHJDOiS8L` z1{MYx1}+9!1_1^+1~CSC25ANbusvE3v!M1cFvu|YGWdZ#A;aL$;K#rOvWX#pA&`NY zfeBOxKwXi?zyyvXF)ius3_-IPxIuK-at00%9R;$VnE@1-5I-t2a4@Ja@G__}2r#HK zh%#t`?N)%80JmEVY$GV<#K5j#Vu*#L0s&A;2w@0?*v%-zzzmKeA7<O#3~`a$84~=M z%~+Q+m}zZc5R(>Q%MfKvFxtkDXvLx{$+C?hbtZ$5B#ThyHiqn33>+-B%Ne-9;sxO? ztc;?p0&ENapOjexwh827Ee0+I1_m7lCI(#wE(U!D0R{sGMFv9#69yv&GX`S@O9oR0 z2L^oxF9r*+FYF+0f&0P->I)_YFNR`<Kn5lTE(Rxt5{6O+W(GwDC5AGFat0O#UItr+ z3I;z0R)$Jwl7gtJVqgaQ+Jb@QKZ5|MWyQ$I$j%T4ijw~f8VCV)h8#u)2DbkUOb9WM zA_gW<bq)zB21G2$Y-gwj#gfc+hB{Cz$!uq6M2{sK1`Y;W23`g`1_1^K22lnlu>VMl zrCQ=*2^8!Z(iF#%D+3dQ8v_@E2ZI2ECxaq`7lR3dH-j024}&FxAA<vf2ZI+wAlMg} zu>?uysIk;SR4lbHP$QN+7@Q!n#JGxq8Jy;3Xl-GT-^tL*$S{wgkI@gp>t<xIVqMPQ zB+0syp`VfA0K-%(7Er359%;q7&y0iFjD0zSoFu0xyPg@FC>tpC%Oosd;FM(XTh74S z!p<nlF3Pd+|3i@W*^CUc{_oP=#xUQEMRyy+^hhg?eP-;;W^BtDBqTXR+4Rg<wYD%Q ziLx58in4^XurZ3ViLx*J{~VD{tQhzh7#Knsco@PM_!z<&G#DZn92g=Qycwbx{1~Dc z0vRG0q8Y*&QW+8$vKbN?ni!H8dKnTKrZc31V<CuvgMooz20X9KfaVpD7$`oN82A`E z85S`tW?*K}U@&G_!myZug~5SAkYOo<9|IdhHiHhsGKN3~7KSDUZm<|DIJaalaQtVG zfoFuN4D1XO7#Ki8T<i?s3^bLUVJb)vl$n+@Fo-k#XJErrFVDaUQ_si%RVo5f$qW_- z7xxhik&t*}C}Cg*mteBYw#ykrKtTryej{e)kQOFJ8Bodc1`&8d;G#Bzft4YXL6{+f zL53k494L?s1}o|r7-XS=!o(m2E+QbsAUgxo9|l%N0R|>eOA4n8WCYki`HBUP3-TCP z8S)u~8S)rp7z%N?02CRF3^-j7Lqr&`;0}Wl23Cer24RL01{sEO94-J=K6qTvjK>AA zFu>!2Dh5`DY6fA3Dh3&bS{yFG8wQM^t_?I6Hbd(|Ur;)50i^>OBWB}S43ZEgi}5T5 zJ_wW5cqW6W^h^dptt|{vGDboxw=t|<4weM*)^B524Nf;I3;*vyq#HQ~b_NE91_oA! zMg}d0CI(Z6W(Es}Rt9H=1_mF74kXw6!ZVgHxXK2FpBGXZ;$mP0r6C1DE>JrKWCIh! FCICBTMJoUR literal 0 HcmV?d00001 diff --git a/bin/coursework/Main.class b/bin/coursework/Main.class index 3d978104687481173a895a9c50c1b4e9b64dec3b..4ff668e892537ec5df1044acc4cfbe5cf09b0d2b 100644 GIT binary patch literal 22761 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 VlFXURX)JOMlFaPPj4bjDk^sRvIw}AF literal 24854 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 diff --git a/src/coursework/Constraints.java b/src/coursework/Constraints.java new file mode 100644 index 0000000..eafc645 --- /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 35d0332..86f2cb4 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(); -- GitLab