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 |