ObjectiveDeck.java

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
Location : <init>
Killed by : com.takenoko.asset.ObjectiveDeckTest.[engine:junit-jupiter]/[class:com.takenoko.asset.ObjectiveDeckTest]/[method:constructor()]
changed conditional boundary → KILLED

2.2
Location : <init>
Killed by : com.takenoko.asset.ObjectiveDeckTest.[engine:junit-jupiter]/[class:com.takenoko.asset.ObjectiveDeckTest]/[method:constructor()]
negated conditional → KILLED

28

1.1
Location : <init>
Killed by : com.takenoko.asset.ObjectiveDeckTest.[engine:junit-jupiter]/[class:com.takenoko.asset.ObjectiveDeckTest]/[method:constructor()]
changed conditional boundary → KILLED

2.2
Location : <init>
Killed by : com.takenoko.asset.ObjectiveDeckTest.[engine:junit-jupiter]/[class:com.takenoko.asset.ObjectiveDeckTest]/[method:constructor()]
negated conditional → KILLED

32

1.1
Location : <init>
Killed by : com.takenoko.asset.ObjectiveDeckTest.[engine:junit-jupiter]/[class:com.takenoko.asset.ObjectiveDeckTest]/[method:constructor()]
changed conditional boundary → KILLED

2.2
Location : <init>
Killed by : com.takenoko.asset.ObjectiveDeckTest.[engine:junit-jupiter]/[class:com.takenoko.asset.ObjectiveDeckTest]/[method:constructor()]
negated conditional → KILLED

36

1.1
Location : <init>
Killed by : com.takenoko.asset.ObjectiveDeckTest.[engine:junit-jupiter]/[class:com.takenoko.asset.ObjectiveDeckTest]/[method:constructor()]
changed conditional boundary → KILLED

2.2
Location : <init>
Killed by : com.takenoko.asset.ObjectiveDeckTest.[engine:junit-jupiter]/[class:com.takenoko.asset.ObjectiveDeckTest]/[method:constructor()]
negated conditional → KILLED

135

1.1
Location : draw
Killed by : com.takenoko.engine.GameEngineTest.[engine:junit-jupiter]/[class:com.takenoko.engine.GameEngineTest]/[nested-class:TestRunGame]/[method:runGame_shouldDisplayALotOfMessages()]
negated conditional → KILLED

140

1.1
Location : lambda$draw$0
Killed by : none
negated conditional → TIMED_OUT

2.2
Location : lambda$draw$0
Killed by : none
replaced boolean return with true for com/takenoko/asset/ObjectiveDeck::lambda$draw$0 → TIMED_OUT

142

1.1
Location : lambda$draw$1
Killed by : none
negated conditional → TIMED_OUT

2.2
Location : lambda$draw$1
Killed by : none
replaced boolean return with true for com/takenoko/asset/ObjectiveDeck::lambda$draw$1 → TIMED_OUT

144

1.1
Location : lambda$draw$2
Killed by : none
negated conditional → TIMED_OUT

2.2
Location : lambda$draw$2
Killed by : none
replaced boolean return with true for com/takenoko/asset/ObjectiveDeck::lambda$draw$2 → TIMED_OUT

148

1.1
Location : draw
Killed by : com.takenoko.bot.utils.HistoryAnalysisTest.[engine:junit-jupiter]/[class:com.takenoko.bot.utils.HistoryAnalysisTest]/[nested-class:IntegrationTest]/[method:test1()]
negated conditional → KILLED

154

1.1
Location : draw
Killed by : com.takenoko.bot.utils.HistoryAnalysisTest.[engine:junit-jupiter]/[class:com.takenoko.bot.utils.HistoryAnalysisTest]/[nested-class:IntegrationTest]/[method:test1()]
negated conditional → KILLED

161

1.1
Location : draw
Killed by : com.takenoko.engine.GameEngineTest.[engine:junit-jupiter]/[class:com.takenoko.engine.GameEngineTest]/[nested-class:TestRunGame]/[method:runGame_shouldDisplayALotOfMessages()]
negated conditional → KILLED

173

1.1
Location : peek
Killed by : com.takenoko.bot.utils.HistoryAnalysisTest.[engine:junit-jupiter]/[class:com.takenoko.bot.utils.HistoryAnalysisTest]/[nested-class:IntegrationTest]/[method:test1()]
replaced return value with null for com/takenoko/asset/ObjectiveDeck::peek → KILLED

178

