| 1 | package com.takenoko.objective; | |
| 2 | ||
| 3 | import static java.lang.Math.abs; | |
| 4 | ||
| 5 | import com.takenoko.engine.Board; | |
| 6 | import com.takenoko.engine.BotState; | |
| 7 | import com.takenoko.layers.tile.ImprovementType; | |
| 8 | import com.takenoko.layers.tile.Tile; | |
| 9 | import com.takenoko.layers.tile.TileColor; | |
| 10 | import com.takenoko.vector.PositionVector; | |
| 11 | import java.util.*; | |
| 12 | ||
| 13 | /** | |
| 14 | * Class SingleGardenerObjective represents a single gardener objective. A single gardener objective | |
| 15 | * is composed of a size, a color and an improvement type. | |
| 16 | */ | |
| 17 | public class SingleGardenerObjective extends Objective { | |
| 18 | private final int targetSize; | |
| 19 | private final TileColor targetColor; | |
| 20 | ||
| 21 | private final ImprovementType targetImprovementType; | |
| 22 | ||
| 23 | public SingleGardenerObjective( | |
| 24 | int targetSize, | |
| 25 | TileColor targetColor, | |
| 26 | ImprovementType targetImprovementType, | |
| 27 | int points) { | |
| 28 | super(ObjectiveType.GARDENER, ObjectiveState.NOT_ACHIEVED, points); | |
| 29 | this.targetSize = targetSize; | |
| 30 | this.targetImprovementType = targetImprovementType; | |
| 31 | this.targetColor = targetColor; | |
| 32 | } | |
| 33 | ||
| 34 | public SingleGardenerObjective(int targetSize, TileColor targetColor, int points) { | |
| 35 | this(targetSize, targetColor, ImprovementType.NONE, points); | |
| 36 | } | |
| 37 | ||
| 38 | @Override | |
| 39 | public void verify(Board board, BotState botState) { | |
| 40 |
1
1. verify : negated conditional → KILLED |
if (!getMatchingPositions(board).isEmpty()) { |
| 41 | this.state = ObjectiveState.ACHIEVED; | |
| 42 | } | |
| 43 | } | |
| 44 | ||
| 45 | @Override | |
| 46 | public void reset() { | |
| 47 | this.state = ObjectiveState.NOT_ACHIEVED; | |
| 48 | } | |
| 49 | ||
| 50 | private boolean match(Board board, PositionVector positionVector, Tile tile) { | |
| 51 |
2
1. match : negated conditional → KILLED 2. match : replaced boolean return with true for com/takenoko/objective/SingleGardenerObjective::match → KILLED |
return board.getBambooAt(positionVector).getBambooCount() == targetSize |
| 52 |
1
1. match : negated conditional → KILLED |
&& isTileEligible(tile); |
| 53 | } | |
| 54 | ||
| 55 | private boolean isTileEligible(Tile tile) { | |
| 56 | /* | |
| 57 | * A tile is eligible if: | |
| 58 | * - It's color matches the target color, or is ANY | |
| 59 | * - It's improvement type matches the target improvement type, or is ANY | |
| 60 | */ | |
| 61 | Optional<ImprovementType> tileImprovement = tile.getImprovement(); | |
| 62 |
3
1. isTileEligible : negated conditional → KILLED 2. isTileEligible : negated conditional → KILLED 3. isTileEligible : replaced boolean return with true for com/takenoko/objective/SingleGardenerObjective::isTileEligible → KILLED |
return (tile.getColor() == targetColor || tile.getColor() == TileColor.ANY) |
| 63 |
2
1. isTileEligible : negated conditional → KILLED 2. isTileEligible : negated conditional → KILLED |
&& (tileImprovement.isPresent() && tileImprovement.get() == targetImprovementType |
| 64 |
1
1. isTileEligible : negated conditional → KILLED |
|| tileImprovement.isPresent() |
| 65 |
1
1. isTileEligible : negated conditional → KILLED |
&& tileImprovement.get() == ImprovementType.ANY); |
| 66 | } | |
| 67 | ||
| 68 | public List<PositionVector> getEligiblePositions(Board board) { | |
| 69 |
1
1. getEligiblePositions : replaced return value with Collections.emptyList for com/takenoko/objective/SingleGardenerObjective::getEligiblePositions → KILLED |
return board.getTiles().entrySet().stream() |
| 70 |
2
1. lambda$getEligiblePositions$0 : replaced boolean return with false for com/takenoko/objective/SingleGardenerObjective::lambda$getEligiblePositions$0 → KILLED 2. lambda$getEligiblePositions$0 : replaced boolean return with true for com/takenoko/objective/SingleGardenerObjective::lambda$getEligiblePositions$0 → KILLED |
.filter(v -> isTileEligible(v.getValue())) |
| 71 | .map(Map.Entry::getKey) | |
| 72 | .toList(); | |
| 73 | } | |
| 74 | ||
| 75 | public List<PositionVector> getMatchingPositions(Board board) { | |
| 76 |
1
1. getMatchingPositions : replaced return value with Collections.emptyList for com/takenoko/objective/SingleGardenerObjective::getMatchingPositions → KILLED |
return board.getTiles().entrySet().stream() |
| 77 |
2
1. lambda$getMatchingPositions$1 : replaced boolean return with false for com/takenoko/objective/SingleGardenerObjective::lambda$getMatchingPositions$1 → KILLED 2. lambda$getMatchingPositions$1 : replaced boolean return with true for com/takenoko/objective/SingleGardenerObjective::lambda$getMatchingPositions$1 → KILLED |
.filter(v -> match(board, v.getKey(), v.getValue())) |
| 78 | .map(Map.Entry::getKey) | |
| 79 | .toList(); | |
| 80 | } | |
| 81 | ||
| 82 | public SingleGardenerObjective copy() { | |
| 83 |
1
1. copy : replaced return value with null for com/takenoko/objective/SingleGardenerObjective::copy → KILLED |
return new SingleGardenerObjective( |
| 84 | targetSize, targetColor, targetImprovementType, getPoints()); | |
| 85 | } | |
| 86 | ||
| 87 | public List<PositionVector> getPositionsToComplete(Board board) { | |
| 88 | ArrayList<PositionVector> toDoActions = new ArrayList<>(); | |
| 89 | ||
| 90 | // PANDA Filter panda moves to only have the ones that are eligible and the moves | |
| 91 | List<PositionVector> pandaMoves = | |
| 92 | board.getPandaPossibleMoves().stream() | |
| 93 | .filter( | |
| 94 | p -> | |
| 95 |
2
1. lambda$getPositionsToComplete$2 : replaced boolean return with false for com/takenoko/objective/SingleGardenerObjective::lambda$getPositionsToComplete$2 → TIMED_OUT 2. lambda$getPositionsToComplete$2 : replaced boolean return with true for com/takenoko/objective/SingleGardenerObjective::lambda$getPositionsToComplete$2 → TIMED_OUT |
this.isTileEligible( |
| 96 | board.getTileAt( | |
| 97 | board.getPandaPosition() | |
| 98 | .add(p) | |
| 99 | .toPositionVector()))) | |
| 100 | .filter( | |
| 101 | p -> | |
| 102 |
2
1. lambda$getPositionsToComplete$3 : replaced boolean return with false for com/takenoko/objective/SingleGardenerObjective::lambda$getPositionsToComplete$3 → TIMED_OUT 2. lambda$getPositionsToComplete$3 : replaced boolean return with true for com/takenoko/objective/SingleGardenerObjective::lambda$getPositionsToComplete$3 → TIMED_OUT |
board.isBambooEatableAt( |
| 103 | board.getPandaPosition().add(p).toPositionVector())) | |
| 104 | .toList(); | |
| 105 | ||
| 106 | for (PositionVector pandaMove : pandaMoves) { | |
| 107 | if (board.getBambooAt(board.getPandaPosition().add(pandaMove).toPositionVector()) | |
| 108 |
2
1. getPositionsToComplete : Replaced integer addition with subtraction → TIMED_OUT 2. getPositionsToComplete : negated conditional → TIMED_OUT |
.getBambooCount() |
| 109 | + 1 | |
| 110 | == targetSize) { | |
| 111 | toDoActions.add(pandaMove); | |
| 112 | } | |
| 113 | } | |
| 114 | ||
| 115 | // GARDENER Filter the gardener moves to only have the ones that are eligible | |
| 116 | List<PositionVector> gardenerMoves = | |
| 117 | board.getGardenerPossibleMoves().stream() | |
| 118 | .filter( | |
| 119 | v -> | |
| 120 |
2
1. lambda$getPositionsToComplete$4 : replaced boolean return with false for com/takenoko/objective/SingleGardenerObjective::lambda$getPositionsToComplete$4 → TIMED_OUT 2. lambda$getPositionsToComplete$4 : replaced boolean return with true for com/takenoko/objective/SingleGardenerObjective::lambda$getPositionsToComplete$4 → TIMED_OUT |
isTileEligible( |
| 121 | board.getTileAt( | |
| 122 | board.getGardenerPosition() | |
| 123 | .add(v) | |
| 124 | .toPositionVector()))) | |
| 125 | .filter( | |
| 126 | p -> | |
| 127 |
2
1. lambda$getPositionsToComplete$5 : replaced boolean return with false for com/takenoko/objective/SingleGardenerObjective::lambda$getPositionsToComplete$5 → TIMED_OUT 2. lambda$getPositionsToComplete$5 : replaced boolean return with true for com/takenoko/objective/SingleGardenerObjective::lambda$getPositionsToComplete$5 → TIMED_OUT |
board.isBambooGrowableAt( |
| 128 | board.getPandaPosition().add(p).toPositionVector())) | |
| 129 | .toList(); | |
| 130 | ||
| 131 | for (PositionVector gardenerMove : gardenerMoves) { | |
| 132 | if (board.getBambooAt(board.getGardenerPosition().add(gardenerMove).toPositionVector()) | |
| 133 |
2
1. getPositionsToComplete : Replaced integer subtraction with addition → TIMED_OUT 2. getPositionsToComplete : negated conditional → TIMED_OUT |
.getBambooCount() |
| 134 | - 1 | |
| 135 | == targetSize) { | |
| 136 | toDoActions.add(gardenerMove); | |
| 137 | } | |
| 138 | } | |
| 139 | ||
| 140 |
1
1. getPositionsToComplete : replaced return value with Collections.emptyList for com/takenoko/objective/SingleGardenerObjective::getPositionsToComplete → TIMED_OUT |
return toDoActions; |
| 141 | } | |
| 142 | ||
| 143 | @Override | |
| 144 | public float getCompletion(Board board, BotState botState) { | |
| 145 |
1
1. getCompletion : replaced float return with 0.0f for com/takenoko/objective/SingleGardenerObjective::getCompletion → KILLED |
return getEligiblePositions(board).stream() |
| 146 |
1
1. lambda$getCompletion$6 : replaced int return with 0 for com/takenoko/objective/SingleGardenerObjective::lambda$getCompletion$6 → NO_COVERAGE |
.max(Comparator.comparingInt(v -> board.getBambooAt(v).getBambooCount())) |
| 147 |
1
1. lambda$getCompletion$7 : replaced Integer return value with 0 for com/takenoko/objective/SingleGardenerObjective::lambda$getCompletion$7 → KILLED |
.map(v -> board.getBambooAt(v).getBambooCount()) |
| 148 |
4
1. lambda$getCompletion$8 : Replaced float division with multiplication → SURVIVED 2. lambda$getCompletion$8 : Replaced integer subtraction with addition → KILLED 3. lambda$getCompletion$8 : Replaced float subtraction with addition → KILLED 4. lambda$getCompletion$8 : replaced Float return value with 0 for com/takenoko/objective/SingleGardenerObjective::lambda$getCompletion$8 → KILLED |
.map(integer -> 1 - ((float) abs(integer - targetSize) / targetSize)) |
| 149 | .orElse(0f); | |
| 150 | } | |
| 151 | ||
| 152 | @Override | |
| 153 | public boolean equals(Object o) { | |
| 154 |
2
1. equals : negated conditional → KILLED 2. equals : replaced boolean return with false for com/takenoko/objective/SingleGardenerObjective::equals → KILLED |
if (this == o) return true; |
| 155 |
3
1. equals : negated conditional → KILLED 2. equals : negated conditional → KILLED 3. equals : replaced boolean return with true for com/takenoko/objective/SingleGardenerObjective::equals → KILLED |
if (o == null || getClass() != o.getClass()) return false; |
| 156 | SingleGardenerObjective that = (SingleGardenerObjective) o; | |
| 157 |
4
1. equals : negated conditional → KILLED 2. equals : negated conditional → KILLED 3. equals : negated conditional → KILLED 4. equals : replaced boolean return with true for com/takenoko/objective/SingleGardenerObjective::equals → KILLED |
return targetSize == that.targetSize |
| 158 | && targetColor == that.targetColor | |
| 159 | && targetImprovementType == that.targetImprovementType; | |
| 160 | } | |
| 161 | ||
| 162 | @Override | |
| 163 | public int hashCode() { | |
| 164 |
1
1. hashCode : replaced int return with 0 for com/takenoko/objective/SingleGardenerObjective::hashCode → KILLED |
return Objects.hash(targetSize, targetColor, targetImprovementType); |
| 165 | } | |
| 166 | ||
| 167 | public int getTargetSize() { | |
| 168 |
1
1. getTargetSize : replaced int return with 0 for com/takenoko/objective/SingleGardenerObjective::getTargetSize → KILLED |
return targetSize; |
| 169 | } | |
| 170 | ||
| 171 | @Override | |
| 172 | public String toString() { | |
| 173 |
1
1. toString : replaced return value with "" for com/takenoko/objective/SingleGardenerObjective::toString → TIMED_OUT |
return "Single Gardener Objective <" |
| 174 | + targetColor | |
| 175 | + " bamboo, " | |
| 176 | + targetSize | |
| 177 | + " high, " | |
| 178 | + targetImprovementType | |
| 179 | + " improvement>"; | |
| 180 | } | |
| 181 | } | |
Mutations | ||
| 40 |
1.1 |
|
| 51 |
1.1 2.2 |
|
| 52 |
1.1 |
|
| 62 |
1.1 2.2 3.3 |
|
| 63 |
1.1 2.2 |
|
| 64 |
1.1 |
|
| 65 |
1.1 |
|
| 69 |
1.1 |
|
| 70 |
1.1 2.2 |
|
| 76 |
1.1 |
|
| 77 |
1.1 2.2 |
|
| 83 |
1.1 |
|
| 95 |
1.1 2.2 |
|
| 102 |
1.1 2.2 |
|
| 108 |
1.1 2.2 |
|
| 120 |
1.1 2.2 |
|
| 127 |
1.1 2.2 |
|
| 133 |
1.1 2.2 |
|
| 140 |
1.1 |
|
| 145 |
1.1 |
|
| 146 |
1.1 |
|
| 147 |
1.1 |
|
| 148 |
1.1 2.2 3.3 4.4 |
|
| 154 |
1.1 2.2 |
|
| 155 |
1.1 2.2 3.3 |
|
| 157 |
1.1 2.2 3.3 4.4 |
|
| 164 |
1.1 |
|
| 168 |
1.1 |
|
| 173 |
1.1 |