From 6f1d9e77c1a59f1c15fb7dfcc5c58320231693fa Mon Sep 17 00:00:00 2001 From: ayazb7 <60544937+ayazb7@users.noreply.github.com> Date: Sat, 2 Apr 2022 00:14:58 +0100 Subject: [PATCH] Adding Game Logic Changes --- tetrecs/.idea/checkstyle-idea.xml | 16 ++++ tetrecs/.idea/google-java-format.xml | 6 ++ tetrecs/.idea/tetrecs.iml | 8 ++ .../java/uk/ac/soton/comp1206/game/Game.java | 84 ++++++++++++++++-- .../java/uk/ac/soton/comp1206/game/Grid.java | 41 ++++++++- .../uk/ac/soton/comp1206/scene/MenuScene.java | 27 ++++-- tetrecs/src/main/resources/style/game.css | 1 + tetrecs/target/classes/module-info.class | Bin 614 -> 629 bytes tetrecs/target/classes/style/game.css | 1 + .../uk/ac/soton/comp1206/game/Game.class | Bin 1865 -> 4229 bytes .../uk/ac/soton/comp1206/game/Grid.class | Bin 1372 -> 2805 bytes .../ac/soton/comp1206/scene/MenuScene.class | Bin 3337 -> 3670 bytes 12 files changed, 169 insertions(+), 15 deletions(-) create mode 100644 tetrecs/.idea/checkstyle-idea.xml create mode 100644 tetrecs/.idea/google-java-format.xml create mode 100644 tetrecs/.idea/tetrecs.iml diff --git a/tetrecs/.idea/checkstyle-idea.xml b/tetrecs/.idea/checkstyle-idea.xml new file mode 100644 index 0000000..25a0edc --- /dev/null +++ b/tetrecs/.idea/checkstyle-idea.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="CheckStyle-IDEA"> + <option name="configuration"> + <map> + <entry key="checkstyle-version" value="9.2.1" /> + <entry key="copy-libs" value="true" /> + <entry key="location-0" value="BUNDLED:(bundled):Sun Checks" /> + <entry key="location-1" value="BUNDLED:(bundled):Google Checks" /> + <entry key="scan-before-checkin" value="false" /> + <entry key="scanscope" value="JavaOnly" /> + <entry key="suppress-errors" value="false" /> + </map> + </option> + </component> +</project> \ No newline at end of file diff --git a/tetrecs/.idea/google-java-format.xml b/tetrecs/.idea/google-java-format.xml new file mode 100644 index 0000000..2aa056d --- /dev/null +++ b/tetrecs/.idea/google-java-format.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="GoogleJavaFormatSettings"> + <option name="enabled" value="false" /> + </component> +</project> \ No newline at end of file diff --git a/tetrecs/.idea/tetrecs.iml b/tetrecs/.idea/tetrecs.iml new file mode 100644 index 0000000..4a4ce55 --- /dev/null +++ b/tetrecs/.idea/tetrecs.iml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module version="4"> + <component name="CheckStyle-IDEA-Module"> + <option name="configuration"> + <map /> + </option> + </component> +</module> \ No newline at end of file diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/game/Game.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/game/Game.java index a379daf..21b1fb6 100644 --- a/tetrecs/src/main/java/uk/ac/soton/comp1206/game/Game.java +++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/game/Game.java @@ -4,6 +4,9 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import uk.ac.soton.comp1206.component.GameBlock; +import java.util.ArrayList; +import java.util.Random; + /** * The Game class handles the main logic, state and properties of the TetrECS game. Methods to manipulate the game state * and to handle actions made by the player should take place inside this class. @@ -27,6 +30,8 @@ public class Game { */ protected final Grid grid; + private GamePiece currentPiece; + /** * Create a new game with the specified rows and columns. Creates a corresponding grid model. * @param cols number of columns @@ -53,6 +58,7 @@ public class Game { */ public void initialiseGame() { logger.info("Initialising game"); + this.currentPiece = spawnPiece(); } /** @@ -65,14 +71,80 @@ public class Game { int y = gameBlock.getY(); //Get the new value for this block - int previousValue = grid.get(x,y); - int newValue = previousValue + 1; - if (newValue > GamePiece.PIECES) { - newValue = 0; + logger.info("Block clicked at x = {} y = {}",x,y); + boolean placed = grid.playPiece(currentPiece, x, y); + if (placed) { + this.afterPiece(); + this.nextPiece(); + } + } + + public GamePiece spawnPiece() { + Random rand = new Random(); + int value = rand.nextInt(15); + logger.info("Spawning piece of value " + (value + 1)); + return GamePiece.createPiece(14); + } + + public void nextPiece() { + this.currentPiece = spawnPiece(); + } + + public void afterPiece() { + ArrayList<Integer> fullCols = new ArrayList<>(); + ArrayList<Integer> fullRows = new ArrayList<>(); + + /** + * Check each vertical column to see if it is full + */ + for (int x = 0; x < grid.getCols(); x++) { + boolean full = true; + for (int y = 0; y < grid.getRows(); y++) { + if (grid.get(x,y) == 0) { + full = false; + } + } + if (full) { + fullCols.add(x); + } + } + + /** + * Check each horizontal row to see if it is full + */ + for (int y = 0; y < grid.getCols(); y++) { + boolean full = true; + for (int x = 0; x < grid.getRows(); x++) { + if (grid.get(x,y) == 0) { + full = false; + } + } + if (full) { + fullRows.add(y); + } + } + + if (fullCols.size() != 0 || fullRows.size() != 0) { + logger.info("Removing rows/columns"); + } + + /** + * Removes all columns which are full + */ + for (int x : fullCols) { + for (int y = 0; y < grid.getCols(); y++) { + grid.set(x,y,0); + } } - //Update the grid with the new value - grid.set(x,y,newValue); + /** + * Removes all rows which are full + */ + for (int y : fullRows) { + for (int x = 0; x < grid.getCols(); x++) { + grid.set(x,y,0); + } + } } /** diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/game/Grid.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/game/Grid.java index 4924c99..e876bee 100644 --- a/tetrecs/src/main/java/uk/ac/soton/comp1206/game/Grid.java +++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/game/Grid.java @@ -2,6 +2,9 @@ package uk.ac.soton.comp1206.game; import javafx.beans.property.IntegerProperty; import javafx.beans.property.SimpleIntegerProperty; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import uk.ac.soton.comp1206.App; /** * The Grid is a model which holds the state of a game board. It is made up of a set of Integer values arranged in a 2D @@ -15,7 +18,7 @@ import javafx.beans.property.SimpleIntegerProperty; * The Grid should be linked to a GameBoard for it's display. */ public class Grid { - + private static final Logger logger = LogManager.getLogger(App.class); /** * The number of columns in this grid */ @@ -87,6 +90,42 @@ public class Grid { } } + public boolean canPlayPiece(GamePiece gamePiece, int placeX, int placeY) { + int[][] blocks = gamePiece.getBlocks(); + placeX = placeX - 1; + placeY = placeY - 1; + + for (int x = 0; x < blocks.length; x++) { + for (int y = 0; y < blocks[x].length; y++) { + int value = blocks[x][y]; + if (value == 0) continue; + if (get(x + placeX, y + placeY) != 0) { + logger.info("Cannot place piece here"); + return false; + } + } + } + return true; + } + + public boolean playPiece(GamePiece gamePiece, int placeX, int placeY) { + if (!this.canPlayPiece(gamePiece, placeX, placeY)) return false; + + logger.info("Placing block at x:{} y:{}",placeX,placeY); + int[][] blocks = gamePiece.getBlocks(); + placeX = placeX - 1; + placeY = placeY - 1; + + for (int x = 0; x < blocks.length; x++) { + for (int y = 0; y < blocks[x].length; y++) { + int value = blocks[x][y]; + if (value == 0) continue; + set(x + placeX, y + placeY, value); + } + } + return true; + } + /** * Get the number of columns in this game * @return number of columns diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/MenuScene.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/MenuScene.java index 4bcc9d8..433d719 100644 --- a/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/MenuScene.java +++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/MenuScene.java @@ -1,7 +1,8 @@ package uk.ac.soton.comp1206.scene; -import javafx.event.ActionEvent; +import javafx.geometry.Pos; import javafx.scene.control.Button; +import javafx.scene.input.MouseEvent; import javafx.scene.layout.*; import javafx.scene.text.Text; import org.apache.logging.log4j.LogManager; @@ -43,17 +44,27 @@ public class MenuScene extends BaseScene { var mainPane = new BorderPane(); menuPane.getChildren().add(mainPane); + VBox menuWidgets = new VBox(); + //Awful title var title = new Text("TetrECS"); title.getStyleClass().add("title"); - mainPane.setTop(title); + menuWidgets.getChildren().add(title); + + VBox menuButtons = new VBox(); + + var singlePlay = new Text("Single Player"); + singlePlay.getStyleClass().add("menuItem"); + singlePlay.setOnMouseClicked(this::startGame); + menuButtons.getChildren().add(singlePlay); + + + menuButtons.setAlignment(Pos.CENTER); + menuWidgets.setAlignment(Pos.TOP_CENTER); - //For now, let us just add a button that starts the game. I'm sure you'll do something way better. - var button = new Button("Play"); - mainPane.setCenter(button); + mainPane.setTop(menuWidgets); + mainPane.setCenter(menuButtons); - //Bind the button action to the startGame method in the menu - button.setOnAction(this::startGame); } /** @@ -68,7 +79,7 @@ public class MenuScene extends BaseScene { * Handle when the Start Game button is pressed * @param event event */ - private void startGame(ActionEvent event) { + private void startGame(MouseEvent event) { gameWindow.startChallenge(); } diff --git a/tetrecs/src/main/resources/style/game.css b/tetrecs/src/main/resources/style/game.css index 2b77c42..df6fa61 100644 --- a/tetrecs/src/main/resources/style/game.css +++ b/tetrecs/src/main/resources/style/game.css @@ -58,6 +58,7 @@ -fx-effect: dropshadow(gaussian, black, 1, 1.0, 1, 1); } + .heading { -fx-fill: white; -fx-font-family: 'Orbitron'; diff --git a/tetrecs/target/classes/module-info.class b/tetrecs/target/classes/module-info.class index 169423cbd32058f54488d9da3774220e62112626..b6eb5d5dc3206e20460f1afbfd5d3d22095a88f2 100644 GIT binary patch delta 299 zcmaFH@|A__)W2Q(7#J9A8Pq3og$OY+@EGbD=mz^a1_XQfhX^xpO-vLCFcfCsWn|#X zN-Rs%D^4!TEGWs$OBZI~XJp_9iKSKOCFkdr6y@g>3o{5ZGH^o$(<*Xvgc*bx8F-)q zxv43ciNXw`6OXDfN=$qs!6L=TATl|TQG{89L1wZ%qYR52BZJK3L`G4rywsBN{Gx0T z28GFSjPi_1lj|7e8C53FV^n5QV`Pv7shNC>Q8k@|ft`V~fq{XWfrkM^@-cvb0El1^ s0+S*P3=Con;$SvAgCv-i29vU2QXWhyf=OjCsR||;89=HS8Ng-%005XYi~s-t delta 331 zcmey$@{EP+)W2Q(7#J9A8Pq0ng)j><a84``2{007;9+Fo%StRu)GJOd$}A|!%u5$$ z;A3Rq2Z^Os=q2apl@#UY6bmy5FfwpM1=A{WbA%a$7#Vn=0=cOvnTf&-A``Eu$%->F z2<MgQm8T{Z=O<^UmgpttWTxhoh%iVpGKfqzWE5c*VUV7z$0)-h%g7)z*^p6`H!roM zJijPggh8H>K?)?oU7Vbnmny=b2;--gfsIgRWRL^N^Caiz7UbuF#Z)I>WVB6ZU|?t9 zXkcLAV&G-~k-Q8bzz-rA1i_>*0|SF7gBY02&L9D%rNE>Nn3MyP3Sd$ROsarMMh1{7 IMh38108))Tt^fc4 diff --git a/tetrecs/target/classes/style/game.css b/tetrecs/target/classes/style/game.css index 2b77c42..df6fa61 100644 --- a/tetrecs/target/classes/style/game.css +++ b/tetrecs/target/classes/style/game.css @@ -58,6 +58,7 @@ -fx-effect: dropshadow(gaussian, black, 1, 1.0, 1, 1); } + .heading { -fx-fill: white; -fx-font-family: 'Orbitron'; diff --git a/tetrecs/target/classes/uk/ac/soton/comp1206/game/Game.class b/tetrecs/target/classes/uk/ac/soton/comp1206/game/Game.class index 502eb787ba62b881f08c8284cd207fea113cba2b..be32772624ed05d9eb70fad41f3f0732615e7bea 100644 GIT binary patch literal 4229 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 E0AJkUjQ{`u delta 819 zcmZowJjus(>ff$?3=9mm43QhT)-&>HGw850=<+b=G3YZgXiPR>5uF^zq@<<IV93K@ z1QKIOPc4b$Vh~_3;bAakFk@t3PERdiWMI|s^wjiZXRw&8%c7<RlDFbvux7AfWMD1^ z$+KyAdU|SxaWU92*t0V@@Gv+sIBjNR^JdiKEhtJY%giq=4ol1_O=V=@$V)AUGI@hb z5|gui6AMBTlX6lgvvC*-v8Sh&IOpdSGctf!LHXsylTA5PxEK@}I2f217#LV4pXXHM z=3roCU}X?tU}SKf%*>^$?ZUvoAjZJTz`&r)z`~%yz{#M>z{jA$AkCo3;L5<jpuoV) zz`!8G;KtxSIhsq7-GhM*thbs=p&q1{4=k_Gz{Oy|z{g++*2BZV$iTqB57NWHz`)3$ z4$;HFz+lP11eW98#2_i8v6DfbiD4rH0|OHS$S5wbGtC*e7%Y&C;f5RI$>0UDnt_4g z5CaPX8$&$<gQ4~|1}$6dZ43r>T3Z-IWn{N87@M((valqWv5K+^@GoItV>V-jNQts; zW3U9-#tgPiiGhQGfx&@+mBEpLi@}9Kl);rjn!$}hiNT#gmBE|AfWZgs3Ofci1_lO0 zs4GA$Zw4Q5AbRL9_%iS?Ffnj3s5AI6@Gvklh%(49_%rY@urNq7h%p2(@G!741Tru% z2s1GLXHaEeV`t!CXV7M3WCR5eBSR2FFvv%f8~Mf5K_LJNS_Xz-u)UB#WQE$x$PmJy z4_3R6Ukn`Z5Vg@*)rLaUGBAK?kX@iK;9Ua`YKZ1!ESfnO!r-x`2#zZT22LT49SpXc b86-iW$H?F!!oUDl!@$7Hz{n5|HZ=kO%)Da^ diff --git a/tetrecs/target/classes/uk/ac/soton/comp1206/game/Grid.class b/tetrecs/target/classes/uk/ac/soton/comp1206/game/Grid.class index 5d628c07162ffec1d8f0e9bb2ab0da9bb901d404..2db3128f7f1a99970c6eb3b5f28bc952ebf73173 100644 GIT binary patch literal 2805 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 delta 583 zcmew=dWVba)W2Q(7#J9A8O%3wg)&b5$h=FOO~cdEQ!|W_fwe3#r!<w3fmOrPQ`2+u zMiyfs_Vm;e=lq;vMg|ZoD8IaTaw@A5BlF}5tdiVp42%q{49X0Q3@Veiu!aY#GB7Y` zF>o<3FsL)IFlaDvGH5dJG3YQzFz7SLGZ-*vFc>meG8iz}Gw3t8GMF%^F)%QgFt9Qx zF~~BgGw?95Fi0_IGiWgIFfcPPFt{;jGH6YXV-si8o?OPJz^=of3$|%4n^Zl>CXnqQ zkAO^30P6tRr^NsQoM7`985kHi!R9eBFfzz6=z;VzFfc?iFfp(&Ffj0HZDA0SHj*)t z-Nqobk%57Mi2-CV7XuRm1A{vQ4}%BTiCPfFAm@P0X5eK|2DuhwIxp081_oXReXzS3 z!9E3rNF=)k*qwY}w*@osFoZDhGK9g6<Yi!DFk~<S%kskw=ZCwTA8NKX0|Nsa1EUW+ zgCYYXgE4~w)ED{;j0_+*uxf2#U|$1wJtSD-!PbQEKvY0YXJjzJs+$*GcRE-%x@J?b G9cBP8uQ@yb diff --git a/tetrecs/target/classes/uk/ac/soton/comp1206/scene/MenuScene.class b/tetrecs/target/classes/uk/ac/soton/comp1206/scene/MenuScene.class index 9d27b9d5339524e9e9c2a3752f5b47e21b3e63dd..b58df00055fca0f690452354818862658dbb1c86 100644 GIT binary patch delta 1317 zcmeB_x+cSQ>ff$?3=9mm42L&z#j!9-Oy0mI!XM_8U%|x?#bC$I5XZ<MHi=y<m4hLH zk%2uVwWP?^IhczfmLZ9Uft5i7#PZ-^NM&STEy*m&Nd@T&;b6#MWZ(_X%uCNnRS3vQ ztV}K9V8~)*;K)tQEA=c%%@tx`WXR!R$Ysc5WMIok%uC5hWn^&H@R``CGC71*UM7~I zfQO-wp@@+|usF5EKhHP6v^do{Co?%aHDz)qt71JTLkUAEJ3|={LpehQBZF{OVp(EZ zg?@T!er{?>QKf!Bela5ho3pE5h-(ldgQyP{d25hUt9Tfy8EP0Ac#2a?9CI?$^Kw)3 zN*Ea=G_dN>3<KF)$HO3153-dj#6KV&Vh0yP7(*iuLlZ;u<P9uJjv#I;4?`P6Gb00M zacYTkYF<fd5f_6FLkAB-CxbmB17C4TVo`~6Mq*A*YF>IO7ehBg4?9CI4?`bAKO=+k z#NRTTKeF;N@^gcNEIczMJ+-8mkwI$mdNxrOQ0z?p%_b)amUJpDDap?(W@O+h1_wAO zyeB)bOS>z<JyD#TnwP4dnO9I+q7M#A*Rs^S5^K#cMh4bY5R;KX9_C>TwUcMCyYj8% zVpzqnnw?<{4}&tp+R3lkkI1iQWZ-ft&CE&3%u82b<Y!~p$i=XUVKY0!79NJJ4BIxJ z<6vR5+rh{n4tECFDt(yU{HzSSxEMGXcJnYSU|1-?u#k~~$1^W4wa7UqvA8(3n4Mw& zWC1QMmV=B8a+3o%#3xVSWSbn#rOr5Eax<5r>qG_y20jL61_lO6237_s27U%<hDi(z z3}OsS3=9kc43inAFo1vngC>I(10w??!&C-)21bSn3=E7r7+4wD85kITO@7H$SHGPh z#&0)6Y@|^9c7{YN7D<+E49P+%I~jbL7{Yb8F{DYdK-jw(q9V65#8|O{6{mv~vq`dn z6lX#dNU~||V#sD-*v61A$qLfQ1{G)B#8AAAp;C7fL+v((N*S=KLU6)hVX7#QlA z7(jlBV-ROxU{GQZVNhYvWl&=<Wl(2uWYA#nWzb}ZWYA(rXV78DXV7J+V$f%3VlZOp zWiV!##bCm)jKPdyJ%a_qE(S}6;|x{|ml&)W?lagiJZG?Hc*o$#@R`Ah;U|L&IBYy1 zzJ`X4DZ^2QX$;fr85kMz8M+x}FwA6NVrXKhV3@@)n}M03mm!xSm0=D83&VN_Z-%)H zvl&<!b}=|G%ww3tz{bGHFdr724B89~42&QQ@(#o|AO#EzK44pUAd*m9nLx1(i3bJ; z21W*^dIkmt4y`Q=>f0FF5e9I9qcNC)ogoBl2qaoLpoTCoa4;-lSj@o4z`?Kt?hZw; zMGOp_LL567x;8VggN$PYhc3iDLJZ6dOBom#m>8BZEN5U~5Mp3rSRu#2$gqxK0|PU| ac7~k{dl>dIFfed2Ff#08IKXg-K@tGI&@hhx delta 974 zcmca6(<#Mu>ff$?3=9mm3>!Cc#j#B8W|7p7Wn^FvNi8XIbq?lYh+>H6VPItt0kJ$d z7?KznSW7ZXa#Fb%!WdF`7*ZM1CM&Qh1+X(@FfvGIC6*<oRp=Kdr{<;VC+Fvt6y@jW zJC&A{<mYiPWHB<Z1mq-EaxtVc#Dlcw@-XBvq%ksZ7N?dtr{<NU76~yhG8FJI6fzV| z{>c(3mCjJY!%)gl#>l{3oLb_a=a^iQnV-kVAg3`|msOfeGmMKthoORpp>lEpn<#fR zLk&AaEe}H-L;dCkHXTMM2_F>ql%!Ua=!c|Mlvpz|uqA;V#mFFwss`1~)|0t8q-|w2 zU}{p!Qu9jmA+B%*v8^@37#Uc>!i)@3*pyAq<#6Sj&c!f;VJ17nEFK1BhS`%3a2%1J z%gDgxRGOKSl9`vTz{t<WFrSNI0mDLehDAIKiy4+|Ud+kD$hd6s3NBgY6<iD)3@dpU z`WX5J82T9*cs%p+Qj45(5{rvdi`g00GBT)6HslhY{GUsJas6ZgZg<9p$r0R&u8j-~ z415gC3=9ks46F>24EzjI3{4CS3}OsS3=9kc49yHJ3?LxDpvj=cz{tSJ(8^%Xz{t?R zz`*Fhz{<eNz`(F+@;>gmdZC!@3~_$C+ZYmr5_dBAGBJef=x$?3-p!C6DU`XLA=`>Y zN0Mb5Lyjbi)-Hy828L}6#TywI7?>D9PH<unU|?WSWDsFcX3%9&WiVw>V{l|pXYggv zV2EVUWJqVwX2@sIVW?uzXJ}zCV3@#Q$S{?`gkb@LDZ?@b3x<sh^_F0Fn?PIyb+;)) zEkheaI|Cy_K7%tu2SX<V6GIDw9zzmC7XvfH0tO+5ZiXHP76wL!UYM^Kv>6x}7(p1} zIySI?BiI5SFq;u-0TU>|!NF0_z~I2Z2o5z4tt|}d+Zf6b25^DJJs8*-Ji&%QLYD(- z2m=EL!vuzj42%pM43psQPy}1Vz`!ZQv4f#%GXp!wI7V=2LEIzAz|1fi9D-9ArZT89 qFbFX)F-&7%WSGM+kAazCDZ_GxRSc^c7#O%17#Y?utYg@~APE319Lih( -- GitLab