| 1 | package com.takenoko.engine; | |
| 2 | ||
| 3 | import com.takenoko.actions.Action; | |
| 4 | import com.takenoko.actions.ActionResult; | |
| 5 | import com.takenoko.actions.weather.ChooseIfApplyWeatherAction; | |
| 6 | import com.takenoko.bot.Bot; | |
| 7 | import com.takenoko.bot.FullRandomBot; | |
| 8 | import com.takenoko.inventory.Inventory; | |
| 9 | import com.takenoko.objective.Objective; | |
| 10 | import com.takenoko.stats.SingleBotStatistics; | |
| 11 | import com.takenoko.ui.ConsoleUserInterface; | |
| 12 | import java.util.List; | |
| 13 | import java.util.UUID; | |
| 14 | ||
| 15 | /** | |
| 16 | * This class is used to manage one bot. | |
| 17 | * | |
| 18 | * <ul> | |
| 19 | * <li>name | |
| 20 | * <li>objective | |
| 21 | * <li>number of actions | |
| 22 | * <li>bamboos eaten counter | |
| 23 | * </ul> | |
| 24 | */ | |
| 25 | public class BotManager { | |
| 26 | private static final ConsoleUserInterface DEFAULT_CONSOLE_USER_INTERFACE = | |
| 27 | new ConsoleUserInterface(); | |
| 28 | private static final String DEFAULT_NAME = "Joe"; | |
| 29 | private static final Bot DEFAULT_BOT = new FullRandomBot(); | |
| 30 | // ATTRIBUTES | |
| 31 | private final ConsoleUserInterface consoleUserInterface; | |
| 32 | private final BotState botState; | |
| 33 | private final String name; | |
| 34 | private final Bot bot; | |
| 35 | private final int defaultNumberOfActions; | |
| 36 | private final SingleBotStatistics singleBotStatistics; | |
| 37 | private final UUID uniqueID = UUID.randomUUID(); | |
| 38 | ||
| 39 | /** | |
| 40 | * Constructor for the class | |
| 41 | * | |
| 42 | * @param consoleUserInterface the console user interface | |
| 43 | * @param name the name of the bot | |
| 44 | * @param bot the bot | |
| 45 | * @param botState the bot state | |
| 46 | * @param botStatistics the extended statistics for this botManager | |
| 47 | */ | |
| 48 | public BotManager( | |
| 49 | ConsoleUserInterface consoleUserInterface, | |
| 50 | String name, | |
| 51 | Bot bot, | |
| 52 | BotState botState, | |
| 53 | SingleBotStatistics botStatistics) { | |
| 54 | this.botState = botState; | |
| 55 | this.consoleUserInterface = consoleUserInterface; | |
| 56 | this.name = name; | |
| 57 | this.bot = bot; | |
| 58 | this.defaultNumberOfActions = botState.getNumberOfActions(); | |
| 59 | this.singleBotStatistics = botStatistics; | |
| 60 | } | |
| 61 | ||
| 62 | public UUID getUniqueID() { | |
| 63 |
1
1. getUniqueID : replaced return value with null for com/takenoko/engine/BotManager::getUniqueID → KILLED |
return uniqueID; |
| 64 | } | |
| 65 | ||
| 66 | /** Default constructor for the class */ | |
| 67 | public BotManager() { | |
| 68 | this( | |
| 69 | DEFAULT_CONSOLE_USER_INTERFACE, | |
| 70 | DEFAULT_NAME, | |
| 71 | DEFAULT_BOT, | |
| 72 | new BotState(), | |
| 73 | new SingleBotStatistics()); | |
| 74 | } | |
| 75 | ||
| 76 | /** | |
| 77 | * Constructor for the class but this time specifying which bot algorithm must be used | |
| 78 | * | |
| 79 | * @param bot the bot | |
| 80 | */ | |
| 81 | public BotManager(Bot bot) { | |
| 82 | this( | |
| 83 | DEFAULT_CONSOLE_USER_INTERFACE, | |
| 84 | DEFAULT_NAME, | |
| 85 | bot, | |
| 86 | new BotState(), | |
| 87 | new SingleBotStatistics()); | |
| 88 | } | |
| 89 | ||
| 90 | public BotManager(Bot bot, String name) { | |
| 91 | this(DEFAULT_CONSOLE_USER_INTERFACE, name, bot, new BotState(), new SingleBotStatistics()); | |
| 92 | } | |
| 93 | ||
| 94 | /** | |
| 95 | * Ask for the bot to choose an action based on his algorithm and then execute the returned | |
| 96 | * action. Objectives are also verified in order to know if the bot has won. | |
| 97 | * | |
| 98 | * @param board the board of the game | |
| 99 | * @param history the history of the game | |
| 100 | */ | |
| 101 | public void playBot(Board board, History history) { | |
| 102 |
1
1. playBot : removed call to com/takenoko/engine/BotState::resetAvailableActions → TIMED_OUT |
botState.resetAvailableActions(board); |
| 103 |
1
1. playBot : removed call to com/takenoko/engine/BotState::setNumberOfActions → KILLED |
botState.setNumberOfActions(defaultNumberOfActions); |
| 104 | ||
| 105 | TurnHistory turnHistory = new TurnHistory(); | |
| 106 | ||
| 107 |
2
1. playBot : changed conditional boundary → TIMED_OUT 2. playBot : negated conditional → TIMED_OUT |
if (board.getRoundNumber() > 0) { |
| 108 |
1
1. playBot : removed call to com/takenoko/engine/Board::rollWeather → TIMED_OUT |
board.rollWeather(); |
| 109 |
1
1. playBot : removed call to com/takenoko/engine/BotManager::displayMessage → SURVIVED |
displayMessage(this.getName() + " rolled weather: " + board.peekWeather()); |
| 110 |
1
1. playBot : removed call to com/takenoko/stats/SingleBotStatistics::updateWeathersRolled → TIMED_OUT |
singleBotStatistics.updateWeathersRolled(board.peekWeather().toString()); |
| 111 |
1
1. playBot : removed call to com/takenoko/engine/BotState::addAvailableAction → TIMED_OUT |
botState.addAvailableAction(ChooseIfApplyWeatherAction.class); |
| 112 | } | |
| 113 |
1
1. playBot : negated conditional → KILLED |
while (canPlayBot()) { |
| 114 |
1
1. playBot : removed call to com/takenoko/engine/BotState::update → KILLED |
botState.update(board); |
| 115 |
1
1. playBot : removed call to com/takenoko/engine/BotManager::displayDebugBotState → TIMED_OUT |
displayDebugBotState(); |
| 116 | ||
| 117 |
1
1. playBot : negated conditional → KILLED |
if (botState.getAvailableActions().isEmpty()) { |
| 118 |
1
1. playBot : removed call to com/takenoko/ui/ConsoleUserInterface::displayError → SURVIVED |
consoleUserInterface.displayError( |
| 119 | "The bot " + name + " has no available actions. This turn is skipped."); | |
| 120 | break; | |
| 121 | } | |
| 122 | ||
| 123 | Action action = bot.chooseAction(board.copy(), botState.copy(), history.copy()); | |
| 124 |
1
1. playBot : negated conditional → KILLED |
if (!botState.getAvailableActions().contains(action.getClass())) { |
| 125 | throw new IllegalStateException( | |
| 126 | "The action " | |
| 127 | + action.getClass().getSimpleName() | |
| 128 | + " is not available for the bot " | |
| 129 | + name | |
| 130 | + ". Please choose another action."); | |
| 131 | } | |
| 132 | ||
| 133 | ActionResult actionResult = action.execute(board, this); | |
| 134 | turnHistory.add(new HistoryItem(action, getRedeemedObjectives())); | |
| 135 |
1
1. playBot : removed call to com/takenoko/engine/BotState::updateAvailableActions → TIMED_OUT |
botState.updateAvailableActions(action, actionResult); |
| 136 | } | |
| 137 |
1
1. playBot : removed call to com/takenoko/engine/History::addTurnHistory → TIMED_OUT |
history.addTurnHistory(this, turnHistory); |
| 138 |
1
1. playBot : removed call to com/takenoko/engine/History::updateHistoryStatistics → TIMED_OUT |
history.updateHistoryStatistics(this); |
| 139 |
2
1. lambda$playBot$0 : removed call to com/takenoko/weather/Weather::revert → TIMED_OUT 2. playBot : removed call to java/util/Optional::ifPresent → TIMED_OUT |
board.getWeather().ifPresent(value -> value.revert(board, this)); |
| 140 | } | |
| 141 | ||
| 142 | /** Display debug messages */ | |
| 143 | private void displayDebugBotState() { | |
| 144 |
1
1. displayDebugBotState : removed call to com/takenoko/ui/ConsoleUserInterface::displayDebug → KILLED |
consoleUserInterface.displayDebug( |
| 145 | this.getName() + " has " + botState.getNumberOfActions() + " actions."); | |
| 146 |
1
1. displayDebugBotState : removed call to com/takenoko/ui/ConsoleUserInterface::displayDebug → TIMED_OUT |
consoleUserInterface.displayDebug( |
| 147 | this.getName() | |
| 148 | + " can play: " | |
| 149 | + botState.getAvailableActions().stream() | |
| 150 | .map(Class::getSimpleName) | |
| 151 | .toList()); | |
| 152 |
1
1. displayDebugBotState : removed call to com/takenoko/ui/ConsoleUserInterface::displayDebug → TIMED_OUT |
consoleUserInterface.displayDebug( |
| 153 | this.getName() + " must complete: " + botState.getObjectives()); | |
| 154 |
1
1. displayDebugBotState : removed call to com/takenoko/ui/ConsoleUserInterface::displayDebug → TIMED_OUT |
consoleUserInterface.displayDebug( |
| 155 | this.getName() | |
| 156 | + " has already played: " | |
| 157 | + botState.getAlreadyDoneActions().stream() | |
| 158 | .map(Class::getSimpleName) | |
| 159 | .toList()); | |
| 160 |
1
1. displayDebugBotState : removed call to com/takenoko/ui/ConsoleUserInterface::displayDebug → TIMED_OUT |
consoleUserInterface.displayDebug( |
| 161 | this.getName() + " has achieved: " + botState.getAchievedObjectives()); | |
| 162 |
1
1. displayDebugBotState : removed call to com/takenoko/ui/ConsoleUserInterface::displayDebug → TIMED_OUT |
consoleUserInterface.displayDebug( |
| 163 | this.getName() + " has redeemed: " + botState.getRedeemedObjectives()); | |
| 164 | ||
| 165 |
1
1. displayDebugBotState : removed call to com/takenoko/ui/ConsoleUserInterface::displayDebug → TIMED_OUT |
consoleUserInterface.displayDebug( |
| 166 | this.getName() + " inventory: " + botState.getInventory()); | |
| 167 | } | |
| 168 | ||
| 169 | private boolean canPlayBot() { | |
| 170 |
3
1. canPlayBot : changed conditional boundary → TIMED_OUT 2. canPlayBot : replaced boolean return with true for com/takenoko/engine/BotManager::canPlayBot → TIMED_OUT 3. canPlayBot : negated conditional → KILLED |
return botState.getNumberOfActions() > 0; |
| 171 | } | |
| 172 | ||
| 173 | /** | |
| 174 | * @return number of actions the bot can do in a turn | |
| 175 | */ | |
| 176 | protected int getNumberOfActions() { | |
| 177 |
1
1. getNumberOfActions : replaced int return with 0 for com/takenoko/engine/BotManager::getNumberOfActions → KILLED |
return botState.getNumberOfActions(); |
| 178 | } | |
| 179 | ||
| 180 | /** | |
| 181 | * @param message the message to display | |
| 182 | */ | |
| 183 | public void displayMessage(String message) { | |
| 184 |
1
1. displayMessage : removed call to com/takenoko/ui/ConsoleUserInterface::displayMessage → KILLED |
consoleUserInterface.displayMessage(message); |
| 185 | } | |
| 186 | ||
| 187 | /** | |
| 188 | * @return the bot name | |
| 189 | */ | |
| 190 | public String getName() { | |
| 191 |
1
1. getName : replaced return value with "" for com/takenoko/engine/BotManager::getName → KILLED |
return name; |
| 192 | } | |
| 193 | ||
| 194 | /** | |
| 195 | * @return the number of bamboo eaten by the bot | |
| 196 | */ | |
| 197 | public int getEatenBambooCounter() { | |
| 198 |
1
1. getEatenBambooCounter : replaced int return with 0 for com/takenoko/engine/BotManager::getEatenBambooCounter → KILLED |
return botState.getEatenBambooCounter(); |
| 199 | } | |
| 200 | ||
| 201 | /** | |
| 202 | * Return the bot inventory | |
| 203 | * | |
| 204 | * @return the bot inventory | |
| 205 | */ | |
| 206 | public Inventory getInventory() { | |
| 207 |
1
1. getInventory : replaced return value with null for com/takenoko/engine/BotManager::getInventory → KILLED |
return botState.getInventory(); |
| 208 | } | |
| 209 | ||
| 210 | public void addAction() { | |
| 211 |
1
1. addAction : removed call to com/takenoko/engine/BotState::addAction → TIMED_OUT |
botState.addAction(); |
| 212 | } | |
| 213 | ||
| 214 | public void reset() { | |
| 215 |
1
1. reset : removed call to com/takenoko/engine/BotState::reset → KILLED |
this.botState.reset(); |
| 216 |
1
1. reset : removed call to com/takenoko/stats/SingleBotStatistics::reset → TIMED_OUT |
singleBotStatistics.reset(); |
| 217 | } | |
| 218 | ||
| 219 | public int getObjectiveScore() { | |
| 220 |
1
1. getObjectiveScore : replaced int return with 0 for com/takenoko/engine/BotManager::getObjectiveScore → KILLED |
return botState.getObjectiveScore(); |
| 221 | } | |
| 222 | ||
| 223 | public List<Objective> getAchievedObjectives() { | |
| 224 |
1
1. getAchievedObjectives : replaced return value with Collections.emptyList for com/takenoko/engine/BotManager::getAchievedObjectives → NO_COVERAGE |
return botState.getAchievedObjectives(); |
| 225 | } | |
| 226 | ||
| 227 | public List<Objective> getRedeemedObjectives() { | |
| 228 |
1
1. getRedeemedObjectives : replaced return value with Collections.emptyList for com/takenoko/engine/BotManager::getRedeemedObjectives → TIMED_OUT |
return botState.getRedeemedObjectives(); |
| 229 | } | |
| 230 | ||
| 231 | public void addObjective(Objective objective) { | |
| 232 |
1
1. addObjective : removed call to com/takenoko/engine/BotState::addObjective → TIMED_OUT |
botState.addObjective(objective); |
| 233 | } | |
| 234 | ||
| 235 | public void redeemObjective(Objective objective) { | |
| 236 |
1
1. redeemObjective : removed call to com/takenoko/engine/BotState::redeemObjective → TIMED_OUT |
botState.redeemObjective(objective); |
| 237 | } | |
| 238 | ||
| 239 | public int getPandaObjectiveScore() { | |
| 240 |
1
1. getPandaObjectiveScore : replaced int return with 0 for com/takenoko/engine/BotManager::getPandaObjectiveScore → SURVIVED |
return botState.getPandaObjectiveScore(); |
| 241 | } | |
| 242 | ||
| 243 | public void setObjectiveAchieved(Objective objective) { | |
| 244 |
1
1. setObjectiveAchieved : removed call to com/takenoko/engine/BotState::setObjectiveAchieved → TIMED_OUT |
botState.setObjectiveAchieved(objective); |
| 245 | } | |
| 246 | ||
| 247 | /** | |
| 248 | * Set the starting deck | |
| 249 | * | |
| 250 | * @param objectives list of objectives | |
| 251 | */ | |
| 252 | public void setStartingDeck(List<Objective> objectives) { | |
| 253 |
1
1. setStartingDeck : removed call to com/takenoko/engine/BotState::setStartingDeck → TIMED_OUT |
botState.setStartingDeck(objectives); |
| 254 | } | |
| 255 | ||
| 256 | public SingleBotStatistics getSingleBotStatistics() { | |
| 257 |
1
1. getSingleBotStatistics : replaced return value with null for com/takenoko/engine/BotManager::getSingleBotStatistics → KILLED |
return singleBotStatistics; |
| 258 | } | |
| 259 | ||
| 260 | public String toString() { | |
| 261 |
1
1. toString : replaced return value with "" for com/takenoko/engine/BotManager::toString → TIMED_OUT |
return name + " | Type: " + bot.getClass().getSimpleName(); |
| 262 | } | |
| 263 | } | |
Mutations | ||
| 63 |
1.1 |
|
| 102 |
1.1 |
|
| 103 |
1.1 |
|
| 107 |
1.1 2.2 |
|
| 108 |
1.1 |
|
| 109 |
1.1 |
|
| 110 |
1.1 |
|
| 111 |
1.1 |
|
| 113 |
1.1 |
|
| 114 |
1.1 |
|
| 115 |
1.1 |
|
| 117 |
1.1 |
|
| 118 |
1.1 |
|
| 124 |
1.1 |
|
| 135 |
1.1 |
|
| 137 |
1.1 |
|
| 138 |
1.1 |
|
| 139 |
1.1 2.2 |
|
| 144 |
1.1 |
|
| 146 |
1.1 |
|
| 152 |
1.1 |
|
| 154 |
1.1 |
|
| 160 |
1.1 |
|
| 162 |
1.1 |
|
| 165 |
1.1 |
|
| 170 |
1.1 2.2 3.3 |
|
| 177 |
1.1 |
|
| 184 |
1.1 |
|
| 191 |
1.1 |
|
| 198 |
1.1 |
|
| 207 |
1.1 |
|
| 211 |
1.1 |
|
| 215 |
1.1 |
|
| 216 |
1.1 |
|
| 220 |
1.1 |
|
| 224 |
1.1 |
|
| 228 |
1.1 |
|
| 232 |
1.1 |
|
| 236 |
1.1 |
|
| 240 |
1.1 |
|
| 244 |
1.1 |
|
| 253 |
1.1 |
|
| 257 |
1.1 |
|
| 261 |
1.1 |