TileDeck.java

1
package com.takenoko.asset;
2
3
import com.takenoko.layers.tile.ImprovementType;
4
import com.takenoko.layers.tile.Tile;
5
import com.takenoko.layers.tile.TileColor;
6
import java.security.SecureRandom;
7
import java.util.ArrayList;
8
import java.util.List;
9
import java.util.Objects;
10
import java.util.Random;
11
import java.util.stream.Collectors;
12
13
/** The deck containing all the improvement chips you can place on the tiles. */
14
public class TileDeck extends ArrayList<Tile> {
15
16
    private final Random random;
17
    private boolean canPeek;
18
19
    public TileDeck() {
20
        this(new SecureRandom());
21
    }
22
23
    public TileDeck(Random random) {
24
        this.random = random;
25
        canPeek = false;
26
27
        // -------- GREEN TILES --------
28 2 1. <init> : changed conditional boundary → KILLED
2. <init> : negated conditional → KILLED
        for (int i = 0; i < 6; i++) {
29
            this.add(new Tile(TileColor.GREEN));
30
        }
31
        this.add(new Tile(ImprovementType.ENCLOSURE, TileColor.GREEN));
32
        this.add(new Tile(ImprovementType.ENCLOSURE, TileColor.GREEN));
33
        this.add(new Tile(ImprovementType.FERTILIZER, TileColor.GREEN));
34
        this.add(new Tile(ImprovementType.WATERSHED, TileColor.GREEN));
35
        this.add(new Tile(ImprovementType.WATERSHED, TileColor.GREEN));
36
37
        // -------- PINK TILES --------
38 2 1. <init> : changed conditional boundary → KILLED
2. <init> : negated conditional → KILLED
        for (int i = 0; i < 4; i++) {
39
            this.add(new Tile());
40
        }
41
        this.add(new Tile(ImprovementType.ENCLOSURE, TileColor.PINK));
42
        this.add(new Tile(ImprovementType.FERTILIZER, TileColor.PINK));
43
        this.add(new Tile(ImprovementType.WATERSHED, TileColor.PINK));
44
45
        // -------- YELLOW TILES --------
46 2 1. <init> : changed conditional boundary → KILLED
2. <init> : negated conditional → KILLED
        for (int i = 0; i < 6; i++) {
47
            this.add(new Tile(TileColor.YELLOW));
48
        }
49
        this.add(new Tile(ImprovementType.ENCLOSURE, TileColor.YELLOW));
50
        this.add(new Tile(ImprovementType.FERTILIZER, TileColor.YELLOW));
51
        this.add(new Tile(ImprovementType.WATERSHED, TileColor.YELLOW));
52
53 1 1. <init> : removed call to com/takenoko/asset/TileDeck::shuffle → TIMED_OUT
        shuffle();
54
    }
55
56
    /** Draw tiles from the deck. */
57
    public void draw() {
58
        canPeek = true;
59
    }
60
61
    /**
62
     * Choose what tile to place on the board.
63
     *
64
     * @param tile the tile to place
65
     */
66
    public void choose(Tile tile) {
67
        // remove the tile from the deck and put the remaining tiles back at the end of the deck, do
68
        // not shuffle
69
70
        List<Tile> tiles = peek();
71 1 1. choose : negated conditional → KILLED
        if (!tiles.contains(tile)) {
72
            throw new IllegalArgumentException("This tile is not in the last drawn tiles.");
73
        }
74
75
        // remove the first 3 tiles from the deck
76 3 1. choose : changed conditional boundary → KILLED
2. choose : negated conditional → KILLED
3. choose : negated conditional → KILLED
        for (int i = 0; i < 3 && !this.isEmpty(); i++) {
77
            this.remove(0);
78
        }
79
80
        tiles.remove(tile);
81
        // put the remaining tiles back at the end of the deck
82
        this.addAll(tiles);
83
        canPeek = false;
84
    }
85
86
    public List<Tile> peek() {
87 1 1. peek : negated conditional → KILLED
        if (!canPeek) {
88
            throw new IllegalStateException("You must draw tiles before peeking.");
89
        }
90 1 1. peek : replaced return value with Collections.emptyList for com/takenoko/asset/TileDeck::peek → KILLED
        return new ArrayList<>(this.stream().limit(3).toList());
91
    }
92
93
    private void shuffle() {
94 2 1. shuffle : negated conditional → TIMED_OUT
2. shuffle : changed conditional boundary → KILLED
        for (int i = 0; i < this.size(); i++) {
95
            int j = random.nextInt(this.size());
96
            Tile temp = this.get(i);
97
            this.set(i, this.get(j));
98
            this.set(j, temp);
99
        }
100
    }
101
102
    @Override
103
    public boolean equals(Object o) {
104 2 1. equals : negated conditional → KILLED
2. equals : replaced boolean return with false for com/takenoko/asset/TileDeck::equals → KILLED
        if (this == o) return true;
105 3 1. equals : negated conditional → KILLED
2. equals : negated conditional → KILLED
3. equals : replaced boolean return with true for com/takenoko/asset/TileDeck::equals → KILLED
        if (o == null || getClass() != o.getClass()) return false;
106 2 1. equals : negated conditional → KILLED
2. equals : replaced boolean return with true for com/takenoko/asset/TileDeck::equals → KILLED
        if (!super.equals(o)) return false;
107
        TileDeck tiles = (TileDeck) o;
108 2 1. equals : replaced boolean return with true for com/takenoko/asset/TileDeck::equals → SURVIVED
2. equals : negated conditional → KILLED
        return canPeek == tiles.canPeek;
109
    }
110
111
    @Override
112
    public int hashCode() {
113 1 1. hashCode : replaced int return with 0 for com/takenoko/asset/TileDeck::hashCode → KILLED
        return Objects.hash(super.hashCode(), canPeek);
114
    }
115
116
    @Override
117
    public String toString() {
118 1 1. toString : replaced return value with "" for com/takenoko/asset/TileDeck::toString → NO_COVERAGE
        return this.stream().map(Tile::toString).collect(Collectors.joining(", "));
119
    }
120
}

