| 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 |
|
| 32 |
1.1 |
|
| 50 |
1.1 |
|
| 66 |
1.1 |
|
| 67 |
1.1 |
|
| 71 |
1.1 |
|
| 73 |
1.1 |
|
| 77 |
1.1 2.2 3.3 |
|
| 79 |
1.1 |
|
| 82 |
1.1 |
|
| 84 |
1.1 |
|
| 88 |
1.1 2.2 3.3 |
|
| 90 |
1.1 |
|
| 92 |
1.1 |
|
| 105 |
1.1 |
|
| 108 |
1.1 |
|
| 113 |
1.1 2.2 |
|
| 117 |
1.1 |
|
| 119 |
1.1 |
|
| 124 |
1.1 |
|
| 130 |
1.1 2.2 3.3 |
|
| 136 |
1.1 |