Pattern.java

1
package com.takenoko.shape;
2
3
import com.takenoko.engine.Board;
4
import com.takenoko.layers.tile.Tile;
5
import com.takenoko.layers.tile.TileColor;
6
import com.takenoko.vector.PositionVector;
7
import java.util.*;
8
import java.util.Map.Entry;
9
import java.util.stream.Collectors;
10
import java.util.stream.IntStream;
11
import org.apache.commons.lang3.tuple.Pair;
12
13
/** Class representing a pattern. */
14
public class Pattern extends Shape {
15
    final HashMap<PositionVector, Set<Shape>> cache = new HashMap<>();
16
17
    /**
18
     * Constructor for the Pattern class. The origin is the element the closest to the origin of the
19
     * coordinate system.
20
     *
21
     * @param elements the elements of the pattern
22
     */
23
    @SafeVarargs
24
    public Pattern(Pair<PositionVector, Tile>... elements) {
25
        super(elements);
26 1 1. <init> : negated conditional → KILLED
        if (!getElements().containsKey(new PositionVector(0, 0, 0))) {
27
            throw new IllegalArgumentException("The pattern must contain the origin");
28
        }
29
    }
30
31
    public Pattern(List<Entry<PositionVector, Tile>> toList) {
32
        super(toList.stream().collect(Collectors.toMap(Entry::getKey, Entry::getValue)));
33 1 1. <init> : negated conditional → KILLED
        if (!getElements().containsKey(new PositionVector(0, 0, 0))) {
34
            throw new IllegalArgumentException("The pattern must contain the origin");
35
        }
36
    }
37
38
    @Override
39
    public int hashCode() {
40 1 1. hashCode : replaced int return with 0 for com/takenoko/shape/Pattern::hashCode → KILLED
        return Objects.hash(getRotatedShapes());
41
    }
42
43
    /**
44
     * Method to match a shape on the board.
45
     *
46
     * @param board the board
47
     * @return the matching translated/rotated shapes
48
     */
49
    public List<Shape> match(Board board) {
50 1 1. match : replaced return value with Collections.emptyList for com/takenoko/shape/Pattern::match → KILLED
        return match(board, false);
51
    }
52
53
    public List<Shape> match(Board board, boolean ignoreIrrigation) {
54
        Map<PositionVector, Tile> tileMap = board.getTilesWithoutPond();
55
        // spotless:off
56 1 1. match : replaced return value with Collections.emptyList for com/takenoko/shape/Pattern::match → KILLED
        return tileMap.keySet().stream().flatMap(tilePosition ->
57
                // For each tilePosition on the board translate the shape to the tilePosition
58 2 1. lambda$match$0 : replaced return value with Collections.emptySet for com/takenoko/shape/Pattern::lambda$match$0 → KILLED
2. lambda$match$3 : replaced return value with Stream.empty for com/takenoko/shape/Pattern::lambda$match$3 → KILLED
                cache.computeIfAbsent(tilePosition, p -> this.translate(p).getRotatedShapes()).stream()
59 2 1. lambda$match$2 : replaced boolean return with false for com/takenoko/shape/Pattern::lambda$match$2 → KILLED
2. lambda$match$2 : replaced boolean return with true for com/takenoko/shape/Pattern::lambda$match$2 → KILLED
                        .filter(rotTransShape -> rotTransShape.getElements().entrySet().stream()
60
                                .allMatch(e ->
61 3 1. lambda$match$1 : negated conditional → KILLED
2. lambda$match$1 : negated conditional → KILLED
3. lambda$match$1 : replaced boolean return with true for com/takenoko/shape/Pattern::lambda$match$1 → KILLED
                                        (ignoreIrrigation || board.isIrrigatedAt(e.getKey())) &&
62 1 1. lambda$match$1 : negated conditional → KILLED
                                                tileMap.containsKey(e.getKey()) && (
63 1 1. lambda$match$1 : negated conditional → KILLED
                                                tileMap.get(e.getKey()).getColor().equals(e.getValue().getColor()) || (
64 1 1. lambda$match$1 : negated conditional → KILLED
                                                        e.getValue().getColor().equals(TileColor.ANY) &&
65 1 1. lambda$match$1 : negated conditional → NO_COVERAGE
                                                                !tileMap.get(e.getKey()).getColor().equals(TileColor.NONE)
66
                                                )
67
                                        )
68
                                ))
69
        ).distinct().toList();
70
        // spotless:on
71
    }
72
73
    public List<Shape> getSubsetMatchPattern(
74
            Board board, int startingSize, boolean ignoreIrrigation) {
75
        // spotless:off
76 1 1. getSubsetMatchPattern : replaced return value with Collections.emptyList for com/takenoko/shape/Pattern::getSubsetMatchPattern → KILLED
        return IntStream.range(startingSize, getElements().size())
77
                .mapToObj(
78 1 1. lambda$getSubsetMatchPattern$5 : replaced return value with null for com/takenoko/shape/Pattern::lambda$getSubsetMatchPattern$5 → KILLED
                        v -> new Pattern(
79
                                getElements().entrySet().stream()
80 1 1. lambda$getSubsetMatchPattern$4 : replaced double return with 0.0d for com/takenoko/shape/Pattern::lambda$getSubsetMatchPattern$4 → TIMED_OUT
                                        .sorted(Comparator.comparingDouble(e -> e.getKey()
81
                                                .distance(new PositionVector(0, 0, 0))))
82
                                        .limit(v)
83
                                        .toList())
84
                )
85 1 1. lambda$getSubsetMatchPattern$6 : replaced return value with Collections.emptyList for com/takenoko/shape/Pattern::lambda$getSubsetMatchPattern$6 → KILLED
                .map(p -> p.match(board, ignoreIrrigation))
86 2 1. lambda$getSubsetMatchPattern$7 : replaced boolean return with true for com/takenoko/shape/Pattern::lambda$getSubsetMatchPattern$7 → TIMED_OUT
2. lambda$getSubsetMatchPattern$7 : negated conditional → KILLED
                .filter(p -> !p.isEmpty())
87
                .flatMap(List::stream)
88
                .toList();
89
        // spotless:on
90
    }
91
92
    @Override
93
    public boolean equals(Object o) {
94 2 1. equals : negated conditional → KILLED
2. equals : replaced boolean return with false for com/takenoko/shape/Pattern::equals → KILLED
        if (this == o) return true;
95 3 1. equals : negated conditional → KILLED
2. equals : negated conditional → KILLED
3. equals : replaced boolean return with true for com/takenoko/shape/Pattern::equals → KILLED
        if (o == null || getClass() != o.getClass()) return false;
96
        Pattern pattern = (Pattern) o;
97 2 1. equals : replaced boolean return with true for com/takenoko/shape/Pattern::equals → TIMED_OUT
2. equals : replaced boolean return with false for com/takenoko/shape/Pattern::equals → KILLED
        return getRotatedShapes().equals(pattern.getRotatedShapes());
98
    }
99
100
    String getColorsString() {
101 1 1. getColorsString : replaced return value with "" for com/takenoko/shape/Pattern::getColorsString → TIMED_OUT
        return this.getElements().values().stream()
102
                .map(Tile::getColor)
103
                .distinct()
104
                .map(Objects::toString)
105
                .collect(Collectors.joining(","));
106
    }
107
108
    public List<Shape> getShapesToCompletePatternObjective(Board board) {
109
        List<Shape> matchedShapes = getSubsetMatchPattern(board, 1, true);
110
111
        List<Shape> missingShapes = new ArrayList<>();
112
        for (Shape subset : matchedShapes) {
113
            // Translate the shape from the origin to a tile of the pattern
114
            for (PositionVector positionVector : subset.getElements().keySet()) {
115
                Set<Shape> rotatedShapes = this.translate(positionVector).getRotatedShapes();
116
                // For each rotation, check if the shape is matching the board
117
                for (Shape rotatedShape : rotatedShapes) {
118
                    // Missing conditions
119
                    Shape missingShape = rotatedShape.getMissingShape(subset);
120
                    missingShapes.add(missingShape);
121
                }
122
            }
123
        }
124
125 1 1. getShapesToCompletePatternObjective : replaced return value with Collections.emptyList for com/takenoko/shape/Pattern::getShapesToCompletePatternObjective → TIMED_OUT
        return missingShapes.stream()
126
                .filter(
127
                        shape ->
128 2 1. lambda$getShapesToCompletePatternObjective$9 : replaced boolean return with false for com/takenoko/shape/Pattern::lambda$getShapesToCompletePatternObjective$9 → TIMED_OUT
2. lambda$getShapesToCompletePatternObjective$9 : replaced boolean return with true for com/takenoko/shape/Pattern::lambda$getShapesToCompletePatternObjective$9 → TIMED_OUT
                                shape.getElements().keySet().stream()
129
                                        .anyMatch(
130
                                                positionVector ->
131 2 1. lambda$getShapesToCompletePatternObjective$8 : replaced boolean return with false for com/takenoko/shape/Pattern::lambda$getShapesToCompletePatternObjective$8 → TIMED_OUT
2. lambda$getShapesToCompletePatternObjective$8 : replaced boolean return with true for com/takenoko/shape/Pattern::lambda$getShapesToCompletePatternObjective$8 → TIMED_OUT
                                                        board.getAvailableTilePositions()
132
                                                                .contains(positionVector)))
133 1 1. lambda$getShapesToCompletePatternObjective$10 : replaced int return with 0 for com/takenoko/shape/Pattern::lambda$getShapesToCompletePatternObjective$10 → TIMED_OUT
                .sorted(Comparator.comparingInt(v -> v.getElements().size()))
134
                .toList();
135
    }
136
}

