Skip to content

Commit

Permalink
Start optimizing code of previous steps
Browse files Browse the repository at this point in the history
  • Loading branch information
Mw3y committed May 6, 2024
1 parent 4f8460b commit 1ef9002
Show file tree
Hide file tree
Showing 13 changed files with 53 additions and 90 deletions.
4 changes: 2 additions & 2 deletions resources/board.css
Original file line number Diff line number Diff line change
Expand Up @@ -320,8 +320,8 @@
#pawn_531 { -fx-translate-x: 86; -fx-translate-y: 34 }
#pawn_532 { -fx-translate-x: 30; -fx-translate-y: 109 }
#marker_5320 { -fx-translate-x: 58; -fx-translate-y: 73 }
#pawn_540 { -fx-translate-x: 64; -fx-translate-y: 64 }
#pawn_541 { -fx-translate-x: 16; -fx-translate-y: 57 }
#pawn_540 { -fx-translate-x: 18; -fx-translate-y: 60 }
#pawn_541 { -fx-translate-x: 113; -fx-translate-y: 31 }
#hut_542 { -fx-translate-x: 85; -fx-translate-y: 39 }
#pawn_542 { -fx-translate-x: 61; -fx-translate-y: 96 }
#pawn_543 { -fx-translate-x: 99; -fx-translate-y: 111 }
Expand Down
2 changes: 1 addition & 1 deletion resources/message-board.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#message-board {
#message-board VBox {
-fx-padding: 5px;
-fx-spacing: 3px;
}
5 changes: 3 additions & 2 deletions src/ch/epfl/chacun/Area.java
Original file line number Diff line number Diff line change
Expand Up @@ -158,18 +158,19 @@ public Set<PlayerColor> majorityOccupants() {
* @return the new area resulting from the connection
*/
public Area<Z> connectTo(Area<Z> newArea) {
Set<Z> zones = new HashSet<>(this.zones);
List<PlayerColor> occupants = new ArrayList<>(this.occupants);
// Calculate the new number of open connections
// The new area will have 2 less open connections, as each area had at least one open connection
int openConnections = this.openConnections - 2;
// Merge the zones of both areas into one
// Add the new occupants to the current ones
if(!this.equals(newArea)) {
Set<Z> zones = new HashSet<>(this.zones);
zones.addAll(newArea.zones);
List<PlayerColor> occupants = new ArrayList<>(this.occupants);
occupants.addAll(newArea.occupants);
// In case both areas are not the same, we need to add the open connections of the new area
openConnections += newArea.openConnections;
return new Area<>(zones, occupants, openConnections);
}
// Create the new area
return new Area<>(zones, occupants, openConnections);
Expand Down
40 changes: 18 additions & 22 deletions src/ch/epfl/chacun/Board.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@
*/
public final class Board {

/**
* An empty board.
*/
public static final Board EMPTY = new Board(new PlacedTile[625], new int[0], ZonePartitions.EMPTY, Set.of());

/**
* The number of tiles that can be placed on one side of the board.
*/
Expand All @@ -29,6 +24,12 @@ public final class Board {
*/
private static final int SIZE = REACH * 2 + 1;

/**
* An empty board.
*/
public static final Board EMPTY =
new Board(new PlacedTile[SIZE * SIZE], new int[0], ZonePartitions.EMPTY, Set.of());

private final ZonePartitions zonePartitions;
private final PlacedTile[] placedTiles;
private final int[] tileIndices;
Expand Down Expand Up @@ -73,7 +74,7 @@ private boolean isPosWithinBoard(Pos pos) {
*/
public PlacedTile tileAt(Pos pos) {
int index = calculateRowMajorIndex(pos);
if (index < 0 || index >= placedTiles.length)
if (!isPosWithinBoard(pos))
return null;
return placedTiles[index];
}
Expand All @@ -98,10 +99,10 @@ public PlacedTile tileWithId(int tileId) {
* Returns the cancelled animals.
* <p>Cancelled animals can be, for example, deer eaten by smilodons.
*
* @return the set of cancelled animals
* @return a vue of the set of cancelled animals
*/
public Set<Animal> cancelledAnimals() {
// Defensive copy
// Defensive vue
return Collections.unmodifiableSet(cancelledAnimals);
}

Expand Down Expand Up @@ -298,7 +299,7 @@ public Set<Area<Zone.River>> riversClosedByLastTile() {
*/
public boolean canAddTile(PlacedTile tile) {
// Check if the tile cannot be placed on the board
if (!insertionPositions().contains(tile.pos()) || tileAt(tile.pos()) != null)
if (!insertionPositions().contains(tile.pos()))
return false;
// Check for potential conflicts with adjacent tiles
for (Direction direction : Direction.ALL) {
Expand Down Expand Up @@ -360,7 +361,7 @@ public Board withNewTile(PlacedTile tile) {
}
}
// Create a new board with the new tile
return new Board(newPlacedTiles, newTileIndices, builder.build(), cancelledAnimals());
return new Board(newPlacedTiles, newTileIndices, builder.build(), cancelledAnimals);
}

/**
Expand All @@ -372,7 +373,6 @@ public Board withNewTile(PlacedTile tile) {
*/
public Board withOccupant(Occupant occupant) {
PlacedTile placedTile = tileWithId(Zone.tileId(occupant.zoneId()));
Preconditions.checkArgument(placedTile.occupant() == null);
// Create the updated zone partitions
ZonePartitions.Builder builder = new ZonePartitions.Builder(zonePartitions);
builder.addInitialOccupant(placedTile.placer(), occupant.kind(),
Expand All @@ -381,7 +381,7 @@ public Board withOccupant(Occupant occupant) {
PlacedTile[] newPlacedTiles = placedTiles.clone();
newPlacedTiles[calculateRowMajorIndex(placedTile.pos())] = placedTile.withOccupant(occupant);
// Create the new Board instance
return new Board(newPlacedTiles, tileIndices.clone(), builder.build(), cancelledAnimals());
return new Board(newPlacedTiles, tileIndices, builder.build(), cancelledAnimals);
}

/**
Expand All @@ -402,7 +402,7 @@ public Board withoutOccupant(Occupant occupant) {
ZonePartitions.Builder builder = new ZonePartitions.Builder(zonePartitions);
builder.removePawn(placedTile.placer(), zone);
// Create the new Board instance
return new Board(newPlacedTiles, tileIndices.clone(), builder.build(), cancelledAnimals());
return new Board(newPlacedTiles, tileIndices, builder.build(), cancelledAnimals);
}

/**
Expand Down Expand Up @@ -448,20 +448,16 @@ public Board withoutGatherersOrFishersIn(Set<Area<Zone.Forest>> forests, Set<Are
public Board withMoreCancelledAnimals(Set<Animal> newlyCancelledAnimals) {
Set<Animal> newCancelledAnimals = new HashSet<>(cancelledAnimals);
newCancelledAnimals.addAll(newlyCancelledAnimals);
return new Board(placedTiles.clone(), tileIndices.clone(), zonePartitions, newCancelledAnimals);
return new Board(placedTiles, tileIndices, zonePartitions, newCancelledAnimals);
}

@Override
public boolean equals(Object obj) {
if (obj instanceof Board board) {
boolean isPlacedTilesEqual = Arrays.equals(placedTiles, board.placedTiles);
boolean isTileIndicesEqual = Arrays.equals(tileIndices, board.tileIndices);
boolean areCancelledAnimalsEqual =
Arrays.equals(cancelledAnimals.toArray(), board.cancelledAnimals.toArray());
boolean areZonePartitionsEqual = zonePartitions.equals(board.zonePartitions);

return isPlacedTilesEqual && isTileIndicesEqual
&& areCancelledAnimalsEqual && areZonePartitionsEqual;
return Arrays.equals(placedTiles, board.placedTiles)
&& Arrays.equals(tileIndices, board.tileIndices)
&& Arrays.equals(cancelledAnimals.toArray(), board.cancelledAnimals.toArray())
&& zonePartitions.equals(board.zonePartitions);
}
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion src/ch/epfl/chacun/Direction.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,6 @@ public Direction rotated(Rotation rotation) {
*/
public Direction opposite() {
// There is only four directions, so we can just add 2 to the ordinal
return ALL.get((ordinal() + 2) % COUNT);
return rotated(Rotation.HALF_TURN);
}
}
58 changes: 13 additions & 45 deletions src/ch/epfl/chacun/GameState.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,36 +18,6 @@
public record GameState(List<PlayerColor> players, TileDecks tileDecks, Tile tileToPlace, Board board,
Action nextAction, MessageBoard messageBoard) {

/**
* The id of the tile containing the shaman
*/
private static final int SHAMAN_TILE_ID = 88;

/**
* The id of the tile containing the hunting trap
*/
private static final int HUNTING_TRAP_TILE_ID = 94;

/**
* The id of the tile containing the log boat
*/
private static final int LOGBOAT_TILE_ID = 93;

/**
* The id of the tile containing the wildfire
*/
private static final int WILD_FIRE_TILE_ID = 85;

/**
* The id of the tile containing the pit trap
*/
private static final int PIT_TRAP_TILE_ID = 92;

/**
* The id of the tile containing the raft
*/
private static final int RAFT_TILE_ID = 91;

/**
* Checks the validity of the arguments.
* <p>
Expand Down Expand Up @@ -174,11 +144,11 @@ public GameState withPlacedTile(PlacedTile placedTile) {
.withTurnFinishedIfOccupationImpossible();

// Handle the MENHIR tiles special traits
return switch (placedTile.tile().id()) {
return switch (placedTile.specialPowerZone().specialPower()) {
/*
The shaman tile allows the player to retake one of his pawns.
*/
case SHAMAN_TILE_ID -> {
case SHAMAN -> {
if (board.occupantCount(currentPlayer(), Occupant.Kind.PAWN) >= 1)
yield new GameState(players, tileDecks, null, boardWithTile,
Action.RETAKE_PAWN, messageBoard);
Expand All @@ -188,13 +158,11 @@ yield new GameState(players, tileDecks, null, boardWithTile,
The hunting trap tile allows the player to get the points corresponding
to the animals present in the adjacent meadow.
*/
case HUNTING_TRAP_TILE_ID -> {
case HUNTING_TRAP -> {
Area<Zone.Meadow> adjacentMeadows = boardWithTile.adjacentMeadow(placedTile.pos(),
(Zone.Meadow) placedTile.specialPowerZone());
// Determine deer to cancel in the adjacent meadows
Set<Animal> cancelledAnimals = computeCancelledAnimals(adjacentMeadows);
Board updatedBoard = boardWithTile
.withMoreCancelledAnimals(cancelledAnimals)
.withMoreCancelledAnimals(Area.animals(adjacentMeadows, Set.of()));
MessageBoard updatedMessageBoard = messageBoard
.withScoredHuntingTrap(currentPlayer(), adjacentMeadows);
Expand All @@ -203,9 +171,9 @@ yield new GameState(players, tileDecks, null, updatedBoard,
}
/*
The logboat tile allows the player to obtain points that depend on the number
of lakes in the hydrographic network containing it.
of lakes in the hydro²graphic network containing it.
*/
case LOGBOAT_TILE_ID -> {
case LOGBOAT -> {
Area<Zone.Water> area = boardWithTile.riverSystemArea((Zone.Water) placedTile.specialPowerZone());
MessageBoard updatedMessageBoard = messageBoard.withScoredLogboat(currentPlayer(), area);
yield new GameState(players, tileDecks, null, boardWithTile,
Expand Down Expand Up @@ -349,10 +317,11 @@ private GameState withFinalPointsCounted() {
MessageBoard updatedMessageBoard = messageBoard;
// Add all points scored with meadow areas
for (Area<Zone.Meadow> meadow : board.meadowAreas()) {
Zone pitTrapZone = meadow.zoneWithSpecialPower(Zone.SpecialPower.PIT_TRAP);
// Check that the meadow does not contain a wildfire
if (!meadow.tileIds().contains(WILD_FIRE_TILE_ID)) {
if (meadow.zoneWithSpecialPower(Zone.SpecialPower.WILD_FIRE) == null) {
// Check if the meadow contains a pit trap
if (meadow.tileIds().contains(PIT_TRAP_TILE_ID)) {
if (pitTrapZone != null) {
// Change the cancelled animals to optimize the points scored by the pit trap
updatedBoard = updatedBoard
.withMoreCancelledAnimals(computeCancelledAnimalsWithPitTrap(meadow, updatedBoard));
Expand All @@ -362,11 +331,10 @@ private GameState withFinalPointsCounted() {
.withMoreCancelledAnimals(computeCancelledAnimals(meadow));
}
// Check if the meadow contains a pit trap
if (meadow.tileIds().contains(PIT_TRAP_TILE_ID)) {
if (pitTrapZone != null) {
// Determine the adjacent meadows of the pit trap
Area<Zone.Meadow> adjacentMeadow = updatedBoard
.adjacentMeadow(updatedBoard.tileWithId(PIT_TRAP_TILE_ID).pos(),
(Zone.Meadow) meadow.zoneWithSpecialPower(Zone.SpecialPower.PIT_TRAP));
Area<Zone.Meadow> adjacentMeadow = updatedBoard.adjacentMeadow(
board.tileWithId(pitTrapZone.tileId()).pos(), (Zone.Meadow) pitTrapZone);
// Attribute points scored by the pit trap
updatedMessageBoard = updatedMessageBoard
.withScoredPitTrap(adjacentMeadow, updatedBoard.cancelledAnimals());
Expand All @@ -376,7 +344,7 @@ private GameState withFinalPointsCounted() {

// Add all points scored with river systems
for (Area<Zone.Water> riverSystem : board.riverSystemAreas()) {
updatedMessageBoard = riverSystem.tileIds().contains(RAFT_TILE_ID)
updatedMessageBoard = riverSystem.zoneWithSpecialPower(Zone.SpecialPower.RAFT) != null
? updatedMessageBoard.withScoredRaft(riverSystem).withScoredRiverSystem(riverSystem)
: updatedMessageBoard.withScoredRiverSystem(riverSystem);
}
Expand Down Expand Up @@ -443,7 +411,7 @@ private Set<Animal> computeCancelledAnimals(Area<Zone.Meadow> meadowArea) {
* @return the set of cancelled animals
*/
private Set<Animal> computeCancelledAnimalsWithPitTrap(Area<Zone.Meadow> meadow, Board board) {
PlacedTile pitTrapTile = board.tileWithId(PIT_TRAP_TILE_ID);
PlacedTile pitTrapTile = board.tileWithId(meadow.zoneWithSpecialPower(Zone.SpecialPower.PIT_TRAP).tileId());
// The area containing the adjacent meadows
Area<Zone.Meadow> adjacentMeadowArea = board.adjacentMeadow(pitTrapTile.pos(),
(Zone.Meadow) pitTrapTile.specialPowerZone());
Expand Down
2 changes: 1 addition & 1 deletion src/ch/epfl/chacun/PlayerColor.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ public enum PlayerColor {
/**
* All possible colors of a player
*/
public static final List<PlayerColor> ALL = List.of(PlayerColor.values());
public static final List<PlayerColor> ALL = List.of(values());

}
2 changes: 1 addition & 1 deletion src/ch/epfl/chacun/TileDecks.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public TileDecks withTopTileDrawnUntil(Tile.Kind kind, Predicate<Tile> predicate
* @return a new deck of tiles after removing the tiles that does not respect the given predicate
*/
private List<Tile> filterDeck(List<Tile> deck, Predicate<Tile> predicate) {
List<Tile> filteredDeck = List.copyOf(deck);
List<Tile> filteredDeck = deck;
while (!filteredDeck.isEmpty() && !predicate.test(filteredDeck.getFirst())) {
filteredDeck = removeDeckFirstTile(filteredDeck);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package ch.epfl.chacun.tile;
package ch.epfl.chacun;

import ch.epfl.chacun.Animal;
import ch.epfl.chacun.Direction;
import ch.epfl.chacun.Tile;
import ch.epfl.chacun.TileSide;
import ch.epfl.chacun.Zone;

import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public final class Tiles {
private Tiles() {}

public static final List<Tile> TILES = createTiles();

private static List<Tile> createTiles() {
Expand Down Expand Up @@ -367,7 +370,7 @@ private static List<Tile> createTiles() {
{ // Tile 24
var l1 = new Zone.Lake(24_8, 1, null);
var z0 = new Zone.Meadow(24_0, List.of(), null);
var z1 = new Zone.River(24_1, 0, null);
var z1 = new Zone.River(24_1, 0, l1);
var a2_0 = new Animal(24_2_0, Animal.Kind.AUROCHS);
var z2 = new Zone.Meadow(24_2, List.of(a2_0), null);
var z3 = new Zone.Forest(24_3, Zone.Forest.Kind.PLAIN);
Expand Down Expand Up @@ -432,7 +435,7 @@ private static List<Tile> createTiles() {
tiles.add(new Tile(28, Tile.Kind.NORMAL, sN, sE, sS, sW));
}
{ // Tile 29
var z0 = new Zone.Forest(29_0, Zone.Forest.Kind.PLAIN);
var z0 = new Zone.Forest(29_0, Zone.Forest.Kind.WITH_MENHIR);
var z1 = new Zone.Meadow(29_1, List.of(), null);
var z2 = new Zone.River(29_2, 0, null);
var z3 = new Zone.Meadow(29_3, List.of(), null);
Expand Down Expand Up @@ -619,13 +622,12 @@ private static List<Tile> createTiles() {
var z3 = new Zone.Forest(45_3, Zone.Forest.Kind.PLAIN);
var a4_0 = new Animal(45_4_0, Animal.Kind.DEER);
var z4 = new Zone.Meadow(45_4, List.of(a4_0), null);
var z5 = new Zone.River(45_5, 0, null);
var z6 = new Zone.Meadow(45_6, List.of(), null);
var z7 = new Zone.Forest(45_7, Zone.Forest.Kind.PLAIN);
var z5 = new Zone.Meadow(45_5, List.of(), null);
var z6 = new Zone.Forest(45_6, Zone.Forest.Kind.PLAIN);
var sN = new TileSide.River(z0, z1, z2);
var sE = new TileSide.Forest(z3);
var sS = new TileSide.River(z4, z5, z6);
var sW = new TileSide.Forest(z7);
var sS = new TileSide.River(z4, z1, z5);
var sW = new TileSide.Forest(z6);
assert tiles.size() == 45;
tiles.add(new Tile(45, Tile.Kind.NORMAL, sN, sE, sS, sW));
}
Expand Down
2 changes: 1 addition & 1 deletion src/ch/epfl/chacun/Zone.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ static int tileId(int zoneId) {
*/
static int localId(int zoneId) {
// zoneId = 10 * tileId + localId
return zoneId - 10 * tileId(zoneId);
return zoneId % 10;
}

/**
Expand Down
1 change: 0 additions & 1 deletion src/ch/epfl/chacun/gui/BoardUITest.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package ch.epfl.chacun.gui;

import ch.epfl.chacun.*;
import ch.epfl.chacun.tile.Tiles;
import javafx.application.Application;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.Scene;
Expand Down
1 change: 0 additions & 1 deletion src/ch/epfl/chacun/gui/ChaCuNUITest.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package ch.epfl.chacun.gui;

import ch.epfl.chacun.*;
import ch.epfl.chacun.tile.Tiles;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
Expand Down
2 changes: 0 additions & 2 deletions src/ch/epfl/chacun/gui/PlayersUITest.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package ch.epfl.chacun.gui;

import ch.epfl.chacun.*;
import ch.epfl.chacun.tile.Tiles;
import javafx.application.Application;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

Expand Down

0 comments on commit 1ef9002

Please sign in to comment.