From b37c71b1351d502639ba20f973f3e98eb169665b Mon Sep 17 00:00:00 2001
From: Guyslain <guyslain.naves@lis-lab.fr>
Date: Fri, 18 Oct 2024 13:39:30 +0200
Subject: [PATCH] update du sujet, 2024

---
 src/main/java/controller/Controller.java      |   3 +-
 src/main/java/controller/Simulation.java      |   2 +-
 .../datastruct/ConstantMatrixInitializer.java |  14 --
 src/main/java/datastruct/Matrix.java          | 182 ------------------
 .../matrix/ConstantMatrixInitializer.java     |  16 ++
 .../{datastruct => matrix}/Coordinate.java    |  39 +++-
 .../CoordinateIterator.java                   |   2 +-
 src/main/java/matrix/ListMatrix.java          |  68 +++++++
 src/main/java/matrix/Matrix.java              |  85 ++++++++
 .../MatrixInitializer.java                    |   8 +-
 .../MatrixIterator.java                       |   2 +-
 src/main/java/model/Cell.java                 |   2 -
 .../model/CellularAutomatonSimulation.java    |  12 +-
 .../java/model/ConstantCellInitializer.java   |   8 +-
 src/main/java/{datastruct => model}/Lens.java |   2 +-
 .../java/model/NextGenerationInitializer.java |  10 +-
 src/main/java/view/FillingMouseListener.java  |   2 +-
 src/main/java/view/MatrixPane.java            |   2 +-
 src/main/java/view/MouseListener.java         |   2 +-
 src/main/java/view/WaitingMouseListener.java  |   2 +-
 .../ConstantMatrixInitializerTest.java        |   6 +-
 .../CoordinateIteratorTest.java               |   2 +-
 .../CoordinateTest.java                       |   2 +-
 .../ListMatrixTest.java}                      |  48 +++--
 .../CellularAutomatonSimulationTest.java      |   2 +-
 .../model/NextGenerationInitializerTest.java  |   3 +-
 26 files changed, 269 insertions(+), 257 deletions(-)
 delete mode 100644 src/main/java/datastruct/ConstantMatrixInitializer.java
 delete mode 100644 src/main/java/datastruct/Matrix.java
 create mode 100644 src/main/java/matrix/ConstantMatrixInitializer.java
 rename src/main/java/{datastruct => matrix}/Coordinate.java (76%)
 rename src/main/java/{datastruct => matrix}/CoordinateIterator.java (98%)
 create mode 100644 src/main/java/matrix/ListMatrix.java
 create mode 100644 src/main/java/matrix/Matrix.java
 rename src/main/java/{datastruct => matrix}/MatrixInitializer.java (51%)
 rename src/main/java/{datastruct => matrix}/MatrixIterator.java (96%)
 rename src/main/java/{datastruct => model}/Lens.java (96%)
 rename src/test/java/{datastruct => matrix}/ConstantMatrixInitializerTest.java (77%)
 rename src/test/java/{datastruct => matrix}/CoordinateIteratorTest.java (98%)
 rename src/test/java/{datastruct => matrix}/CoordinateTest.java (99%)
 rename src/test/java/{datastruct/MatrixTest.java => matrix/ListMatrixTest.java} (64%)

diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java
index 32e5657..01dae37 100644
--- a/src/main/java/controller/Controller.java
+++ b/src/main/java/controller/Controller.java
@@ -1,6 +1,6 @@
 package controller;
 
-import datastruct.Coordinate;
+import matrix.Coordinate;
 import javafx.animation.Animation;
 import javafx.animation.KeyFrame;
 import javafx.animation.Timeline;
@@ -11,7 +11,6 @@ import javafx.scene.control.Label;
 import javafx.scene.control.ToggleButton;
 import javafx.scene.control.ToggleGroup;
 import javafx.util.Duration;
-import model.CellularAutomatonSimulation;
 import view.MatrixPane;
 
 import static java.util.Objects.requireNonNull;
diff --git a/src/main/java/controller/Simulation.java b/src/main/java/controller/Simulation.java
index 8c33146..71e5d0f 100644
--- a/src/main/java/controller/Simulation.java
+++ b/src/main/java/controller/Simulation.java
@@ -1,6 +1,6 @@
 package controller;
 
-import datastruct.Coordinate;
+import matrix.Coordinate;
 import javafx.scene.paint.Color;
 import model.OnChangeListener;
 
