HistoryAnalysis.java

1
package com.takenoko.bot.utils;
2
3
import com.takenoko.actions.actors.ForcedMovePandaAction;
4
import com.takenoko.actions.actors.MovePandaAction;
5
import com.takenoko.engine.GameEngine;
6
import com.takenoko.engine.History;
7
import com.takenoko.objective.Objective;
8
import java.util.Collections;
9
import java.util.Map;
10
import java.util.UUID;
11
import java.util.stream.Collectors;
12
13
/** Class that analyses the history of a game. */
14
public class HistoryAnalysis {
15
16
    private static final double MID_GAME_THRESHOLD = 0.25;
17
    private static final double LATE_GAME_THRESHOLD = 0.75;
18
    public static final double DEFAULT_RUSH_PANDA_THRESHOLD = 0.8;
19
20
    private HistoryAnalysis() {}
21
22
    /**
23
     * Retrieves the current score for each bot manager in the history.
24
     *
25
     * @param history the history to analyse
26
     * @return a map of the current score for each bot manager in the history.
27
     */
28
    public static Map<UUID, Integer> getCurrentBotScores(History history) {
29 1 1. getCurrentBotScores : replaced return value with Collections.emptyMap for com/takenoko/bot/utils/HistoryAnalysis::getCurrentBotScores → KILLED
        return history.getLatestHistoryItems().entrySet().stream()
30
                .map(
31
                        uuidHistoryItemEntry ->
32 1 1. lambda$getCurrentBotScores$0 : replaced return value with null for com/takenoko/bot/utils/HistoryAnalysis::lambda$getCurrentBotScores$0 → KILLED
                                Map.entry(
33
                                        uuidHistoryItemEntry.getKey(),
34
                                        uuidHistoryItemEntry
35
                                                .getValue()
36
                                                .redeemedObjectives()
37
                                                .stream()
38
                                                .mapToInt(Objective::getPoints)
39
                                                .sum()))
40
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
41
    }
42
43
    /**
44
     * Calculates the maximum current score of all bot managers in the history.
45
     *
46
     * @param history the history to analyse
47
     * @return the maximum current score of all bot managers in the history.
48
     */
49
    public static int getMaxCurrentBotScore(History history) {
50 1 1. getMaxCurrentBotScore : replaced int return with 0 for com/takenoko/bot/utils/HistoryAnalysis::getMaxCurrentBotScore → KILLED
        return Collections.max(getCurrentBotScores(history).values());
51
    }
52
53
    /**
54
     * Calculate the game progress as an Link{@code GameProgress} Enum.
55
     *
56
     * @param history the history to analyse
57
     * @return the game progress as an Link{@code GameProgress} Enum.
58
     */
59
    public static GameProgress getGameProgress(History history) {
60
        // if no-one has completed less that MID_GAME_THRESHOLD objectives, the game is in the
61
        // early game
62
        // if someone has completed more than LATE_GAME_THRESHOLD objectives, the game is in the
63
        // late game
64
        // otherwise, the game is in the mid-game
65
66 1 1. getGameProgress : negated conditional → KILLED
        if (history.getLatestHistoryItems() == null) {
67 1 1. getGameProgress : replaced return value with null for com/takenoko/bot/utils/HistoryAnalysis::getGameProgress → NO_COVERAGE
            return GameProgress.EARLY_GAME;
68
        }
69
70
        if (history.getLatestHistoryItems().values().stream()
71 1 1. getGameProgress : negated conditional → KILLED
                .allMatch(
72
                        historyItem ->
73 1 1. lambda$getGameProgress$1 : replaced boolean return with true for com/takenoko/bot/utils/HistoryAnalysis::lambda$getGameProgress$1 → KILLED
                                historyItem.redeemedObjectives().size()
74
                                                / (double)
75
                                                        GameEngine
76
                                                                .DEFAULT_NUMBER_OF_OBJECTIVES_TO_WIN
77 3 1. lambda$getGameProgress$1 : changed conditional boundary → TIMED_OUT
2. lambda$getGameProgress$1 : Replaced double division with multiplication → KILLED
3. lambda$getGameProgress$1 : negated conditional → KILLED
                                                                .get(history.keySet().size())
78
                                        < MID_GAME_THRESHOLD)) {
79 1 1. getGameProgress : replaced return value with null for com/takenoko/bot/utils/HistoryAnalysis::getGameProgress → KILLED
            return GameProgress.EARLY_GAME;
80
        }
81
        if (history.getLatestHistoryItems().values().stream()
82 1 1. getGameProgress : negated conditional → KILLED
                .anyMatch(
83
                        historyItem ->
84 1 1. lambda$getGameProgress$2 : replaced boolean return with true for com/takenoko/bot/utils/HistoryAnalysis::lambda$getGameProgress$2 → KILLED
                                historyItem.redeemedObjectives().size()
85
                                                / (double)
86
                                                        GameEngine
87
                                                                .DEFAULT_NUMBER_OF_OBJECTIVES_TO_WIN
88 3 1. lambda$getGameProgress$2 : changed conditional boundary → TIMED_OUT
2. lambda$getGameProgress$2 : Replaced double division with multiplication → KILLED
3. lambda$getGameProgress$2 : negated conditional → KILLED
                                                                .get(history.keySet().size())
89
                                        > LATE_GAME_THRESHOLD)) {
90 1 1. getGameProgress : replaced return value with null for com/takenoko/bot/utils/HistoryAnalysis::getGameProgress → KILLED
            return GameProgress.LATE_GAME;
91
        }
92 1 1. getGameProgress : replaced return value with null for com/takenoko/bot/utils/HistoryAnalysis::getGameProgress → KILLED
        return GameProgress.MID_GAME;
93
    }
94
95
    /**
96
     * Analyse the history and determine the bots which are using the Rush Panda strategy.
97
     *
98
     * @param history the history to analyse
99
     * @return a map of the bot managers which are using the Rush Panda strategy.
100
     */
101
    static Map<UUID, Boolean> analyzeRushPanda(History history, double threshold) {
102
        // if the bot has moved a panda more than threshold times, it is using the Rush Panda
103
        // strategy
104
105 1 1. analyzeRushPanda : replaced return value with Collections.emptyMap for com/takenoko/bot/utils/HistoryAnalysis::analyzeRushPanda → KILLED
        return history.entrySet().stream()
106
                .map(
107
                        uuidListEntry ->
108 1 1. lambda$analyzeRushPanda$5 : replaced return value with null for com/takenoko/bot/utils/HistoryAnalysis::lambda$analyzeRushPanda$5 → KILLED
                                Map.entry(
109
                                        uuidListEntry.getKey(),
110
                                        uuidListEntry.getValue().stream()
111
                                                                .filter(
112
                                                                        roundHistory ->
113 2 1. lambda$analyzeRushPanda$4 : replaced boolean return with false for com/takenoko/bot/utils/HistoryAnalysis::lambda$analyzeRushPanda$4 → KILLED
2. lambda$analyzeRushPanda$4 : replaced boolean return with true for com/takenoko/bot/utils/HistoryAnalysis::lambda$analyzeRushPanda$4 → KILLED
                                                                                roundHistory
114
                                                                                        .stream()
115
                                                                                        .anyMatch(
116
                                                                                                action ->
117 1 1. lambda$analyzeRushPanda$3 : replaced boolean return with true for com/takenoko/bot/utils/HistoryAnalysis::lambda$analyzeRushPanda$3 → KILLED
                                                                                                        action.action()
118
                                                                                                                        .getClass()
119 1 1. lambda$analyzeRushPanda$3 : negated conditional → KILLED
                                                                                                                        .equals(
120
                                                                                                                                MovePandaAction
121
                                                                                                                                        .class)
122
                                                                                                                || action.action()
123
                                                                                                                        .getClass()
124 1 1. lambda$analyzeRushPanda$3 : negated conditional → KILLED
                                                                                                                        .equals(
125
                                                                                                                                ForcedMovePandaAction
126
                                                                                                                                        .class)))
127
                                                                .count()
128
                                                        / (double)
129
                                                                history.get(uuidListEntry.getKey())
130 3 1. lambda$analyzeRushPanda$5 : changed conditional boundary → TIMED_OUT
2. lambda$analyzeRushPanda$5 : Replaced double division with multiplication → KILLED
3. lambda$analyzeRushPanda$5 : negated conditional → KILLED
                                                                        .size()
131
                                                > threshold))
132
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
133
    }
134
135
    public static Map<UUID, Boolean> analyzeRushPanda(History history) {
136 1 1. analyzeRushPanda : replaced return value with Collections.emptyMap for com/takenoko/bot/utils/HistoryAnalysis::analyzeRushPanda → KILLED
        return analyzeRushPanda(history, DEFAULT_RUSH_PANDA_THRESHOLD);
137
    }
138
}

