| 1 | package com.takenoko.asset; | |
| 2 | ||
| 3 | import com.takenoko.layers.tile.ImprovementType; | |
| 4 | import com.takenoko.layers.tile.TileColor; | |
| 5 | import com.takenoko.objective.*; | |
| 6 | import com.takenoko.shape.PatternFactory; | |
| 7 | import java.security.SecureRandom; | |
| 8 | import java.util.*; | |
| 9 | import java.util.stream.Collectors; | |
| 10 | import java.util.stream.Stream; | |
| 11 | ||
| 12 | /** The deck containing all the different objectives. */ | |
| 13 | public class ObjectiveDeck extends ArrayList<Objective> { | |
| 14 | private final Random random; | |
| 15 | private transient Objective lastDrawnObjective; | |
| 16 | ||
| 17 | public ObjectiveDeck() { | |
| 18 | this(new SecureRandom()); | |
| 19 | } | |
| 20 | ||
| 21 | public ObjectiveDeck(Random random) { | |
| 22 | this.random = random; | |
| 23 | lastDrawnObjective = null; | |
| 24 | // --- Panda objectives --- | |
| 25 |
2
1. <init> : changed conditional boundary → KILLED 2. <init> : negated conditional → KILLED |
for (int i = 0; i < 5; i++) { |
| 26 | add(new PandaObjective(Map.of(TileColor.GREEN, 2), 3)); // 2 GREEN | |
| 27 | } | |
| 28 |
2
1. <init> : changed conditional boundary → KILLED 2. <init> : negated conditional → KILLED |
for (int i = 0; i < 4; i++) { |
| 29 | add(new PandaObjective(Map.of(TileColor.YELLOW, 2), 4)); // 2 YELLOW | |
| 30 | } | |
| 31 | ||
| 32 |
2
1. <init> : changed conditional boundary → KILLED 2. <init> : negated conditional → KILLED |
for (int i = 0; i < 3; i++) { |
| 33 | add(new PandaObjective(Map.of(TileColor.PINK, 2), 5)); // 2 PINK | |
| 34 | } | |
| 35 | ||
| 36 |
2
1. <init> : changed conditional boundary → KILLED 2. <init> : negated conditional → KILLED |
for (int i = 0; i < 3; i++) { |
| 37 | add( | |
| 38 | new PandaObjective( | |
| 39 | Map.of( | |
| 40 | TileColor.GREEN, 1, | |
| 41 | TileColor.YELLOW, 1, | |
| 42 | TileColor.PINK, 1), | |
| 43 | 6)); // 1 GREEN, 1 YELLOW, 1 PINK | |
| 44 | } | |
| 45 | // --- Pattern objectives --- | |
| 46 | // LINE | |
| 47 | add(new PatternObjective(PatternFactory.LINE.createPattern(TileColor.GREEN), 2)); // GREEN | |
| 48 | add(new PatternObjective(PatternFactory.LINE.createPattern(TileColor.YELLOW), 3)); // YELLOW | |
| 49 | add(new PatternObjective(PatternFactory.LINE.createPattern(TileColor.PINK), 4)); // PINK | |
| 50 | // CURVED LINE | |
| 51 | add(new PatternObjective(PatternFactory.CURVE.createPattern(TileColor.GREEN), 2)); // GREEN | |
| 52 | add( | |
| 53 | new PatternObjective( | |
| 54 | PatternFactory.CURVE.createPattern(TileColor.YELLOW), 3)); // YELLOW | |
| 55 | add(new PatternObjective(PatternFactory.CURVE.createPattern(TileColor.PINK), 4)); // PINK | |
| 56 | // UNIFORM SQUARE | |
| 57 | add( | |
| 58 | new PatternObjective( | |
| 59 | PatternFactory.TRIANGLE.createPattern(TileColor.GREEN), 2)); // GREEN | |
| 60 | add( | |
| 61 | new PatternObjective( | |
| 62 | PatternFactory.TRIANGLE.createPattern(TileColor.YELLOW), 3)); // YELLOW | |
| 63 | add(new PatternObjective(PatternFactory.TRIANGLE.createPattern(TileColor.PINK), 4)); // PINK | |
| 64 | // UNIFORM RECTANGLE | |
| 65 | add( | |
| 66 | new PatternObjective( | |
| 67 | PatternFactory.DIAMOND.createPattern(TileColor.GREEN), 3)); // GREEN | |
| 68 | add( | |
| 69 | new PatternObjective( | |
| 70 | PatternFactory.DIAMOND.createPattern(TileColor.YELLOW), 4)); // YELLOW | |
| 71 | add(new PatternObjective(PatternFactory.DIAMOND.createPattern(TileColor.PINK), 5)); // PINK | |
| 72 | // MIXED COLORS | |
| 73 | add( | |
| 74 | new PatternObjective( | |
| 75 | PatternFactory.MIXED_COLORS_DIAMOND.createPattern(TileColor.YELLOW), | |
| 76 | 3)); // GREEN + YELLOW | |
| 77 | add( | |
| 78 | new PatternObjective( | |
| 79 | PatternFactory.MIXED_COLORS_DIAMOND.createPattern(TileColor.GREEN), | |
| 80 | 4)); // GREEN + PINK | |
| 81 | add( | |
| 82 | new PatternObjective( | |
| 83 | PatternFactory.MIXED_COLORS_DIAMOND.createPattern(TileColor.PINK), | |
| 84 | 5)); // PINK + YELLOW | |
| 85 | ||
| 86 | // --- Gardener objectives --- | |
| 87 | // WITHOUT IMPROVEMENT | |
| 88 | // SINGLE COLUMN | |
| 89 | add(new SingleGardenerObjective(4, TileColor.GREEN, 5)); // 4 GREEN | |
| 90 | add(new SingleGardenerObjective(4, TileColor.YELLOW, 6)); // 4 YELLOW | |
| 91 | add(new SingleGardenerObjective(4, TileColor.PINK, 7)); // 4 PINK | |
| 92 | ||
| 93 | // WITH IMPROVEMENT | |
| 94 | // GREEN | |
| 95 | add( | |
| 96 | new SingleGardenerObjective( | |
| 97 | 4, TileColor.GREEN, ImprovementType.ENCLOSURE, 4)); // 4 GREEN | |
| 98 | add( | |
| 99 | new SingleGardenerObjective( | |
| 100 | 4, TileColor.GREEN, ImprovementType.WATERSHED, 4)); // 4 GREEN | |
| 101 | add( | |
| 102 | new SingleGardenerObjective( | |
| 103 | 4, TileColor.GREEN, ImprovementType.FERTILIZER, 3)); // 4 GREEN | |
| 104 | // YELLOW | |
| 105 | add( | |
| 106 | new SingleGardenerObjective( | |
| 107 | 4, TileColor.YELLOW, ImprovementType.ENCLOSURE, 5)); // 4 YELLOW | |
| 108 | add( | |
| 109 | new SingleGardenerObjective( | |
| 110 | 4, TileColor.YELLOW, ImprovementType.WATERSHED, 5)); // 4 YELLOW | |
| 111 | add( | |
| 112 | new SingleGardenerObjective( | |
| 113 | 4, TileColor.YELLOW, ImprovementType.FERTILIZER, 4)); // 4 YELLOW | |
| 114 | // PINK | |
| 115 | add(new SingleGardenerObjective(4, TileColor.PINK, ImprovementType.ENCLOSURE, 6)); // 4 PINK | |
| 116 | add(new SingleGardenerObjective(4, TileColor.PINK, ImprovementType.WATERSHED, 6)); // 4 PINK | |
| 117 | add( | |
| 118 | new SingleGardenerObjective( | |
| 119 | 4, TileColor.PINK, ImprovementType.FERTILIZER, 5)); // 4 PINK | |
| 120 | ||
| 121 | // IMPROVEMENT AGNOSTIC | |
| 122 | // MULTIPLE COLUMNS | |
| 123 | add( | |
| 124 | new MultipleGardenerObjective( | |
| 125 | new SingleGardenerObjective(3, TileColor.PINK, 0), 2, 6)); // 3 PINK | |
| 126 | add( | |
| 127 | new MultipleGardenerObjective( | |
| 128 | new SingleGardenerObjective(3, TileColor.YELLOW, 0), 3, 7)); // 3 YELLOW | |
| 129 | add( | |
| 130 | new MultipleGardenerObjective( | |
| 131 | new SingleGardenerObjective(3, TileColor.GREEN, 0), 4, 8)); // 3 GREEN | |
| 132 | } | |
| 133 | ||
| 134 | public void draw(ObjectiveType objectiveType) { | |
| 135 |
1
1. draw : negated conditional → KILLED |
if (isEmpty()) { |
| 136 | throw new IllegalStateException("Cannot draw from an empty deck"); | |
| 137 | } | |
| 138 | ||
| 139 | List<Objective> pandaObjectives = | |
| 140 |
2
1. lambda$draw$0 : negated conditional → TIMED_OUT 2. lambda$draw$0 : replaced boolean return with true for com/takenoko/asset/ObjectiveDeck::lambda$draw$0 → TIMED_OUT |
this.stream().filter(o -> o.getType() == ObjectiveType.PANDA).toList(); |
| 141 | List<Objective> gardenerObjectives = | |
| 142 |
2
1. lambda$draw$1 : negated conditional → TIMED_OUT 2. lambda$draw$1 : replaced boolean return with true for com/takenoko/asset/ObjectiveDeck::lambda$draw$1 → TIMED_OUT |
this.stream().filter(o -> o.getType() == ObjectiveType.GARDENER).toList(); |
| 143 | List<Objective> shapeObjectives = | |
| 144 |
2
1. lambda$draw$2 : negated conditional → TIMED_OUT 2. lambda$draw$2 : replaced boolean return with true for com/takenoko/asset/ObjectiveDeck::lambda$draw$2 → TIMED_OUT |
this.stream().filter(o -> o.getType() == ObjectiveType.SHAPE).toList(); |
| 145 | ||
| 146 | switch (objectiveType) { | |
| 147 | case PANDA -> { | |
| 148 |
1
1. draw : negated conditional → KILLED |
if (pandaObjectives.isEmpty()) { |
| 149 | throw new IllegalStateException("Cannot draw from an empty panda deck"); | |
| 150 | } | |
| 151 | lastDrawnObjective = pandaObjectives.get(random.nextInt(pandaObjectives.size())); | |
| 152 | } | |
| 153 | case GARDENER -> { | |
| 154 |
1
1. draw : negated conditional → KILLED |
if (gardenerObjectives.isEmpty()) { |
| 155 | throw new IllegalStateException("Cannot draw from an empty gardener deck"); | |
| 156 | } | |
| 157 | lastDrawnObjective = | |
| 158 | gardenerObjectives.get(random.nextInt(gardenerObjectives.size())); | |
| 159 | } | |
| 160 | case SHAPE -> { | |
| 161 |
1
1. draw : negated conditional → KILLED |
if (shapeObjectives.isEmpty()) { |
| 162 | throw new IllegalStateException("Cannot draw from an empty shape deck"); | |
| 163 | } | |
| 164 | lastDrawnObjective = shapeObjectives.get(random.nextInt(shapeObjectives.size())); | |
| 165 | } | |
| 166 | default -> throw new IllegalArgumentException( | |
| 167 | "Objective type specified does not exists"); | |
| 168 | } | |
| 169 | remove(lastDrawnObjective); | |
| 170 | } | |
| 171 | ||
| 172 | public Objective peek() { | |
| 173 |
1
1. peek : replaced return value with null for com/takenoko/asset/ObjectiveDeck::peek → KILLED |
return lastDrawnObjective; |
| 174 | } | |
| 175 | ||
| 176 | @Override | |
| 177 | public boolean equals(Object o) { | |
| 178 |
2
1. equals : negated conditional → SURVIVED 2. equals : replaced boolean return with false for com/takenoko/asset/ObjectiveDeck::equals → NO_COVERAGE |
if (this == o) return true; |
| 179 |
3
1. equals : replaced boolean return with true for com/takenoko/asset/ObjectiveDeck::equals → NO_COVERAGE 2. equals : negated conditional → KILLED 3. equals : negated conditional → KILLED |
if (o == null || getClass() != o.getClass()) return false; |
| 180 |
2
1. equals : replaced boolean return with true for com/takenoko/asset/ObjectiveDeck::equals → NO_COVERAGE 2. equals : negated conditional → KILLED |
if (!super.equals(o)) return false; |
| 181 | ObjectiveDeck that = (ObjectiveDeck) o; | |
| 182 |
2
1. equals : replaced boolean return with true for com/takenoko/asset/ObjectiveDeck::equals → SURVIVED 2. equals : replaced boolean return with false for com/takenoko/asset/ObjectiveDeck::equals → KILLED |
return Objects.equals(lastDrawnObjective, that.lastDrawnObjective); |
| 183 | } | |
| 184 | ||
| 185 | @Override | |
| 186 | public int hashCode() { | |
| 187 |
1
1. hashCode : replaced int return with 0 for com/takenoko/asset/ObjectiveDeck::hashCode → TIMED_OUT |
return Objects.hash(super.hashCode(), lastDrawnObjective); |
| 188 | } | |
| 189 | ||
| 190 | @Override | |
| 191 | public String toString() { | |
| 192 |
1
1. toString : replaced return value with "" for com/takenoko/asset/ObjectiveDeck::toString → NO_COVERAGE |
return "ObjectiveDeck{" |
| 193 | + this.stream().map(Objects::toString).collect(Collectors.joining(", ")) | |
| 194 | + "}"; | |
| 195 | } | |
| 196 | ||
| 197 | /** | |
| 198 | * Create the starter deck for a player | |
| 199 | * | |
| 200 | * @return List of objectives | |
| 201 | */ | |
| 202 | public List<Objective> getStarterDeck() { | |
| 203 | List<Objective> drawnObjective = | |
| 204 | Stream.concat( | |
| 205 | this.stream().filter(PandaObjective.class::isInstance).limit(1), | |
| 206 | Stream.concat( | |
| 207 | this.stream() | |
| 208 | .filter(PatternObjective.class::isInstance) | |
| 209 | .limit(1), | |
| 210 | this.stream() | |
| 211 | .filter( | |
| 212 | o -> | |
| 213 |
3
1. lambda$getStarterDeck$3 : negated conditional → TIMED_OUT 2. lambda$getStarterDeck$3 : negated conditional → TIMED_OUT 3. lambda$getStarterDeck$3 : replaced boolean return with true for com/takenoko/asset/ObjectiveDeck::lambda$getStarterDeck$3 → TIMED_OUT |
o instanceof SingleGardenerObjective |
| 214 | || o | |
| 215 | instanceof | |
| 216 | MultipleGardenerObjective) | |
| 217 | .limit(1))) | |
| 218 | .toList(); | |
| 219 | ||
| 220 | for (Objective objective : drawnObjective) { | |
| 221 | this.remove(objective); | |
| 222 | } | |
| 223 | ||
| 224 |
1
1. getStarterDeck : replaced return value with Collections.emptyList for com/takenoko/asset/ObjectiveDeck::getStarterDeck → KILLED |
return drawnObjective; |
| 225 | } | |
| 226 | ||
| 227 | public boolean hasObjectiveType(ObjectiveType objectiveType) { | |
| 228 |
5
1. hasObjectiveType : replaced boolean return with true for com/takenoko/asset/ObjectiveDeck::hasObjectiveType → TIMED_OUT 2. lambda$hasObjectiveType$4 : negated conditional → TIMED_OUT 3. lambda$hasObjectiveType$4 : replaced boolean return with true for com/takenoko/asset/ObjectiveDeck::lambda$hasObjectiveType$4 → TIMED_OUT 4. hasObjectiveType : changed conditional boundary → KILLED 5. hasObjectiveType : negated conditional → KILLED |
return this.stream().filter(o -> o.getType() == objectiveType).toList().size() > 0; |
| 229 | } | |
| 230 | } | |
Mutations | ||
| 25 |
1.1 2.2 |
|
| 28 |
1.1 2.2 |
|
| 32 |
1.1 2.2 |
|
| 36 |
1.1 2.2 |
|
| 135 |
1.1 |
|
| 140 |
1.1 2.2 |
|
| 142 |
1.1 2.2 |
|
| 144 |
1.1 2.2 |
|
| 148 |
1.1 |
|
| 154 |
1.1 |
|
| 161 |
1.1 |
|
| 173 |
1.1 |
|
| 178 |
1.1 2.2 |
|
| 179 |
1.1 2.2 3.3 |
|
| 180 |
1.1 2.2 |
|
| 182 |
1.1 2.2 |
|
| 187 |
1.1 |
|
| 192 |
1.1 |
|
| 213 |
1.1 2.2 3.3 |
|
| 224 |
1.1 |
|
| 228 |
1.1 2.2 3.3 4.4 5.5 |