diff --git a/src/main/java/datastruct/ConstantMatrixInitializer.java b/src/main/java/datastruct/ConstantMatrixInitializer.java
deleted file mode 100644
index e13032b..0000000
--- a/src/main/java/datastruct/ConstantMatrixInitializer.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package datastruct;
-
-public class ConstantMatrixInitializer<T> implements MatrixInitializer<T> {
-
-    private final T constant;
-
-    public ConstantMatrixInitializer(T constant) {
-        this.constant = constant;
-    }
-    @Override
-    public T initialValueAt(Coordinate coordinate) {
-        return constant;
-    }
-}
diff --git a/src/main/java/datastruct/Matrix.java b/src/main/java/datastruct/Matrix.java
deleted file mode 100644
index f98bd7a..0000000
--- a/src/main/java/datastruct/Matrix.java
+++ /dev/null
@@ -1,182 +0,0 @@
-package datastruct;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-
-/**
- * Represents a matrix, a rectangular array, with generic values in each cell.
- *
- * @param <T> The type of values stored in the matrix cells.
- */
-public class Matrix<T> implements Iterable<T> {
-
-    private final List<List<T>> matrix;
-    private final int width;
-    private final int height;
-
-    /**
-     * Creates a new {@link Matrix} with the specified width, height, and an initializer to set
-     * values.
-     *
-     * @param width       The width of the {@link Matrix}.
-     * @param height      The height of the {@link Matrix}.
-     * @param initializer A matrix initializer to set values in the {@link Matrix}.
-     */
-    public Matrix(int width, int height, MatrixInitializer<T> initializer) {
-        this.width = width;
-        this.height = height;
-        this.matrix = new ArrayList<>();
-        this.initializeWith(initializer);
-    }
-
-    /**
-     * Creates a new {@link Matrix} with the specified width, height, and initial value for all
-     * cells.
-     *
-     * @param width        The width of the {@link Matrix}.
-     * @param height       The height of the {@link Matrix}.
-     * @param initialValue The initial value to set in all cells of the {@link Matrix}.
-     */
-    public Matrix(int width, int height, T initialValue) {
-        this(width, height, new ConstantMatrixInitializer<>(initialValue));
-    }
-
-    private void initializeWith(MatrixInitializer<T> initializer) {
-        for (int x = 0; x < width; x++) {
-            List<T> row = new ArrayList<>();
-            this.matrix.add(row);
-            for (int y = 0; y < height; y++) {
-                row.add(initializer.initialValueAt(Coordinate.of(x, y)));
-            }
-        }
-    }
-
-    /**
-     * Returns the width of the {@link Matrix}.
-     *
-     * @return The width of the {@link Matrix}.
-     */
-    public int width() {
-        return width;
-    }
-
-    /**
-     * Returns the height of the {@link Matrix}.
-     *
-     * @return The height of the {@link Matrix}.
-     */
-    public int height() {
-        return height;
-    }
-
-    /**
-     * Gets the value at the specified coordinates (x, y) in the {@link Matrix}.
-     *
-     * @param x The x-coordinate.
-     * @param y The y-coordinate.
-     * @return The value at the specified coordinates.
-     */
-    public T get(int x, int y) {
-        return this.matrix.get(x).get(y);
-    }
-
-    /**
-     * Gets the value at the specified {@link Coordinate} in the {@link Matrix}.
-     *
-     * @param coordinate The {@link Coordinate}.
-     * @return The value at the specified {@link Coordinate}.
-     */
-    public T get(Coordinate coordinate) {
-        return this.get(coordinate.x(), coordinate.y());
-    }
-
-    /**
-     * Sets the value at the specified coordinates (x, y) in the {@link Matrix}.
-     *
-     * @param x     The x-coordinate.
-     * @param y     The y-coordinate.
-     * @param value The value to set at the specified coordinates.
-     */
-    public void set(int x, int y, T value) {
-        this.matrix.get(x).set(y, value);
-    }
-
-
-    /**
-     * Sets the value at the specified {@link Coordinate} in the {@link Matrix}.
-     *
-     * @param coordinate The {@link Coordinate}.
-     * @param value      The value to set at the specified {@link Coordinate}.
-     */
-    public void set(Coordinate coordinate, T value) {
-        this.set(coordinate.x(), coordinate.y(), value);
-    }
-
-    /**
-     * Returns an {@link Iterator} that allows iterating over the elements in the {@link Matrix} in
-     * row-major order.
-     *
-     * @return An {@link Iterator} for the {@link Matrix}.
-     */
-    public Iterator<T> iterator() {
-        Iterator<Coordinate> coordIterator = this.coordinatesIterator();
-        return new MatrixIterator<>(this, coordIterator);
-    }
-
-    /**
-     * Returns an {@link Iterable} that provides access to the {@link Coordinate}s of the
-     * {@link Matrix} in row-major order. This means that a {@code for} loop on a {@link Matrix}
-     * will loop over the coordinates of the {@link Matrix}.
-     *
-     * @return An {@link Iterable} for the {@link Coordinate}s of the {@link Matrix}.
-     */
-    public Iterable<Coordinate> coordinates() {
-        return this::coordinatesIterator;
-    }
-
-    /**
-     * Returns an {@link Iterator} that allows iterating over the {@link Coordinate}s in the
-     * {@link Matrix} in row-major order.
-     *
-     * @return An {@link Iterator} for the {@link Matrix}.
-     */
-    private Iterator<Coordinate> coordinatesIterator() {
-        return new CoordinateIterator(this.width, this.height);
-    }
-
-    /**
-     * Returns a lens for accessing and modifying the value at the specified coordinates (x, y) in
-     * the {@link Matrix}.
-     *
-     * @param x The x-coordinate.
-     * @param y The y-coordinate.
-     * @return A lens for the specified coordinates.
-     */
-    public Lens<T> at(int x, int y) {
-        return new Lens<T>() {
-            @Override
-            public T get() {
-                return Matrix.this.get(x, y);
-            }
-
-            @Override
-            public void set(T value) {
-                Matrix.this.set(x, y, value);
-            }
-        };
-    }
-
-    /**
-     * Returns a lens for accessing and modifying the value at the specified coordinate in the
-     * {@link Matrix}.
-     *
-     * @param coordinate The {@link Coordinate}.
-     * @return A lens for the specified  {@link Coordinate}.
-     */
-    public Lens<T> at(Coordinate coordinate) {
-        return this.at(coordinate.x(), coordinate.y());
-    }
-
-}
diff --git a/src/main/java/matrix/ConstantMatrixInitializer.java b/src/main/java/matrix/ConstantMatrixInitializer.java
new file mode 100644
index 0000000..88d798b
--- /dev/null
+++ b/src/main/java/matrix/ConstantMatrixInitializer.java
@@ -0,0 +1,16 @@
+package matrix;
+
+public class ConstantMatrixInitializer<T> implements MatrixInitializer<T> {
+
+  // TODO: add instance variables
+
+  public ConstantMatrixInitializer(T constant) {
+    // TODO
+  }
+
+    @Override
+    public T initialValueAt(Coordinate coordinate) {
+      // TODO
+      return null;
+    }
+}
diff --git a/src/main/java/datastruct/Coordinate.java b/src/main/java/matrix/Coordinate.java
similarity index 76%
rename from src/main/java/datastruct/Coordinate.java
rename to src/main/java/matrix/Coordinate.java
index f7f7e22..f3e5ac0 100644
--- a/src/main/java/datastruct/Coordinate.java
+++ b/src/main/java/matrix/Coordinate.java
@@ -1,6 +1,5 @@
-package datastruct;
+package matrix;
 
