ALL = List.of(PlayerColor.values());
+
+}
diff --git a/src/ch/epfl/chacun/Points.java b/src/ch/epfl/chacun/Points.java
new file mode 100644
index 0000000..0ac5540
--- /dev/null
+++ b/src/ch/epfl/chacun/Points.java
@@ -0,0 +1,126 @@
+package ch.epfl.chacun;
+
+/**
+ * Helper class to calculate the points for different elements of the game.
+ *
+ * @author Maxence Espagnet (sciper: 372808)
+ * @author Balthazar Baillat (sciper: 373420)
+ */
+public final class Points {
+
+ // Forest points
+ private final static int CLOSED_FOREST_POINTS_BY_MAJORITY_OCCUPANTS = 2;
+ private final static int CLOSED_FOREST_POINTS_BY_MUSHROOM = 3;
+
+ // River points
+ private final static int CLOSED_RIVER_POINTS_BY_MAJORITY_OCCUPANTS = 1;
+ private final static int CLOSED_RIVER_POINTS_BY_FISH = 1;
+
+ // Meadow points
+ private final static int MEADOW_POINTS_BY_MAMMOTH = 3;
+ private final static int MEADOW_POINTS_BY_AUROCHS = 2;
+ private final static int MEADOW_POINTS_BY_DEER = 1;
+
+ // Logboat points
+ private final static int LOGBOAT_POINTS_BY_LAKE = 2;
+
+ // Raft points
+ private final static int RAFT_POINTS_BY_LAKE = 1;
+
+ /**
+ * Private constructor to prevent instantiation.
+ */
+ private Points() {
+ }
+
+ /**
+ * Returns the number of points obtained by the majority pickers in a closed
+ * forest made up of {@code tileCount} tiles and {@code mushroomGroupCount} mushroom groups.
+ *
+ * @param tileCount the number of tiles in the closed forest
+ * @param mushroomGroupCount the number of mushroom groups in the closed forest
+ * @return the points given to a player for a closed forest
+ * @throws IllegalArgumentException if the tile count is not greater than 1 or the mushroom group count is negative
+ */
+ public static int forClosedForest(int tileCount, int mushroomGroupCount) {
+ Preconditions.checkArgument(tileCount > 1);
+ Preconditions.checkArgument(mushroomGroupCount >= 0);
+ return CLOSED_FOREST_POINTS_BY_MAJORITY_OCCUPANTS * tileCount + CLOSED_FOREST_POINTS_BY_MUSHROOM * mushroomGroupCount;
+ }
+
+ /**
+ * Returns the number of points obtained by the majority anglers in
+ * a closed river made up of {@code tileCount} tiles and in which {@code fishCount} fish swim.
+ *
+ * @param tileCount the number of tiles in the closed river
+ * @param fishCount the number of fish in the closed river
+ * @return the points given to a player for a closed river
+ * @throws IllegalArgumentException if the tile count is not greater than 1
+ * or if the fish count is negative
+ */
+ public static int forClosedRiver(int tileCount, int fishCount) {
+ Preconditions.checkArgument(tileCount > 1);
+ Preconditions.checkArgument(fishCount >= 0);
+ return CLOSED_RIVER_POINTS_BY_MAJORITY_OCCUPANTS * tileCount + CLOSED_RIVER_POINTS_BY_FISH * fishCount;
+ }
+
+ /**
+ * Returns the number of points obtained by the majority hunters in a
+ * meadow containing {@code mammothCount} mammoths, {@code aurochsCount} aurochs and {@code deerCount} deer.
+ *
+ * Deer eaten by smilodons are not included in deerCount.
+ *
+ * @param mammothCount the number of mammoths in the meadow
+ * @param aurochsCount the number of aurochs in the meadow
+ * @param deerCount the number of deers in the meadow
+ * @return the points given to a player for a meadow
+ * @throws IllegalArgumentException if the mammoth count is not positive
+ * or if the aurochs count is not positive
+ * or if the deer count is not positive
+ */
+ public static int forMeadow(int mammothCount, int aurochsCount, int deerCount) {
+ Preconditions.checkArgument(mammothCount >= 0);
+ Preconditions.checkArgument(aurochsCount >= 0);
+ Preconditions.checkArgument(deerCount >= 0);
+ return MEADOW_POINTS_BY_MAMMOTH * mammothCount + MEADOW_POINTS_BY_AUROCHS * aurochsCount + MEADOW_POINTS_BY_DEER * deerCount;
+ }
+
+ /**
+ * Returns the number of points obtained by the majority of anglers in a
+ * river system in which {@code fishCount} fish swim.
+ *
+ * @param fishCount the number of fish in the lake
+ * @return the points given to a player for a river system
+ * @throws IllegalArgumentException if the fish count is not positive
+ */
+ public static int forRiverSystem(int fishCount) {
+ Preconditions.checkArgument(fishCount >= 0);
+ return CLOSED_RIVER_POINTS_BY_FISH * fishCount;
+ }
+
+ /**
+ * Returns the number of points obtained by the player depositing the
+ * logboat in a river system containing {@code lakeCount} lakes.
+ *
+ * @param lakeCount the number of lakes in the river system
+ * @return the points given to a player for a logboat
+ * @throws IllegalArgumentException if the lake count is not strictly positive
+ */
+ public static int forLogboat(int lakeCount) {
+ Preconditions.checkArgument(lakeCount > 0);
+ return LOGBOAT_POINTS_BY_LAKE * lakeCount;
+ }
+
+ /**
+ * Returns the number of additional points obtained by the majority anglers
+ * on the river network containing the raft and including {@code lakeCount} lakes.
+ *
+ * @param lakeCount the number of lakes in the river network
+ * @return the points given to a player for a raft
+ * @throws IllegalArgumentException if the lake count is not strictly positive
+ */
+ public static int forRaft(int lakeCount) {
+ Preconditions.checkArgument(lakeCount > 0);
+ return RAFT_POINTS_BY_LAKE * lakeCount;
+ }
+}
diff --git a/src/ch/epfl/chacun/Pos.java b/src/ch/epfl/chacun/Pos.java
new file mode 100644
index 0000000..bf08260
--- /dev/null
+++ b/src/ch/epfl/chacun/Pos.java
@@ -0,0 +1,41 @@
+package ch.epfl.chacun;
+
+/**
+ * Represents a position on the board of size 25x25.
+ *
+ * @param x the x coordinate of the position
+ * @param y the y coordinate of the position
+ * @author Maxence Espagnet (sciper: 372808)
+ * @author Balthazar Baillat (sciper: 373420)
+ */
+public record Pos(int x, int y) {
+
+ // The origin of the board
+ public final static Pos ORIGIN = new Pos(0, 0);
+
+ /**
+ * Translates the current position by a given amount.
+ *
+ * @param dX the amount by which the x coordinate should be translated
+ * @param dY the amount by which the x coordinate should be translated
+ * @return the translated position
+ */
+ public Pos translated(int dX, int dY) {
+ return new Pos(x + dX, y + dY);
+ }
+
+ /**
+ * Returns the neighbor of the current position in a given direction.
+ *
+ * @param direction the direction in which to find the neighbor
+ * @return the neighbor of the current position in the given direction
+ */
+ public Pos neighbor(Direction direction) {
+ return switch (direction) {
+ case N -> translated(0, -1);
+ case E -> translated(1, 0);
+ case S -> translated(0, 1);
+ case W -> translated(-1, 0);
+ };
+ }
+}
diff --git a/src/ch/epfl/chacun/Preconditions.java b/src/ch/epfl/chacun/Preconditions.java
new file mode 100644
index 0000000..7ab2f11
--- /dev/null
+++ b/src/ch/epfl/chacun/Preconditions.java
@@ -0,0 +1,28 @@
+package ch.epfl.chacun;
+
+/**
+ * Helper class to check preconditions.
+ *
+ * @author Maxence Espagnet (sciper: 372808)
+ * @author Balthazar Baillat (sciper: 373420)
+ */
+public final class Preconditions {
+
+ /**
+ * Private constructor to prevent instantiation.
+ */
+ private Preconditions() {
+ }
+
+ /**
+ * Throws an IllegalArgumentException if the given precondition is false.
+ *
+ * @param precondition the precondition to check
+ * @throws IllegalArgumentException if the precondition is false
+ */
+ public static void checkArgument(boolean precondition) {
+ if (!precondition) {
+ throw new IllegalArgumentException();
+ }
+ }
+}
diff --git a/src/ch/epfl/chacun/Rotation.java b/src/ch/epfl/chacun/Rotation.java
new file mode 100644
index 0000000..91478df
--- /dev/null
+++ b/src/ch/epfl/chacun/Rotation.java
@@ -0,0 +1,60 @@
+package ch.epfl.chacun;
+
+import java.util.List;
+
+/**
+ * Represents the different possible rotations of a tile.
+ *
+ * @author Maxence Espagnet (sciper: 372808)
+ * @author Balthazar Baillat (sciper: 373420)
+ */
+public enum Rotation {
+ NONE, // 0 degrees
+ RIGHT, // 90 degrees
+ HALF_TURN, // 180 degrees
+ LEFT; // 270 degrees
+
+ // All the possible rotations
+ public static final List ALL = List.of(Rotation.values());
+ // The number of different rotations
+ public static final int COUNT = ALL.size();
+
+ /**
+ * Calculates the addition of two rotations.
+ *
+ * @param that the rotation to add to the current one
+ * @return a new rotation which is the sum of the two rotations
+ */
+ public Rotation add(Rotation that) {
+ return ALL.get((this.ordinal() + that.ordinal()) % COUNT);
+ }
+
+ /**
+ * Calculates the opposite rotation of the current one.
+ * The opposite rotation is the rotation that, when added to the current one, gives the NONE rotation.
+ *
+ * @return the opposite rotation
+ */
+ public Rotation negated() {
+ return ALL.get((COUNT - this.ordinal()) % COUNT);
+ }
+
+ /**
+ * Calculates the number of quarter turns clockwise of the current rotation.
+ *
+ * @return the number of quarter turns clockwise of the rotation
+ */
+ public int quarterTurnsCW() {
+ return this.ordinal();
+ }
+
+ /**
+ * Converts the rotation to degrees clockwise.
+ *
+ * @return the number of degrees clockwise of the rotation
+ */
+ public int degreesCW() {
+ return this.quarterTurnsCW() * 90;
+ }
+
+}
diff --git a/src/ch/epfl/chacun/Tile.java b/src/ch/epfl/chacun/Tile.java
new file mode 100644
index 0000000..e3a62f7
--- /dev/null
+++ b/src/ch/epfl/chacun/Tile.java
@@ -0,0 +1,69 @@
+package ch.epfl.chacun;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Represents a tile of the game.
+ *
+ * @param id the id of the tile
+ * @param kind the kind of the tile
+ * @param n north side of the tile
+ * @param e east side od^f the tile
+ * @param s south side of the tile
+ * @param w west side of the tile
+ * @author Maxence Espagnet (sciper: 372808)
+ * @author Balthazar Baillat (sciper: 373420)
+ */
+public record Tile(int id, Kind kind, TileSide n, TileSide e, TileSide s, TileSide w) {
+
+ /**
+ * Returns the list of all the possible sides of the tile.
+ *
+ * @return the list of all the possible sides of the tile
+ */
+ public List sides() {
+ return List.of(n, e, s, w);
+ }
+
+ /**
+ * Returns the set of all the zones that touch at least one side of the tile.
+ *
+ * @return the set of all the zones that touch at least one side of the tile
+ */
+ public Set sideZones() {
+ Set zones = new HashSet<>();
+ zones.addAll(n.zones());
+ zones.addAll(e.zones());
+ zones.addAll(s.zones());
+ zones.addAll(w.zones());
+ return zones;
+ }
+
+ /**
+ * Returns the set of all the zones that are contained in the tile.
+ *
+ * @return the set of all the zones that are contained in the tile
+ */
+ public Set zones() {
+ Set sideZones = sideZones();
+ Set zones = new HashSet<>(sideZones);
+ for (Zone zone : sideZones) {
+ if (zone instanceof Zone.River river) {
+ if (river.hasLake())
+ zones.add(river.lake());
+ }
+ }
+ return zones;
+ }
+
+ /**
+ * Represents the different kinds of tiles.
+ */
+ public enum Kind {
+ START,
+ NORMAL,
+ MENHIR;
+ }
+}
diff --git a/src/ch/epfl/chacun/TileDecks.java b/src/ch/epfl/chacun/TileDecks.java
new file mode 100644
index 0000000..943ee37
--- /dev/null
+++ b/src/ch/epfl/chacun/TileDecks.java
@@ -0,0 +1,121 @@
+package ch.epfl.chacun;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Predicate;
+
+/**
+ * Represents the three decks of tiles.
+ *
+ * @param startTiles
+ * @param normalTiles
+ * @param menhirTiles
+ * @author Maxence Espagnet (sciper: 372808)
+ * @author Balthazar Baillat (sciper: 373420)
+ */
+public record TileDecks(List startTiles, List normalTiles, List menhirTiles) {
+ /**
+ * Makes a defensive copy of the tile lists.
+ *
+ * @param startTiles the deck containing the start tiles
+ * @param normalTiles the deck containing the normal tiles
+ * @param menhirTiles the deck containing the menhir tiles
+ */
+ public TileDecks {
+ startTiles = List.copyOf(startTiles);
+ normalTiles = List.copyOf(normalTiles);
+ menhirTiles = List.copyOf(menhirTiles);
+ }
+
+ /**
+ * Returns the size of the deck containing tiles of a given kind.
+ *
+ * @param kind the kind of tile
+ * @return the size of the deck o a given kind
+ */
+ public int deckSize(Tile.Kind kind) {
+ return switch (kind) {
+ case START -> startTiles.size();
+ case NORMAL -> normalTiles.size();
+ case MENHIR -> menhirTiles.size();
+ };
+ }
+
+ /**
+ * Returns the tile at the top of the deck containing tiles of the given kind,
+ * or null if the deck is empty.
+ *
+ * @param kind the kind of tile
+ * @return the tile at the top of the deck containing tiles of the given kind,
+ * or null if the deck is empty
+ */
+ public Tile topTile(Tile.Kind kind) {
+ return deckSize(kind) <= 0 ? null : switch (kind) {
+ case START -> startTiles.getFirst();
+ case NORMAL -> normalTiles.getFirst();
+ case MENHIR -> menhirTiles.getFirst();
+ };
+ }
+
+ /**
+ * Returns a new triplet of decks after removing from the receiver triplet the top tile of the deck
+ * containing tiles of a given kind.
+ *
+ * @param kind the kind of tile
+ * @return a new triplet of decks after removing from the receiver triplet the top tile of the deck
+ * containing tiles of a given kind
+ * @throws IllegalArgumentException if the receiver deck of the given tile kind is empty
+ */
+ public TileDecks withTopTileDrawn(Tile.Kind kind) {
+ if (deckSize(kind) <= 0) {
+ throw new IllegalArgumentException("The deck of the given tile kind is empty");
+ }
+
+ return switch (kind) {
+ case START -> new TileDecks(removeDeckFirstTile(startTiles), normalTiles, menhirTiles);
+ case NORMAL -> new TileDecks(startTiles, removeDeckFirstTile(normalTiles), menhirTiles);
+ case MENHIR -> new TileDecks(startTiles, normalTiles, removeDeckFirstTile(menhirTiles));
+ };
+ }
+
+ /**
+ * Returns a new triplet of decks after testing on the receiver deck containing the given tile kind a
+ * given predicate using the {@code testPredicateOnDeck} function.
+ *
+ * @param kind the kind of tile
+ * @param predicate the predicate to test
+ * @return a new triplet of decks after testing a given predicate on the receiver triplet
+ */
+ public TileDecks withTopTileDrawnUntil(Tile.Kind kind, Predicate predicate) {
+ return switch (kind) {
+ case START -> new TileDecks(filterDeck(startTiles, predicate), normalTiles, menhirTiles);
+ case NORMAL -> new TileDecks(startTiles, filterDeck(normalTiles, predicate), menhirTiles);
+ case MENHIR -> new TileDecks(startTiles, normalTiles, filterDeck(menhirTiles, predicate));
+ };
+ }
+
+ /**
+ * Modify a deck of tiles by removing the tiles that does not respect a given predicate.
+ *
+ * @param deck the deck of tiles
+ * @param predicate the predicate to check
+ * @return a new deck of tiles after removing the tiles that does not respect the given predicate
+ */
+ private List filterDeck(List deck, Predicate predicate) {
+ List filteredDeck = List.copyOf(deck);
+ while (!filteredDeck.isEmpty() && !predicate.test(filteredDeck.getFirst())) {
+ filteredDeck = removeDeckFirstTile(filteredDeck);
+ }
+ return filteredDeck;
+ }
+
+ /**
+ * Removes the first tile from a given deck of tiles.
+ *
+ * @param deck the deck of tiles
+ * @return a new deck that excludes the first tile from the original deck
+ */
+ private List removeDeckFirstTile(List deck) {
+ return deck.subList(1, deck.size());
+ }
+}
\ No newline at end of file
diff --git a/src/ch/epfl/chacun/TileSide.java b/src/ch/epfl/chacun/TileSide.java
new file mode 100644
index 0000000..514bc05
--- /dev/null
+++ b/src/ch/epfl/chacun/TileSide.java
@@ -0,0 +1,81 @@
+package ch.epfl.chacun;
+
+import java.util.List;
+
+/**
+ * Represents the different possible sides of a tile.
+ *
+ * @author Maxence Espagnet (sciper: 372808)
+ * @author Balthazar Baillat (sciper: 373420)
+ */
+public sealed interface TileSide {
+
+ /**
+ * Returns {@code true} if and only if the given edge ({@code that})
+ * is of the same kind as the current one ({@code this}).
+ *
+ * @param that the edge to compare with the current one
+ * @return {@code true} if and only if the given edge is of the same kind as the current one
+ */
+ boolean isSameKindAs(TileSide that);
+
+ /**
+ * Returns the zones that touch the edge represented by the receiver ({@code this}).
+ *
+ * @return the zones that touch the current edge
+ */
+ List zones();
+
+ /**
+ * Represents a side of a tile that is a forest.
+ *
+ * @param forest the forest zone
+ */
+ record Forest(Zone.Forest forest) implements TileSide {
+ @Override
+ public boolean isSameKindAs(TileSide that) {
+ return that instanceof Forest;
+ }
+
+ @Override
+ public List zones() {
+ return List.of(forest);
+ }
+ }
+
+ /**
+ * Represents a side of a tile that is a meadow.
+ *
+ * @param meadow the meadow zone
+ */
+ record Meadow(Zone.Meadow meadow) implements TileSide {
+ @Override
+ public boolean isSameKindAs(TileSide that) {
+ return that instanceof Meadow;
+ }
+
+ @Override
+ public List zones() {
+ return List.of(meadow);
+ }
+ }
+
+ /**
+ * Represents a side which contains a river between two meadows.
+ *
+ * @param meadow1 the first meadow zone found clockwise
+ * @param river the river zone
+ * @param meadow2 the second meadow zone found clockwise
+ */
+ record River(Zone.Meadow meadow1, Zone.River river, Zone.Meadow meadow2) implements TileSide {
+ @Override
+ public boolean isSameKindAs(TileSide that) {
+ return that instanceof River;
+ }
+
+ @Override
+ public List zones() {
+ return List.of(meadow1, river, meadow2);
+ }
+ }
+}
diff --git a/src/ch/epfl/chacun/Zone.java b/src/ch/epfl/chacun/Zone.java
new file mode 100644
index 0000000..92df429
--- /dev/null
+++ b/src/ch/epfl/chacun/Zone.java
@@ -0,0 +1,143 @@
+package ch.epfl.chacun;
+
+import java.util.List;
+
+/**
+ * Represents the different possible zones of a tile.
+ *
+ * @author Maxence Espagnet (sciper: 372808)
+ * @author Balthazar Baillat (sciper: 373420)
+ */
+public sealed interface Zone {
+
+ /**
+ * Calculates the id of the tile containing the zone.
+ *
+ * @param zoneId the id of the zone
+ * @return the tileId of the zone
+ */
+ static int tileId(int zoneId) {
+ // Since a zoneId is obtained using zoneId = 10 * tileId + localId and localId is between 0 and 9
+ // We can use integer division to obtain the tileId
+ return (int) (zoneId / 10);
+ }
+
+ /**
+ * Calculates the "local" identifier of the zone.
+ *
+ * @param zoneId the id of the zone
+ * @return the local identifier of the zone
+ */
+ static int localId(int zoneId) {
+ // zoneId = 10 * tileId + localId
+ return zoneId - 10 * tileId(zoneId);
+ }
+
+ /**
+ * Returns the identifier of the zone.
+ *
+ * @return the identifier of the zone
+ */
+ int id();
+
+ /**
+ * Default method to calculate the tileId of the zone.
+ *
+ * @return the tileId of the zone
+ */
+ default int tileId() {
+ return tileId(id());
+ }
+
+ /**
+ * Default method to calculate the localId of the zone.
+ *
+ * @return the localId of the zone
+ */
+ default int localId() {
+ return localId(id());
+ }
+
+ /**
+ * Returns the special power of the zone.
+ *
+ * @return the special power of the zone
+ */
+ default SpecialPower specialPower() {
+ return null;
+ }
+
+ /**
+ * Represents the different special powers.
+ */
+ enum SpecialPower {
+ SHAMAN, LOGBOAT, HUNTING_TRAP, PIT_TRAP, WILD_FIRE, RAFT;
+ }
+
+ /**
+ * Represents a water zone.
+ */
+ sealed interface Water extends Zone {
+ /**
+ * Returns the number of fishes in the zone.
+ *
+ * @return the number of fishes in the zone
+ */
+ int fishCount();
+ }
+
+ /**
+ * Represents a forest zone.
+ *
+ * @param id the identifier of the zone
+ * @param kind the kind of the forest
+ */
+ record Forest(int id, Kind kind) implements Zone {
+ // Represents the different kinds of forests.
+ public enum Kind {
+ PLAIN, WITH_MENHIR, WITH_MUSHROOMS
+ }
+ }
+
+ /**
+ * Represents a meadow zone.
+ *
+ * @param id the identifier of the zone
+ * @param animals the animals present in the meadow
+ * @param specialPower the special power of the meadow
+ */
+ record Meadow(int id, List animals, SpecialPower specialPower) implements Zone {
+
+ /**
+ * Makes a defensive copy of the animal list.
+ */
+ public Meadow {
+ // Defensive copy of animals
+ animals = List.copyOf(animals);
+ }
+ }
+
+ /**
+ * Represents a lake zone.
+ *
+ * @param id the identifier of the zone
+ * @param fishCount the number of fishes in the lake
+ * @param specialPower the special power of the lake
+ */
+ record Lake(int id, int fishCount, SpecialPower specialPower) implements Water {
+ }
+
+ /**
+ * Represents a river zone.
+ *
+ * @param id the identifier of the zone
+ * @param fishCount the number of fishes in the river
+ * @param lake (optional) the lake connected to the river
+ */
+ record River(int id, int fishCount, Lake lake) implements Water {
+ // Returns True if the river is connected to a lake.
+ public boolean hasLake() {
+ return lake != null;
+ }
+ }
+}
diff --git a/src/ch/epfl/cs108/Submit.java b/src/ch/epfl/cs108/Submit.java
index 263dcbc..0acd42b 100644
--- a/src/ch/epfl/cs108/Submit.java
+++ b/src/ch/epfl/cs108/Submit.java
@@ -33,9 +33,9 @@ public final class Submit {
// CONFIGURATION
// -------------
// Jeton du premier membre du groupe
- private static final String TOKEN_1 = "";
+ private static final String TOKEN_1 = "boopo3Ah";
// Jeton du second membre (identique au premier pour les personnes travaillant seules)
- private static final String TOKEN_2 = "";
+ private static final String TOKEN_2 = "coh8ooPh";
// Noms des éventuels fichiers Java additionnels à inclure (p.ex. "MyClass.java")
private static final List ADDITIONAL_FILES =
List.of();
diff --git a/src/ch/epfl/sigcheck/SignatureChecks_2.java b/src/ch/epfl/sigcheck/SignatureChecks_2.java
new file mode 100644
index 0000000..609ab00
--- /dev/null
+++ b/src/ch/epfl/sigcheck/SignatureChecks_2.java
@@ -0,0 +1,144 @@
+package ch.epfl.sigcheck;
+
+// Attention : cette classe n'est *pas* un test JUnit, et son code n'est pas
+// destiné à être exécuté. Son seul but est de vérifier, autant que possible,
+// que les noms et les types des différentes entités à définir pour cette
+// étape du projet sont corrects.
+
+final class SignatureChecks_2 {
+ private SignatureChecks_2() {}
+
+ void checkTileSide() throws Exception {
+ v02 = v01.isSameKindAs(v01);
+ v03 = v01.zones();
+ }
+
+ void checkTileSide_River() throws Exception {
+ v04 = new ch.epfl.chacun.TileSide.River(v05, v06, v05);
+ v02 = v04.equals(v07);
+ v08 = v04.hashCode();
+ v02 = v04.isSameKindAs(v01);
+ v05 = v04.meadow1();
+ v05 = v04.meadow2();
+ v06 = v04.river();
+ v09 = v04.toString();
+ v03 = v04.zones();
+ }
+
+ void checkTileSide_Meadow() throws Exception {
+ v10 = new ch.epfl.chacun.TileSide.Meadow(v05);
+ v02 = v10.equals(v07);
+ v08 = v10.hashCode();
+ v02 = v10.isSameKindAs(v01);
+ v05 = v10.meadow();
+ v09 = v10.toString();
+ v03 = v10.zones();
+ }
+
+ void checkTileSide_Forest() throws Exception {
+ v11 = new ch.epfl.chacun.TileSide.Forest(v12);
+ v02 = v11.equals(v07);
+ v12 = v11.forest();
+ v08 = v11.hashCode();
+ v02 = v11.isSameKindAs(v01);
+ v09 = v11.toString();
+ v03 = v11.zones();
+ }
+
+ void checkTile() throws Exception {
+ v13 = new ch.epfl.chacun.Tile(v08, v14, v01, v01, v01, v01);
+ v01 = v13.e();
+ v02 = v13.equals(v07);
+ v08 = v13.hashCode();
+ v08 = v13.id();
+ v14 = v13.kind();
+ v01 = v13.n();
+ v01 = v13.s();
+ v15 = v13.sideZones();
+ v16 = v13.sides();
+ v09 = v13.toString();
+ v01 = v13.w();
+ v15 = v13.zones();
+ }
+
+ void checkTile_Kind() throws Exception {
+ v14 = ch.epfl.chacun.Tile.Kind.MENHIR;
+ v14 = ch.epfl.chacun.Tile.Kind.NORMAL;
+ v14 = ch.epfl.chacun.Tile.Kind.START;
+ v14 = ch.epfl.chacun.Tile.Kind.valueOf(v09);
+ v17 = ch.epfl.chacun.Tile.Kind.values();
+ }
+
+ void checkPlacedTile() throws Exception {
+ v18 = new ch.epfl.chacun.PlacedTile(v13, v19, v20, v21);
+ v18 = new ch.epfl.chacun.PlacedTile(v13, v19, v20, v21, v22);
+ v02 = v18.equals(v07);
+ v23 = v18.forestZones();
+ v08 = v18.hashCode();
+ v08 = v18.id();
+ v08 = v18.idOfZoneOccupiedBy(v24);
+ v14 = v18.kind();
+ v25 = v18.meadowZones();
+ v22 = v18.occupant();
+ v19 = v18.placer();
+ v21 = v18.pos();
+ v26 = v18.potentialOccupants();
+ v27 = v18.riverZones();
+ v20 = v18.rotation();
+ v01 = v18.side(v28);
+ v29 = v18.specialPowerZone();
+ v13 = v18.tile();
+ v09 = v18.toString();
+ v18 = v18.withNoOccupant();
+ v18 = v18.withOccupant(v22);
+ v29 = v18.zoneWithId(v08);
+ }
+
+ void checkTileDecks() throws Exception {
+ v30 = new ch.epfl.chacun.TileDecks(v31, v31, v31);
+ v08 = v30.deckSize(v14);
+ v02 = v30.equals(v07);
+ v08 = v30.hashCode();
+ v32 = v30.menhirTiles();
+ v32 = v30.normalTiles();
+ v32 = v30.startTiles();
+ v09 = v30.toString();
+ v13 = v30.topTile(v14);
+ v30 = v30.withTopTileDrawn(v14);
+ v30 = v30.withTopTileDrawnUntil(v14, v33);
+ }
+
+ ch.epfl.chacun.TileSide v01;
+ boolean v02;
+ java.util.List v03;
+ ch.epfl.chacun.TileSide.River v04;
+ ch.epfl.chacun.Zone.Meadow v05;
+ ch.epfl.chacun.Zone.River v06;
+ Object v07;
+ int v08;
+ String v09;
+ ch.epfl.chacun.TileSide.Meadow v10;
+ ch.epfl.chacun.TileSide.Forest v11;
+ ch.epfl.chacun.Zone.Forest v12;
+ ch.epfl.chacun.Tile v13;
+ ch.epfl.chacun.Tile.Kind v14;
+ java.util.Set v15;
+ java.util.List v16;
+ ch.epfl.chacun.Tile.Kind[] v17;
+ ch.epfl.chacun.PlacedTile v18;
+ ch.epfl.chacun.PlayerColor v19;
+ ch.epfl.chacun.Rotation v20;
+ ch.epfl.chacun.Pos v21;
+ ch.epfl.chacun.Occupant v22;
+ java.util.Set v23;
+ ch.epfl.chacun.Occupant.Kind v24;
+ java.util.Set v25;
+ java.util.Set v26;
+ java.util.Set v27;
+ ch.epfl.chacun.Direction v28;
+ ch.epfl.chacun.Zone v29;
+ ch.epfl.chacun.TileDecks v30;
+ java.util.List v31;
+ java.util.List v32;
+ java.util.function.Predicate v33;
+}
diff --git a/test/ch/epfl/chacun/PlacedTileTest.java b/test/ch/epfl/chacun/PlacedTileTest.java
new file mode 100644
index 0000000..14ec483
--- /dev/null
+++ b/test/ch/epfl/chacun/PlacedTileTest.java
@@ -0,0 +1,176 @@
+package ch.epfl.chacun;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.junit.Assert.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class PlacedTileTest {
+
+ @Test
+ void placedTileConstructorThrowsOnNullTile() {
+ assertThrows(NullPointerException.class, () -> new PlacedTile(null, null, Rotation.NONE, Pos.ORIGIN));
+ }
+
+ @Test
+ void placedTileConstructorThrowsOnNullRotation() {
+ Tile tile = new Tile(0, null, null, null, null, null);
+ assertThrows(NullPointerException.class, () -> new PlacedTile(tile, null, null, Pos.ORIGIN));
+ }
+
+ @Test
+ void placedTileConstructorThrowsOnNullPos() {
+ Tile tile = new Tile(0, null, null, null, null, null);
+ assertThrows(NullPointerException.class, () -> new PlacedTile(tile, null, Rotation.NONE, null));
+ }
+
+ @Test
+ void placedTileConstructorDoesntThrowOnNullPlacer() {
+ Tile tile = new Tile(0, null, null, null, null, null);
+ assertDoesNotThrow(() -> new PlacedTile(tile, null, Rotation.NONE, Pos.ORIGIN));
+ }
+
+ @Test
+ void placedTileSideWorks() {
+ TileSide north = new TileSide.River(null, null, null);
+ TileSide east = new TileSide.Forest(new Zone.Forest(0, Zone.Forest.Kind.PLAIN));
+ TileSide south = new TileSide.Forest(new Zone.Forest(1, Zone.Forest.Kind.WITH_MENHIR));
+ TileSide west = new TileSide.Meadow(null);
+
+ List ALL = List.of(north, east, south, west);
+ Tile tile = new Tile(0, null, north, east, south, west);
+ for (int i = 0; i < 4; i++) {
+ Direction direction = Direction.ALL.get(i);
+ for (int j = 0; j < 4; j++) {
+ Rotation rotation = Rotation.ALL.get(j);
+ PlacedTile placedTile = new PlacedTile(tile, null, rotation, Pos.ORIGIN);
+ assertEquals(ALL.get(direction.rotated(rotation.negated()).ordinal()), placedTile.side(direction));
+ }
+ }
+ }
+
+ @Test
+ void zoneWithIdWorks() {
+ Zone.Forest forest1 = new Zone.Forest(0, Zone.Forest.Kind.PLAIN);
+ Zone.Forest forest2 = new Zone.Forest(1, Zone.Forest.Kind.WITH_MENHIR);
+ Zone.Meadow meadow1 = new Zone.Meadow(2, List.of(new Animal(2, Animal.Kind.AUROCHS)), Zone.Meadow.SpecialPower.HUNTING_TRAP);
+ Zone.River river = new Zone.River(3, 9, null);
+ Zone.Meadow meadow2 = new Zone.Meadow(4, List.of(new Animal(2, Animal.Kind.AUROCHS)), Zone.Meadow.SpecialPower.HUNTING_TRAP);
+
+ TileSide north = new TileSide.Meadow(meadow1);
+ TileSide east = new TileSide.Forest(forest1);
+ TileSide south = new TileSide.River(meadow1, river, meadow2);
+ TileSide west = new TileSide.Forest(forest2);
+ Tile tile = new Tile(0, null, north, east, south, west);
+ PlacedTile placedTile = new PlacedTile(tile, null, Rotation.NONE, Pos.ORIGIN);
+
+ assertEquals(forest1, placedTile.zoneWithId(0));
+ assertEquals(forest2, placedTile.zoneWithId(1));
+ assertEquals(meadow1, placedTile.zoneWithId(2));
+ assertEquals(river, placedTile.zoneWithId(3));
+ assertEquals(meadow2, placedTile.zoneWithId(4));
+ }
+
+ @Test
+ void zoneWithIdThrowsOnUnknownId() {
+ Zone.Forest forest1 = new Zone.Forest(0, Zone.Forest.Kind.PLAIN);
+ Zone.Forest forest2 = new Zone.Forest(1, Zone.Forest.Kind.WITH_MENHIR);
+ Zone.Meadow meadow1 = new Zone.Meadow(2, List.of(new Animal(2, Animal.Kind.AUROCHS)), Zone.Meadow.SpecialPower.HUNTING_TRAP);
+ Zone.River river = new Zone.River(3, 9, null);
+ Zone.Meadow meadow2 = new Zone.Meadow(4, List.of(new Animal(2, Animal.Kind.AUROCHS)), Zone.Meadow.SpecialPower.HUNTING_TRAP);
+
+ TileSide north = new TileSide.Meadow(meadow1);
+ TileSide east = new TileSide.Forest(forest1);
+ TileSide south = new TileSide.River(meadow1, river, meadow2);
+ TileSide west = new TileSide.Forest(forest2);
+ Tile tile = new Tile(0, null, north, east, south, west);
+ PlacedTile placedTile = new PlacedTile(tile, null, Rotation.NONE, Pos.ORIGIN);
+
+ assertThrows(IllegalArgumentException.class, () -> placedTile.zoneWithId(10));
+ }
+
+ @Test
+ public void testPotentialOccupantsReturnsCorrectValue() {
+ Zone.Meadow meadow = new Zone.Meadow(613, List.of(new Animal(6131, Animal.Kind.AUROCHS)), Zone.Meadow.SpecialPower.HUNTING_TRAP);
+ Zone.Meadow meadow2 = new Zone.Meadow(614, List.of(new Animal(6141, Animal.Kind.MAMMOTH)), null);
+ Zone.Forest forest2 = new Zone.Forest(615, Zone.Forest.Kind.PLAIN);
+ Zone.Forest forest = new Zone.Forest(612, Zone.Forest.Kind.WITH_MENHIR);
+ TileSide forestSide = new TileSide.Forest(forest);
+ TileSide meadowSide = new TileSide.Meadow(meadow);
+ TileSide forestSide2 = new TileSide.Forest(forest2);
+ TileSide meadowSide2 = new TileSide.Meadow(meadow2);
+ Tile tile = new Tile(1, Tile.Kind.NORMAL, forestSide, meadowSide, forestSide2, meadowSide2);
+ PlayerColor Habib = PlayerColor.RED;
+
+ PlacedTile placedTile = new PlacedTile(tile, Habib, Rotation.RIGHT, new Pos(0, 0));
+
+ Set set = new HashSet<>();
+ set.add(new Occupant(Occupant.Kind.PAWN, 613));
+ set.add(new Occupant(Occupant.Kind.PAWN, 614));
+ set.add(new Occupant(Occupant.Kind.PAWN, 615));
+ set.add(new Occupant(Occupant.Kind.PAWN, 612));
+
+ assertEquals(set, placedTile.potentialOccupants());
+
+ PlacedTile placedTile2 = new PlacedTile(tile, null, Rotation.RIGHT, new Pos(0, 0));
+
+ assertEquals(new HashSet<>(), placedTile2.potentialOccupants());
+
+ Zone.River river = new Zone.River(623, 3, null);
+ Zone.Lake lake = new Zone.Lake(628, 0, Zone.SpecialPower.LOGBOAT);
+ Zone.River river2 = new Zone.River(624, 2, lake);
+
+ TileSide riverSide1 = new TileSide.River(meadow, river, meadow2);
+ TileSide riverSide2 = new TileSide.River(meadow2, river2, meadow);
+
+ Tile tile2 = new Tile(1, Tile.Kind.NORMAL, forestSide, riverSide1, riverSide2, meadowSide2);
+ PlacedTile placedTile3 = new PlacedTile(tile2, Habib, Rotation.RIGHT, new Pos(0, 0));
+
+ Set set2 = new HashSet<>();
+ set2.add(new Occupant(Occupant.Kind.PAWN, 623));
+ set2.add(new Occupant(Occupant.Kind.PAWN, 624));
+ set2.add(new Occupant(Occupant.Kind.HUT, 628));
+ set2.add(new Occupant(Occupant.Kind.HUT, 623));
+
+ set2.add(new Occupant(Occupant.Kind.PAWN, 613));
+ set2.add(new Occupant(Occupant.Kind.PAWN, 614));
+ set2.add(new Occupant(Occupant.Kind.PAWN, 612));
+
+ assertEquals(set2, placedTile3.potentialOccupants());
+ }
+
+ @Test
+ public void testWithOccupantWorks() {
+ Zone.Meadow meadow = new Zone.Meadow(613, List.of(new Animal(6131, Animal.Kind.AUROCHS)), Zone.Meadow.SpecialPower.HUNTING_TRAP);
+ Zone.Meadow meadow2 = new Zone.Meadow(614, List.of(new Animal(6141, Animal.Kind.MAMMOTH)), null);
+ Zone.Forest forest2 = new Zone.Forest(615, Zone.Forest.Kind.PLAIN);
+ Zone.Forest forest = new Zone.Forest(612, Zone.Forest.Kind.WITH_MENHIR);
+ TileSide forestSide = new TileSide.Forest(forest);
+ TileSide meadowSide = new TileSide.Meadow(meadow);
+ TileSide forestSide2 = new TileSide.Forest(forest2);
+ TileSide meadowSide2 = new TileSide.Meadow(meadow2);
+ Tile tile = new Tile(1, Tile.Kind.NORMAL, forestSide, meadowSide, forestSide2, meadowSide2);
+ PlayerColor Habib = PlayerColor.RED;
+
+ PlacedTile placedTile = new PlacedTile(tile, Habib, Rotation.RIGHT, new Pos(0, 0));
+
+ Occupant occupant = new Occupant(Occupant.Kind.PAWN, 613);
+ assertThrows(IllegalArgumentException.class, () -> {
+ PlacedTile withOccupant = placedTile.withOccupant(occupant);
+ withOccupant.withOccupant(new Occupant(Occupant.Kind.PAWN, 613));
+ });
+
+ PlacedTile withOccupant = placedTile.withOccupant(new Occupant(Occupant.Kind.PAWN, 613));
+ assertEquals(occupant, withOccupant.occupant());
+
+ assertEquals(613, withOccupant.idOfZoneOccupiedBy(Occupant.Kind.PAWN));
+ assertEquals(-1, withOccupant.idOfZoneOccupiedBy(Occupant.Kind.HUT));
+
+ }
+
+}
diff --git a/test/ch/epfl/chacun/TileDecksTest.java b/test/ch/epfl/chacun/TileDecksTest.java
new file mode 100644
index 0000000..b628945
--- /dev/null
+++ b/test/ch/epfl/chacun/TileDecksTest.java
@@ -0,0 +1,97 @@
+package ch.epfl.chacun;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
+
+public class TileDecksTest {
+ @Test
+ void deckSizeWorks(){
+ List startTiles = new ArrayList<>(1);
+ List normalTiles = new ArrayList<>(1);
+ List menhirTiles = new ArrayList<>(1);
+
+ startTiles.add(new Tile(0, Tile.Kind.START, null, null, null, null));
+ normalTiles.add(new Tile(1, Tile.Kind.NORMAL, null, null, null, null));
+ menhirTiles.add(new Tile(2, Tile.Kind.MENHIR, null, null, null, null));
+
+ TileDecks tileDecks = new TileDecks(startTiles, normalTiles, menhirTiles);
+
+ assertEquals(startTiles.size(), tileDecks.deckSize(Tile.Kind.START));
+ assertEquals(normalTiles.size(), tileDecks.deckSize(Tile.Kind.NORMAL));
+ assertEquals(menhirTiles.size(), tileDecks.deckSize(Tile.Kind.MENHIR));
+
+ }
+
+ @Test
+ void topTileReturnsNullOnEmptyDeck(){
+ List startTiles = new ArrayList<>(1);
+ List normalTiles = new ArrayList<>(1);
+ List menhirTiles = new ArrayList<>(1);
+
+ TileDecks tileDecks = new TileDecks(startTiles, normalTiles, menhirTiles);
+
+ assertEquals(null, tileDecks.topTile(Tile.Kind.START));
+ assertEquals(null, tileDecks.topTile(Tile.Kind.NORMAL));
+ assertEquals(null, tileDecks.topTile(Tile.Kind.MENHIR));
+ }
+
+ @Test
+ void topTileWorks(){
+ List startTiles = new ArrayList<>(1);
+ List normalTiles = new ArrayList<>(1);
+ List menhirTiles = new ArrayList<>(1);
+
+ startTiles.add(new Tile(0, Tile.Kind.START, null, null, null, null));
+ normalTiles.add(new Tile(1, Tile.Kind.NORMAL, null, null, null, null));
+ menhirTiles.add(new Tile(2, Tile.Kind.MENHIR, null, null, null, null));
+
+ TileDecks tileDecks = new TileDecks(startTiles, normalTiles, menhirTiles);
+
+ assertEquals(startTiles.getFirst().id(), tileDecks.topTile(Tile.Kind.START).id());
+ assertEquals(normalTiles.getFirst().id(), tileDecks.topTile(Tile.Kind.NORMAL).id());
+ assertEquals(menhirTiles.getFirst().id(), tileDecks.topTile(Tile.Kind.MENHIR).id());
+ }
+
+ @Test
+ void withTopTileDrawnThrowsOnEmptyDeck(){
+ List startTiles = new ArrayList<>(1);
+ List normalTiles = new ArrayList<>(1);
+ List menhirTiles = new ArrayList<>(1);
+
+ TileDecks tileDecks = new TileDecks(startTiles, normalTiles, menhirTiles);
+
+ assertThrows(IllegalArgumentException.class, () -> tileDecks.withTopTileDrawn(Tile.Kind.START));
+ assertThrows(IllegalArgumentException.class, () -> tileDecks.withTopTileDrawn(Tile.Kind.NORMAL));
+ assertThrows(IllegalArgumentException.class, () -> tileDecks.withTopTileDrawn(Tile.Kind.MENHIR));
+ }
+
+ @Test
+ void withTopTileWorks(){
+ List startTiles1 = new ArrayList<>(1);
+ List normalTiles1 = new ArrayList<>(1);
+ List menhirTiles1 = new ArrayList<>(1);
+
+ List startTiles2 = new ArrayList<>(1);
+ List normalTiles2 = new ArrayList<>(1);
+ List menhirTiles2 = new ArrayList<>(1);
+
+ startTiles1.add(new Tile(0, Tile.Kind.START, null, null, null, null));
+ normalTiles1.add(new Tile(1, Tile.Kind.NORMAL, null, null, null, null));
+ menhirTiles1.add(new Tile(2, Tile.Kind.MENHIR, null, null, null, null));
+
+ TileDecks tileDecks1 = new TileDecks(startTiles1, normalTiles1, menhirTiles1);
+ TileDecks tileDecks2 = new TileDecks(startTiles2, normalTiles2, menhirTiles2);
+
+ assertEquals(tileDecks2.deckSize(Tile.Kind.START), tileDecks1.withTopTileDrawn(Tile.Kind.START)
+ .deckSize(Tile.Kind.START));
+ assertEquals(tileDecks2.deckSize(Tile.Kind.NORMAL), tileDecks1.withTopTileDrawn(Tile.Kind.NORMAL)
+ .deckSize(Tile.Kind.NORMAL));
+ assertEquals(tileDecks2.deckSize(Tile.Kind.MENHIR), tileDecks1.withTopTileDrawn(Tile.Kind.MENHIR)
+ .deckSize(Tile.Kind.MENHIR));
+ }
+}
diff --git a/test/ch/epfl/chacun/TileSideTest.java b/test/ch/epfl/chacun/TileSideTest.java
new file mode 100644
index 0000000..76a9c07
--- /dev/null
+++ b/test/ch/epfl/chacun/TileSideTest.java
@@ -0,0 +1,87 @@
+package ch.epfl.chacun;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class TileSideTest {
+
+ @Test
+ void isSameKindDoesntWorkForDifferentKinds() {
+ Zone.Forest forest = new Zone.Forest(0, Zone.Forest.Kind.PLAIN);
+ Zone.Meadow meadow = new Zone.Meadow(0, new ArrayList<>(), null);
+
+ TileSide.Forest forestSide = new TileSide.Forest(forest);
+ TileSide.Meadow meadowSide = new TileSide.Meadow(meadow);
+
+ assertFalse(forestSide.isSameKindAs(meadowSide));
+ }
+
+ @Test
+ void isSameKindWorksForForest() {
+ Zone.Forest forest1 = new Zone.Forest(0, Zone.Forest.Kind.PLAIN);
+ Zone.Forest forest2 = new Zone.Forest(1, Zone.Forest.Kind.WITH_MENHIR);
+
+ TileSide.Forest forestSide1 = new TileSide.Forest(forest1);
+ TileSide.Forest forestSide2 = new TileSide.Forest(forest2);
+
+ assertTrue(forestSide1.isSameKindAs(forestSide2));
+ }
+
+ @Test
+ void isSameKindWorksForMeadow() {
+ Zone.Meadow meadow1 = new Zone.Meadow(0, new ArrayList<>(), null);
+ Zone.Meadow meadow2 = new Zone.Meadow(1, new ArrayList<>(), null);
+
+ TileSide.Meadow meadowSide1 = new TileSide.Meadow(meadow1);
+ TileSide.Meadow meadowSide2 = new TileSide.Meadow(meadow2);
+
+ assertTrue(meadowSide1.isSameKindAs(meadowSide2));
+ }
+
+ @Test
+ void isSameKindWorksForRiver() {
+ Zone.Meadow meadow1 = new Zone.Meadow(0, new ArrayList<>(), null);
+ Zone.River river1 = new Zone.River(0, 9, null);
+ Zone.River river2 = new Zone.River(0, 6, null);
+ Zone.Meadow meadow2 = new Zone.Meadow(0, new ArrayList<>(), null);
+
+ TileSide.River riverSide1 = new TileSide.River(meadow1, river1, meadow2);
+ TileSide.River riverSide2 = new TileSide.River(meadow2, river2, meadow1);
+
+ assertTrue(riverSide1.isSameKindAs(riverSide2));
+ }
+
+ @Test
+ void zonesWorksForForest() {
+ Zone.Forest forest = new Zone.Forest(0, Zone.Forest.Kind.PLAIN);
+ TileSide.Forest forestSide = new TileSide.Forest(forest);
+ List expectedZones = List.of(forest);
+
+ assertEquals(expectedZones, forestSide.zones());
+ }
+
+ @Test
+ void zonesWorksForMeadows() {
+ Zone.Meadow meadow1 = new Zone.Meadow(0, new ArrayList<>(), null);
+ TileSide.Meadow meadowSide = new TileSide.Meadow(meadow1);
+ List expectedZones = List.of(meadow1);
+
+ assertEquals(expectedZones, meadowSide.zones());
+ }
+ @Test
+ void zonesWorksForRiver() {
+ Zone.Meadow meadow1 = new Zone.Meadow(0, new ArrayList<>(), null);
+ Zone.River river = new Zone.River(1, 9, null);
+ Zone.Meadow meadow2 = new Zone.Meadow(2, new ArrayList<>(), null);
+
+ List expectedZones = List.of(meadow1, river, meadow2);
+ TileSide.River riverSide = new TileSide.River(meadow1, river, meadow2);
+
+ assertEquals(expectedZones, riverSide.zones());
+ }
+}
diff --git a/test/ch/epfl/chacun/TileTest.java b/test/ch/epfl/chacun/TileTest.java
new file mode 100644
index 0000000..7ce9d45
--- /dev/null
+++ b/test/ch/epfl/chacun/TileTest.java
@@ -0,0 +1,65 @@
+package ch.epfl.chacun;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+
+public class TileTest {
+
+ @Test
+ void sidesWorksWithAllSidesProvided() {
+ Zone.Forest forest = new Zone.Forest(1, Zone.Forest.Kind.PLAIN);
+ Zone.Meadow meadow1 = new Zone.Meadow(2, new ArrayList<>(), null);
+ Zone.River river1 = new Zone.River(3, 9, null);
+ Zone.Meadow meadow2 = new Zone.Meadow(4, new ArrayList<>(), null);
+
+ TileSide.Forest forestSide = new TileSide.Forest(forest);
+ TileSide.Meadow meadowSide1 = new TileSide.Meadow(meadow1);
+ TileSide.River riverSide = new TileSide.River(meadow1, river1, meadow2);
+ TileSide.Meadow meadowSide2 = new TileSide.Meadow(meadow2);
+ Tile tile = new Tile(0, null, forestSide, meadowSide1, riverSide, meadowSide2);
+
+ List expectedSides = List.of(forestSide, meadowSide1, riverSide, meadowSide2);
+ assertEquals(expectedSides, tile.sides());
+ }
+
+ @Test
+ void sideZonesWorksWithRiverAndOtherZones() {
+ Zone.Forest forest = new Zone.Forest(1, Zone.Forest.Kind.PLAIN);
+ Zone.Meadow meadow1 = new Zone.Meadow(2, new ArrayList<>(), null);
+ Zone.River river1 = new Zone.River(3, 9, null);
+ Zone.Meadow meadow2 = new Zone.Meadow(4, new ArrayList<>(), null);
+
+ TileSide.Forest forestSide = new TileSide.Forest(forest);
+ TileSide.Meadow meadowSide1 = new TileSide.Meadow(meadow1);
+ TileSide.River riverSide = new TileSide.River(meadow1, river1, meadow2);
+ TileSide.Meadow meadowSide2 = new TileSide.Meadow(meadow2);
+ Tile tile = new Tile(0, null, forestSide, meadowSide1, riverSide, meadowSide2);
+
+ Set expectedSideZones = Set.of(forest, meadow1, river1, meadow2);
+ assertEquals(expectedSideZones, tile.sideZones());
+ }
+
+ @Test
+ void zonesWorksWithLake() {
+ Zone.Forest forest = new Zone.Forest(1, Zone.Forest.Kind.PLAIN);
+ Zone.Meadow meadow1 = new Zone.Meadow(2, new ArrayList<>(), null);
+ Zone.Lake lake = new Zone.Lake(3, 9, null);
+ Zone.River river1 = new Zone.River(3, 9, lake);
+ Zone.Meadow meadow2 = new Zone.Meadow(4, new ArrayList<>(), null);
+
+ TileSide.Forest forestSide = new TileSide.Forest(forest);
+ TileSide.Meadow meadowSide1 = new TileSide.Meadow(meadow1);
+ TileSide.River riverSideWithLake = new TileSide.River(meadow1, river1, meadow2);
+ TileSide.Meadow meadowSide2 = new TileSide.Meadow(meadow2);
+ Tile tile = new Tile(0, null, forestSide, meadowSide1, riverSideWithLake, meadowSide2);
+
+ Set expectedZones = Set.of(forest, meadow1, river1, lake, meadow2);
+ assertEquals(expectedZones, tile.zones());
+ }
+
+}