Mutations

29

1.1
Location : getCurrentBotScores
Killed by : com.takenoko.bot.utils.HistoryAnalysisTest.[engine:junit-jupiter]/[class:com.takenoko.bot.utils.HistoryAnalysisTest]/[nested-class:GetCurrentBotScores]/[method:shouldReturnMapOfCurrentScores()]
replaced return value with Collections.emptyMap for com/takenoko/bot/utils/HistoryAnalysis::getCurrentBotScores → KILLED

32

1.1
Location : lambda$getCurrentBotScores$0
Killed by : com.takenoko.bot.utils.HistoryAnalysisTest.[engine:junit-jupiter]/[class:com.takenoko.bot.utils.HistoryAnalysisTest]/[nested-class:GetCurrentBotScores]/[method:shouldReturnMapOfCurrentScores()]
replaced return value with null for com/takenoko/bot/utils/HistoryAnalysis::lambda$getCurrentBotScores$0 → KILLED

50

1.1
Location : getMaxCurrentBotScore
Killed by : com.takenoko.bot.utils.HistoryAnalysisTest.[engine:junit-jupiter]/[class:com.takenoko.bot.utils.HistoryAnalysisTest]/[nested-class:GetMaxCurrentBotScore]/[method:shouldReturnMaxScore()]
replaced int return with 0 for com/takenoko/bot/utils/HistoryAnalysis::getMaxCurrentBotScore → KILLED