Mutations

26

1.1
Location : <init>
Killed by : com.takenoko.shape.PatternTest.[engine:junit-jupiter]/[class:com.takenoko.shape.PatternTest]/[nested-class:TestEquals]/[method:equals_shouldReturnTrueWhenCalledOnSelf()]
negated conditional → KILLED

33

1.1
Location : <init>
Killed by : com.takenoko.shape.PatternTest.[engine:junit-jupiter]/[class:com.takenoko.shape.PatternTest]/[nested-class:TestGetSubsetMatchPattern]/[method:getSubsetMatchPattern_shouldReturnSubsetOfPatternThatMatchesBoard()]
negated conditional → KILLED

40

1.1
Location : hashCode
Killed by : com.takenoko.shape.PatternTest.[engine:junit-jupiter]/[class:com.takenoko.shape.PatternTest]/[nested-class:TestHashCode]/[method:hashCode_shouldReturnDifferentHashCodeWhenPatternsAreNotEqual()]
replaced int return with 0 for com/takenoko/shape/Pattern::hashCode → KILLED

50

1.1
Location : match
Killed by : com.takenoko.shape.PatternTest.[engine:junit-jupiter]/[class:com.takenoko.shape.PatternTest]/[nested-class:TestMatch]/[method:match_shouldReturnTrueWhenPatternMatchesSingleTilePattern()]
replaced return value with Collections.emptyList for com/takenoko/shape/Pattern::match → KILLED

