From a0811bf22af909cbb654c4a787285ee09d34df56 Mon Sep 17 00:00:00 2001
From: ayazb7 <60544937+ayazb7@users.noreply.github.com>
Date: Fri, 8 Apr 2022 23:29:56 +0100
Subject: [PATCH] Adding Instruction scene and UI changes

---
 .../soton/comp1206/component/GameBlock.java   |  55 ++++++-
 .../soton/comp1206/component/GameBoard.java   |  19 ++-
 .../soton/comp1206/component/PieceBoard.java  |   5 +
 .../comp1206/event/NextPieceListener.java     |   2 +-
 .../java/uk/ac/soton/comp1206/game/Game.java  |  24 +--
 .../soton/comp1206/scene/ChallengeScene.java  |  42 +++--
 .../comp1206/scene/InstructionScene.java      | 144 ++++++++++++++++++
 .../uk/ac/soton/comp1206/scene/MenuScene.java |  47 ++++--
 .../main/java/uk/ac/soton/comp1206/test.java  |  54 +++++++
 .../uk/ac/soton/comp1206/ui/GameWindow.java   |   4 +
 .../ac/soton/comp1206/utility/Multimedia.java |   1 +
 .../soton/comp1206/component/GameBlock.class  | Bin 4846 -> 5607 bytes
 .../component/GameBlockCoordinate.class       | Bin 2398 -> 2398 bytes
 .../soton/comp1206/component/GameBoard.class  | Bin 4739 -> 5321 bytes
 .../uk/ac/soton/comp1206/game/Game.class      | Bin 7125 -> 7158 bytes
 .../uk/ac/soton/comp1206/game/GamePiece.class | Bin 3892 -> 3892 bytes
 .../uk/ac/soton/comp1206/game/Grid.class      | Bin 2663 -> 2663 bytes
 .../comp1206/network/Communicator$1.class     | Bin 1376 -> 1376 bytes
 .../comp1206/network/Communicator$2.class     | Bin 2330 -> 2330 bytes
 .../soton/comp1206/network/Communicator.class | Bin 4093 -> 4093 bytes
 .../ac/soton/comp1206/scene/BaseScene.class   | Bin 1485 -> 1485 bytes
 .../soton/comp1206/scene/ChallengeScene.class | Bin 8475 -> 9276 bytes
 .../ac/soton/comp1206/scene/MenuScene.class   | Bin 4179 -> 4450 bytes
 .../uk/ac/soton/comp1206/ui/GamePane.class    | Bin 2086 -> 2086 bytes
 .../uk/ac/soton/comp1206/ui/GameWindow.class  | Bin 4612 -> 4765 bytes
 25 files changed, 349 insertions(+), 48 deletions(-)
 create mode 100644 tetrecs/src/main/java/uk/ac/soton/comp1206/scene/InstructionScene.java
 create mode 100644 tetrecs/src/main/java/uk/ac/soton/comp1206/test.java

diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/component/GameBlock.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/component/GameBlock.java
index 50106ed..d80b3b7 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/component/GameBlock.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/component/GameBlock.java
@@ -4,6 +4,7 @@ import javafx.beans.property.IntegerProperty;
 import javafx.beans.property.SimpleIntegerProperty;
 import javafx.beans.value.ObservableValue;
 import javafx.scene.canvas.Canvas;
+import javafx.scene.canvas.GraphicsContext;
 import javafx.scene.effect.BlendMode;
 import javafx.scene.paint.*;
 import org.apache.logging.log4j.LogManager;