66

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

67

1.1
Location : getGameProgress
Killed by : none
replaced return value with null for com/takenoko/bot/utils/HistoryAnalysis::getGameProgress → NO_COVERAGE

71

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

73

1.1
Location : lambda$getGameProgress$1
Killed by : com.takenoko.bot.utils.HistoryAnalysisTest.[engine:junit-jupiter]/[class:com.takenoko.bot.utils.HistoryAnalysisTest]/[nested-class:GetGameProgress]/[method:shouldReturnLateGame()]
replaced boolean return with true for com/takenoko/bot/utils/HistoryAnalysis::lambda$getGameProgress$1 → KILLED

77

1.1
Location : lambda$getGameProgress$1
Killed by : none
changed conditional boundary → TIMED_OUT

2.2
Location : lambda$getGameProgress$1
Killed by : com.takenoko.bot.utils.HistoryAnalysisTest.[engine:junit-jupiter]/[class:com.takenoko.bot.utils.HistoryAnalysisTest]/[nested-class:GetGameProgress]/[method:shouldReturnEarlyGame()]
Replaced double division with multiplication → KILLED

3.3
Location : lambda$getGameProgress$1
Killed by : com.takenoko.bot.utils.HistoryAnalysisTest.[engine:junit-jupiter]/[class:com.takenoko.bot.utils.HistoryAnalysisTest]/[nested-class:GetGameProgress]/[method:shouldReturnEarlyGame()]
negated conditional → KILLED

79

1.1
Location : getGameProgress
Killed by : com.takenoko.bot.utils.HistoryAnalysisTest.[engine:junit-jupiter]/[class:com.takenoko.bot.utils.HistoryAnalysisTest]/[nested-class:GetGameProgress]/[method:shouldReturnEarlyGame()]
replaced return value with null for com/takenoko/bot/utils/HistoryAnalysis::getGameProgress → KILLED

82

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

84

1.1
Location : lambda$getGameProgress$2
Killed by : com.takenoko.bot.utils.HistoryAnalysisTest.[engine:junit-jupiter]/[class:com.takenoko.bot.utils.HistoryAnalysisTest]/[nested-class:GetGameProgress]/[method:shouldReturnMidGame()]
replaced boolean return with true for com/takenoko/bot/utils/HistoryAnalysis::lambda$getGameProgress$2 → KILLED

88

1.1
Location : lambda$getGameProgress$2
Killed by : none
changed conditional boundary → TIMED_OUT

2.2
Location : lambda$getGameProgress$2
Killed by : com.takenoko.bot.utils.HistoryAnalysisTest.[engine:junit-jupiter]/[class:com.takenoko.bot.utils.HistoryAnalysisTest]/[nested-class:GetGameProgress]/[method:shouldReturnMidGame()]
Replaced double division with multiplication → KILLED

3.3
Location : lambda$getGameProgress$2
Killed by : com.takenoko.bot.utils.HistoryAnalysisTest.[engine:junit-jupiter]/[class:com.takenoko.bot.utils.HistoryAnalysisTest]/[nested-class:GetGameProgress]/[method:shouldReturnMidGame()]
negated conditional → KILLED

90

1.1
Location : getGameProgress
Killed by : com.takenoko.bot.utils.HistoryAnalysisTest.[engine:junit-jupiter]/[class:com.takenoko.bot.utils.HistoryAnalysisTest]/[nested-class:GetGameProgress]/[method:shouldReturnLateGame()]
replaced return value with null for com/takenoko/bot/utils/HistoryAnalysis::getGameProgress → KILLED

92

1.1
Location : getGameProgress
Killed by : com.takenoko.bot.utils.HistoryAnalysisTest.[engine:junit-jupiter]/[class:com.takenoko.bot.utils.HistoryAnalysisTest]/[nested-class:GetGameProgress]/[method:shouldReturnMidGame()]
replaced return value with null for com/takenoko/bot/utils/HistoryAnalysis::getGameProgress → KILLED

