| 1 | package com.takenoko.layers.tile; | |
| 2 | ||
| 3 | import com.takenoko.engine.Board; | |
| 4 | import com.takenoko.layers.bamboo.LayerBambooStack; | |
| 5 | import com.takenoko.vector.PositionVector; | |
| 6 | import com.takenoko.vector.Vector; | |
| 7 | import java.util.*; | |
| 8 | ||
| 9 | /** The TileLayer class is used to manage the tiles on the board. */ | |
| 10 | public class TileLayer { | |
| 11 | final HashMap<PositionVector, Tile> tiles; | |
| 12 | final HashSet<PositionVector> availableTilePositions; | |
| 13 | ||
| 14 | /** Create a new TileLayer. */ | |
| 15 | public TileLayer() { | |
| 16 | tiles = new HashMap<>(); | |
| 17 | availableTilePositions = new HashSet<>(); | |
| 18 | availableTilePositions.add(new PositionVector(0, 0, 0)); | |
| 19 | tiles.put(new PositionVector(0, 0, 0), new Pond()); | |
| 20 |
1
1. <init> : removed call to com/takenoko/layers/tile/TileLayer::updateAvailableTilePositions → KILLED |
updateAvailableTilePositions(new PositionVector(0, 0, 0)); |
| 21 | } | |
| 22 | ||
| 23 | public TileLayer(TileLayer tileLayer) { | |
| 24 | tiles = | |
| 25 | tileLayer.tiles.keySet().stream() | |
| 26 | .collect( | |
| 27 | HashMap::new, | |
| 28 | (m, k) -> m.put(k.copy(), tileLayer.tiles.get(k).copy()), | |
| 29 | HashMap::putAll); | |
| 30 | availableTilePositions = | |
| 31 | tileLayer.availableTilePositions.stream() | |
| 32 | .map(PositionVector::copy) | |
| 33 | .collect(HashSet::new, HashSet::add, HashSet::addAll); | |
| 34 | } | |
| 35 | ||
| 36 | /** | |
| 37 | * Place a tile on the board. and update the available tiles and the available tile positions. | |
| 38 | * | |
| 39 | * @param tile the tile to add to the board | |
| 40 | * @param position the position of the tile | |
| 41 | * @param board the board | |
| 42 | * @return the LayerBambooStack at the position of the tile | |
| 43 | */ | |
| 44 | public LayerBambooStack placeTile(Tile tile, PositionVector position, Board board) { | |
| 45 |
1
1. placeTile : negated conditional → KILLED |
if (tiles.containsKey(position)) { |
| 46 | throw new IllegalArgumentException("Tile already present at this position"); | |
| 47 | } | |
| 48 |
1
1. placeTile : negated conditional → KILLED |
if (!availableTilePositions.contains(position)) { |
| 49 | throw new IllegalArgumentException("Tile position not available"); | |
| 50 | } | |
| 51 | tiles.put(position, tile); | |
| 52 |
1
1. placeTile : removed call to com/takenoko/engine/Board::chooseTileInTileDeck → KILLED |
board.chooseTileInTileDeck(tile); |
| 53 |
1
1. placeTile : removed call to com/takenoko/layers/tile/TileLayer::updateAvailableTilePositions → KILLED |
updateAvailableTilePositions(position); |
| 54 |
1
1. placeTile : removed call to com/takenoko/engine/Board::updateAvailableIrrigationChannelPositions → KILLED |
board.updateAvailableIrrigationChannelPositions(position); |
| 55 |
1
1. placeTile : replaced return value with null for com/takenoko/layers/tile/TileLayer::placeTile → KILLED |
return board.getBambooAt(position); |
| 56 | } | |
| 57 | ||
| 58 | /** | |
| 59 | * Update the available tile positions after placing a tile. | |
| 60 | * | |
| 61 | * @param position the position of the tile to remove | |
| 62 | */ | |
| 63 | private void updateAvailableTilePositions(PositionVector position) { | |
| 64 | availableTilePositions.remove(position); | |
| 65 | for (Vector neighbor : position.getNeighbors()) { | |
| 66 |
1
1. updateAvailableTilePositions : negated conditional → KILLED |
if (isPositionAvailable(neighbor.toPositionVector())) { |
| 67 | availableTilePositions.add(neighbor.toPositionVector()); | |
| 68 | } | |
| 69 | } | |
| 70 | } | |
| 71 | ||
| 72 | /** | |
| 73 | * Check if a position is available. A position is available if: - it is not already occupied by | |
| 74 | * a tile - it has at least 2 neighbors or 1 neighbor is a pond | |
| 75 | * | |
| 76 | * @param position the position to check | |
| 77 | */ | |
| 78 | private boolean isPositionAvailable(PositionVector position) { | |
| 79 |
1
1. isPositionAvailable : negated conditional → KILLED |
if (isTile(position)) { |
| 80 |
1
1. isPositionAvailable : replaced boolean return with true for com/takenoko/layers/tile/TileLayer::isPositionAvailable → KILLED |
return false; |
| 81 | } | |
| 82 | int nbNeighbors = 0; | |
| 83 | for (Vector neighbor : position.getNeighbors()) { | |
| 84 | ||
| 85 |
1
1. isPositionAvailable : negated conditional → KILLED |
if (isTile(neighbor.toPositionVector())) { |
| 86 |
1
1. isPositionAvailable : negated conditional → KILLED |
if (tiles.get(neighbor.toPositionVector()).getType() == TileType.POND) { |
| 87 |
1
1. isPositionAvailable : replaced boolean return with false for com/takenoko/layers/tile/TileLayer::isPositionAvailable → KILLED |
return true; |
| 88 | } | |
| 89 |
1
1. isPositionAvailable : Changed increment from 1 to -1 → KILLED |
nbNeighbors++; |
| 90 | } | |
| 91 | } | |
| 92 |
3
1. isPositionAvailable : changed conditional boundary → KILLED 2. isPositionAvailable : negated conditional → KILLED 3. isPositionAvailable : replaced boolean return with true for com/takenoko/layers/tile/TileLayer::isPositionAvailable → KILLED |
return nbNeighbors >= 2; |
| 93 | } | |
| 94 | ||
| 95 | /** | |
| 96 | * Get the tiles on the board. | |
| 97 | * | |
| 98 | * @return the tiles on the board | |
| 99 | */ | |
| 100 | public Map<PositionVector, Tile> getTiles() { | |
| 101 |
1
1. getTiles : replaced return value with Collections.emptyMap for com/takenoko/layers/tile/TileLayer::getTiles → KILLED |
return tiles; |
| 102 | } | |
| 103 | ||
| 104 | /** | |
| 105 | * Get the available tiles. | |
| 106 | * | |
| 107 | * @return the available tiles | |
| 108 | */ | |
| 109 | public List<PositionVector> getAvailableTilePositions() { | |
| 110 |
1
1. getAvailableTilePositions : replaced return value with Collections.emptyList for com/takenoko/layers/tile/TileLayer::getAvailableTilePositions → KILLED |
return availableTilePositions.stream().toList(); |
| 111 | } | |
| 112 | ||
| 113 | /** | |
| 114 | * Get the available tiles. | |
| 115 | * | |
| 116 | * @return the list of available tiles | |
| 117 | */ | |
| 118 | public List<Tile> getAvailableTiles() { | |
| 119 | // This list only contains one new tile for now | |
| 120 | // It will then be used when we have a specific number of tiles | |
| 121 | List<Tile> availableTiles = new ArrayList<>(); | |
| 122 | availableTiles.add(new Tile()); | |
| 123 |
1
1. getAvailableTiles : replaced return value with Collections.emptyList for com/takenoko/layers/tile/TileLayer::getAvailableTiles → KILLED |
return availableTiles; |
| 124 | } | |
| 125 | ||
| 126 | /** | |
| 127 | * Get the positions where an improvement can be placed. | |
| 128 | * | |
| 129 | * @return the positions where an improvement can be placed | |
| 130 | */ | |
| 131 | public List<PositionVector> getAvailableImprovementPositions(Board board) { | |
| 132 |
1
1. getAvailableImprovementPositions : replaced return value with Collections.emptyList for com/takenoko/layers/tile/TileLayer::getAvailableImprovementPositions → KILLED |
return board.getTiles().keySet().stream() |
| 133 |
2
1. lambda$getAvailableImprovementPositions$1 : negated conditional → KILLED 2. lambda$getAvailableImprovementPositions$1 : replaced boolean return with true for com/takenoko/layers/tile/TileLayer::lambda$getAvailableImprovementPositions$1 → KILLED |
.filter(position -> board.getTileAt(position).getType() != TileType.POND) |
| 134 |
2
1. lambda$getAvailableImprovementPositions$2 : replaced boolean return with false for com/takenoko/layers/tile/TileLayer::lambda$getAvailableImprovementPositions$2 → KILLED 2. lambda$getAvailableImprovementPositions$2 : replaced boolean return with true for com/takenoko/layers/tile/TileLayer::lambda$getAvailableImprovementPositions$2 → KILLED |
.filter(position -> board.getTileAt(position).getImprovement().isEmpty()) |
| 135 |
2
1. lambda$getAvailableImprovementPositions$3 : replaced boolean return with false for com/takenoko/layers/tile/TileLayer::lambda$getAvailableImprovementPositions$3 → KILLED 2. lambda$getAvailableImprovementPositions$3 : replaced boolean return with true for com/takenoko/layers/tile/TileLayer::lambda$getAvailableImprovementPositions$3 → KILLED |
.filter(position -> (board.getBambooAt(position)).isEmpty()) |
| 136 | .toList(); | |
| 137 | } | |
| 138 | ||
| 139 | /** | |
| 140 | * Get the tile placed on the board but without the pond. | |
| 141 | * | |
| 142 | * @return the tile placed on the board but without the pond. | |
| 143 | */ | |
| 144 | public Map<PositionVector, Tile> getTilesWithoutPond() { | |
| 145 | Map<PositionVector, Tile> filteredMap = new HashMap<>(tiles); | |
| 146 | filteredMap.remove(new PositionVector(0, 0, 0)); | |
| 147 |
1
1. getTilesWithoutPond : replaced return value with Collections.emptyMap for com/takenoko/layers/tile/TileLayer::getTilesWithoutPond → KILLED |
return filteredMap; |
| 148 | } | |
| 149 | ||
| 150 | /** | |
| 151 | * Check if there is a tile at the given position. | |
| 152 | * | |
| 153 | * @param position the position of the tile | |
| 154 | * @return if there is a tile at the position | |
| 155 | */ | |
| 156 | public boolean isTile(PositionVector position) { | |
| 157 |
2
1. isTile : replaced boolean return with false for com/takenoko/layers/tile/TileLayer::isTile → KILLED 2. isTile : replaced boolean return with true for com/takenoko/layers/tile/TileLayer::isTile → KILLED |
return getTiles().containsKey(position); |
| 158 | } | |
| 159 | ||
| 160 | /** | |
| 161 | * Return the tile at the given position. | |
| 162 | * | |
| 163 | * @param positionVector the position of the tile | |
| 164 | * @return the tile at the given position | |
| 165 | */ | |
| 166 | public Tile getTileAt(PositionVector positionVector) { | |
| 167 |
1
1. getTileAt : negated conditional → KILLED |
if (!isTile(positionVector)) { |
| 168 | throw new IllegalArgumentException("No tile at this position"); | |
| 169 | } | |
| 170 |
1
1. getTileAt : replaced return value with null for com/takenoko/layers/tile/TileLayer::getTileAt → KILLED |
return tiles.get(positionVector); |
| 171 | } | |
| 172 | ||
| 173 | public TileLayer copy() { | |
| 174 |
1
1. copy : replaced return value with null for com/takenoko/layers/tile/TileLayer::copy → KILLED |
return new TileLayer(this); |
| 175 | } | |
| 176 | ||
| 177 | @Override | |
| 178 | public boolean equals(Object o) { | |
| 179 |
2
1. equals : negated conditional → KILLED 2. equals : replaced boolean return with false for com/takenoko/layers/tile/TileLayer::equals → KILLED |
if (this == o) return true; |
| 180 |
3
1. equals : negated conditional → KILLED 2. equals : negated conditional → KILLED 3. equals : replaced boolean return with true for com/takenoko/layers/tile/TileLayer::equals → KILLED |
if (o == null || getClass() != o.getClass()) return false; |
| 181 | TileLayer tileLayer = (TileLayer) o; | |
| 182 |
2
1. equals : negated conditional → KILLED 2. equals : replaced boolean return with true for com/takenoko/layers/tile/TileLayer::equals → KILLED |
return getTiles().equals(tileLayer.getTiles()) |
| 183 |
1
1. equals : negated conditional → KILLED |
&& getAvailableTilePositions().equals(tileLayer.getAvailableTilePositions()); |
| 184 | } | |
| 185 | ||
| 186 | @Override | |
| 187 | public int hashCode() { | |
| 188 |
1
1. hashCode : replaced int return with 0 for com/takenoko/layers/tile/TileLayer::hashCode → KILLED |
return Objects.hash(getTiles(), getAvailableTilePositions()); |
| 189 | } | |
| 190 | ||
| 191 | public void applyImprovement( | |
| 192 | ImprovementType improvementType, PositionVector positionVector, Board board) { | |
| 193 |
1
1. applyImprovement : negated conditional → KILLED |
if (!board.getAvailableImprovementPositions().contains(positionVector)) { |
| 194 | throw new IllegalStateException("Tile not available for improvement"); | |
| 195 | } | |
| 196 | Tile tile = board.getTileAt(positionVector); | |
| 197 |
1
1. applyImprovement : removed call to com/takenoko/layers/tile/Tile::setImprovement → KILLED |
tile.setImprovement(improvementType); |
| 198 | } | |
| 199 | } | |
Mutations | ||
| 20 |
1.1 |
|
| 45 |
1.1 |
|
| 48 |
1.1 |
|
| 52 |
1.1 |
|
| 53 |
1.1 |
|
| 54 |
1.1 |
|
| 55 |
1.1 |
|
| 66 |
1.1 |
|
| 79 |
1.1 |
|
| 80 |
1.1 |
|
| 85 |
1.1 |
|
| 86 |
1.1 |
|
| 87 |
1.1 |
|
| 89 |
1.1 |
|
| 92 |
1.1 2.2 3.3 |
|
| 101 |
1.1 |
|
| 110 |
1.1 |
|
| 123 |
1.1 |
|
| 132 |
1.1 |
|
| 133 |
1.1 2.2 |
|
| 134 |
1.1 2.2 |
|
| 135 |
1.1 2.2 |
|
| 147 |
1.1 |
|
| 157 |
1.1 2.2 |
|
| 167 |
1.1 |
|
| 170 |
1.1 |
|
| 174 |
1.1 |
|
| 179 |
1.1 2.2 |
|
| 180 |
1.1 2.2 3.3 |
|
| 182 |
1.1 2.2 |
|
| 183 |
1.1 |
|
| 188 |
1.1 |
|
| 193 |
1.1 |
|
| 197 |
1.1 |