diff --git a/src/main/java/SimulatorApplication.java b/src/main/java/SimulatorApplication.java
index 0fed297543cac4bfb5ea3722d445cbc71aea4745..1e2f7b34dadbe4ce66bfd4f13200e43cdef09ff5 100644
--- a/src/main/java/SimulatorApplication.java
+++ b/src/main/java/SimulatorApplication.java
@@ -7,16 +7,13 @@ import javafx.scene.Parent;
 import javafx.scene.Scene;
 import javafx.stage.Stage;
 import model.CellularAutomatonSimulation;
-import model.automata.BriansBrainAutomaton;
-import model.automata.GameOfLifeAutomaton;
+import model.automata.BiColorAutomaton;
 import model.automata.SeedsAutomaton;
 
 import java.io.IOException;
 import java.net.URL;
 import java.util.Random;
 
-import static java.util.Objects.requireNonNull;
-
 /**
  * Entry point for <i>The Game of Life</i> application.
  *
@@ -41,7 +38,7 @@ public class SimulatorApplication extends Application {
   public SimulatorApplication() {
     this.simulation =
       new CellularAutomatonSimulation<>(
-              new SeedsAutomaton(NUMBER_OF_COLUMNS,NUMBER_OF_ROWS),
+              new BiColorAutomaton(NUMBER_OF_COLUMNS,NUMBER_OF_ROWS),
               GENERATOR
       );
   }
diff --git a/src/main/java/controller/Controller.java b/src/main/java/controller/Controller.java
index 84e73a3ad497c0ee5a5258d884062d50cb1cb4ce..0e8cf64017bd9532e0b2dd930c69b71b2e0d0dc7 100644
--- a/src/main/java/controller/Controller.java
+++ b/src/main/java/controller/Controller.java
@@ -65,7 +65,14 @@ public class Controller {
     }
 
     private void setGenerationNumberLabelTextProperty() {
-        generationNumberLabel.textProperty().bind(simulation.generationNumberProperty().asString());
+        updateGenerationNumber(0);
+        this.simulation.setGenerationNumberChangeListener(
+                (oldValue, newValue) -> updateGenerationNumber(newValue)
+        );
+    }
+
+    private void updateGenerationNumber(int newValue) {
+        generationNumberLabel.textProperty().set(String.valueOf(newValue));
     }
 
     private void initializeMatrixPane() {
diff --git a/src/main/java/controller/Simulation.java b/src/main/java/controller/Simulation.java
index 674a0fd910b383cc55a0ba0e1245ce5309a45499..8c33146524a2ac98ab455a906ffbfa086ecfb61c 100644
--- a/src/main/java/controller/Simulation.java
+++ b/src/main/java/controller/Simulation.java
@@ -1,28 +1,82 @@
 package controller;
 
 import datastruct.Coordinate;
-import javafx.beans.property.ReadOnlyLongProperty;
 import javafx.scene.paint.Color;
 import model.OnChangeListener;
 
+/**
+ * Represents a simulation of a 2D cellular automaton, such as the Game of Life.
+ * Provides methods for updating the simulation, retrieving information, and managing listeners.
+ */
 public interface Simulation extends Iterable<Coordinate> {
 
+    /**
+     * Returns the number of columns in the simulation grid.
+     *
+     * @return The number of columns in the grid.
+     */
     int numberOfColumns();
+
+    /**
+     * Returns the number of rows in the simulation grid.
+     *
+     * @return The number of rows in the grid.
+     */
     int numberOfRows();
 
+
+    /**
+     * Updates the simulation to the next generation. This is done by computing, for each
+     * coordinate, a new state that depends on the states of its neighbours.
+     */
     void updateToNextGeneration();
 
+    /**
+     * Changes the state at a given {@link Coordinate}. This is used to edit the grid with the mouse. It
+     * is not part of the simulation of the cellular automaton.
+     *
+     * @param coordinate The {@link Coordinate} to advance to the next state.
+     */
     void next(Coordinate coordinate);
 
+    /**
+     * Copies the state from the source {@link Coordinate} to the destination {@link Coordinate}.
+     *
+     * @param source      The source {@link Coordinate}.
+     * @param destination The destination {@link Coordinate}.
+     */
     void copy(Coordinate source, Coordinate destination);
 
+    /**
+     * Gets the {@link Color} associated with the state at the specified {@link Coordinate}.
+     *
+     * @param coordinate The {@link Coordinate} to retrieve the color for.
+     * @return The {@link Color} associated with the state at the specified {@link Coordinate}.
+     */
     Color getColor(Coordinate coordinate);
 
+    /**
+     * Sets a listener to be executed when the state at the specified {@link Coordinate} changes.
+     *
+     * @param coordinate The {@link Coordinate} to listen for changes.
+     * @param listener   The listener to execute when the state changes.
+     */
     void setChangeListener(Coordinate coordinate, Runnable listener);
 
-    ReadOnlyLongProperty generationNumberProperty();
+    /**
+     * Sets a listener to be executed when the generation number changes.
+     *
+     * @param listener The listener to execute when the generation number changes.
+     */
+    void setGenerationNumberChangeListener(OnChangeListener<Integer> listener);
 
+    /**
+     * Resets the simulation to random states.
+     */
     void reset();
 
+    /**
+     * Clears the simulation, setting all states to their default values.
+     */
     void clear();
 }
diff --git a/src/main/java/datastruct/Coordinate.java b/src/main/java/datastruct/Coordinate.java
index b807b96f43bb714c2e9bec01e48bf033d4fff566..18282bc801ba34a0517152502bd175dbd19d14c3 100644
--- a/src/main/java/datastruct/Coordinate.java
+++ b/src/main/java/datastruct/Coordinate.java
@@ -3,28 +3,63 @@ package datastruct;
 import java.util.ArrayList;
 import java.util.List;
 