@@ -64,6 +65,10 @@ public class GameBlock extends Canvas {
    */
   private final IntegerProperty value = new SimpleIntegerProperty(0);
 
+  private boolean isCentre = false;
+
+  private boolean isHovering = false;
+
   /**
    * Create a new single Game Block
    *
@@ -113,22 +118,31 @@ public class GameBlock extends Canvas {
       //If the block is not empty, paint with the colour represented by the value
       paintColor(COLOURS[value.get()]);
     }
+
+    if (isHovering) {
+      paintHoverTile();
+    }
+
+    if (isCentre) {
+      paintCentreCircle();
+    }
+
   }
 
   /**
    * Paint this canvas empty
    */
   private void paintEmpty() {
-    var gc = getGraphicsContext2D();
+    GraphicsContext gc = getGraphicsContext2D();
 
     //Clear
-    gc.clearRect(0.0D, 0.0D, this.width, this.height);
+    gc.clearRect(0, 0, this.width, this.height);
 
     //Fill
-    Color gradStart = Color.color(0.0D, 0.0D, 0.6D, 0.3D);
-    Color gradEnd = Color.color(0.0D, 0.0D, 0.2D, 0.5D);
-    gc.setFill(new LinearGradient(0.0D, 0.0D, 1.0D, 1.0D, true, CycleMethod.REFLECT, new Stop(0.0D, gradStart), new Stop(1.0D, gradEnd)));
-    gc.fillRect(0.0D, 0.0D, this.width, this.height);
+    Color gradStart = Color.color(0.0, 0.0, 0.6, 0.3);
+    Color gradEnd = Color.color(0.0, 0.0, 0.2, 0.5);
+    gc.setFill(new LinearGradient(0.0, 0.0, 1.0, 1.0, true, CycleMethod.REFLECT, new Stop(0, gradStart), new Stop(1, gradEnd)));
+    gc.fillRect(0, 0, this.width, this.height);
 
     //Border
     gc.setStroke(Color.WHITE);
@@ -142,21 +156,46 @@ public class GameBlock extends Canvas {
    * @param colour the colour to paint
    */
   private void paintColor(Paint colour) {
-    var gc = getGraphicsContext2D();
+    GraphicsContext gc = getGraphicsContext2D();
 
     //Clear
     gc.clearRect(0, 0, width, height);
 
     //Colour fill
     gc.setFill(colour);
-    gc.setGlobalAlpha(1);
     gc.fillRect(0, 0, width, height);
 
+    gc.setFill(Color.color(1,1,1,0.3));
+    gc.fillPolygon(new double[]{0, width, 0}, new double[]{0, 0, height}, 3);
+
     //Border
     gc.setStroke(Color.BLACK);
     gc.strokeRect(0, 0, width, height);
   }
 
+  private void paintCentreCircle() {
+    GraphicsContext gc = getGraphicsContext2D();
+    gc.setFill(Color.color(1.0, 1.0, 1.0, 0.6));
+    gc.fillOval(this.width / 4, this.height / 4, this.width / 2, this.height / 2);
+  }
+
+  private void paintHoverTile() {
+    GraphicsContext gc = getGraphicsContext2D();
+    gc.setFill(Color.color(1.0, 1.0, 1.0, 0.4));
+    gc.fillRect(0,0, width, height);
+  }
+
+  public void setCentre() {
+    this.isCentre = true;
+    paint();
+  }
+
+  public void setHovering(boolean hovering) {
+    this.isHovering = hovering;
+    paint();
+  }
+
+
   /**
    * Get the column of this block
    *
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/component/GameBoard.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/component/GameBoard.java
index 1131d32..e375840 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/component/GameBoard.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/component/GameBoard.java
@@ -60,6 +60,8 @@ public class GameBoard extends GridPane {
 
   protected RightClickListener rightClickListener;
 
+  protected boolean isPieceBoard = false;
+
   /**
    * Create a new GameBoard, based off a given grid, with a visual width and height.
    *
@@ -161,6 +163,11 @@ public class GameBoard extends GridPane {
         blockRightClicked(block);
       }
     });
+
+    block.setOnMouseEntered(e -> hover(block));
+
+    block.setOnMouseExited(e -> unhover(block));
+
     return block;
   }
 
@@ -183,8 +190,6 @@ public class GameBoard extends GridPane {
    * @param block block clicked on
    */
   private void blockClicked(GameBlock block) {
-    logger.info("Block clicked: {}", block);
-
     if (blockClickedListener != null) {
       blockClickedListener.blockClicked(block);
     }
@@ -196,4 +201,14 @@ public class GameBoard extends GridPane {
     }
   }
 
+  private void hover(GameBlock block) {
+    if (isPieceBoard) return;
+    block.setHovering(true);
+  }
+
+  private void unhover(GameBlock block) {
+    if (isPieceBoard) return;
+    block.setHovering(false);
+  }
+
 }
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/component/PieceBoard.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/component/PieceBoard.java
index 5abd200..1a8b872 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/component/PieceBoard.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/component/PieceBoard.java
@@ -7,6 +7,7 @@ public class PieceBoard extends GameBoard {
 
   public PieceBoard(double width, double height) {
     super(3, 3, width, height);
+    this.isPieceBoard = true;
   }
 
   public void displayPiece(GamePiece piece, int placeX, int placeY) {
@@ -26,4 +27,8 @@ public class PieceBoard extends GameBoard {
     this.blockClickedListener = handler;
   }
 
+  public void drawCentre() {
+    this.blocks[1][1].setCentre();
+  }
+
 }
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/event/NextPieceListener.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/event/NextPieceListener.java
index 09971bd..77fc3c9 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/event/NextPieceListener.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/event/NextPieceListener.java
@@ -3,5 +3,5 @@ package uk.ac.soton.comp1206.event;
 import uk.ac.soton.comp1206.game.GamePiece;
 
 public interface NextPieceListener {
-  void nextPiece(GamePiece paramGamePiece);
+  void nextPiece(GamePiece piece);
 }
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 c32f3c4..de325d8 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
@@ -44,7 +44,7 @@ public class Game {
 
   private int remainder = 0;
 
-  protected NextPieceListener nextPieceHandler = null;
+  protected NextPieceListener nextPieceListener = null;
 
   /**
    * Create a new game with the specified rows and columns. Creates a corresponding grid model.
@@ -118,8 +118,8 @@ public class Game {
     this.currentPiece = this.nextPiece;
     this.nextPiece = spawnPiece();
 
-    if (this.nextPieceHandler != null) {
-      this.nextPieceHandler.nextPiece(this.currentPiece);
+    if (this.nextPieceListener != null) {
+      this.nextPieceListener.nextPiece(this.currentPiece);
     }
 
     logger.info("Current piece is : {}", this.currentPiece);
@@ -132,7 +132,7 @@ public class Game {
     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++) {
@@ -147,7 +147,7 @@ public class Game {
       }
     }
 
-    /**
+    /*
      * Check each horizontal row to see if it is full
      */
     for (int y = 0; y < grid.getCols(); y++) {
@@ -164,7 +164,7 @@ public class Game {
 
     int numGridBlocks = 0;
 
-    /**
+    /*
      * Removes all columns which are full
      */
     for (int x : fullCols) {
@@ -176,8 +176,8 @@ public class Game {
       }
     }
 
-    /**
-     * Removes all rows which are full
+    /*
+      Removes all rows which are full
      */
     for (int y : fullRows) {
       for (int x = 0; x < grid.getCols(); x++) {
@@ -204,7 +204,9 @@ public class Game {
       Multimedia.playSound("clear.wav");
       this.setMultiplier(multiplier.get() + 1);
     } else {
-      this.setMultiplier(1);
+      if (this.getMultiplier().get() > 1) {
+        this.setMultiplier(1);
+      }
     }
   }
 
@@ -249,8 +251,8 @@ public class Game {
     return nextPiece;
   }
 
-  public void setOnNextPiece(NextPieceListener handler) {
-    this.nextPieceHandler = handler;
+  public void setNextPieceListener(NextPieceListener listener) {
+    this.nextPieceListener = listener;
   }
 
   public void rotatePiece(int rotations) {
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/ChallengeScene.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/ChallengeScene.java
index 265a260..a30155f 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/ChallengeScene.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/ChallengeScene.java
@@ -4,6 +4,8 @@ import javafx.beans.property.Property;
 import javafx.beans.value.ObservableValue;
 import javafx.geometry.Insets;
 import javafx.geometry.Pos;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyEvent;
 import javafx.scene.layout.*;
 import javafx.scene.paint.Color;
 import javafx.scene.paint.Paint;
@@ -20,6 +22,7 @@ import uk.ac.soton.comp1206.ui.GamePane;
 import uk.ac.soton.comp1206.ui.GameWindow;
 import uk.ac.soton.comp1206.utility.Multimedia;
 
+import java.security.Key;
 import java.util.ArrayList;
 
 /**
@@ -44,6 +47,29 @@ public class ChallengeScene extends BaseScene {
     logger.info("Creating Challenge Scene");
   }
 
+  /**
+   * Initialise the scene and start the game
+   */
+  @Override
+  public void initialise() {
+    logger.info("Initialising Challenge");
+    Multimedia.playBackgroundMusic("game_start.wav", false);
+    Multimedia.getBackgroundPlayer().setOnEndOfMedia(() -> Multimedia.playBackgroundMusic("game.wav", true));
+
+    this.game.setNextPieceListener(this::nextPiece);
+
+    this.scene.setOnKeyPressed(this::keyHandler);
+
+    game.start();
+  }
+
+  private void keyHandler(KeyEvent e) {
+    if (e.getCode().equals(KeyCode.ESCAPE)) {
+      Multimedia.stopSound();
+      this.gameWindow.startMenu();
+    }
+  }
+
   /**
    * Build the Challenge window
    */
@@ -151,10 +177,12 @@ public class ChallengeScene extends BaseScene {
 
     this.currentPieceBoard = new PieceBoard(gameWindow.getWidth() / 6, gameWindow.getWidth() / 6);
     this.currentPieceBoard.setOnClick(this::rotateBlock);
+    this.currentPieceBoard.drawCentre();
     gameInfo.getChildren().add(this.currentPieceBoard);
 
     this.nextPieceBoard = new PieceBoard(gameWindow.getWidth() / 10, gameWindow.getWidth() / 10);
     this.nextPieceBoard.setOnClick(this::swapPiece);
+    this.nextPieceBoard.drawCentre();
     gameInfo.getChildren().add(this.nextPieceBoard);
 
     gameInfo.setAlignment(Pos.CENTER);
@@ -170,6 +198,7 @@ public class ChallengeScene extends BaseScene {
 
   private void swapPiece(GameBlock gameBlock) {
     logger.info("Swapping current and next piece");
+    Multimedia.playSound("rotate.wav");
     this.currentPieceBoard.displayPiece(this.game.getNextPiece());
     this.nextPieceBoard.displayPiece(this.game.getCurrentPiece());
     this.game.swapPiece();
@@ -209,19 +238,6 @@ public class ChallengeScene extends BaseScene {
     game = new Game(5, 5);
   }
 
-  /**
-   * Initialise the scene and start the game
-   */
-  @Override
-  public void initialise() {
-    logger.info("Initialising Challenge");
-    Multimedia.playBackgroundMusic("game_start.wav", false);
-    Multimedia.getBackgroundPlayer().setOnEndOfMedia(() -> Multimedia.playBackgroundMusic("game.wav", true));
-
-    this.game.setOnNextPiece(this::nextPiece);
-    game.start();
-  }
-
   protected void nextPiece(GamePiece nextPiece) {
     logger.info("Next piece to place: " + nextPiece);
     this.currentPieceBoard.displayPiece(nextPiece);
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/InstructionScene.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/InstructionScene.java
new file mode 100644
index 0000000..5dc8b06
--- /dev/null
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/scene/InstructionScene.java
@@ -0,0 +1,144 @@
+package uk.ac.soton.comp1206.scene;
+
+import javafx.geometry.Pos;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.StackPane;
+import javafx.scene.layout.VBox;
+import javafx.scene.text.Text;
+import javafx.scene.text.TextAlignment;
+import javafx.scene.text.TextFlow;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import uk.ac.soton.comp1206.component.GameBlock;
+import uk.ac.soton.comp1206.component.PieceBoard;
+import uk.ac.soton.comp1206.game.Game;
+import uk.ac.soton.comp1206.game.GamePiece;
+import uk.ac.soton.comp1206.ui.GamePane;
+import uk.ac.soton.comp1206.ui.GameWindow;
+import uk.ac.soton.comp1206.utility.Multimedia;
+
+public class InstructionScene extends BaseScene{
+  private static final Logger logger = LogManager.getLogger(InstructionScene.class);
+
+  private int pieceNumber = 0;
+
+  private PieceBoard pieceBoard;
+  /**
+   * Create a new scene, passing in the GameWindow the scene will be displayed in
+   *
+   * @param gameWindow the game window
+   */
+  public InstructionScene(GameWindow gameWindow) {
+    super(gameWindow);
+
+    logger.info("Creating Instructions Scene");
+  }
+
+  @Override
+  public void initialise() {
+    this.scene.setOnKeyPressed(this::escapeToMenu);
+  }
+
+  @Override
+  public void build() {
+    logger.info("Building " + this.getClass().getName());
+
+    root = new GamePane(gameWindow.getWidth(), gameWindow.getHeight());
+
+    StackPane instructionsPane = new StackPane();
+    instructionsPane.setMaxWidth(gameWindow.getWidth());
+    instructionsPane.setMaxHeight(gameWindow.getHeight());
+    instructionsPane.getStyleClass().add("menu-background");
+    root.getChildren().add(instructionsPane);
+
+    BorderPane mainPane = new BorderPane();
+    instructionsPane.getChildren().add(mainPane);
+
+    VBox widgets = new VBox();
+
+    Text instructionsTitle = new Text("How to Play");
+    instructionsTitle.getStyleClass().add("heading");
+    widgets.getChildren().add(instructionsTitle);
+
+
+    Text instructionsText = new Text("TetrECS is a fast-paced gravity-free block placement game, where you must survive by clearing rows through careful placement of the upcoming blocks before the time runs out. Lose all 3 lives and you're destroyed!");
+    TextFlow instructionTextBox = new TextFlow(instructionsText);
+    instructionsText.getStyleClass().add("instructions");
+    instructionTextBox.setTextAlignment(TextAlignment.CENTER);
+    widgets.getChildren().add(instructionTextBox);
+
+    ImageView instructionsImage = new ImageView(getClass().getResource("/images/Instructions.png").toExternalForm());
+    instructionsImage.setPreserveRatio(true);
+    instructionsImage.setFitWidth(this.gameWindow.getWidth() / 1.5D);
+    widgets.getChildren().add(instructionsImage);
+
+    Text gamePiecesLabel = new Text("Game Pieces");
+    gamePiecesLabel.getStyleClass().add("heading");
+    widgets.getChildren().add(gamePiecesLabel);
+
+    HBox pieceBoards = buildPieceBoards();
+    widgets.getChildren().add(pieceBoards);
+
+    widgets.setAlignment(Pos.TOP_CENTER);
+    widgets.setSpacing(10);
+
+    mainPane.setCenter(widgets);
+  }
+
+  private HBox buildPieceBoards() {
+    HBox pieceBoardLayout = new HBox();
+
+    ImageView prevArrow = new ImageView(getClass().getResource("/images/leftArrow.png").toExternalForm());
+    prevArrow.setOnMouseClicked(this::displayPrevPiece);
+    pieceBoardLayout.getChildren().add(prevArrow);
+
+    GamePiece piece = GamePiece.createPiece(pieceNumber);
+    pieceBoard = new PieceBoard((this.gameWindow.getWidth() / 6), (this.gameWindow.getWidth() / 6));
+    pieceBoard.displayPiece(piece);
+    pieceBoardLayout.getChildren().add(pieceBoard);
+
+    ImageView nextArrow = new ImageView(getClass().getResource("/images/rightArrow.png").toExternalForm());
+    nextArrow.setOnMouseClicked(this::displayNextPiece);
+    pieceBoardLayout.getChildren().add(nextArrow);
+
+    pieceBoardLayout.setAlignment(Pos.CENTER);
+    pieceBoardLayout.setSpacing(10);
+
+    return pieceBoardLayout;
+
+  }
+
+  private void displayNextPiece(MouseEvent event) {
+    if (pieceNumber != 14) {
+      pieceNumber++;
+    } else {
+      pieceNumber = 0;
+    }
+
+    GamePiece piece = GamePiece.createPiece(pieceNumber);
+    pieceBoard.displayPiece(piece);
+  }
+
+  private void displayPrevPiece(MouseEvent event) {
+    if (pieceNumber != 0) {
+      pieceNumber--;
+    } else {
+      pieceNumber = 14;
+    }
+
+    GamePiece piece = GamePiece.createPiece(pieceNumber);
+    pieceBoard.displayPiece(piece);
+  }
+
+  private void escapeToMenu(KeyEvent e) {
+    if (e.getCode().equals(KeyCode.ESCAPE)) {
+      Multimedia.stopSound();
+      this.gameWindow.startMenu();
+    }
+  }
+}
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 c5797a5..04effde 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,5 +1,6 @@
 package uk.ac.soton.comp1206.scene;
 
+import javafx.event.EventHandler;
 import javafx.geometry.Pos;
 import javafx.scene.control.Button;
 import javafx.scene.input.MouseEvent;
@@ -8,6 +9,7 @@ import javafx.scene.media.MediaPlayer;
 import javafx.scene.text.Text;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
+import uk.ac.soton.comp1206.App;
 import uk.ac.soton.comp1206.ui.GamePane;
 import uk.ac.soton.comp1206.ui.GameWindow;
 import uk.ac.soton.comp1206.utility.Multimedia;
@@ -38,7 +40,7 @@ public class MenuScene extends BaseScene {
 
     root = new GamePane(gameWindow.getWidth(), gameWindow.getHeight());
 
-    var menuPane = new StackPane();
+    StackPane menuPane = new StackPane();
     menuPane.setMaxWidth(gameWindow.getWidth());
     menuPane.setMaxHeight(gameWindow.getHeight());
     menuPane.getStyleClass().add("menu-background");
@@ -49,30 +51,46 @@ public class MenuScene extends BaseScene {
 
     VBox menuWidgets = new VBox();
 
-    Region space = new Region();
-    space.setPrefHeight(100);
-    HBox.setHgrow(space, Priority.ALWAYS);
-    menuWidgets.getChildren().add(space);
-
     //Awful title
-    var title = new Text("TetrECS");
+    Text title = new Text("TetrECS");
     title.getStyleClass().add("bigtitle");
     menuWidgets.getChildren().add(title);
 
     VBox menuButtons = new VBox();
 
-    var singlePlay = new Text("Single Player");
+    Text singlePlay = new Text("Single Player");
     singlePlay.getStyleClass().add("menuItem");
     singlePlay.setOnMouseClicked(this::startGame);
     menuButtons.getChildren().add(singlePlay);
 
+    Text multiPlayLabel = new Text("Multi Player");
+    multiPlayLabel.getStyleClass().add("menuItem");
+    menuButtons.getChildren().add(multiPlayLabel);
+
+    Text instructions = new Text("How To Play");
+    instructions.getStyleClass().add("menuItem");
+    instructions.setOnMouseClicked(this::showInstructions);
+    menuButtons.getChildren().add(instructions);
+
+    Text exitLabel = new Text("Exit");
+    exitLabel.getStyleClass().add("menuItem");
+    exitLabel.setOnMouseClicked(new EventHandler<MouseEvent>() {
+      @Override
+      public void handle(MouseEvent mouseEvent) {
+        App.getInstance().shutdown();
+      }
+    });
+    menuButtons.getChildren().add(exitLabel);
+
     menuButtons.setAlignment(Pos.CENTER);
+    menuButtons.setSpacing(5);
+
+    menuWidgets.getChildren().add(menuButtons);
     menuWidgets.setAlignment(Pos.CENTER);
+    menuWidgets.setSpacing(150);
 
-    mainPane.setTop(menuWidgets);
-    mainPane.setCenter(menuButtons);
+    mainPane.setCenter(menuWidgets);
 
-    Multimedia.playBackgroundMusic("menu.mp3", true);
   }
 
   /**
@@ -80,17 +98,20 @@ public class MenuScene extends BaseScene {
    */
   @Override
   public void initialise() {
-
+    Multimedia.playBackgroundMusic("menu.mp3", true);
   }
 
   /**
    * Handle when the Start Game button is pressed
    *
-   * @param event event
    */
   private void startGame(MouseEvent event) {
     Multimedia.stopSound();
     gameWindow.startChallenge();
   }
 
+  private void showInstructions(MouseEvent event) {
+    gameWindow.displayInstructions();
+  }
+
 }
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/test.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/test.java
new file mode 100644
index 0000000..cca7bea
--- /dev/null
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/test.java
@@ -0,0 +1,54 @@
+package uk.ac.soton.comp1206;
+
+import javafx.application.Application;
+import javafx.scene.Group;
+import javafx.scene.Scene;
+import javafx.scene.canvas.Canvas;
+import javafx.scene.canvas.GraphicsContext;
+import javafx.scene.paint.Color;
+import javafx.stage.Stage;
+
+public class test extends Application {
+
+  public static void main(String[] args) {
+    launch(args);
+  }
+
+  @Override
+  public void start(Stage primaryStage) {
+    primaryStage.setTitle("Drawing Operations Test");
+    Group root = new Group();
+    Canvas canvas = new Canvas(300, 250);
+    GraphicsContext gc = canvas.getGraphicsContext2D();
+    drawShapes(gc);
+    root.getChildren().add(canvas);
+    primaryStage.setScene(new Scene(root));
+    primaryStage.show();
+  }
+
+  private void drawShapes(GraphicsContext gc) {
+
+    int firstX = 90;
+    int secondX = 190;
+    int thirdX = 10;
+
+    int firstY =30;
+    int secondY =170;
+    int thirdY =170;
+
+    gc.setFill(Color.GREEN);
+    gc.setStroke(Color.BLUE);
+    gc.fillPolygon(new double[]{firstX, secondX,thirdX},
+        new double[]{firstY, secondY, thirdY}, 3);
+
+    gc.strokePolygon(new double[]{firstX, secondX,thirdX},
+        new double[]{firstY, secondY, thirdY}, 3);
+
+    gc.setFill(javafx.scene.paint.Color.BLACK);
+    gc.fillText("1", firstX - 3, firstY - 4);
+    gc.fillText("2", secondX - 3, secondY - 4);
+    gc.fillText("3", thirdX - 3, thirdY - 4);
+
+
+  }
+}
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/ui/GameWindow.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/ui/GameWindow.java
index 924668b..1b0408d 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/ui/GameWindow.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/ui/GameWindow.java
@@ -88,6 +88,10 @@ public class GameWindow {
     loadScene(new ChallengeScene(this));
   }
 
+  public void displayInstructions() {
+    loadScene(new InstructionScene(this));
+  }
+
   /**
    * Setup the default settings for the stage itself (the window), such as the title and minimum width and height.
    */
diff --git a/tetrecs/src/main/java/uk/ac/soton/comp1206/utility/Multimedia.java b/tetrecs/src/main/java/uk/ac/soton/comp1206/utility/Multimedia.java
index a524f1d..b99422c 100644
--- a/tetrecs/src/main/java/uk/ac/soton/comp1206/utility/Multimedia.java
+++ b/tetrecs/src/main/java/uk/ac/soton/comp1206/utility/Multimedia.java
@@ -46,6 +46,7 @@ public class Multimedia {
   }
 
   public static void stopSound() {
+    logger.info("Stopping all current audio tracks");
     if (mediaPlayer != null) {
       mediaPlayer.stop();
     }
diff --git a/tetrecs/target/classes/uk/ac/soton/comp1206/component/GameBlock.class b/tetrecs/target/classes/uk/ac/soton/comp1206/component/GameBlock.class
index 191944d061dfb8e127c3714cc9e7ba0b0dea72d2..808af90aa5b3248584c35fcb8db560e91e5fa62f 100644
GIT binary patch
delta 3214
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

delta 2466
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

diff --git a/tetrecs/target/classes/uk/ac/soton/comp1206/component/GameBlockCoordinate.class b/tetrecs/target/classes/uk/ac/soton/comp1206/component/GameBlockCoordinate.class
index de29963eeff81260c4fd827cf833254e1e8f3f2a..a20b83652745ed51e0ad402743af24bcac4b412a 100644
GIT binary patch
delta 159
zcmca7bWdnQF{_{w0}F#B11Ezr10RD5gD`{Y<aRdo$*Wo27<DJ>vx!b-XH#c1o2<{~
z&Fjd(%HYJn&EU)+%-}e=oh^dVck%<aP~HdzR)$ChZiXlZVTOpw?QEKpv)T0-Qzk!P
zlb^hcJy<ZGft{g%fsdh(L71V4L7$;`vK+?@(OL#}hB^jrhI$4mh6V;rhDHVxhUUqq
NIU*Q)C#!H;0RRN=Au0d>

delta 159
zcmca7bWdnQF{_{=0}F#B11EzL10RDjgD`{2<aRdo$*Wo27_}$svx!b-XH#c1o~+O2
z&1=iR%3#O9&0x<U%wRjYoh^dVWAX#GP~JcWR)!!3ZiZk6VTQoT?QEKpv)T0-V<taf
zlb^hcJy<Z6ft?|ZfsY}bL6{+fL7yRWvK+?@(Lx4xh9U-ThGGUOh7tx%hEfI-hVsd$
NIU*SAC#!H;0RY~LAYcFh

diff --git a/tetrecs/target/classes/uk/ac/soton/comp1206/component/GameBoard.class b/tetrecs/target/classes/uk/ac/soton/comp1206/component/GameBoard.class
index 7d7f7ec15155e1956eee50ce3814870034b662b0..781238acd474eba9b2a2e3287691835c48217712 100644
GIT binary patch
literal 5321
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

delta 2331
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
I496HG0SsV_LjV8(

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 9bee46cc02c85f4d236ae529187f1b0a6ca79b2f..a449eff117cc19e136d41dd7a6494a42d597634e 100644
GIT binary patch
delta 2460
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
IRArC^037qW2><{9

delta 2439
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
XOv*6IF)%Q2F)%X9Gb%DFGe`meOBb;*

diff --git a/tetrecs/target/classes/uk/ac/soton/comp1206/game/GamePiece.class b/tetrecs/target/classes/uk/ac/soton/comp1206/game/GamePiece.class
index ddf9544daf0af815a0ae54f0b67fcb34868d21c6..580673cfa6c805087cf2419b840265615cd04929 100644
GIT binary patch
delta 286
zcmdlYw?%G)B3HdSgAaoiLpy^u!(;{nhI0&t47V7}7)2S(85J397-JZ088aB17#A}*
zGp=XwV0^{k$@rbYkI9I^pUIvfgsF-ll&PH|is=wTG}C#81ZFOVL}qb@H0B_Nbmn-5
z9OhXJxy;KMikKfU6f?hPs9@1zsAMr`sADN&sAs8XXkiH4ynu_Jk+YwHm0=<S7sI5<
zJGiH7&ShX>n8(1$FrR^sVF80M!(s+mh9wMI3`-fz8J02FGb~|nWmwGM&9HKE1<w@5
zjgxtKZ5Ve=_Tu&AJ<Pz)aD;)I;V^?B!?DQ=c%SK>VGv|E%OJ;ajzOE@Jc9+pMFv-f
pOAJ8_ml@(2t}^5>Tw|zYxX#eVaFd~%;nw8Md~S@7C;#HJ0sw?IN6!EN

delta 286
zcmdlYw?%G)B3Hc{gAaoyLpy^O!(;}1hI0%C47V6e8ATb)7!?_;8Dki17&90g85c7+
zF|KEDXMDxr!T6oQm&u61kI9}Pn5l{(gsGh&lIajb6w`TzcxEn!1ZHuDROTRtH0F4Q
zZ01=EIn2u$3Yi}<6fwVNC}+`Ps9-T?sAVZ)sAH*TXl4l9ynu_Jk+YY9m7$-3i($g#
z9o*A3XECra%x2(Zn8U!wFqc7?VF80I!$JlvhD8kK42v1;85T0QGAv;5W>_}4f@ccj
z+R41UHjG;*d+~bm?qy(S*vG)lu$MuQ;lShtyw7xxF$gjoXOLq!!Jy4>lEH%EG=nR{
p8HON+vkdVJ=NWPsE-+LwTx4itxXjSaaAoplJ~zfYlYjA90RTk@M;HJA

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 915e5a5f1411e7a79631ab290a29233d57d65412..dda7f01ba1ac9ba52ef54d6cb3a478b7f95a46ae 100644
GIT binary patch
delta 217
zcmaDZ@?2yC2dk<M0}F#L11EzX10RDSg9L*KgFJ&Ng9d{cgC&D0gFS-@gDZpOWL?&F
zM(4>}StD5e7<d@`CkwIVa7HumFvKwMGQ>@8XWOZp%)rKw!obCl%D~5v&LGK<!Jy8N
z$zaHk#bC*h&EUb1!{Eh`!4SZZ&Je~>Fgcg~pKb{Q4?`J)5JNeG7()ev6hjq*Dnm7c
zF+&Z5EkiAXD?=SaFhey%BtsQLJVWE;862lYTN$_*+89I_+8GoW+8ERrS{Za0x+Yg}
SrZG;Me4o>XarR^xE^h!|Z7OmA

delta 217
zcmaDZ@?2yC2dk<!0}F!=11Ezn10RC{g9L*ygFJ%?g9d{sgC&CrgFS;WgDZo@WL?&F
zM#srpStD4z8F(0cCJV9UaE3GRFhnr$GDJ;oXWOY8&%nlzz`(_j$iT;t%pl2-!l2HO
z%3#Ql#$d^i&fvk2!QjP^!Vtia%n-(qGdY+2pKbvI4?_`y5JNG87()qz6hj$<DnmJg
zF+&A|Ekh-PD?=4SFhe;*BtscPJVWi|862lY8yUD5nixbFni&)rni$j=8X0sL+9p?U
SrZM(TzRzjHICZiNmp1?>ZYj|K

diff --git a/tetrecs/target/classes/uk/ac/soton/comp1206/network/Communicator$1.class b/tetrecs/target/classes/uk/ac/soton/comp1206/network/Communicator$1.class
index 6cf9ed610db485c27836ddf9faf5b23efdcddf94..abda44096f5c2d3ed642efb0dcc4c79b26164ceb 100644
GIT binary patch
delta 17
YcmaFB^?+-`e->5~1}+BE$t<if061U-_y7O^

delta 17
YcmaFB^?+-`e->6_1}+AZ$t<if060<v_5c6?

diff --git a/tetrecs/target/classes/uk/ac/soton/comp1206/network/Communicator$2.class b/tetrecs/target/classes/uk/ac/soton/comp1206/network/Communicator$2.class
index 07139d84c2c6f90d7f2d1cfcf13aa85386d96adc..21785825fa458046db9bc0b5e4dd8ea84ce41b64 100644
GIT binary patch
delta 59
zcmbOwG)rhhFgv5=<Pi1{P8$YJ23rOp2K&hy*-JQ`83Y+z7(^LdC+l%!b9yoeGI%kF
PGI&qc<4~M@m?InjeEbYm

delta 59
zcmbOwG)rhhFgv5g<Pi1{PHP5E1{($;2D`}{*-JPb83Y-e7(^MIC+l%!bGk7IGPpB{
PGI&hZ<4~M@m?Injdp8V1

diff --git a/tetrecs/target/classes/uk/ac/soton/comp1206/network/Communicator.class b/tetrecs/target/classes/uk/ac/soton/comp1206/network/Communicator.class
index 99b1802aaca6b067117bc3a8accfe11812f42414..974892993abe7ee1d082096ca1d673b565ceab26 100644
GIT binary patch
delta 101
zcmew>|5tv4FR!8{Lo`DuLmY!2Lp*~&LjgkoLkU9=Lk~kR!$gJ<hN%o;lk<2daK<t4
zF(fdEGbB!C=ksOFWZ-7VnjFdJ&04^~$xt|XC11W^6$2kb4TBCtErSU|9fLVT{bWu4
FD*(l~7f}EJ

delta 101
zcmew>|5tv4FR!8nLo`DWLmY!QLp*~ILji*?LkWXFLk~j$!$gKahN%p}lk<2da7Hok
zF~l&4GsI42=ksMvVc=#+ogB&M&6>@?$&fR7C11W^2?HNP8G{Z(IfDs91%o+5<z!9%
FD*(5_7Wx1H

diff --git a/tetrecs/target/classes/uk/ac/soton/comp1206/scene/BaseScene.class b/tetrecs/target/classes/uk/ac/soton/comp1206/scene/BaseScene.class
index 09b4b896d839e039f7d0ec3c035aa395856ad37e..e252884720d19dffd51de46627128d39f4a583c5 100644
GIT binary patch
delta 49
zcmX@heU^K}P8Lpa1{MYh22KXa$%j~a1+^JC7<3rq8FU#;8T1&e81yG6um&(%Oy0;U
F0{{iw3D5ul

delta 49
zcmX@heU^K}P8Lov1{MZ!22KWv$%j~a1vMEs7_=DV8MGNp8FUz|7<4Bmum&)iPTt5W
F0{{e|3BUjV

diff --git a/tetrecs/target/classes/uk/ac/soton/comp1206/scene/ChallengeScene.class b/tetrecs/target/classes/uk/ac/soton/comp1206/scene/ChallengeScene.class
index 307d07de2a84933ea7a5dc80b9504e5c98c000a8..4ed833df05b29d0433119ea8087b1537728ac426 100644
GIT binary patch
delta 5311
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
Kyv%r&K@tEsVdgsk

delta 4561
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

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 ab27c55069861c8e139ae82305e1f07cad2366a0..9da2e51ae65b3730019681f359fe29c48c7382c4 100644
GIT binary patch
delta 1737
zcmcbt@JNa4)W2Q(7#J9A8J=(CYGkPw%StRuOsmi@PEO5B)h|h{DA5l|ttjDONMK}O
z4@oU4a&->oVu)o(;$dKA5CO3~I2ckH890(M(@Qc-a#Fb%q8LIr7%~_cc!M+Z(sNQ3
z0&)^7Q;RqlvKSdSa#Qn4Jxfw^g%}taa(EbW8S)qz*fJ9HQgTum8JsnICJV7SbHp+f
z@GulI6itq0GqvDgC}Cva@h#0M$%LC!#>l|!kzcM5k`ERVVqjv(;b5p_WMFZv$Sh%J
zsAgnPo7kwruVTo>P{mLSa%vqTgXUxbHVwWoPKE}CMs|iK9)@OymdW$ktl8Rl7}^;+
zCO=@)vS)J;VE_Y=H+py&dKsJ<8Mum5OM(j$lQZ+u*&LD%K;^?2Ch{;$VwlXxz*(GH
z;+&dSl3FxbmR(YggJCMvr+T>s##{{38D_9E%;aI1#W0(ZL49JQ=;V5K=a}gXb9or%
zG1!B&m*f`&=a=TCa53mGEZ|{S2omKhE=epZan4B0$w|#iPX$RW=3!U@k`hkIEH21N
ztn|z)E-5NaF3HT#E9PQY#;}~7VFeGvN`_UN|FK6fPOjy&)#A$q1so^_d=isVa~K(T
zGLbYfGH|9=WR`%XChy?P5)>%T$S+4WcCrGOwgI<aYH^8gYHm_$Q86QffKz^cNpVS0
zVu5dJNk)E3F+Ur_DK3W73}@IG&hjuQGn|{8%XLKl0wV*LQ)y;SN@iZV0wX^g!zC_;
z%M4f88Lsj$Tw}PtIe?pm(f=kRgSdtdG|8owrRJ6ByMjn-%`kpehTB{W91M4O81^$9
z5MVgK&&qHgB=CTT;V{DiMg|_wyu8#R=bXgi;?!bxhR2Kys*?|Li%;Ib#mC0Z@RX53
z4$5Vpe2+(ln~i~yft3M7uAa=wtLVChfq{XKfti7UL5_iyL7su1L4jc{0|SE?0}}%S
zg8;)ihV|fx7GTh1&|+X@U}V_9V9&tFu$qB^X&D160~Z4W<Fv`yylwSD@!J^^tym;k
zwlO3NrR-$zWnu`|-Nuk6$pT^TW{8U1&Jbh8x|<<3QYamym`#!mq&O3zK$1;s7eh7!
z!#0L|Nmh_XHi$S_eKANqyCgfZdaxpPsG@q1sih!Q9FiQ!syMWEF_a^j$^q2?QeOd5
z&nd}?te$f>Lsg{Kc7__bJ2)XaBw05x)Nf;Gm1GrR=-kH84fY%>L{4{8Jy=dxgrRR6
zL${9ZHiiis85kIt7(f9$i9v;dfkB-?gh7)*mqDAsltG8VkwKTimqCvql0ly#oxzYH
zpTUTsiot}TiNTzqm%)Nz7K0_jG6rjg^$fNQyBO>kjx*RZTw-uwxX<9k@QT5i;X8v1
zBMXBYBR_*XqYQ%wW4$_qC!-02H={j+52Fu*FJmM_Fk>1+C}SQ&7-Jbj1Y;9JBx5H-
z6ypSj7{;j#ao|`^gTx;+mQ5KG88$L(Vqj#*XH;j{%&>)liJ^&6gkdYgHU?&fUPexa
z?F>5@SQyqbJZIR+u#JJ0VHd+4hFuIh7}ywI)ibPN*v+tmft`_`p`Bq5!wv=xMtg>E
zhP@0s7&sXi8TP@F4TC8I69Xdy0|UFz6qX$f(-6VL1x|CR3~UT(VAt_LltEp`1j+!A
zl*i!Czz9~$y@O$n))of!Z4C445#~VBb1nljLmmScLq6CnNP6amn#I7t&2W(65ZIK%
z3<sd5I)M2M3>*+67a>f9xU7hQouL@XG!D3F91I8R!Nzeg9D(~&5$t>h22LT49Slo1
zGq8iqV+1D%Q2qnuF&2iS;6!qa;Wz^W0}BHqLlwgb1_lNh24;qn42%rt87?v~Gu&Xf
i#c&tOy2o&r;UNP91E{dC0_RKyhDQuf7@jdPNCE)dHj3Z?

delta 1456
zcmaE)bXkGx)W2Q(7#J9A86IuqYGkRG%1SItOsmi@PEO5B)z3++%r7m`4@ynX%+KRu
zh-I*2bBJUB0}wBnharW*nUR6FIJG38C^gL^H8VY<gp(nSA)TEegNGrLA&Zeg2Ahci
zMVa|UnI)Bs3~Y`*;f|5Pj0|!<S&3!!7<R){T5~bvFyyi`<nb`%GZZi~NMJM8!zsUl
zk%6N)wZtR6D8HPM!9)XOD#B2|{FGE{R3WGzA@&HAR9b6>aWO<Ogs?LdGct%xR^${5
z<zOgfWMB_TEh%z!4(4JgVkqZfU}X>iu{<~!su&qKk}}gvGD~t&IT&gf8F+&;^U`xt
z6#{Y+D^rU&80r`qIC4|-N<B+bbA=cf85(#P8X1}<|6vK_C}L>gVQ6J&n;gn&%FD^n
z!O+Rh(8a^h&CoMho6VZ7kB6b3VZ!7bHmw9MhA@UnJPeZ=rZ6(F6{nVj<QFh9h+*>{
z$o*jq(|8!BgVb^sr<ORU=9PdPG85_$z1#w0E{53*bJ!W?@-WO}n9s<dKCw}BvLd^)
z%xs2*JPeB%>=_w2i%aqgg7ZuBQn(m&7?$ubES=oIF3P=}VFf$GN*;z)468REV2@x_
zE-pw+PGw|}!5XZPq%&EB({XYmXU60|oSKu3xkUI*a50=@IK|FznukG|;mqVvt|Rj2
z7#X;nN;7j(GV{_E82Q;4E^skiWVpo6aG8hU3d7aS7The1jMpdI^2jRR<YM4pxW&V;
zpW%Q2!vRJH9?!hI)FS7c#Ny)AVs?gmj0~!i8@W{3*cl!$GRRGC<dU0wg-3>)m4T6g
zm4S_ckzvi`-#m)0YZ(|A_!yWO7#O4(SQ%s(_!(pw)-f<Jh%qoRFfa%(tY_E&PU->-
znhaVDj0}tn8yW0Dx)~UlKqhf8Ffgi4PULN?-_8(k#UjZf!jQ0yAxV;D6GQ3_hHTw!
z426;`I~jbL7{Yfm6h#V^Y-cF5VwGgw#!w+t2@waYVTG`FGekvhXNa+411qiuDQ1^s
z2Pv+FD3D~=+Qm@Mz_5*>S&|K8I6G9lo^2CD`!<GNT?nP4yNzL@4oJyVp&2YY7-nr`
zU|?Wk0C~5FL56{WL4`qtL5)F|L4(1RL6gCeL5sncL7O3xL5CroL60GyL7$<D!H}Ve
z!I+_&!GvKlgDJyo1~Z1`43-R=7_1ofGgvd6X0T<r!eGyEpTU9Q4MV*n!*>QJMivGa
zMji%NMqvhbMhONFMmYvAMimBcaF_-$fI|x!rlt%Z7&b9%W?*E<XV}KDg<&fL6GIcj
zVuo!D+ZmV{x*29M>|of*z{0SJp_pM8!)^vvhARw#40{;1Gq5q-XK-WK%dne)oq>^I
zA0$5N85kI}85kHCK^Wm#P)sv01cUA8fk;B_X96W1NK7)gGcbbVn|lYt0<A3!>f0C=
zBaDC~k0=IahG+&Zh8VC>kmSJ)HHv|On<4EW!yyJn1`dY95ce=JFerlUV_@JE;@H8k
zY%>Ep$V^6X96+2U!obXM1RO6%8ICb9FbFX)F&t-LWH`%ko`IR+8p92S+YEOY7#O%1
O7#Z#|+-G>mAPE34pjr(8

diff --git a/tetrecs/target/classes/uk/ac/soton/comp1206/ui/GamePane.class b/tetrecs/target/classes/uk/ac/soton/comp1206/ui/GamePane.class
index b89f5029abe56275431d1d3109046c4af613db37..aac6d099b65852a7465d1d7c047deefa6723d8bc 100644
GIT binary patch
delta 117
zcmZ1`uuNdXD^^)G1{MYx22KW920jLL24Myb1_=f&1{DTv25knN$?R-_tR@Vs45pJ~
z*&f^4GO#eXFz_?DGDtCaFeos1GH5V(Gw3q-GuSZ%F}N@UGk7tCF~l;2GZZjHG1M|d
VGc+^AFmy7+GAv|>n_SDj5&#)o6Po}4

delta 117
zcmZ1`uuNdXD^^)m1{MYx22KW920jKg24Mzu1_=gD1{DS^25koI$?R-_tVRs1491gV
z*&f?kGq5l?G4L}uGe|MGF(@#&GiWe)GUzh+GT1Q$Ft{)TGI%kBFvK#1G88aGFw`<c
VGBh(pF?2FSGc06?nOw`h5&#jd6LA0l

diff --git a/tetrecs/target/classes/uk/ac/soton/comp1206/ui/GameWindow.class b/tetrecs/target/classes/uk/ac/soton/comp1206/ui/GameWindow.class
index e4fc4bffe0885a514f134baa33bd64f7c118cc4f..0b960e06fab7295baebee34e45c826c20124ffc9 100644
GIT binary patch
delta 1864
zcmZosnXAfm>ff$?3=9mm3@<iv)v>U#Gek2oXis+J5S@IUnN8O-uehYBG`S=*KQA~r
zH7}KmA&Mc8gCUNQfjuO(q{!7dn2RBSA(5RSiH9M1@&XnWhXjUH9)>iAbVdg5;?xq~
z%)Ic-l#&ca1{Mt$%`lMSOdf_TkTefO+9NeHJ)=a3fq@~1has0CZ!!z3Hb(+O0S`kV
zL(yb&R!fBv9)?l|Hbw^a<eb#RywU<LhH{1qc7{qGhANP-3e2&SSF?(;)$lOXGSp2z
z#%je;&d|Wa(8$m<nS)J(t%Zl7m7#628Ji+U0z(H#ymN9qo19=b4?_<_FCznUQE46{
zgO!F4$h3)ZypuPuNpSZwOkii2$ipy+Ve;h5Y_5`185xAK63Y_PD)fs%p`i~B6LyB_
zlMUHr1*S1Db27|gn9a^GhlgP<!@S9H>`ok07#8p_ure&1yn@{_b}=J^lygpMVo_#Z
zx<YAzLP1e#S!RA|u>#mME(TeKr92GFK%U|Q`L)O=v$!NRFSV!`<mDAS3@brWT$y>9
zC7FpinZ>DG467N|ursXXVOYnoezF~hm-1?cjXVsSK*~6ZGfGQR^2_tM7`8BMWoOvN
z!?2xU2P1>><c}OOlaF&;6%kI!EH21NtVD|A;?1)-l^FRhaWPzGxWdkGm51RP!}ZOl
zxL6n&Z%#hXEo*q2i-CjT4iCdghEoC{#KzCc@Bk$CkcZ&}$XXuHyu8#R=bXgi;?!bx
zh9{F{d9+xbF*3+aR^XAFoXKORSj$kyz`(!+iVg+_1_1^&26Zsa$iT|5lYx<8*W?2{
zPWHPQ7#Oq|xEL51v>8|!bQm}pbQ$;<^cjR1j2OfjOc|sZEEwb&tQm9|>=+Cf>>2ie
z)w3`#Fc>oIW!N{_kyn#(*W_$oA9IjNVhpSd3=FOeTnruzQVgC9S`1zcRt(-?T|5ko
z3=9m`AYBX$42%p~3~XRmyyKPA2kGTvU}9ik2xQ=42trcN3s=7%q8?<%WNSXDdW4<`
z1|Eh;ta=V0^f0i1?dR3n%@7r-wVfem8$<9$Z~!3;iecbkh{bA<7~G(224=89^@dto
z7zBi3w=u+n7+PBx*xR=;q(Irc0wM|R+ZZxH++7UW3=G>C@)5Q{f+?ASlOcsclp&Qt
zg&~c>fFT{pW^mwwgDI3D3=~WZ3=CxqOyD5W(%QyQtX;p2p-fAAD?_!G_BMw4tqjc|
ztF*Q-G;d>Q*V@I<#lWzGp$}oD90NN81497=3qvsj2SW)1FGDGVC_@>80z)N(CPNk2
zYB7lM&=3cui-Qbx42%qn3^H)<$1-q&y{}!bwVPo|<Zgy(k=q$&fPJsEg@Lzy6T{5y
z4D(T)gKz~O12Y2yLj!|6LnDJ0Llf9mNV?F5+R6wjgP<OEVPFE=CA5h_TWHZv216zW
ztt|{H+ZdK?WMHUgU}6Bp9K^^D1}=t920?}{BqN33Mjm2lf*Pq0_6`FBD=4Hkz@s0O
z5*ZjKA!%lXYd*|y1dC>N-8E>sXJgfU6ry|b1_3c}iiOy;1gqL(49Bt9q=N3uwV0X(
zm_VfhRI?G(j~rTC7^=51EQbYuJp(uv85k;&4B&wHQ-BLp)Ibd|gc`uUgJIP+h7B<N
zFzsnb+SwUSGn`>yVBlal3pRWg0|SF1IMNsxIE6TNFl^q;pbavBkzuz31Iz>o24;qH
y;NUyYaDjn=0hI7AGB7jTV7SF_mjT4O$8ewF9>XIB1_mw$Mux`>PZ^#wNCE)(7jI4g

delta 1715
zcmbQM+M>dB>ff$?3=9mm3{N(4)v-u$Fhnylu!p3U6uCMFb1}p+#IZBP^Drb#zQ&@W
z9?Ou#!;s97!pOi~oLb_WnHQd!Qj)>Qz@p)z83t0E#>0@#kTO}3RhTW4harn0d$JX)
zHb*Q&E)PQ<L;mDkR!iwZ9)=<YHbw^a<eb#RywU<Lh7yKSc7`$@hVsb=Sxwn0c^Ik~
zswe+pwc;pYsO4d(W2m2O$ELy7$ivXY&^$SZO;IP7p%o<F#>gP9;ggkEmY7zdU!0tp
zm#QBOBCR#UgcukZI(Qg58M-F#WOL>2Vd!ON=;LANXP7XVliihZ(qw;jamFc=)7fPO
zCNnT|GE8Tf!Ok#~hhY}O?8#Huoj4{k%;jNVWtcbl9=j#ug2@sbigt^57#4%v%?EOK
zkxyoENorndQ8CE*OL-WUfuy)H^D;{^6LT_)Q@I#cFsx)}SjEGznqdtigT!P*F44(7
z97YN&7}oJHtOu#)D9$J?Ny#tI<6_vzu!)^vGY`WShOLwDaeUeQf>VK!?;IDyd4>z@
z3>SGAE-_r*EXK{k$ar<KG>@#wbuI=Dh8sK#M;VR@fDju$E5jX-*j*lmBOs%BJoEBW
zi=1;3i;Gi>*%=-%GN?{I$SuoPtm2cOpIutO&hUtlK@KD|c?*xZViiL*0|NsSD0~?h
z7z7y97}OaU82A|&8CV&%F)%W0pUlJSWWR%ffkBIb3rw;wXftp!=rHgx=rIU07&3@6
zm@r5)m@~*TSTX1@*fJO}*fH#cs$^g=WZ1>9dvY(YCgb+W+j)J=K_-bYure?(xG-=r
zxHCvGcra)&crsWqc!72CFfcMOFj#|hF)%PNGH5Zdfn8z6Csz;B%f-ONz`zi|z{3!T
zq@EY9eh)-F0|SFO0}I$JUaj2>;gMR~86vka1aAa;7Gw~}SO$hLtcHle4asI;1{-3i
zwS}QxKqzV(LyXoI1_7-t4D9XO7!sjuUICGW_H7KQAnq=P3<id63^@p!Al{8(;ADtp
z5M_vCP+^E?FknbPvKbsmVDE-9gn_)vz`#((zy$WHmew|g0_|-K#ai{+TNx^}w6`(T
zY-MNwS*5jwp<x?Ci`FiNb_RwW4BZGT<rvr*7#K1bSQxSyI2dvmco}jTL>clJ6c`E_
zG#QG(R*ON5hlU&|e)lp|GcYnRGRVNaAIrcA_P(~(Zib2Vk-HftM{Z}B3iiF$76#t-
zO$^hvGt5DC4#E|D49pA+3>6IW43!L83{_xTA@QpXwUrT69zZ?p!oUQ!OK1~=w$S{Y
z42Db$T3Z-YwlOS(npn@kzyL9_fq{#mkwK853CTzyxRLu9>Y+yJgT2GRzzPbf4QNr{
ziKLkou6aMh0W6x?*Dx?J)H5+463#@dx({O2%?r|vta&C@&4(BcW3gHV?(TYUv@kF%
z#MCXo1j_tS-9}Jfb7*a0sMyA^1R8t{3{d@rNcuS-9v9#O6(~^shEV<NI~bO4V^|B<
z4zoWVNk2QoafTBN3=A9$C&8v~XJBAZ1V<wS1E&zj4u%bz8MHwrFd~JW1Oqd}DR69@
uW;nyZzyL~#XBn6ot}t9<xXA!w-D0@SaEsv{0|NsW10%zIhKCG~86*J~RYOSt

-- 
GitLab