105

1.1
Location : analyzeRushPanda
Killed by : com.takenoko.bot.utils.HistoryAnalysisTest.[engine:junit-jupiter]/[class:com.takenoko.bot.utils.HistoryAnalysisTest]/[nested-class:AnalyzeRushPanda]/[method:shouldReturnTrueWhenBotHasRushedPanda()]
replaced return value with Collections.emptyMap for com/takenoko/bot/utils/HistoryAnalysis::analyzeRushPanda → KILLED

108

1.1
Location : lambda$analyzeRushPanda$5
Killed by : com.takenoko.bot.utils.HistoryAnalysisTest.[engine:junit-jupiter]/[class:com.takenoko.bot.utils.HistoryAnalysisTest]/[nested-class:AnalyzeRushPanda]/[method:shouldReturnTrueWhenBotHasRushedPanda()]
replaced return value with null for com/takenoko/bot/utils/HistoryAnalysis::lambda$analyzeRushPanda$5 → KILLED

113

1.1
Location : lambda$analyzeRushPanda$4
Killed by : com.takenoko.bot.utils.HistoryAnalysisTest.[engine:junit-jupiter]/[class:com.takenoko.bot.utils.HistoryAnalysisTest]/[nested-class:AnalyzeRushPanda]/[method:shouldReturnTrueWhenBotHasRushedPanda()]
replaced boolean return with false for com/takenoko/bot/utils/HistoryAnalysis::lambda$analyzeRushPanda$4 → KILLED

2.2
Location : lambda$analyzeRushPanda$4
Killed by : com.takenoko.bot.utils.HistoryAnalysisTest.[engine:junit-jupiter]/[class:com.takenoko.bot.utils.HistoryAnalysisTest]/[nested-class:AnalyzeRushPanda]/[method:shouldReturnFalseWhenBotHasNotRushedPanda()]
replaced boolean return with true for com/takenoko/bot/utils/HistoryAnalysis::lambda$analyzeRushPanda$4 → KILLED

117

1.1
Location : lambda$analyzeRushPanda$3
Killed by : com.takenoko.bot.utils.HistoryAnalysisTest.[engine:junit-jupiter]/[class:com.takenoko.bot.utils.HistoryAnalysisTest]/[nested-class:AnalyzeRushPanda]/[method:shouldReturnFalseWhenBotHasNotRushedPanda()]
replaced boolean return with true for com/takenoko/bot/utils/HistoryAnalysis::lambda$analyzeRushPanda$3 → KILLED

119

1.1
Location : lambda$analyzeRushPanda$3
Killed by : com.takenoko.bot.utils.HistoryAnalysisTest.[engine:junit-jupiter]/[class:com.takenoko.bot.utils.HistoryAnalysisTest]/[nested-class:AnalyzeRushPanda]/[method:shouldReturnFalseWhenBotHasNotRushedPanda()]
negated conditional → KILLED

124

1.1
Location : lambda$analyzeRushPanda$3
Killed by : com.takenoko.bot.utils.HistoryAnalysisTest.[engine:junit-jupiter]/[class:com.takenoko.bot.utils.HistoryAnalysisTest]/[nested-class:AnalyzeRushPanda]/[method:shouldReturnFalseWhenBotHasNotRushedPanda()]
negated conditional → KILLED

130

1.1
Location : lambda$analyzeRushPanda$5
Killed by : none
changed conditional boundary → TIMED_OUT

2.2
Location : lambda$analyzeRushPanda$5
Killed by : com.takenoko.bot.utils.HistoryAnalysisTest.[engine:junit-jupiter]/[class:com.takenoko.bot.utils.HistoryAnalysisTest]/[nested-class:AnalyzeRushPanda]/[method:shouldReturnFalseWhenBotHasNotRushedPanda()]
Replaced double division with multiplication → KILLED

3.3
Location : lambda$analyzeRushPanda$5
Killed by : com.takenoko.bot.utils.HistoryAnalysisTest.[engine:junit-jupiter]/[class:com.takenoko.bot.utils.HistoryAnalysisTest]/[nested-class:AnalyzeRushPanda]/[method:shouldReturnTrueWhenBotHasRushedPanda()]
negated conditional → KILLED

136

1.1
Location : analyzeRushPanda
Killed by : com.takenoko.bot.utils.HistoryAnalysisTest.[engine:junit-jupiter]/[class:com.takenoko.bot.utils.HistoryAnalysisTest]/[nested-class:AnalyzeRushPanda]/[method:shouldReturnFalseWhenBotHasNotRushedPanda()]
replaced return value with Collections.emptyMap for com/takenoko/bot/utils/HistoryAnalysis::analyzeRushPanda → KILLED

Active mutators

Tests examined


Report generated by PIT 1.8.0