+/**
+ * Represents a 2D integer coordinate used to specify positions in a grid.
+ */
 public record Coordinate(int x, int y) {
 
+    /**
+     * Creates a new {@link Coordinate} instance with the given {@code x} and {@code y} values.
+     *
+     * @param x The x-coordinate value.
+     * @param y The y-coordinate value.
+     * @return A new {@link Coordinate} instance.
+     */
     public static Coordinate of(int x, int y) {
-        return new Coordinate(x,y);
+        return new Coordinate(x, y);
     }
 
+    /**
+     * Computes and returns the {@link Coordinate} to the left of this one.
+     *
+     * @return The left adjacent {@link Coordinate}.
+     */
     public Coordinate left() {
-        return new Coordinate(x-1,y);
+        return new Coordinate(x - 1, y);
     }
 
+    /**
+     * Computes and returns the {@link Coordinate} to the right of this one.
+     *
+     * @return The right adjacent {@link Coordinate}.
+     */
     public Coordinate right() {
-        return new Coordinate(x+1,y);
+        return new Coordinate(x + 1, y);
     }
 
+    /**
+     * Computes and returns the {@link Coordinate} above this one.
+     *
+     * @return The above adjacent {@link Coordinate}.
+     */
     public Coordinate above() {
-        return new Coordinate(x,y+1);
+        return new Coordinate(x, y + 1);
     }
 
+    /**
+     * Computes and returns the {@link Coordinate} below this one.
+     *
+     * @return The below adjacent {@link Coordinate}.
+     */
     public Coordinate below() {
-        return new Coordinate(x, y-1);
+        return new Coordinate(x, y - 1);
     }
 
+    /**
+     * Computes and returns a list of orthogonal (adjacent in horizontal or vertical direction) neighbors.
+     *
+     * @return A list of orthogonal neighboring {@link Coordinate}s.
+     */
     public List<Coordinate> orthogonalNeighbours() {
         return List.of(
                 this.right(),
@@ -34,6 +69,11 @@ public record Coordinate(int x, int y) {
         );
     }
 
+    /**
+     * Computes and returns a list of diagonal (adjacent in diagonal direction) neighbors.
+     *
+     * @return A list of diagonal neighboring {@link Coordinate}s.
+     */
     public List<Coordinate> diagonalNeighbours() {
         return List.of(
                 this.right().above(),
@@ -43,9 +83,19 @@ public record Coordinate(int x, int y) {
         );
     }
 
+    /**
+     * Computes and returns a list of all orthogonal and diagonal neighbors.
+     *
+     * @return A list of all neighboring {@link Coordinate}s.
+     */
     public List<Coordinate> orthodiagonalNeighbours() {
         List<Coordinate> neighbours = new ArrayList<>(this.orthogonalNeighbours());
         neighbours.addAll(this.diagonalNeighbours());
         return neighbours;
     }
-}
+
+    @Override
+    public String toString() {
+        return "(" + this.x + "," + this.y + ")";
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/datastruct/CoordinateIterator.java b/src/main/java/datastruct/CoordinateIterator.java
index 5ea7c49278fbf82eb221c86f66c052fd0b29db82..312d2de44356ad8974160f83d4d5e46d4762de84 100644
--- a/src/main/java/datastruct/CoordinateIterator.java
+++ b/src/main/java/datastruct/CoordinateIterator.java
@@ -3,33 +3,54 @@ package datastruct;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 
+/**
+ * An {@link Iterator} for generating 2D {@link Coordinate}s within a specified width and
+ * height range.
+ */
 class CoordinateIterator implements Iterator<Coordinate> {
     private final int width;
     private final int height;
     private int x = 0;
     private int y = 0;
 
+    /**
+     * Creates a new {@link CoordinateIterator} with the specified width and height.
+     *
+     * @param width  The width of the coordinate range.
+     * @param height The height of the coordinate range.
+     */
     public CoordinateIterator(int width, int height) {
         this.width = width;
         this.height = height;
     }
 
+    /**
+     * Checks if there are more {@link Coordinate}s to iterate over.
+     *
+     * @return true if there are more {@link Coordinate}s; otherwise, false.
+     */
     @Override
     public boolean hasNext() {
         return y < this.height;
     }
 
+    /**
+     * Returns the next {@link Coordinate} in the iteration.
+     *
+     * @return The next {@link Coordinate} in the iteration.
+     * @throws NoSuchElementException if there are no more {@link Coordinate}s to iterate over.
+     */
     @Override
     public Coordinate next() {
         if (!this.hasNext()) {
             throw new NoSuchElementException();
         }
-        Coordinate coord = new Coordinate(this.x, this.y);
+        Coordinate coordinate = new Coordinate(this.x, this.y);
         this.x = this.x + 1;
         if (this.x == this.width) {
             this.x = 0;
             this.y = this.y + 1;
         }
-        return coord;
+        return coordinate;
     }
 }
diff --git a/src/main/java/datastruct/Lens.java b/src/main/java/datastruct/Lens.java
index c9845ddc5c735b1b8f50d0f78e8603db8053e75e..a98fd46ffe1fc6f6f63b51ba704c87ecb83e1122 100644
--- a/src/main/java/datastruct/Lens.java
+++ b/src/main/java/datastruct/Lens.java
@@ -1,7 +1,22 @@
 package datastruct;
 
+/**
+ * A lens interface representing a view into a mutable state.
+ *
+ * @param <S> The type of the value stored in the lens.
+ */
 public interface Lens<S> {
+    /**
+     * Gets the value from the {@link Lens}.
+     *
+     * @return The value stored in the place designated by {@link Lens}.
+     */
     S get();
 
+    /**
+     * Sets a new value into the {@link Lens}.
+     *
+     * @param value The new value to set in the place designated by the {@link Lens}.
+     */
     void set(S value);
 }
diff --git a/src/main/java/datastruct/Matrix.java b/src/main/java/datastruct/Matrix.java
index 9290fa6d835f82b5566626e33507713bf2bf1852..f98bd7a2a5b7bcf877287220867bb5204be79eef 100644
--- a/src/main/java/datastruct/Matrix.java
+++ b/src/main/java/datastruct/Matrix.java
@@ -4,14 +4,26 @@ 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;
@@ -19,6 +31,14 @@ public class Matrix<T> implements Iterable<T> {
         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));
     }
@@ -28,65 +48,135 @@ public class Matrix<T> implements Iterable<T> {
             List<T> row = new ArrayList<>();
             this.matrix.add(row);
             for (int y = 0; y < height; y++) {
-                row.add(initializer.initialValueAt(Coordinate.of(x,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);
     }
 
-    public T get(Coordinate coord) {
-        return this.get(coord.x(), coord.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);
+        this.matrix.get(x).set(y, value);
     }
 
-    public void set(Coordinate coord, T value) {
-        this.set(coord.x(), coord.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);
+                return Matrix.this.get(x, y);
             }
 
             @Override
             public void set(T value) {
-                Matrix.this.set(x,y,value);
+                Matrix.this.set(x, y, value);
             }
         };
     }
 
-    public Lens<T> at(Coordinate coord) {
-        return this.at(coord.x(), coord.y());
+    /**
+     * 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/datastruct/MatrixInitializer.java b/src/main/java/datastruct/MatrixInitializer.java
index c7fb5c599969870cb89675547551097b883bd77e..dab2bf2900018e92094a81c9b04bdd005852e83e 100644
--- a/src/main/java/datastruct/MatrixInitializer.java
+++ b/src/main/java/datastruct/MatrixInitializer.java
@@ -1,6 +1,18 @@
 package datastruct;
 
+/**
+ * An interface for initializing a {@link Matrix} by providing initial values for each cell.
+ *
+ * @param <T> The type of values to initialize the {@link Matrix} with.
+ */
 public interface MatrixInitializer<T> {
 
+    /**
+     * Returns the initial value to be set in a {@link Matrix} cell at the specified
+     * {@link Coordinate}.
+     *
+     * @param coordinate The {@link Coordinate} at which to set the initial value.
+     * @return The initial value for the specified cell.
+     */
     T initialValueAt(Coordinate coordinate);
 }
diff --git a/src/main/java/model/Cell.java b/src/main/java/model/Cell.java
index 7da6824291fbca70781a2ca2dadfdaba1b3bfb12..35022e794c14515447f284343801cb33f29409d8 100644
--- a/src/main/java/model/Cell.java
+++ b/src/main/java/model/Cell.java
@@ -5,10 +5,12 @@ import datastruct.Lens;
 import java.util.ArrayList;
 import java.util.List;
 
+
 /**
- * {@link Cell} instances represent the cells of the grid in a simulation of cellular automata.
+ * A class representing a cell that holds a value and allows adding listeners to track value changes.
+ *
+ * @param <T> The type of value stored in the cell.
  */
-
 public class Cell<T> implements Lens<T> {
     private T content;
     private final List<OnChangeListener<T>> listeners = new ArrayList<>();
@@ -21,19 +23,26 @@ public class Cell<T> implements Lens<T> {
         this.content = initialContent;
     }
 
+    /** Add a {@link OnChangeListener} to react to any change of value in the cell.
+     *
+     * @param listener the {@link OnChangeListener} to activate when the value in the cell is
+     *                 changed.
+     */
     public void addOnChangeListener(OnChangeListener<T> listener) {
         this.listeners.add(listener);
     }
 
     /**
-     * Sets the content of this {@link Cell}.
+     * Sets the content of this {@link Cell}. This will also call all the listeners that were
+     * registered by the method {@code addOnChangeListener}.
      *
      * @param value the new content of this {@link Cell}
      */
     public void set(T value) {
+        T oldValue = this.content;
         this.content = value;
         for (OnChangeListener<T> listener : this.listeners) {
-            listener.valueChanged(this.content, value);
+            listener.valueChanged(oldValue, value);
         }
     }
 
@@ -45,6 +54,4 @@ public class Cell<T> implements Lens<T> {
     public T get(){
         return this.content;
     }
-
-
 }
diff --git a/src/main/java/model/CellularAutomaton.java b/src/main/java/model/CellularAutomaton.java
index 92b83c4e296bf10fcefd8d20e627871a2127a95e..a2762ce4880c225220c6d8a9826272fee06e40a8 100644
--- a/src/main/java/model/CellularAutomaton.java
+++ b/src/main/java/model/CellularAutomaton.java
@@ -2,9 +2,41 @@ package model;
 
 import java.util.Random;
 
+/**
+ * Represents a cellular automaton, which defines the main parameters of a cellular automaton.
+ * The rules for updating states are defined in the class used as {@code S}.
+ *
+ * @param <S> The type of state used in the cellular automaton.
+ */
 public interface CellularAutomaton<S extends State<S>> {
+
+    /**
+     * Returns the number of columns in the grid of the cellular automaton.
+     *
+     * @return The number of columns in the grid.
+     */
     int numberOfColumns();
+
+    /**
+     * Returns the number of rows in the grid of the cellular automaton.
+     *
+     * @return The number of rows in the grid.
+     */
     int numberOfRows();
+
+    /**
+     * Returns the default state that is used to initialize cells in the automaton.
+     *
+     * @return The default state for cells in the automaton.
+     */
     S defaultState();
+
+
+    /**
+     * Generates a random state using the specified random number generator.
+     *
+     * @param generator The random number generator to use.
+     * @return A randomly generated state.
+     */
     S randomState(Random generator);
-}
+}
\ No newline at end of file
diff --git a/src/main/java/model/CellularAutomatonSimulation.java b/src/main/java/model/CellularAutomatonSimulation.java
index aa7404c84cf17b1d4a7c926035892bb6451b0104..0604e8f94125498202801b825faa5e85f5eba5c1 100644
--- a/src/main/java/model/CellularAutomatonSimulation.java
+++ b/src/main/java/model/CellularAutomatonSimulation.java
@@ -3,30 +3,31 @@ package model;
 import controller.Simulation;
 import datastruct.Coordinate;
 import datastruct.Matrix;
-import javafx.beans.property.ReadOnlyLongProperty;
-import javafx.beans.property.ReadOnlyLongWrapper;
 import javafx.scene.paint.Color;
+
 import java.util.Iterator;
 import java.util.Random;
-import java.util.function.Supplier;
 
 
 
 /**
  * {@link CellularAutomatonSimulation} instances run <i>The Game of Life</i>.
+ *
+ *  @param <S> The type of state used in the simulation.
  */
 public class CellularAutomatonSimulation<S extends State<S>>
         implements Simulation {
 
     private final Matrix<Cell<S>> grid;
-    private final ReadOnlyLongWrapper generationNumber = new ReadOnlyLongWrapper();
+    private final Cell<Integer> generationNumber = new Cell<>(0);
     private final CellularAutomaton<S> automaton;
     private final Random generator;
 
     /**
      * Creates a new {@link CellularAutomatonSimulation} instance for a given automaton.
      *
-     * @param automaton         a description of the {@link CellularAutomaton}
+     * @param automaton  A description of the {@link CellularAutomaton}.
+     * @param generator  The {@link Random} instance used for random state generation.
      */
     public CellularAutomatonSimulation(CellularAutomaton<S> automaton, Random generator) {
         this.automaton = automaton;
@@ -38,18 +39,6 @@ public class CellularAutomatonSimulation<S extends State<S>>
         this.generator = generator;
     }
 
-    /**
-     * Goes through each {@link Cell} in this {@code CellGrid} and sets it states with a
-     * state obtained from the supplier.
-     *
-     * @param generator {@link Random} instance used to generate a random state for each cell
-     *                  {@link Cell}.
-     */
-    public void fillRandomly(Random generator) {
-        for (Cell<S> cell : this.grid) {
-            cell.set(this.automaton.randomState(generator));
-        }
-    }
 
     @Override
     public int numberOfColumns() {
@@ -61,24 +50,32 @@ public class CellularAutomatonSimulation<S extends State<S>>
         return this.grid.height();
     }
 
+    /**
+     * Returns the {@link Cell} at the specified coordinate.
+     *
+     * @param coordinate The coordinate of the cell to retrieve.
+     * @return The cell at the specified coordinate.
+     */
     public Cell<S> at(Coordinate coordinate) {
         return this.grid.get(coordinate);
     }
 
+    @Override
     public void updateToNextGeneration() {
-        this.generationNumber.set(getGenerationNumber() + 1);
+        this.generationNumber.set(this.generationNumber.get()+1);
         Matrix<S> nextStates = this.nextGenerationMatrix();
         for (Coordinate coordinate : this.grid.coordinates()) {
             this.at(coordinate).set(nextStates.get(coordinate));
         }
     }
-    /** Computes the {link Matrix} of states obtained after a single step of updates
+
+    /** Computes the {@link Matrix} 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() {
-        return new Matrix<S>(
+        return new Matrix<>(
                 this.grid.width(),
                 this.grid.height(),
                 new NextGenerationInitializer<>(this)
@@ -92,7 +89,6 @@ public class CellularAutomatonSimulation<S extends State<S>>
 
     @Override
     public void copy(Coordinate source, Coordinate destination) {
-        System.out.println("bip (" + source + ") (" + destination + ")");
         S state = this.at(source).get();
         this.at(destination).set(state);
     }
@@ -109,29 +105,13 @@ public class CellularAutomatonSimulation<S extends State<S>>
         );
     }
 
-
-    /**
-     * Returns the current generationNumber.
-     *
-     * @return the current generationNumber
-     */
-    private long getGenerationNumber() {
-        return this.generationNumber.get();
-    }
-
-    /**
-     * Returns the generationNumber {@link ReadOnlyLongProperty}.
-     *
-     * @return the generationNumber {@link ReadOnlyLongProperty}
-     */
-    public ReadOnlyLongProperty generationNumberProperty() {
-        return this.generationNumber.getReadOnlyProperty();
+    @Override
+    public void setGenerationNumberChangeListener(OnChangeListener<Integer> listener){
+        this.generationNumber.addOnChangeListener(listener);
     }
 
 
-    /**
-     * Clears the current game.
-     */
+    @Override
     public void clear() {
         for (Cell<S> cell : this.grid) {
             cell.set(this.automaton.defaultState());
@@ -139,12 +119,13 @@ public class CellularAutomatonSimulation<S extends State<S>>
         this.generationNumber.set(0);
     }
 
-    /**
-     * Clears the current game and randomly generates a new one.
-     */
+
+    @Override
     public void reset() {
-        this.clear();
-        this.fillRandomly(this.generator);
+        for (Cell<S> cell : this.grid) {
+            cell.set(this.automaton.randomState(generator));
+        }
+        this.generationNumber.set(0);
     }
 
     @Override
diff --git a/src/main/java/model/ConstantCellInitializer.java b/src/main/java/model/ConstantCellInitializer.java
index 43edd965d7b331c4ff1a3a590836e8eb79069d42..1016b57944589521427e57bab3f446fbd1e9d1ff 100644
--- a/src/main/java/model/ConstantCellInitializer.java
+++ b/src/main/java/model/ConstantCellInitializer.java
@@ -1,11 +1,23 @@
 package model;
 
 import datastruct.Coordinate;
+import datastruct.Matrix;
 import datastruct.MatrixInitializer;
 
+/**
+ *  An initializer for {@link Matrix} of {@link Cell}s, where each cell is initialized to the
+ *  same value.
+ *
+ * @param <T> the type of content of each cell
+ */
 public class ConstantCellInitializer<T>  implements MatrixInitializer<Cell<T>> {
     private final T defaultValue;
 
+    /** Make a new {@link MatrixInitializer} with cells containing a {@link Cell} with the same
+     * value.
+     *
+     * @param defaultValue the value stored in each cell.
+     */
     public ConstantCellInitializer(T defaultValue) {
         this.defaultValue = defaultValue;
     }
diff --git a/src/main/java/model/NextGenerationInitializer.java b/src/main/java/model/NextGenerationInitializer.java
index f344e93ff3a3ecf0bf6493603abe3e80d71e3d26..1242f43362c6a7765311b9897f371a877335ba7f 100644
--- a/src/main/java/model/NextGenerationInitializer.java
+++ b/src/main/java/model/NextGenerationInitializer.java
@@ -1,16 +1,27 @@
 package model;
 
 import datastruct.Coordinate;
-import datastruct.Matrix;
 import datastruct.MatrixInitializer;
-
+import datastruct.Matrix;
+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
+ * of its neighbours in a {@link Simulation} of a cellular automaton.
+ *
+ * @param <S> the type of states in the simulation.
+ */
 public class NextGenerationInitializer<S extends State<S>> implements MatrixInitializer<S> {
 
     private final CellularAutomatonSimulation<S> simulation;
 
+    /** Create a {@link MatrixInitializer} to compute the next generation in
+     * a 2D cellular automaton.
+     *
+     * @param simulation the {@link Simulation} representing the cellular automaton.
+     */
     public NextGenerationInitializer(CellularAutomatonSimulation<S> simulation) {
         this.simulation = simulation;
     }
@@ -26,6 +37,14 @@ public class NextGenerationInitializer<S extends State<S>> implements MatrixInit
         return state.update(neighbours);
     }
 
+    /** Computes the grid {@link Coordinate} for an arbitrary {@link Coordinate}, even outside
+     * the grid. This is done by considering that the grid wraps over its edges, connecting the left side to the right
+     * side, and the top side to the bottom side. This way, every cell has 4 orthogonal
+     * neighbours and 4 diagonal neighbours.
+     *
+     * @param coordinate a {@link Coordinate} that may be outside the grid.
+     * @return a corresponding {@link Coordinate}, that is inside the grid.
+     */
     private Coordinate wrap(Coordinate coordinate) {
         return new Coordinate(
                 modulo(coordinate.x(),this.simulation.numberOfColumns()),
diff --git a/src/main/java/model/State.java b/src/main/java/model/State.java
index b21230c956f98eb71432c3a274ae7de0a63b5cdd..213723ba0f41e83066099b81e99058f78155930c 100644
--- a/src/main/java/model/State.java
+++ b/src/main/java/model/State.java
@@ -4,12 +4,51 @@ import javafx.scene.paint.Color;
 
 import java.util.List;
 
+/**
+ * Represents a state of a cell in a cellular automaton, and the update rules for the cellular
+ * automaton.
+ *
+ * @param <S> The type of state used in the cellular automaton.
+ */
 public interface State<S> {
 
+    /**
+     * Returns the color associated with this state.
+     *
+     * @return The color representing this state.
+     */
     Color getColor();
 
+    /**
+     * Computes and returns the next state based on the rules of the cellular automaton.
+     *
+     * @return The next state.
+     */
     S next();
 
+    /**
+     * Updates the state based on the states of its neighboring cells.
+     *
+     * @param neighbours A list of neighboring cell states.
+     * @return The updated state based on the neighbors.
+     */
     S update(List<State<S>> neighbours);
 
-}
+    /**
+     * Counts the occurrences of a specific state within a list of neighboring states.
+     *
+     * @param <T>       The type of state to count.
+     * @param state     The state to count occurrences of.
+     * @param neighbours A list of neighboring states to search within.
+     * @return The number of times the specified state appears in the list of neighbors.
+     */
+    static <T> int count(T state, List<T> neighbours) {
+        int count = 0;
+        for (T neighbour : neighbours) {
+            if (neighbour.equals(state)) {
+                count++;
+            }
+        }
+        return count;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/model/automata/BiColorAutomaton.java b/src/main/java/model/automata/BiColorAutomaton.java
index 7a1cb11974610f963918a930efdd1b572886310d..da2c939ff54abb18130a84f4a1b0424da7905056 100644
--- a/src/main/java/model/automata/BiColorAutomaton.java
+++ b/src/main/java/model/automata/BiColorAutomaton.java
@@ -1,7 +1,5 @@
 package model.automata;
 
-import model.CellularAutomaton;
-
 import java.util.Random;
 
 public class BiColorAutomaton extends AbstractAutomaton<BiColorState> {
diff --git a/src/main/java/model/automata/BiColorState.java b/src/main/java/model/automata/BiColorState.java
index bdeb690e2ddc48f4020b803ed69b0ebb8f28f281..834429677919d14824deccca824629db6d9f20a5 100644
--- a/src/main/java/model/automata/BiColorState.java
+++ b/src/main/java/model/automata/BiColorState.java
@@ -4,7 +4,6 @@ import javafx.scene.paint.Color;
 import model.State;
 
 import java.util.List;
-import java.util.Random;
 
 public enum BiColorState implements State<BiColorState> {
     BLUE, RED, DEAD;
@@ -31,22 +30,15 @@ public enum BiColorState implements State<BiColorState> {
 
     @Override
     public BiColorState update(List<State<BiColorState>> neighbours) {
-        int countBlue = 0;
-        int countRed = 0;
-        for (State<BiColorState> neighbour : neighbours) {
-            if (neighbour == RED) {
-                countRed++;
-            }
-            if (neighbour == BLUE) {
-                countBlue++;
-            }
-        }
+        int countBlue = State.count(BLUE, neighbours);
+        int countRed = State.count(RED, neighbours);
+        int countAlive = countBlue + countRed;
         if (this == DEAD) {
-            return (countBlue + countRed != 3)? DEAD:
+            return (countAlive != 3)? DEAD:
                     countBlue > countRed? BLUE:
                             RED;
         }
-        return 2 <= countBlue + countRed && countBlue + countRed <= 3? this:
+        return 2 <= countAlive && countAlive <= 3? this:
                 DEAD;
     }
 
diff --git a/src/main/java/model/automata/BriansBrainState.java b/src/main/java/model/automata/BriansBrainState.java
index 1f831b884bf0f3e64ba7115a9be31fe1ec350da9..565868366c40ebfc312e0bc5338f47b9f6b28ac4 100644
--- a/src/main/java/model/automata/BriansBrainState.java
+++ b/src/main/java/model/automata/BriansBrainState.java
@@ -4,7 +4,6 @@ import javafx.scene.paint.Color;
 import model.State;
 
 import java.util.List;
-import java.util.Random;
 
 public enum BriansBrainState implements State<BriansBrainState> {
     ON, OFF, DYING;
@@ -33,19 +32,11 @@ public enum BriansBrainState implements State<BriansBrainState> {
             case ON -> DYING;
             case DYING -> OFF;
             case OFF -> {
-                int count = countList(ON, neighbours);
+                int count = State.count(ON, neighbours);
                 yield count==2 ? ON : OFF;
             }
         };
     }
 
-    static <T>  int countList(T value, List<T> elements) {
-        int count = 0;
-        for (T v : elements) {
-            if (v.equals(value)) {
-                count++;
-            }
-        }
-        return count;
-    }
+
 }
diff --git a/src/main/java/model/automata/GameOfLifeAutomaton.java b/src/main/java/model/automata/GameOfLifeAutomaton.java
index cfe2b731614561bf6ed11d8b78e36831038ac9e1..a25c577efe4a9443b6586af9c499edadd662c53b 100644
--- a/src/main/java/model/automata/GameOfLifeAutomaton.java
+++ b/src/main/java/model/automata/GameOfLifeAutomaton.java
@@ -1,12 +1,10 @@
 package model.automata;
 
-import model.CellularAutomaton;
-
 import java.util.Random;
 
 public class GameOfLifeAutomaton extends AbstractAutomaton<GameOfLifeState> {
 
-    protected GameOfLifeAutomaton(int numberOfColumns, int numberOfRows) {
+    public GameOfLifeAutomaton(int numberOfColumns, int numberOfRows) {
         super(numberOfColumns, numberOfRows);
     }
 
diff --git a/src/main/java/model/automata/GameOfLifeState.java b/src/main/java/model/automata/GameOfLifeState.java
index 8e4e5466832d3331cc851ebded9b4b6e7d7ea27d..1d8c75cd7062228220be0c25fcebdb447557e6fa 100644
--- a/src/main/java/model/automata/GameOfLifeState.java
+++ b/src/main/java/model/automata/GameOfLifeState.java
@@ -4,7 +4,6 @@ import javafx.scene.paint.Color;
 import model.State;
 
 import java.util.List;
-import java.util.Random;
 
 /**
  * {@link GameOfLifeState} instances represent the possible states of a {@link GameOfLifeState}.
@@ -31,12 +30,7 @@ public enum GameOfLifeState implements State<GameOfLifeState> {
 
     @Override
     public GameOfLifeState update(List<State<GameOfLifeState>> neighbours) {
-        int countAlive = 0;
-        for (State<GameOfLifeState> state : neighbours) {
-            if (state.equals(ALIVE)) {
-                countAlive++;
-            }
-        }
+        int countAlive = State.count(ALIVE, neighbours);
         boolean isAlive =
                 (this == DEAD && 3 == countAlive)
                 || (this == ALIVE && 2 <= countAlive && countAlive <= 3);
diff --git a/src/main/java/model/automata/SeedsAutomaton.java b/src/main/java/model/automata/SeedsAutomaton.java
index 9a9b4a3ba054933b21010e93b1e9e795dd9f4436..c7204df48d2c126ee3f70c1f2208dc7de3128beb 100644
--- a/src/main/java/model/automata/SeedsAutomaton.java
+++ b/src/main/java/model/automata/SeedsAutomaton.java
@@ -14,7 +14,7 @@ public class SeedsAutomaton extends AbstractAutomaton<SeedsState> {
 
     @Override
     public SeedsState randomState(Random generator) {
-        return generator.nextInt() == 0?
+        return generator.nextInt(10) == 0?
                 SeedsState.ON:
                 SeedsState.OFF;
     }
diff --git a/src/main/java/model/automata/SeedsState.java b/src/main/java/model/automata/SeedsState.java
index ebfe4c36201d712956b74de5cbcaedb6b258a5a1..c167fadb7c8466c2d383917a375ba5f59e0f82ef 100644
--- a/src/main/java/model/automata/SeedsState.java
+++ b/src/main/java/model/automata/SeedsState.java
@@ -5,14 +5,13 @@ import model.State;
 
 import java.util.List;
 
-import static model.automata.BriansBrainState.countList;
 
 public enum SeedsState implements State<SeedsState> {
     ON, OFF;
     @Override
     public Color getColor() {
         return switch (this) {
-            case ON -> Color.WHITE;
+            case ON -> Color.GOLD;
             case OFF -> Color.BLACK;
         };
     }
@@ -29,7 +28,7 @@ public enum SeedsState implements State<SeedsState> {
     public SeedsState update(List<State<SeedsState>> neighbours) {
         return switch (this) {
             case ON -> OFF;
-            case OFF -> countList(ON,neighbours) == 2 ? ON: OFF;
+            case OFF -> State.count(ON,neighbours) == 2 ? ON: OFF;
         };
     }
 
diff --git a/src/main/java/view/FillingMouseListener.java b/src/main/java/view/FillingMouseListener.java
index 5e7b207620519eb55bb9e53851bee7497c247a1a..a4946eb3188788e721932033b65154f418b8d41b 100644
--- a/src/main/java/view/FillingMouseListener.java
+++ b/src/main/java/view/FillingMouseListener.java
@@ -14,7 +14,7 @@ public class FillingMouseListener implements MouseListener {
     }
 
     @Override
-    public void onMouseReleased(MouseEvent event, Coordinate coord) {
+    public void onMouseReleased(MouseEvent event, Coordinate coordinate) {
         this.matrix.resetWaitingListener();
     }
 
@@ -34,4 +34,5 @@ public class FillingMouseListener implements MouseListener {
                 new FillingMouseListener(this.matrix, coordinate)
         );
     }
+
 }
diff --git a/src/main/java/view/MatrixPane.java b/src/main/java/view/MatrixPane.java
index 41ed00d6c7f10030ee0cf1ddc977ea59da7b0954..050f73930aeb7f17b4b95ed8bb2ff3aec5f9dfda 100644
--- a/src/main/java/view/MatrixPane.java
+++ b/src/main/java/view/MatrixPane.java
@@ -52,6 +52,7 @@ public class MatrixPane extends GridPane {
     }
 
     private void addEventHandler(Rectangle cellRectangle, Coordinate coord) {
+
         cellRectangle.addEventHandler(
                 MouseEvent.MOUSE_PRESSED,
                 event -> mouseListener.onMousePressed(event, coord)
diff --git a/src/main/java/view/MouseListener.java b/src/main/java/view/MouseListener.java
index ef8323377e67bde77d6f61b895bf8b662f996914..775cc91de92b1ca00c324365a04ecd53c0439cff 100644
--- a/src/main/java/view/MouseListener.java
+++ b/src/main/java/view/MouseListener.java
@@ -9,4 +9,5 @@ interface MouseListener {
     default void onMouseReleased(MouseEvent event, Coordinate coordinate) {}
     default void onMouseEntered(MouseEvent event, Coordinate coordinate) {};
 
+
 }
diff --git a/src/main/java/view/WaitingMouseListener.java b/src/main/java/view/WaitingMouseListener.java
index b56d65a2321f1d0b50b03f60024ca853e6348efa..68601debb4757abdd55450b8b6d58f16ff5e8ba3 100644
--- a/src/main/java/view/WaitingMouseListener.java
+++ b/src/main/java/view/WaitingMouseListener.java
@@ -13,8 +13,10 @@ class WaitingMouseListener implements MouseListener {
     }
 
     @Override
-    public void onMousePressed(MouseEvent event, Coordinate coord) {
-       this.matrix.getController().getSimulation().next(coord);
-        matrix.setMouseListener(new FillingMouseListener(this.matrix, coord));
+    public void onMousePressed(MouseEvent event, Coordinate coordinate) {
+        this.matrix.getController().getSimulation().next(coordinate);
+        this.matrix.setMouseListener(new FillingMouseListener(this.matrix, coordinate));
     }
+
+
 }
diff --git a/src/test/java/datastruct/ConstantMatrixInitializerTest.java b/src/test/java/datastruct/ConstantMatrixInitializerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..4db9c2a7d37554e5eb11c7a6c15a28064421dbe5
--- /dev/null
+++ b/src/test/java/datastruct/ConstantMatrixInitializerTest.java
@@ -0,0 +1,31 @@
+package datastruct;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class ConstantMatrixInitializerTest {
+    @Test
+    public void testMatrixInitializationWithConstantValue() {
+        Matrix<String> matrix = new Matrix<>(3, 3, new ConstantMatrixInitializer<>("X"));
+
+        // Test that all cells have the constant value.
+        for (int x = 0; x < 3; x++) {
+            for (int y = 0; y < 3; y++) {
+                assertEquals("X", matrix.get(x, y));
+            }
+        }
+    }
+
+    @Test
+    public void testMatrixInitializationWithConstantValue2() {
+        Matrix<Integer> matrix = new Matrix<>(3, 5, new ConstantMatrixInitializer<>(12));
+
+        // Test that all cells have the constant value.
+        for (int x = 0; x < 3; x++) {
+            for (int y = 0; y < 5; y++) {
+                assertEquals(12, matrix.get(x, y));
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/datastruct/CoordinateIteratorTest.java b/src/test/java/datastruct/CoordinateIteratorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..90be82e7250425d8ff455b65f74a6f0dadd5ac22
--- /dev/null
+++ b/src/test/java/datastruct/CoordinateIteratorTest.java
@@ -0,0 +1,53 @@
+package datastruct;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.NoSuchElementException;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class CoordinateIteratorTest {
+
+    @Test
+    public void testIteratorWithZeroDimensions() {
+        CoordinateIterator iterator = new CoordinateIterator(0, 0);
+        assertFalse(iterator.hasNext());
+    }
+
+    @Test
+    public void testIteratorWithOneDimension() {
+        CoordinateIterator iterator = new CoordinateIterator(5, 1);
+        assertTrue(iterator.hasNext());
+        assertEquals(Coordinate.of(0, 0), iterator.next());
+        assertTrue(iterator.hasNext());
+        assertEquals(Coordinate.of(1, 0), iterator.next());
+        assertTrue(iterator.hasNext());
+        assertEquals(Coordinate.of(2, 0), iterator.next());
+        assertTrue(iterator.hasNext());
+        assertEquals(Coordinate.of(3, 0), iterator.next());
+        assertTrue(iterator.hasNext());
+        assertEquals(Coordinate.of(4, 0), iterator.next());
+        assertFalse(iterator.hasNext());
+        assertThrows(NoSuchElementException.class, iterator::next);
+    }
+
+    @Test
+    public void testIteratorWithTwoDimensions() {
+        CoordinateIterator iterator = new CoordinateIterator(3, 2);
+        assertTrue(iterator.hasNext());
+        assertEquals(Coordinate.of(0, 0), iterator.next());
+        assertTrue(iterator.hasNext());
+        assertEquals(Coordinate.of(1, 0), iterator.next());
+        assertTrue(iterator.hasNext());
+        assertEquals(Coordinate.of(2, 0), iterator.next());
+        assertTrue(iterator.hasNext());
+        assertEquals(Coordinate.of(0, 1), iterator.next());
+        assertTrue(iterator.hasNext());
+        assertEquals(Coordinate.of(1, 1), iterator.next());
+        assertTrue(iterator.hasNext());
+        assertEquals(Coordinate.of(2, 1), iterator.next());
+        assertFalse(iterator.hasNext());
+        assertThrows(NoSuchElementException.class, iterator::next);
+    }
+
+}
\ No newline at end of file
diff --git a/src/test/java/datastruct/CoordinateTest.java b/src/test/java/datastruct/CoordinateTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..bddaae9ce239168d12a0c5f89b6411d41bb8243f
--- /dev/null
+++ b/src/test/java/datastruct/CoordinateTest.java
@@ -0,0 +1,100 @@
+package datastruct;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class CoordinateTest {
+    @Test
+    public void testCoordinateCreation() {
+        Coordinate coordinate = Coordinate.of(3, 4);
+        assertEquals(3, coordinate.x());
+        assertEquals(4, coordinate.y());
+    }
+
+    @Test
+    public void testLeft() {
+        Coordinate coordinate = Coordinate.of(3, 4);
+        Coordinate left = coordinate.left();
+        assertEquals(2, left.x());
+        assertEquals(4, left.y());
+    }
+
+    @Test
+    public void testRight() {
+        Coordinate coordinate = Coordinate.of(3, 4);
+        Coordinate right = coordinate.right();
+        assertEquals(4, right.x());
+        assertEquals(4, right.y());
+    }
+
+    @Test
+    public void testAbove() {
+        Coordinate coordinate = Coordinate.of(3, 4);
+        Coordinate above = coordinate.above();
+        assertEquals(3, above.x());
+        assertEquals(5, above.y());
+    }
+
+    @Test
+    public void testBelow() {
+        Coordinate coordinate = Coordinate.of(3, 4);
+        Coordinate below = coordinate.below();
+        assertEquals(3, below.x());
+        assertEquals(3, below.y());
+    }
+
+    @Test
+    public void testOrthogonalNeighbours() {
+        Coordinate coordinate = Coordinate.of(3, 4);
+        List<Coordinate> neighbours = coordinate.orthogonalNeighbours();
+        assertEquals(4, neighbours.size());
+        assertTrue(neighbours.contains(Coordinate.of(2, 4)));
+        assertTrue(neighbours.contains(Coordinate.of(4, 4)));
+        assertTrue(neighbours.contains(Coordinate.of(3, 3)));
+        assertTrue(neighbours.contains(Coordinate.of(3, 5)));
+        assertFalse(neighbours.contains(coordinate));
+        assertFalse(neighbours.contains(Coordinate.of(1, 4)));
+        assertFalse(neighbours.contains(Coordinate.of(5, 4)));
+        assertFalse(neighbours.contains(Coordinate.of(3, 6)));
+        assertFalse(neighbours.contains(Coordinate.of(3, 1)));
+    }
+
+    @Test
+    public void testDiagonalNeighbours() {
+        Coordinate coordinate = Coordinate.of(3, 4);
+        List<Coordinate> neighbours = coordinate.diagonalNeighbours();
+        assertEquals(4, neighbours.size());
+        assertTrue(neighbours.contains(Coordinate.of(2, 3)));
+        assertTrue(neighbours.contains(Coordinate.of(4, 3)));
+        assertTrue(neighbours.contains(Coordinate.of(2, 5)));
+        assertTrue(neighbours.contains(Coordinate.of(4, 5)));
+        assertFalse(neighbours.contains(coordinate));
+        assertFalse(neighbours.contains(Coordinate.of(1, 4)));
+        assertFalse(neighbours.contains(Coordinate.of(5, 4)));
+        assertFalse(neighbours.contains(Coordinate.of(3, 6)));
+        assertFalse(neighbours.contains(Coordinate.of(3, 1)));
+    }
+
+    @Test
+    public void testOrthodiagonalNeighbours() {
+        Coordinate coordinate = Coordinate.of(3, 4);
+        List<Coordinate> neighbours = coordinate.orthodiagonalNeighbours();
+        assertEquals(8, neighbours.size());
+        assertTrue(neighbours.contains(Coordinate.of(2, 4)));
+        assertTrue(neighbours.contains(Coordinate.of(4, 4)));
+        assertTrue(neighbours.contains(Coordinate.of(3, 3)));
+        assertTrue(neighbours.contains(Coordinate.of(3, 5)));
+        assertTrue(neighbours.contains(Coordinate.of(2, 3)));
+        assertTrue(neighbours.contains(Coordinate.of(4, 3)));
+        assertTrue(neighbours.contains(Coordinate.of(2, 5)));
+        assertTrue(neighbours.contains(Coordinate.of(4, 5)));
+        assertFalse(neighbours.contains(coordinate));
+        assertFalse(neighbours.contains(Coordinate.of(1, 4)));
+        assertFalse(neighbours.contains(Coordinate.of(5, 4)));
+        assertFalse(neighbours.contains(Coordinate.of(3, 6)));
+        assertFalse(neighbours.contains(Coordinate.of(3, 1)));
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/datastruct/MatrixTest.java b/src/test/java/datastruct/MatrixTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..346c29bed09667ea471416d7f5455ebe0597ca72
--- /dev/null
+++ b/src/test/java/datastruct/MatrixTest.java
@@ -0,0 +1,88 @@
+package datastruct;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.Iterator;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class MatrixTest {
+
+    private final MatrixInitializer<Integer> sumInitializer =
+            coord -> coord.x() + coord.y();
+
+    @Test
+    public void testMatrixCreationWithInitializer() {
+        Matrix<Integer> matrix = new Matrix<>(3, 4, sumInitializer);
+        assertEquals(3, matrix.width());
+        assertEquals(4, matrix.height());
+        assertEquals(4, matrix.get(2, 2));
+        assertEquals(3, matrix.get(1, 2));
+        assertEquals(3, matrix.get(2, 1));
+        assertEquals(2, matrix.get(1, 1));
+    }
+
+    @Test
+    public void testMatrixCreationWithInitialValue() {
+        Matrix<String> matrix = new Matrix<>(2, 2, "Foo");
+        assertEquals(2, matrix.width());
+        assertEquals(2, matrix.height());
+        assertEquals("Foo", matrix.get(1, 1)); // Test a specific cell value.
+    }
+
+    @Test
+    public void testMatrixSetAndGet() {
+        Matrix<Integer> matrix = new Matrix<>(3, 3, 0);
+        matrix.set(1, 1, 42);
+        assertEquals(42, matrix.get(1, 1));
+        matrix.set(0, 2, 10);
+        assertEquals(10, matrix.get(0, 2));
+        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");
+        assertEquals(4, matrix.width());
+        assertEquals(2, matrix.height());
+        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);
+        Iterator<Integer> iterator = matrix.iterator();
+        assertTrue(iterator.hasNext());
+        assertEquals(0, iterator.next());
+        assertTrue(iterator.hasNext());
+        assertEquals(1, iterator.next());
+        assertTrue(iterator.hasNext());
+        assertEquals(1, iterator.next());
+        assertTrue(iterator.hasNext());
+        assertEquals(2, iterator.next());
+        assertFalse(iterator.hasNext());
+    }
+
+    @Test
+    public void testMatrixCoordinates() {
+        Matrix<Integer> matrix = new Matrix<>(2, 2, 0);
+        Iterable<Coordinate> coordinates = matrix.coordinates();
+        int count = 0;
+        for (Coordinate coord : coordinates) {
+            count++;
+        }
+        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));
+    }
+}
diff --git a/src/test/java/model/CellTest.java b/src/test/java/model/CellTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..f879455b3b32fdc6864a47d1fbc2e8a053d75453
--- /dev/null
+++ b/src/test/java/model/CellTest.java
@@ -0,0 +1,40 @@
+package model;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class CellTest {
+
+    private record Change<T>(T oldValue, T newValue) {}
+    private static class MockListener<T> implements OnChangeListener<T> {
+        private Change<T> lastChange = null;
+
+        public boolean checksLastChange(T oldValue, T newValue) {
+            return this.lastChange != null
+                    && this.lastChange.oldValue.equals(oldValue)
+                    && this.lastChange.newValue.equals(newValue);
+        }
+
+        @Override
+        public void valueChanged(T oldValue, T newValue) {
+            lastChange = new Change<>(oldValue, newValue);
+        }
+    }
+    @Test
+    public void testCellValueChangeWithListener() {
+        Cell<Integer> cell = new Cell<>(42);
+        MockListener<Integer> mockListener = new MockListener<>();
+        cell.addOnChangeListener(mockListener);
+        cell.set(99);
+        assertTrue(mockListener.checksLastChange(42, 99));
+        assertEquals(99, cell.get());
+    }
+
+    @Test
+    public void testCellWithoutListener() {
+        Cell<String> cell = new Cell<>("Foo");
+        cell.set("Bar");
+        assertEquals("Bar", cell.get());
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/model/CellularAutomatonSimulationTest.java b/src/test/java/model/CellularAutomatonSimulationTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..81c4eaca06a853af85fc445d56c4e9e22ae0b846
--- /dev/null
+++ b/src/test/java/model/CellularAutomatonSimulationTest.java
@@ -0,0 +1,162 @@
+package model;
+
+import datastruct.Coordinate;
+import javafx.scene.paint.Color;
+import model.automata.GameOfLifeAutomaton;
+import static model.automata.GameOfLifeState.*;
+import model.automata.GameOfLifeState;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import static org.junit.jupiter.api.Assertions.*;
+
+
+class CellularAutomatonSimulationTest {
+
+    private final CellularAutomatonSimulation<GameOfLifeState> simulation;
+    private final CellularAutomaton<GameOfLifeState> automaton;
+    private final Random randomGenerator;
+
+    CellularAutomatonSimulationTest() {
+        this.randomGenerator = new Random();
+        this.automaton = new GameOfLifeAutomaton(4,3);
+        this.simulation = new CellularAutomatonSimulation<>(automaton, randomGenerator);
+    }
+    @BeforeEach
+    public void setUp() {
+        this.simulation.clear();
+    }
+
+    @Test
+    public void testNumberOfColumns() {
+        assertEquals(4, simulation.numberOfColumns());
+    }
+
+    @Test
+    public void testNumberOfRows() {
+        assertEquals(3, simulation.numberOfRows());
+    }
+
+    @Test
+    public void testAt() {
+        Coordinate coordinate = Coordinate.of(1, 2);
+        Cell<GameOfLifeState> cell = simulation.at(coordinate);
+        assertEquals(DEAD,cell.get());
+    }
+
+    @Test
+    public void testUpdateToNextGeneration() {
+        GameOfLifeState[][] input =
+                { {ALIVE, ALIVE, ALIVE, DEAD},
+                  {ALIVE, DEAD, DEAD, DEAD},
+                  {DEAD, ALIVE, DEAD, DEAD}
+                };
+        GameOfLifeState[][] output =
+                { {ALIVE, DEAD, ALIVE, ALIVE},
+                  {ALIVE, DEAD, ALIVE, ALIVE},
+                  {DEAD, DEAD, ALIVE, ALIVE}
+                };
+        for (Coordinate coordinate : this.simulation) {
+            this.simulation.at(coordinate).set(input[coordinate.y()][coordinate.x()]);
+        }
+        simulation.updateToNextGeneration();
+        for (Coordinate coordinate : this.simulation) {
+            assertEquals(
+                    output[coordinate.y()][coordinate.x()],
+                    this.simulation.at(coordinate).get(),
+                    "Generation at " + coordinate
+            );
+        }
+    }
+
+    @Test
+    public void testNext() {
+        Coordinate coordinate = Coordinate.of(1, 1);
+        Cell<GameOfLifeState> cell = simulation.at(coordinate);
+        GameOfLifeState oldState = cell.get();
+        simulation.next(coordinate);
+        assertNotEquals(oldState, cell.get());
+    }
+
+    @Test
+    public void testCopy() {
+        Coordinate source = Coordinate.of(1, 1);
+        Coordinate destination = Coordinate.of(2, 2);
+        this.simulation.at(source).set(ALIVE);
+        simulation.copy(source, destination);
+        assertEquals(
+                ALIVE,
+                this.simulation.at(destination).get()
+        );
+    }
+
+    @Test
+    public void testColor() {
+        Coordinate coordinate = Coordinate.of(1, 1);
+        assertEquals(Color.WHITE, this.simulation.getColor(coordinate));
+        this.simulation.at(coordinate).set(ALIVE);
+        assertEquals(Color.RED, this.simulation.getColor(coordinate));
+    }
+
+    @Test
+    public void testSetChangeListener() {
+        Coordinate coordinate = Coordinate.of(1, 1);
+        Coordinate otherCoordinate = Coordinate.of(0,2);
+        Cell<GameOfLifeState> cell = simulation.at(coordinate);
+        List<GameOfLifeState> states = new ArrayList<>();
+        Runnable listener = () -> states.add(this.simulation.at(coordinate).get());
+        simulation.setChangeListener(coordinate, listener);
+        this.simulation.at(otherCoordinate).set(ALIVE);
+        assertEquals(Collections.emptyList(), states);
+        this.simulation.at(coordinate).set(ALIVE);
+        this.simulation.at(otherCoordinate).set(DEAD);
+        assertEquals(List.of(ALIVE), states);
+        this.simulation.at(coordinate).set(ALIVE);
+        this.simulation.at(otherCoordinate).set(ALIVE);
+        this.simulation.at(coordinate).set(DEAD);
+        assertEquals(List.of(ALIVE, ALIVE, DEAD), states);
+    }
+
+    @Test
+    public void testSetGenerationNumberChangeListener() {
+        List<Integer> values = new ArrayList<>();
+        OnChangeListener<Integer> listener = (oldValue, newValue) -> values.add(newValue);
+        simulation.setGenerationNumberChangeListener(listener);
+        assertEquals(Collections.emptyList(), values);
+        simulation.clear();
+        assertEquals(List.of(0), values);
+        simulation.updateToNextGeneration();
+        assertEquals(List.of(0,1), values);
+        simulation.updateToNextGeneration();
+        simulation.updateToNextGeneration();
+        assertEquals(List.of(0,1,2,3), values);
+    }
+
+    @Test
+    public void testClear() {
+        for (Coordinate coordinate : this.simulation) {
+            this.simulation.at(coordinate).set(ALIVE);
+        }
+        this.simulation.clear();
+        for (Coordinate coordinate : this.simulation) {
+            assertEquals(DEAD, this.simulation.at(coordinate).get());
+        }
+    }
+
+    @Test
+    public void testReset() {
+        randomGenerator.setSeed(321);
+        this.simulation.reset();
+        int count = 0;
+        for (Coordinate coordinate : this.simulation) {
+            if (this.simulation.at(coordinate).get().equals(ALIVE)) {
+                count = count + 1;
+            }
+        }
+        assertEquals(7, count);
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/model/GridTest.java b/src/test/java/model/GridTest.java
deleted file mode 100644
index 5487ff213b734cddcbff9f72b01aa75ef217b843..0000000000000000000000000000000000000000
--- a/src/test/java/model/GridTest.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package model;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class GridTest {
-  private CellGrid grid;
-
-//  @BeforeEach
-//  public void initializeGrid() {
-//    grid = new CellGrid(6, 6);
-//  }
-//
-//  @Test
-//  public void testGetNeighbours() {
-//    assertThat(grid.getNeighbors(1, 1)).isNotNull();
-//    assertThat(grid.getNeighbors(1, 1)).hasSize(8);
-//    assertThat(grid.getNeighbors(1, 1))
-//            .containsExactlyInAnyOrder(grid.getCell(0, 0),
-//                    grid.getCell(0, 1),
-//                    grid.getCell(0, 2),
-//                    grid.getCell(1, 0),
-//                    grid.getCell(1, 2),
-//                    grid.getCell(2, 0),
-//                    grid.getCell(2, 1),
-//                    grid.getCell(2, 2));
-//  }
-//
-//  @Test
-//  public void testCountAliveNeighbours() {
-//    assertThat(grid.countAliveNeighbors(1, 1)).isEqualTo(0);
-//    grid.getCell(2, 2).setState(CellState.ALIVE);
-//    grid.getCell(0, 0).setState(CellState.ALIVE);
-//    assertThat(grid.countAliveNeighbors(1, 1)).isEqualTo(2);
-//  }
-//
-//  @Test
-//  public void testCalculateNextState() {
-//    grid.getCell(1, 0).setState(CellState.ALIVE);
-//    grid.getCell(1, 1).setState(CellState.ALIVE);
-//    grid.getCell(1, 2).setState(CellState.ALIVE);
-//    assertThat(grid.calculateNextState(0, 0).isAlive).isFalse();
-//    assertThat(grid.calculateNextState(1, 0).isAlive).isFalse();
-//    assertThat(grid.calculateNextState(1, 1).isAlive).isTrue();
-//    assertThat(grid.calculateNextState(2, 1).isAlive).isTrue();
-//  }
-
-}
\ No newline at end of file
diff --git a/src/test/java/model/StateTest.java b/src/test/java/model/StateTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..54a77f44535f8acaf01369425c8d9c0c928ee058
--- /dev/null
+++ b/src/test/java/model/StateTest.java
@@ -0,0 +1,39 @@
+package model;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static model.State.count;
+import static org.junit.jupiter.api.Assertions.*;
+
+class StateTest {
+    @Test
+    public void testCountMethodWithInteger() {
+        List<Integer> neighbours = List.of(1, 2, 1, 3, 1);
+        int result = count(1, neighbours);
+        assertEquals(3, result);
+    }
+
+    @Test
+    public void testCountMethodWithString() {
+        List<String> neighbours = List.of("apple", "banana", "apple", "cherry", "apple");
+        int result = count("apple", neighbours);
+        assertEquals(3, result);
+    }
+
+    @Test
+    public void testCountMethodWithEmptyList() {
+        List<Double> neighbours = List.of();
+        int result = count(5.0, neighbours);
+        assertEquals(0, result);
+    }
+
+    @Test
+    public void testCountMethodWithNoMatchingElements() {
+        List<Character> neighbours = List.of('a', 'b', 'c');
+        int result = count('x', neighbours);
+        assertEquals(0, result);
+    }
+
+}
\ No newline at end of file
diff --git a/src/test/java/model/automata/GameOfLifeStateTest.java b/src/test/java/model/automata/GameOfLifeStateTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..8c9f0d19fdcb829cd024e82853bb20b38867f8a1
--- /dev/null
+++ b/src/test/java/model/automata/GameOfLifeStateTest.java
@@ -0,0 +1,70 @@
+package model.automata;
+
+import javafx.scene.paint.Color;
+import model.State;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static model.automata.GameOfLifeState.*;
+import static org.junit.jupiter.api.Assertions.*;
+
+class GameOfLifeStateTest {
+    @Test
+    public void testGetColor() {
+        assertEquals(Color.WHITE, DEAD.getColor());
+        assertEquals(Color.RED, ALIVE.getColor());
+    }
+
+    @Test
+    public void testNext() {
+        assertEquals(ALIVE.next(), DEAD);
+        assertEquals(DEAD.next(), ALIVE);
+    }
+
+    @Test
+    public void testAliveUpdate() {
+        // Test with three alive neighbors, should be ALIVE
+        List<State<GameOfLifeState>> aliveNeighbors =
+                List.of(ALIVE, DEAD, ALIVE, DEAD, ALIVE);
+        assertEquals(ALIVE, ALIVE.update(aliveNeighbors));
+
+        // Test with two alive neighbors, should be ALIVE
+        List<State<GameOfLifeState>> twoAliveNeighbors =
+                List.of(ALIVE, DEAD, ALIVE, DEAD, DEAD);
+        assertEquals(ALIVE, ALIVE.update(twoAliveNeighbors));
+
+        // Test with four alive neighbors, should be DEAD
+        List<State<GameOfLifeState>> fourAliveNeighbors =
+                List.of(ALIVE, ALIVE, DEAD, ALIVE, ALIVE);
+        assertEquals(DEAD, ALIVE.update(fourAliveNeighbors));
+
+        // Test with zero alive neighbors, should be DEAD
+        List<State<GameOfLifeState>> zeroAliveNeighbors =
+                List.of(DEAD, DEAD, DEAD, DEAD);
+        assertEquals(DEAD, ALIVE.update(zeroAliveNeighbors));
+    }
+
+    @Test
+    public void testDeadUpdate() {
+        // Test with three alive neighbors, should be ALIVE
+        List<State<GameOfLifeState>> aliveNeighbors =
+                List.of(ALIVE, DEAD, ALIVE, DEAD, ALIVE);
+        assertEquals(ALIVE, DEAD.update(aliveNeighbors));
+
+        // Test with two alive neighbors, should be DEAD
+        List<State<GameOfLifeState>> twoAliveNeighbors =
+                List.of(ALIVE, DEAD, ALIVE, DEAD, DEAD);
+        assertEquals(DEAD, DEAD.update(twoAliveNeighbors));
+
+        // Test with four alive neighbors, should be DEAD
+        List<State<GameOfLifeState>> fourAliveNeighbors =
+                List.of(ALIVE, ALIVE, DEAD, ALIVE, ALIVE);
+        assertEquals(DEAD, DEAD.update(fourAliveNeighbors));
+
+        // Test with zero alive neighbors, should be DEAD
+        List<State<GameOfLifeState>> zeroAliveNeighbors =
+                List.of(DEAD, DEAD, DEAD, DEAD);
+        assertEquals(DEAD, DEAD.update(zeroAliveNeighbors));
+    }
+}
\ No newline at end of file