| 1 | package com.takenoko.bot.unitary; | |
| 2 | ||
| 3 | import com.takenoko.actions.irrigation.PlaceIrrigationFromInventoryAction; | |
| 4 | import com.takenoko.bot.PriorityBot; | |
| 5 | import com.takenoko.bot.utils.pathfinding.irrigation.IrrigationPathFinding; | |
| 6 | import com.takenoko.engine.Board; | |
| 7 | import com.takenoko.engine.BotState; | |
| 8 | import com.takenoko.engine.History; | |
| 9 | import com.takenoko.layers.irrigation.EdgePosition; | |
| 10 | import com.takenoko.layers.tile.Tile; | |
| 11 | import com.takenoko.objective.Objective; | |
| 12 | import com.takenoko.objective.PatternObjective; | |
| 13 | import com.takenoko.shape.Shape; | |
| 14 | import com.takenoko.vector.PositionVector; | |
| 15 | import java.util.*; | |
| 16 | ||
| 17 | public class SmartPlaceIrrigation extends PriorityBot { | |
| 18 | private final List<EdgePosition> irrigationToPlace = new ArrayList<>(); | |
| 19 | ||
| 20 | @Override | |
| 21 | protected void fillAction(Board board, BotState botState, History history) { | |
| 22 | // Complete a PatternObjective by adding irrigation channels | |
| 23 |
1
1. fillAction : negated conditional → TIMED_OUT |
if (botState.getAvailableActions().contains(PlaceIrrigationFromInventoryAction.class)) { |
| 24 | // Because it is empty, we have to analyze the board to find the best irrigation path | |
| 25 |
1
1. fillAction : negated conditional → TIMED_OUT |
if (irrigationToPlace.isEmpty()) { |
| 26 |
1
1. fillAction : removed call to com/takenoko/bot/unitary/SmartPlaceIrrigation::analyzeIrrigationToPlaceToCompletePatternObjective → TIMED_OUT |
analyzeIrrigationToPlaceToCompletePatternObjective(board, botState); |
| 27 | } | |
| 28 | // If there is a path to complete the objective, we place the first edge | |
| 29 |
1
1. fillAction : negated conditional → KILLED |
if (!irrigationToPlace.isEmpty()) { |
| 30 |
1
1. fillAction : removed call to com/takenoko/bot/unitary/SmartPlaceIrrigation::addActionWithPriority → TIMED_OUT |
this.addActionWithPriority( |
| 31 | new PlaceIrrigationFromInventoryAction(irrigationToPlace.remove(0)), | |
| 32 | DEFAULT_PRIORITY); | |
| 33 | } | |
| 34 | } | |
| 35 | } | |
| 36 | ||
| 37 | @Override | |
| 38 | public boolean equals(Object o) { | |
| 39 |
2
1. equals : negated conditional → NO_COVERAGE 2. equals : replaced boolean return with false for com/takenoko/bot/unitary/SmartPlaceIrrigation::equals → NO_COVERAGE |
if (this == o) return true; |
| 40 |
3
1. equals : negated conditional → NO_COVERAGE 2. equals : negated conditional → NO_COVERAGE 3. equals : replaced boolean return with true for com/takenoko/bot/unitary/SmartPlaceIrrigation::equals → NO_COVERAGE |
if (o == null || getClass() != o.getClass()) return false; |
| 41 |
2
1. equals : negated conditional → NO_COVERAGE 2. equals : replaced boolean return with true for com/takenoko/bot/unitary/SmartPlaceIrrigation::equals → NO_COVERAGE |
if (!super.equals(o)) return false; |
| 42 | SmartPlaceIrrigation that = (SmartPlaceIrrigation) o; | |
| 43 |
2
1. equals : replaced boolean return with false for com/takenoko/bot/unitary/SmartPlaceIrrigation::equals → NO_COVERAGE 2. equals : replaced boolean return with true for com/takenoko/bot/unitary/SmartPlaceIrrigation::equals → NO_COVERAGE |
return Objects.equals(irrigationToPlace, that.irrigationToPlace); |
| 44 | } | |
| 45 | ||
| 46 | @Override | |
| 47 | public int hashCode() { | |
| 48 |
1
1. hashCode : replaced int return with 0 for com/takenoko/bot/unitary/SmartPlaceIrrigation::hashCode → NO_COVERAGE |
return Objects.hash(super.hashCode(), irrigationToPlace); |
| 49 | } | |
| 50 | ||
| 51 | /** | |
| 52 | * This method will add the edge position to the irrigationToPlace list so that the bot knows | |
| 53 | * that he has to place them in order to complete is pattern objectiv | |
| 54 | * | |
| 55 | * @param board the board | |
| 56 | * @param botState the bot state | |
| 57 | */ | |
| 58 | public void analyzeIrrigationToPlaceToCompletePatternObjective(Board board, BotState botState) { | |
| 59 | // Verify that the bot has | |
| 60 | // - at least one pattern objective that is not already completed | |
| 61 |
1
1. analyzeIrrigationToPlaceToCompletePatternObjective : negated conditional → TIMED_OUT |
if (!allPatternObjectivesAreCompleted(botState)) { |
| 62 | // Get all the shapes that could be completed by placing an irrigation | |
| 63 | List<List<Shape>> candidateShapes = getCandidateShapes(board, botState); | |
| 64 | ||
| 65 | // If it is not empty, be intelligent | |
| 66 |
1
1. analyzeIrrigationToPlaceToCompletePatternObjective : negated conditional → TIMED_OUT |
if (!candidateShapes.isEmpty()) { |
| 67 | List<List<EdgePosition>> allPossiblePaths = new ArrayList<>(); | |
| 68 | for (List<Shape> shapeList : candidateShapes) { | |
| 69 | for (Shape shape : shapeList) { | |
| 70 | // Get the position vector and tile of the shape | |
| 71 | Map<PositionVector, Tile> map = shape.getElements(); | |
| 72 | // Find the tiles that are not irrigated yet | |
| 73 | List<PositionVector> candidateTilesToIrrigate = | |
| 74 | map.keySet().stream() | |
| 75 |
2
1. lambda$analyzeIrrigationToPlaceToCompletePatternObjective$0 : negated conditional → TIMED_OUT 2. lambda$analyzeIrrigationToPlaceToCompletePatternObjective$0 : replaced boolean return with true for com/takenoko/bot/unitary/SmartPlaceIrrigation::lambda$analyzeIrrigationToPlaceToCompletePatternObjective$0 → TIMED_OUT |
.filter(tile -> !board.isIrrigatedAt(tile)) |
| 76 | .toList(); | |
| 77 | // Find which irrigation to place to irrigate all the tiles of the shape | |
| 78 | List<EdgePosition> possibleEdgePositions = | |
| 79 | IrrigationPathFinding.getShortestIrrigationPath( | |
| 80 | candidateTilesToIrrigate, board); | |
| 81 | ||
| 82 | // Verify that the number of irrigation needed does not exceed the number of | |
| 83 | // irrigation available | |
| 84 | if (botState.getInventory().getIrrigationChannelsCount() | |
| 85 |
2
1. analyzeIrrigationToPlaceToCompletePatternObjective : changed conditional boundary → TIMED_OUT 2. analyzeIrrigationToPlaceToCompletePatternObjective : negated conditional → TIMED_OUT |
> possibleEdgePositions.size()) { |
| 86 | allPossiblePaths.add(possibleEdgePositions); | |
| 87 | } | |
| 88 | } | |
| 89 | } | |
| 90 | ||
| 91 |
1
1. analyzeIrrigationToPlaceToCompletePatternObjective : removed call to java/util/List::clear → TIMED_OUT |
irrigationToPlace.clear(); |
| 92 | // Choose the shortest path | |
| 93 | allPossiblePaths.stream() | |
| 94 | .min(Comparator.comparingInt(List::size)) | |
| 95 |
1
1. analyzeIrrigationToPlaceToCompletePatternObjective : removed call to java/util/Optional::ifPresent → TIMED_OUT |
.ifPresent(irrigationToPlace::addAll); |
| 96 | } | |
| 97 | } | |
| 98 | } | |
| 99 | ||
| 100 | /** | |
| 101 | * Check if any of the pattern objectives are completed | |
| 102 | * | |
| 103 | * @param botState the bot state | |
| 104 | * @return true if there is at least a pattern objective completed, false otherwise | |
| 105 | */ | |
| 106 | public boolean allPatternObjectivesAreCompleted(BotState botState) { | |
| 107 | for (Objective objective : getCurrentPatternObjectives(botState)) { | |
| 108 |
1
1. allPatternObjectivesAreCompleted : negated conditional → TIMED_OUT |
if (!objective.isAchieved()) { |
| 109 |
1
1. allPatternObjectivesAreCompleted : replaced boolean return with true for com/takenoko/bot/unitary/SmartPlaceIrrigation::allPatternObjectivesAreCompleted → TIMED_OUT |
return false; |
| 110 | } | |
| 111 | } | |
| 112 |
1
1. allPatternObjectivesAreCompleted : replaced boolean return with false for com/takenoko/bot/unitary/SmartPlaceIrrigation::allPatternObjectivesAreCompleted → TIMED_OUT |
return true; |
| 113 | } | |
| 114 | ||
| 115 | /** | |
| 116 | * Get all the shape matching the patterns on the current pattern objectives | |
| 117 | * | |
| 118 | * @param board the board | |
| 119 | * @param botState the bot state | |
| 120 | * @return the list of shapes matching the pattern objectives | |
| 121 | */ | |
| 122 | public List<List<Shape>> getCandidateShapes(Board board, BotState botState) { | |
| 123 | List<PatternObjective> patternObjectives = getCurrentPatternObjectives(botState); | |
| 124 | ||
| 125 | List<List<Shape>> matchedPatterns = new ArrayList<>(); | |
| 126 | for (PatternObjective patternObjective : patternObjectives) { | |
| 127 | matchedPatterns.add(patternObjective.getPattern().match(board, true)); | |
| 128 | } | |
| 129 | ||
| 130 |
1
1. getCandidateShapes : replaced return value with Collections.emptyList for com/takenoko/bot/unitary/SmartPlaceIrrigation::getCandidateShapes → TIMED_OUT |
return matchedPatterns; |
| 131 | } | |
| 132 | ||
| 133 | public List<PatternObjective> getCurrentPatternObjectives(BotState botState) { | |
| 134 |
1
1. getCurrentPatternObjectives : replaced return value with Collections.emptyList for com/takenoko/bot/unitary/SmartPlaceIrrigation::getCurrentPatternObjectives → TIMED_OUT |
return botState.getObjectives().stream() |
| 135 | .filter(PatternObjective.class::isInstance) | |
| 136 | .map(PatternObjective.class::cast) | |
| 137 | .toList(); | |
| 138 | } | |
| 139 | } | |
Mutations | ||
| 23 |
1.1 |
|
| 25 |
1.1 |
|
| 26 |
1.1 |
|
| 29 |
1.1 |
|
| 30 |
1.1 |
|
| 39 |
1.1 2.2 |
|
| 40 |
1.1 2.2 3.3 |
|
| 41 |
1.1 2.2 |
|
| 43 |
1.1 2.2 |
|
| 48 |
1.1 |
|
| 61 |
1.1 |
|
| 66 |
1.1 |
|
| 75 |
1.1 2.2 |
|
| 85 |
1.1 2.2 |
|
| 91 |
1.1 |
|
| 95 |
1.1 |
|
| 108 |
1.1 |
|
| 109 |
1.1 |
|
| 112 |
1.1 |
|
| 130 |
1.1 |
|
| 134 |
1.1 |