-import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -62,7 +61,15 @@ public record Coordinate(int x, int y) {
 
     /**
      * Computes and returns a list of orthogonal (adjacent in horizontal or vertical direction) neighbors.
-     *
+     *  | | | |
+     * ---------
+     *  | |X| |
+     * ---------
+     *  |X|O|X|
+     * ---------
+     *  | |X| |
+     * ---------
+     * | | | |
      * @return A list of orthogonal neighboring {@link Coordinate}s.
      */
     public List<Coordinate> orthogonalNeighbours() {
@@ -72,6 +79,15 @@ public record Coordinate(int x, int y) {
 
     /**
      * Computes and returns a list of diagonal (adjacent in diagonal direction) neighbors.
+     *  | | | |
+     * ---------
+     *  |X| |X|
+     * ---------
+     *  | |O| |
+     * ---------
+     *  |X| |X|
+     * ---------
+     * | | | |
      *
      * @return A list of diagonal neighboring {@link Coordinate}s.
      */
@@ -82,6 +98,15 @@ public record Coordinate(int x, int y) {
 
     /**
      * Computes and returns a list of all orthogonal and diagonal neighbors.
+     *      *  | | | |
+     *      * ---------
+     *      *  |X|X|X|
+     *      * ---------
+     *      *  |X|O|X|
+     *      * ---------
+     *      *  |X|X|X|
+     *      * ---------
+     *      * | | | |
      *
      * @return A list of all neighboring {@link Coordinate}s.
      */
@@ -94,4 +119,12 @@ public record Coordinate(int x, int y) {
     public String toString() {
         return "(" + this.x + "," + this.y + ")";
     }
+
+  public Coordinate minus(Coordinate corner) {
+    return new Coordinate(this.x - corner.x, this.y - corner.y);
+  }
+
+  public Coordinate plus(Coordinate corner) {
+      return new Coordinate(this.x + corner.x, this.y + corner.y);
+  }
 }
\ No newline at end of file
diff --git a/src/main/java/datastruct/CoordinateIterator.java b/src/main/java/matrix/CoordinateIterator.java
similarity index 98%
rename from src/main/java/datastruct/CoordinateIterator.java
rename to src/main/java/matrix/CoordinateIterator.java
index 37360d0..810b712 100644
--- a/src/main/java/datastruct/CoordinateIterator.java
+++ b/src/main/java/matrix/CoordinateIterator.java
@@ -1,4 +1,4 @@
-package datastruct;
+package matrix;
 
 import java.util.Iterator;
 import java.util.NoSuchElementException;
diff --git a/src/main/java/matrix/ListMatrix.java b/src/main/java/matrix/ListMatrix.java
new file mode 100644
index 0000000..990ffa8
--- /dev/null
+++ b/src/main/java/matrix/ListMatrix.java
@@ -0,0 +1,68 @@
+package matrix;
+
+import java.util.List;
+
+
+/**
+ * Represents a matrix, a rectangular array, with generic values in each cell.
+ *
+ * @param <T> The type of values stored in the matrix cells.
+ */
+public class ListMatrix<T> implements Matrix<T> {
+
+  private final List<List<T>> matrix;
+  private final int width;
+  private final int height;
+
+  /**
+   * Creates a new {@link ListMatrix} with the specified width, height, and an initializer to set
+   * values.
+   *
+   * @param width       The width of the {@link ListMatrix}.
+   * @param height      The height of the {@link ListMatrix}.
+   * @param initializer A matrix initializer to set values in the {@link ListMatrix}.
+   */
+  public ListMatrix(int width, int height, MatrixInitializer<T> initializer) {
+    // TODO
+    this.width = 0;
+    this.height = 0;
+    this.matrix = null;
+    this.initializeWith(initializer); // fills the matrix using initializer
+  }
+
+  public ListMatrix(int width, int height, T constant) {
+    this(width, height, new ConstantMatrixInitializer<>(constant));
+  }
+
+  private void initializeWith(MatrixInitializer<T> initializer) {
+    // TODO initialize each cell of the matrix, with a value determined by initializer
+  }
+
+  public int width() {
+    // TODO
+    return 0;
+  }
+
+  public int height() {
+    // TODO
+    return 0;
+  }
+
+  @Override
+  public T get(int x, int y) {
+    // TODO
+    return null;
+  }
+
+
+  @Override
+  public void set(int x, int y, T newValue) {
+    // TODO
+  }
+
+  public Matrix<T> subMatrix(Coordinate corner, int width, int height) {
+    // TODO
+    return this;
+  }
+
+}
diff --git a/src/main/java/matrix/Matrix.java b/src/main/java/matrix/Matrix.java
new file mode 100644
index 0000000..3a79773
--- /dev/null
+++ b/src/main/java/matrix/Matrix.java
@@ -0,0 +1,85 @@
+package matrix;
+
+import java.util.Iterator;
+
+public interface Matrix<T> extends Iterable<T> {
+
+  /**
+   * Returns the width of the {@link Matrix}.
+   *
+   * @return The width of the {@link Matrix}.
+   */
+  int width();
+
+  /**
+   * Returns the height of the {@link Matrix}.
+   *
+   * @return The height of the {@link Matrix}.
+   */
+  int height();
+
+  /**
+   * Returns the value at the specified coordinates (x, y) in
+   * the {@link Matrix}.
+   *
+   * @param x The x-coordinate.
+   * @param y The y-coordinate.
+   * @return The content of the matrix at the coordinates (x,y).
+   */
+  T get(int x, int y);
+  /**
+   * Returns the value at the specified coordinates (x, y) in
+   * the {@link Matrix}.
+   *
+   * @param coordinate The coordinates (x,y).
+   * @return The content of the matrix at the coordinates (x,y).
+   */
+  default T get(Coordinate coordinate) {
+    return this.get(coordinate.x(), coordinate.y());
+  }
+
+  /**
+   *  Changes the value at the specified coordinates (x,y) in the {@link Matrix}
+   *
+   * @param x the x-coordinate
+   * @param y the y-coordinate
+   * @param newValue the value to assign to coordinates (x,y).
+   */
+  void set(int x, int y, T newValue);
+
+  /**
+   *  Changes the value at the specified coordinates (x,y) in the {@link Matrix}
+   *
+   * @param coordinate The coordinates (x,y)
+   * @param newValue the value to assign to coordinates (x,y).
+   */
+  default void set(Coordinate coordinate, T newValue) {
+    this.set(coordinate.x(), coordinate.y(), newValue);
+  }
+
+  Matrix<T> subMatrix(Coordinate corner, int width, int height);
+
+
+  /**
+   * Returns an {@link Iterable} that provides access to the {@link Coordinate}s of the
+   * {@link Matrix} in row-major order. This means that a {@code for} loop on a {@link Matrix}
+   * will loop over the coordinates of the {@link Matrix}.
+   *
+   * @return An {@link Iterable} for the {@link Coordinate}s of the {@link Matrix}.
+   */
+  default Iterable<Coordinate> coordinates() {
+    return () -> new CoordinateIterator(this.width(), this.height());
+  }
+
+  /**
+   * Returns an {@link Iterator} that allows iterating over the elements in the {@link Matrix} in
+   * row-major order.
+   *
+   * @return An {@link Iterator} for the {@link Matrix}.
+   */
+  default Iterator<T> iterator() {
+    Iterator<Coordinate> coords =
+      new CoordinateIterator(this.width(),this.height());
+    return new MatrixIterator<>(this, coords);
+  }
+}
diff --git a/src/main/java/datastruct/MatrixInitializer.java b/src/main/java/matrix/MatrixInitializer.java
similarity index 51%
rename from src/main/java/datastruct/MatrixInitializer.java
rename to src/main/java/matrix/MatrixInitializer.java
index dab2bf2..492d15c 100644
--- a/src/main/java/datastruct/MatrixInitializer.java
+++ b/src/main/java/matrix/MatrixInitializer.java
@@ -1,14 +1,14 @@
-package datastruct;
+package matrix;
 
 /**
- * An interface for initializing a {@link Matrix} by providing initial values for each cell.
+ * An interface for initializing a {@link ListMatrix} by providing initial values for each cell.
  *
- * @param <T> The type of values to initialize the {@link Matrix} with.
+ * @param <T> The type of values to initialize the {@link ListMatrix} with.
  */
 public interface MatrixInitializer<T> {
 
     /**
-     * Returns the initial value to be set in a {@link Matrix} cell at the specified
+     * Returns the initial value to be set in a {@link ListMatrix} cell at the specified
      * {@link Coordinate}.
      *
      * @param coordinate The {@link Coordinate} at which to set the initial value.
diff --git a/src/main/java/datastruct/MatrixIterator.java b/src/main/java/matrix/MatrixIterator.java
similarity index 96%
rename from src/main/java/datastruct/MatrixIterator.java
rename to src/main/java/matrix/MatrixIterator.java
index f0d1f66..d775f9e 100644
--- a/src/main/java/datastruct/MatrixIterator.java
+++ b/src/main/java/matrix/MatrixIterator.java
@@ -1,4 +1,4 @@
-package datastruct;
+package matrix;
 
 import java.util.Iterator;
 import java.util.NoSuchElementException;
diff --git a/src/main/java/model/Cell.java b/src/main/java/model/Cell.java
index 0378034..f7f6274 100644
--- a/src/main/java/model/Cell.java
+++ b/src/main/java/model/Cell.java
@@ -1,7 +1,5 @@
 package model;
 
-import datastruct.Lens;
-
 import java.util.ArrayList;
 import java.util.List;
 
diff --git a/src/main/java/model/CellularAutomatonSimulation.java b/src/main/java/model/CellularAutomatonSimulation.java
index 4f51254..d08c7a4 100644
--- a/src/main/java/model/CellularAutomatonSimulation.java
+++ b/src/main/java/model/CellularAutomatonSimulation.java
@@ -1,8 +1,8 @@
 package model;
 
 import controller.Simulation;
-import datastruct.Coordinate;
-import datastruct.Matrix;
+import matrix.Coordinate;
+import matrix.ListMatrix;
 import javafx.scene.paint.Color;
 
 import java.util.Iterator;
@@ -18,7 +18,7 @@ import java.util.Random;
 public class CellularAutomatonSimulation<S extends State<S>>
         implements Simulation {
 
-    private final Matrix<Cell<S>> grid;
+    private final ListMatrix<Cell<S>> grid;
     private final Cell<Integer> generationNumber = new Cell<>(0);
     private final CellularAutomaton<S> automaton;
     private final Random generator;
@@ -31,7 +31,7 @@ public class CellularAutomatonSimulation<S extends State<S>>
      */
     public CellularAutomatonSimulation(CellularAutomaton<S> automaton, Random generator) {
         this.automaton = automaton;
-        this.grid = new Matrix<>(
+        this.grid = new ListMatrix<>(
                 automaton.numberOfColumns(),
                 automaton.numberOfRows(),
                 new ConstantCellInitializer<>(automaton.defaultState())
@@ -68,12 +68,12 @@ public class CellularAutomatonSimulation<S extends State<S>>
         //TODO: à compléter, en utilisant nextGenerationMatrix()
     }
 
-    /** Computes the {@link Matrix} of states obtained after a single step of updates
+    /** Computes the {@link ListMatrix} of states obtained after a single step of updates
      * of the simulation.
      *
      * @return the states of each cell after one generation
      */
-    private Matrix<S> nextGenerationMatrix() {
+    private ListMatrix<S> nextGenerationMatrix() {
         //TODO: à compléter
         return null;
     }
diff --git a/src/main/java/model/ConstantCellInitializer.java b/src/main/java/model/ConstantCellInitializer.java
index c447145..39a5b71 100644
--- a/src/main/java/model/ConstantCellInitializer.java
+++ b/src/main/java/model/ConstantCellInitializer.java
@@ -1,11 +1,11 @@
 package model;
 
-import datastruct.Coordinate;
-import datastruct.Matrix;
-import datastruct.MatrixInitializer;
+import matrix.Coordinate;
+import matrix.ListMatrix;
+import matrix.MatrixInitializer;
 
 /**
- *  An initializer for {@link Matrix} of {@link Cell}s, where each cell is initialized to the
+ *  An initializer for {@link ListMatrix} of {@link Cell}s, where each cell is initialized to the
  *  same value.
  *
  * @param <T> the type of content of each cell
diff --git a/src/main/java/datastruct/Lens.java b/src/main/java/model/Lens.java
similarity index 96%
rename from src/main/java/datastruct/Lens.java
rename to src/main/java/model/Lens.java
index a98fd46..254415e 100644
--- a/src/main/java/datastruct/Lens.java
+++ b/src/main/java/model/Lens.java
@@ -1,4 +1,4 @@
-package datastruct;
+package model;
 
 /**
  * A lens interface representing a view into a mutable state.
diff --git a/src/main/java/model/NextGenerationInitializer.java b/src/main/java/model/NextGenerationInitializer.java
index ad03fdf..f9462bf 100644
--- a/src/main/java/model/NextGenerationInitializer.java
+++ b/src/main/java/model/NextGenerationInitializer.java
@@ -1,14 +1,12 @@
 package model;
 
-import datastruct.Coordinate;
-import datastruct.MatrixInitializer;
-import datastruct.Matrix;
+import matrix.Coordinate;
+import matrix.MatrixInitializer;
+import matrix.ListMatrix;
 import controller.Simulation;
-import java.util.ArrayList;
-import java.util.List;
 
 /**
- * An initializer for a {@link Matrix} of states, where each state is computed based on the value
+ * An initializer for a {@link ListMatrix} of states, where each state is computed based on the value
  * of its neighbours in a {@link Simulation} of a cellular automaton.
  *
  * @param <S> the type of states in the simulation.
diff --git a/src/main/java/view/FillingMouseListener.java b/src/main/java/view/FillingMouseListener.java
index a4946eb..30a9a29 100644
--- a/src/main/java/view/FillingMouseListener.java
+++ b/src/main/java/view/FillingMouseListener.java
@@ -1,6 +1,6 @@
 package view;
 
-import datastruct.Coordinate;
+import matrix.Coordinate;
 import javafx.scene.input.MouseEvent;
 
 public class FillingMouseListener implements MouseListener {
diff --git a/src/main/java/view/MatrixPane.java b/src/main/java/view/MatrixPane.java
index 050f739..99f049e 100644
--- a/src/main/java/view/MatrixPane.java
+++ b/src/main/java/view/MatrixPane.java
@@ -1,7 +1,7 @@
 package view;
 
 import controller.Controller;
-import datastruct.Coordinate;
+import matrix.Coordinate;
 import javafx.scene.input.MouseDragEvent;
 import javafx.scene.input.MouseEvent;
 import javafx.scene.layout.GridPane;
diff --git a/src/main/java/view/MouseListener.java b/src/main/java/view/MouseListener.java
index 775cc91..5852db0 100644
--- a/src/main/java/view/MouseListener.java
+++ b/src/main/java/view/MouseListener.java
@@ -1,6 +1,6 @@
 package view;
 
-import datastruct.Coordinate;
+import matrix.Coordinate;
 import javafx.scene.input.MouseEvent;
 
 interface MouseListener {
diff --git a/src/main/java/view/WaitingMouseListener.java b/src/main/java/view/WaitingMouseListener.java
index 68601de..ecab1d1 100644
--- a/src/main/java/view/WaitingMouseListener.java
+++ b/src/main/java/view/WaitingMouseListener.java
@@ -1,6 +1,6 @@
 package view;
 
-import datastruct.Coordinate;
+import matrix.Coordinate;
 import javafx.scene.input.MouseEvent;
 
 class WaitingMouseListener implements MouseListener {
diff --git a/src/test/java/datastruct/ConstantMatrixInitializerTest.java b/src/test/java/matrix/ConstantMatrixInitializerTest.java
similarity index 77%
rename from src/test/java/datastruct/ConstantMatrixInitializerTest.java
rename to src/test/java/matrix/ConstantMatrixInitializerTest.java
index 4db9c2a..7435089 100644
--- a/src/test/java/datastruct/ConstantMatrixInitializerTest.java
+++ b/src/test/java/matrix/ConstantMatrixInitializerTest.java
@@ -1,4 +1,4 @@
-package datastruct;
+package matrix;
 
 import org.junit.jupiter.api.Test;
 
@@ -7,7 +7,7 @@ import static org.junit.jupiter.api.Assertions.*;
 class ConstantMatrixInitializerTest {
     @Test
     public void testMatrixInitializationWithConstantValue() {
-        Matrix<String> matrix = new Matrix<>(3, 3, new ConstantMatrixInitializer<>("X"));
+        ListMatrix<String> matrix = new ListMatrix<>(3, 3, new ConstantMatrixInitializer<>("X"));
 
         // Test that all cells have the constant value.
         for (int x = 0; x < 3; x++) {
@@ -19,7 +19,7 @@ class ConstantMatrixInitializerTest {
 
     @Test
     public void testMatrixInitializationWithConstantValue2() {
-        Matrix<Integer> matrix = new Matrix<>(3, 5, new ConstantMatrixInitializer<>(12));
+        ListMatrix<Integer> matrix = new ListMatrix<>(3, 5, new ConstantMatrixInitializer<>(12));
 
         // Test that all cells have the constant value.
         for (int x = 0; x < 3; x++) {
diff --git a/src/test/java/datastruct/CoordinateIteratorTest.java b/src/test/java/matrix/CoordinateIteratorTest.java
similarity index 98%
rename from src/test/java/datastruct/CoordinateIteratorTest.java
rename to src/test/java/matrix/CoordinateIteratorTest.java
index 90be82e..5339f99 100644
--- a/src/test/java/datastruct/CoordinateIteratorTest.java
+++ b/src/test/java/matrix/CoordinateIteratorTest.java
@@ -1,4 +1,4 @@
-package datastruct;
+package matrix;
 
 import org.junit.jupiter.api.Test;
 
diff --git a/src/test/java/datastruct/CoordinateTest.java b/src/test/java/matrix/CoordinateTest.java
similarity index 99%
rename from src/test/java/datastruct/CoordinateTest.java
rename to src/test/java/matrix/CoordinateTest.java
index bddaae9..fccb4c9 100644
--- a/src/test/java/datastruct/CoordinateTest.java
+++ b/src/test/java/matrix/CoordinateTest.java
@@ -1,4 +1,4 @@
-package datastruct;
+package matrix;
 
 import org.junit.jupiter.api.Test;
 
diff --git a/src/test/java/datastruct/MatrixTest.java b/src/test/java/matrix/ListMatrixTest.java
similarity index 64%
rename from src/test/java/datastruct/MatrixTest.java
rename to src/test/java/matrix/ListMatrixTest.java
index 346c29b..f2f309a 100644
--- a/src/test/java/datastruct/MatrixTest.java
+++ b/src/test/java/matrix/ListMatrixTest.java
@@ -1,4 +1,4 @@
-package datastruct;
+package matrix;
 
 import org.junit.jupiter.api.Test;
 
@@ -6,14 +6,14 @@ import java.util.Iterator;
 
 import static org.junit.jupiter.api.Assertions.*;
 
-class MatrixTest {
+class ListMatrixTest {
 
     private final MatrixInitializer<Integer> sumInitializer =
             coord -> coord.x() + coord.y();
 
     @Test
     public void testMatrixCreationWithInitializer() {
-        Matrix<Integer> matrix = new Matrix<>(3, 4, sumInitializer);
+        ListMatrix<Integer> matrix = new ListMatrix<>(3, 4, sumInitializer);
         assertEquals(3, matrix.width());
         assertEquals(4, matrix.height());
         assertEquals(4, matrix.get(2, 2));
@@ -24,7 +24,7 @@ class MatrixTest {
 
     @Test
     public void testMatrixCreationWithInitialValue() {
-        Matrix<String> matrix = new Matrix<>(2, 2, "Foo");
+        ListMatrix<String> matrix = new ListMatrix<>(2, 2, "Foo");
         assertEquals(2, matrix.width());
         assertEquals(2, matrix.height());
         assertEquals("Foo", matrix.get(1, 1)); // Test a specific cell value.
@@ -32,28 +32,28 @@ class MatrixTest {
 
     @Test
     public void testMatrixSetAndGet() {
-        Matrix<Integer> matrix = new Matrix<>(3, 3, 0);
-        matrix.set(1, 1, 42);
+        ListMatrix<Integer> matrix = new ListMatrix<>(3, 3, 0);
+        matrix.set(1, 1,42);
         assertEquals(42, matrix.get(1, 1));
-        matrix.set(0, 2, 10);
+        matrix.set(0, 2,10);
         assertEquals(10, matrix.get(0, 2));
-        matrix.set(Coordinate.of(2, 2), 99);
+        matrix.set(Coordinate.of(2, 2),99);
         assertEquals(99, matrix.get(Coordinate.of(2, 2)));
     }
 
     @Test
     public void testMatrixWidthAndHeight() {
-        Matrix<String> matrix = new Matrix<>(4, 2, "A");
+        ListMatrix<String> matrix = new ListMatrix<>(4, 2, "A");
         assertEquals(4, matrix.width());
         assertEquals(2, matrix.height());
-        matrix.set(3, 1, "B");
+        matrix.set(3, 1,"B");
         assertEquals(4, matrix.width());
         assertEquals(2, matrix.height());
     }
 
     @Test
     public void testMatrixIterator() {
-        Matrix<Integer> matrix = new Matrix<>(2, 2, sumInitializer);
+        ListMatrix<Integer> matrix = new ListMatrix<>(2, 2, sumInitializer);
         Iterator<Integer> iterator = matrix.iterator();
         assertTrue(iterator.hasNext());
         assertEquals(0, iterator.next());
@@ -68,7 +68,7 @@ class MatrixTest {
 
     @Test
     public void testMatrixCoordinates() {
-        Matrix<Integer> matrix = new Matrix<>(2, 2, 0);
+        ListMatrix<Integer> matrix = new ListMatrix<>(2, 2, 0);
         Iterable<Coordinate> coordinates = matrix.coordinates();
         int count = 0;
         for (Coordinate coord : coordinates) {
@@ -77,12 +77,24 @@ class MatrixTest {
         assertEquals(4, count);
     }
 
+
     @Test
-    public void testMatrixLens() {
-        Matrix<Integer> matrix = new Matrix<>(2, 2, 0);
-        Lens<Integer> lens = matrix.at(1, 1);
-        assertEquals(0, lens.get());
-        lens.set(42);
-        assertEquals(42, matrix.get(1, 1));
+    public void testSubMatrix() {
+      Matrix<Integer> matrix = new ListMatrix<>(5, 5, 0);
+      for (int x = 0; x < 5; x++) {
+        for (int y = 0; y < 5; y++) {
+          matrix.set(x,y,x + y * 5);
+        }
+      }
+      Matrix<Integer> sub = matrix.subMatrix(Coordinate.of(2,1),2,3);
+      assertEquals(2, sub.width());
+      assertEquals(3, sub.height());
+      for (int x = 2; x < 4; x++) {
+        for (int y = 1; y < 4; y++) {
+          assertEquals(x + y * 5, sub.get(x-2,y-1));
+        }
+      }
     }
+
+
 }
diff --git a/src/test/java/model/CellularAutomatonSimulationTest.java b/src/test/java/model/CellularAutomatonSimulationTest.java
index 81c4eac..cd7dd67 100644
--- a/src/test/java/model/CellularAutomatonSimulationTest.java
+++ b/src/test/java/model/CellularAutomatonSimulationTest.java
@@ -1,6 +1,6 @@
 package model;
 
-import datastruct.Coordinate;
+import matrix.Coordinate;
 import javafx.scene.paint.Color;
 import model.automata.GameOfLifeAutomaton;
 import static model.automata.GameOfLifeState.*;
diff --git a/src/test/java/model/NextGenerationInitializerTest.java b/src/test/java/model/NextGenerationInitializerTest.java
index b2e8ea7..8edee89 100644
--- a/src/test/java/model/NextGenerationInitializerTest.java
+++ b/src/test/java/model/NextGenerationInitializerTest.java
@@ -1,7 +1,6 @@
 package model;
 
-import controller.Simulation;
-import datastruct.Coordinate;
+import matrix.Coordinate;
 import model.automata.GameOfLifeAutomaton;
 import model.automata.GameOfLifeState;
 import org.junit.jupiter.api.BeforeEach;
-- 
GitLab