1.1
Location : equals
Killed by : none
negated conditional → SURVIVED

2.2
Location : equals
Killed by : none
replaced boolean return with false for com/takenoko/asset/ObjectiveDeck::equals → NO_COVERAGE

179

1.1
Location : equals
Killed by : com.takenoko.asset.GameAssetsTest.[engine:junit-jupiter]/[class:com.takenoko.asset.GameAssetsTest]/[nested-class:TestEquals]/[method:equals_WhenGameAssets_S_AreEqual_ThenReturnsTrue()]
negated conditional → KILLED

2.2
Location : equals
Killed by : com.takenoko.asset.GameAssetsTest.[engine:junit-jupiter]/[class:com.takenoko.asset.GameAssetsTest]/[nested-class:TestEquals]/[method:equals_WhenGameAssets_S_AreEqual_ThenReturnsTrue()]
negated conditional → KILLED

3.3
Location : equals
Killed by : none
replaced boolean return with true for com/takenoko/asset/ObjectiveDeck::equals → NO_COVERAGE

180

1.1
Location : equals
Killed by : com.takenoko.asset.GameAssetsTest.[engine:junit-jupiter]/[class:com.takenoko.asset.GameAssetsTest]/[nested-class:TestEquals]/[method:equals_WhenGameAssets_S_AreEqual_ThenReturnsTrue()]
negated conditional → KILLED

2.2
Location : equals
Killed by : none
replaced boolean return with true for com/takenoko/asset/ObjectiveDeck::equals → NO_COVERAGE

182

1.1
Location : equals
Killed by : com.takenoko.asset.GameAssetsTest.[engine:junit-jupiter]/[class:com.takenoko.asset.GameAssetsTest]/[nested-class:TestEquals]/[method:equals_WhenGameAssets_S_AreEqual_ThenReturnsTrue()]
replaced boolean return with false for com/takenoko/asset/ObjectiveDeck::equals → KILLED

2.2
Location : equals
Killed by : none
replaced boolean return with true for com/takenoko/asset/ObjectiveDeck::equals → SURVIVED

187

1.1
Location : hashCode
Killed by : none
replaced int return with 0 for com/takenoko/asset/ObjectiveDeck::hashCode → TIMED_OUT

192

1.1
Location : toString
Killed by : none
replaced return value with "" for com/takenoko/asset/ObjectiveDeck::toString → NO_COVERAGE

213

1.1
Location : lambda$getStarterDeck$3
Killed by : none
negated conditional → TIMED_OUT

2.2
Location : lambda$getStarterDeck$3
Killed by : none
negated conditional → TIMED_OUT

3.3
Location : lambda$getStarterDeck$3
Killed by : none
replaced boolean return with true for com/takenoko/asset/ObjectiveDeck::lambda$getStarterDeck$3 → TIMED_OUT

224

1.1
Location : getStarterDeck
Killed by : com.takenoko.asset.ObjectiveDeckTest.[engine:junit-jupiter]/[class:com.takenoko.asset.ObjectiveDeckTest]/[nested-class:TestGetStarterDeck]/[method:getStarterDeck()]
replaced return value with Collections.emptyList for com/takenoko/asset/ObjectiveDeck::getStarterDeck → KILLED

228

1.1
Location : hasObjectiveType
Killed by : com.takenoko.engine.GameEngineTest.[engine:junit-jupiter]/[class:com.takenoko.engine.GameEngineTest]/[nested-class:TestRunGame]/[method:runGame_shouldDisplayALotOfMessages()]
changed conditional boundary → KILLED

2.2
Location : hasObjectiveType
Killed by : com.takenoko.bot.ColletBotTest.[engine:junit-jupiter]/[class:com.takenoko.bot.ColletBotTest]/[nested-class:IntegrationTests]/[method:whenTheBotChoosesAnObjectiveItTakesThePandaOnesIfThereAreSomeAvailables()]
negated conditional → KILLED

3.3
Location : hasObjectiveType
Killed by : none
replaced boolean return with true for com/takenoko/asset/ObjectiveDeck::hasObjectiveType → TIMED_OUT

4.4
Location : lambda$hasObjectiveType$4
Killed by : none
negated conditional → TIMED_OUT

5.5
Location : lambda$hasObjectiveType$4
Killed by : none
replaced boolean return with true for com/takenoko/asset/ObjectiveDeck::lambda$hasObjectiveType$4 → TIMED_OUT

Active mutators

Tests examined


Report generated by PIT 1.8.0