56

1.1
Location : match
Killed by : com.takenoko.shape.PatternTest.[engine:junit-jupiter]/[class:com.takenoko.shape.PatternTest]/[nested-class:TestMatch]/[method:match_shouldReturnTrueWhenPatternMatchesSingleTilePattern()]
replaced return value with Collections.emptyList for com/takenoko/shape/Pattern::match → KILLED

58

1.1
Location : lambda$match$0
Killed by : com.takenoko.shape.PatternTest.[engine:junit-jupiter]/[class:com.takenoko.shape.PatternTest]/[nested-class:TestMatch]/[method:match_shouldReturnTrueWhenPatternMatchesSingleTilePattern()]
replaced return value with Collections.emptySet for com/takenoko/shape/Pattern::lambda$match$0 → KILLED

2.2
Location : lambda$match$3
Killed by : com.takenoko.shape.PatternTest.[engine:junit-jupiter]/[class:com.takenoko.shape.PatternTest]/[nested-class:TestMatch]/[method:match_shouldReturnTrueWhenPatternMatchesSingleTilePattern()]
replaced return value with Stream.empty for com/takenoko/shape/Pattern::lambda$match$3 → KILLED

59

1.1
Location : lambda$match$2
Killed by : com.takenoko.shape.PatternTest.[engine:junit-jupiter]/[class:com.takenoko.shape.PatternTest]/[nested-class:TestMatch]/[method:match_shouldReturnTrueWhenPatternMatchesSingleTilePattern()]
replaced boolean return with false for com/takenoko/shape/Pattern::lambda$match$2 → KILLED