Mutations

28

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

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

38

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

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

46

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

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

53

1.1
Location : <init>
Killed by : none
removed call to com/takenoko/asset/TileDeck::shuffle → TIMED_OUT

71

1.1
Location : choose
Killed by : com.takenoko.asset.TileDeckTest.[engine:junit-jupiter]/[class:com.takenoko.asset.TileDeckTest]/[nested-class:Choose]/[method:whenChoosingATileThatIsNotPresentInTheLastDrawnTilesAnExceptionIsThrown()]
negated conditional → KILLED

76

1.1
Location : choose
Killed by : com.takenoko.asset.TileDeckTest.[engine:junit-jupiter]/[class:com.takenoko.asset.TileDeckTest]/[nested-class:Bug1Fix]/[method:whenChoosingATileTheTileIsRemovedFromTheDeckAndTheTilesThatAreNotChosenAreReturnedAreAddedToTheEndOfTheDeck()]
changed conditional boundary → KILLED

2.2
Location : choose
Killed by : com.takenoko.asset.TileDeckTest.[engine:junit-jupiter]/[class:com.takenoko.asset.TileDeckTest]/[nested-class:Bug1Fix]/[method:whenChoosingATileTheTileIsRemovedFromTheDeckAndTheTilesThatAreNotChosenAreReturnedAreAddedToTheEndOfTheDeck()]
negated conditional → KILLED

3.3
Location : choose
Killed by : com.takenoko.asset.TileDeckTest.[engine:junit-jupiter]/[class:com.takenoko.asset.TileDeckTest]/[nested-class:Bug1Fix]/[method:whenChoosingATileTheTileIsRemovedFromTheDeckAndTheTilesThatAreNotChosenAreReturnedAreAddedToTheEndOfTheDeck()]
negated conditional → KILLED

87

1.1
Location : peek
Killed by : com.takenoko.asset.TileDeckTest.[engine:junit-jupiter]/[class:com.takenoko.asset.TileDeckTest]/[nested-class:DrawAndPeek]/[method:whenDrawinfTilesThreeTilesAreDrawn()]
negated conditional → KILLED

90

1.1
Location : peek
Killed by : com.takenoko.asset.TileDeckTest.[engine:junit-jupiter]/[class:com.takenoko.asset.TileDeckTest]/[nested-class:DrawAndPeek]/[method:whenDrawinfTilesThreeTilesAreDrawn()]
replaced return value with Collections.emptyList for com/takenoko/asset/TileDeck::peek → KILLED

94

1.1
Location : shuffle
Killed by : com.takenoko.asset.TileDeckTest.[engine:junit-jupiter]/[class:com.takenoko.asset.TileDeckTest]/[nested-class:Constructor]/[method:whenCreatingATileDeckTheDeckIsNotEmptyAndContains27Tiles()]
changed conditional boundary → KILLED

2.2
Location : shuffle
Killed by : none
negated conditional → TIMED_OUT

104

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

2.2
Location : equals
Killed by : com.takenoko.asset.TileDeckTest.[engine:junit-jupiter]/[class:com.takenoko.asset.TileDeckTest]/[nested-class:Equals]/[method:equals_returnTrueWhenComparingToSelf()]
replaced boolean return with false for com/takenoko/asset/TileDeck::equals → KILLED

105

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

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

3.3
Location : equals
Killed by : com.takenoko.asset.TileDeckTest.[engine:junit-jupiter]/[class:com.takenoko.asset.TileDeckTest]/[nested-class:Equals]/[method:returnFalseWhenComparingATileDeckToObject()]
replaced boolean return with true for com/takenoko/asset/TileDeck::equals → KILLED

106

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

2.2
Location : equals
Killed by : com.takenoko.asset.TileDeckTest.[engine:junit-jupiter]/[class:com.takenoko.asset.TileDeckTest]/[nested-class:Equals]/[method:whenComparingTwoTileDecksTheyAreNotEqualIfTheyHaveDifferentTiles()]
replaced boolean return with true for com/takenoko/asset/TileDeck::equals → KILLED

108

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

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

113

1.1
Location : hashCode
Killed by : com.takenoko.asset.TileDeckTest.[engine:junit-jupiter]/[class:com.takenoko.asset.TileDeckTest]/[nested-class:HashCode]/[method:whenComparingTwoTileDecksTheyHaveDifferentHashCodesIfTheyHaveDifferentTiles()]
replaced int return with 0 for com/takenoko/asset/TileDeck::hashCode → KILLED

118

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

Active mutators

Tests examined


Report generated by PIT 1.8.0