2.2
Location : lambda$match$2
Killed by : com.takenoko.shape.PatternTest.[engine:junit-jupiter]/[class:com.takenoko.shape.PatternTest]/[nested-class:TestMatch]/[method:match_shouldReturnFalseWhenPatternDoesNotMatchPattern()]
replaced boolean return with true for com/takenoko/shape/Pattern::lambda$match$2 → KILLED

61

1.1
Location : lambda$match$1
Killed by : com.takenoko.shape.PatternTest.[engine:junit-jupiter]/[class:com.takenoko.shape.PatternTest]/[nested-class:TestMatch]/[method:match_shouldReturnTrueWhenPatternMatchesSingleTilePattern()]
negated conditional → KILLED

2.2
Location : lambda$match$1
Killed by : com.takenoko.shape.PatternTest.[engine:junit-jupiter]/[class:com.takenoko.shape.PatternTest]/[nested-class:TestMatch]/[method:match_shouldReturnTrueWhenPatternMatchesSingleTilePattern()]
negated conditional → KILLED

3.3
Location : lambda$match$1
Killed by : com.takenoko.shape.PatternTest.[engine:junit-jupiter]/[class:com.takenoko.shape.PatternTest]/[nested-class:TestMatch]/[method:match_shouldReturnFalseWhenPatternDoesNotMatchPattern()]
replaced boolean return with true for com/takenoko/shape/Pattern::lambda$match$1 → KILLED

62

1.1
Location : lambda$match$1
Killed by : com.takenoko.shape.PatternTest.[engine:junit-jupiter]/[class:com.takenoko.shape.PatternTest]/[nested-class:TestMatch]/[method:match_shouldReturnTrueWhenPatternMatchesSingleTilePattern()]
negated conditional → KILLED

63

1.1
Location : lambda$match$1
Killed by : com.takenoko.shape.PatternTest.[engine:junit-jupiter]/[class:com.takenoko.shape.PatternTest]/[nested-class:TestMatch]/[method:match_shouldReturnTrueWhenPatternMatchesSingleTilePattern()]
negated conditional → KILLED

64

1.1
Location : lambda$match$1
Killed by : com.takenoko.shape.PatternTest.[engine:junit-jupiter]/[class:com.takenoko.shape.PatternTest]/[nested-class:TestMatch]/[method:match_shouldReturnTrueWhenPatternMatchesNTilePattern()]
negated conditional → KILLED

65

1.1
Location : lambda$match$1
Killed by : none
negated conditional → NO_COVERAGE

76

1.1
Location : getSubsetMatchPattern
Killed by : com.takenoko.shape.PatternTest.[engine:junit-jupiter]/[class:com.takenoko.shape.PatternTest]/[nested-class:TestGetSubsetMatchPattern]/[method:getSubsetMatchPattern_shouldReturnSubsetOfPatternThatMatchesBoard()]
replaced return value with Collections.emptyList for com/takenoko/shape/Pattern::getSubsetMatchPattern → KILLED

78

1.1
Location : lambda$getSubsetMatchPattern$5
Killed by : com.takenoko.shape.PatternTest.[engine:junit-jupiter]/[class:com.takenoko.shape.PatternTest]/[nested-class:TestGetSubsetMatchPattern]/[method:getSubsetMatchPattern_shouldReturnSubsetOfPatternThatMatchesBoard()]
replaced return value with null for com/takenoko/shape/Pattern::lambda$getSubsetMatchPattern$5 → KILLED

80

1.1
Location : lambda$getSubsetMatchPattern$4
Killed by : none
replaced double return with 0.0d for com/takenoko/shape/Pattern::lambda$getSubsetMatchPattern$4 → TIMED_OUT

85

1.1
Location : lambda$getSubsetMatchPattern$6
Killed by : com.takenoko.shape.PatternTest.[engine:junit-jupiter]/[class:com.takenoko.shape.PatternTest]/[nested-class:TestGetSubsetMatchPattern]/[method:getSubsetMatchPattern_shouldReturnSubsetOfPatternThatMatchesBoard()]
replaced return value with Collections.emptyList for com/takenoko/shape/Pattern::lambda$getSubsetMatchPattern$6 → KILLED

86

1.1
Location : lambda$getSubsetMatchPattern$7
Killed by : com.takenoko.shape.PatternTest.[engine:junit-jupiter]/[class:com.takenoko.shape.PatternTest]/[nested-class:TestGetSubsetMatchPattern]/[method:getSubsetMatchPattern_shouldReturnSubsetOfPatternThatMatchesBoard()]
negated conditional → KILLED

2.2
Location : lambda$getSubsetMatchPattern$7
Killed by : none
replaced boolean return with true for com/takenoko/shape/Pattern::lambda$getSubsetMatchPattern$7 → TIMED_OUT

94

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

2.2
Location : equals
Killed by : com.takenoko.shape.PatternTest.[engine:junit-jupiter]/[class:com.takenoko.shape.PatternTest]/[nested-class:TestEquals]/[method:equals_shouldReturnTrueWhenCalledOnSelf()]
replaced boolean return with false for com/takenoko/shape/Pattern::equals → KILLED

95

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

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

3.3
Location : equals
Killed by : com.takenoko.shape.PatternTest.[engine:junit-jupiter]/[class:com.takenoko.shape.PatternTest]/[nested-class:TestEquals]/[method:equals_shouldReturnFalseWhenCalledOnAnotherClass()]
replaced boolean return with true for com/takenoko/shape/Pattern::equals → KILLED

97

1.1
Location : equals
Killed by : com.takenoko.shape.PatternTest.[engine:junit-jupiter]/[class:com.takenoko.shape.PatternTest]/[nested-class:TestEquals]/[method:equals_shouldReturnTrueWhenPatternsAreEqual()]
replaced boolean return with false for com/takenoko/shape/Pattern::equals → KILLED

2.2
Location : equals
Killed by : none
replaced boolean return with true for com/takenoko/shape/Pattern::equals → TIMED_OUT

101

1.1
Location : getColorsString
Killed by : none
replaced return value with "" for com/takenoko/shape/Pattern::getColorsString → TIMED_OUT

125

1.1
Location : getShapesToCompletePatternObjective
Killed by : none
replaced return value with Collections.emptyList for com/takenoko/shape/Pattern::getShapesToCompletePatternObjective → TIMED_OUT

128

1.1
Location : lambda$getShapesToCompletePatternObjective$9
Killed by : none
replaced boolean return with false for com/takenoko/shape/Pattern::lambda$getShapesToCompletePatternObjective$9 → TIMED_OUT

2.2
Location : lambda$getShapesToCompletePatternObjective$9
Killed by : none
replaced boolean return with true for com/takenoko/shape/Pattern::lambda$getShapesToCompletePatternObjective$9 → TIMED_OUT

131

1.1
Location : lambda$getShapesToCompletePatternObjective$8
Killed by : none
replaced boolean return with false for com/takenoko/shape/Pattern::lambda$getShapesToCompletePatternObjective$8 → TIMED_OUT

2.2
Location : lambda$getShapesToCompletePatternObjective$8
Killed by : none
replaced boolean return with true for com/takenoko/shape/Pattern::lambda$getShapesToCompletePatternObjective$8 → TIMED_OUT

133

1.1
Location : lambda$getShapesToCompletePatternObjective$10
Killed by : none
replaced int return with 0 for com/takenoko/shape/Pattern::lambda$getShapesToCompletePatternObjective$10 → TIMED_OUT

Active mutators

Tests examined


Report generated by PIT 1.8.0