Search in sources :

Example 46 with UnitAttachment

use of games.strategy.triplea.attachments.UnitAttachment in project triplea by triplea-game.

the class DiceRoll method airBattle.

static DiceRoll airBattle(final List<Unit> unitsList, final boolean defending, final PlayerID player, final IDelegateBridge bridge, final String annotation) {
    {
        final Set<Unit> duplicatesCheckSet1 = new HashSet<>(unitsList);
        if (unitsList.size() != duplicatesCheckSet1.size()) {
            throw new IllegalStateException("Duplicate Units Detected: Original List:" + unitsList + "  HashSet:" + duplicatesCheckSet1);
        }
    }
    final GameData data = bridge.getData();
    final boolean lhtrBombers = Properties.getLhtrHeavyBombers(data);
    final List<Unit> units = new ArrayList<>(unitsList);
    final int rollCount = AirBattle.getAirBattleRolls(unitsList, defending);
    if (rollCount == 0) {
        return new DiceRoll(new ArrayList<>(), 0, 0);
    }
    int[] random;
    final List<Die> dice = new ArrayList<>();
    int hitCount = 0;
    // bonus is normally 1 for most games
    final int extraRollBonus = Math.max(1, data.getDiceSides() / 6);
    int totalPower = 0;
    // We iterate through the units to find the total strength of the units
    for (final Unit current : units) {
        final UnitAttachment ua = UnitAttachment.get(current.getType());
        final int rolls = AirBattle.getAirBattleRolls(current, defending);
        int totalStrength = 0;
        final int strength = Math.min(data.getDiceSides(), Math.max(0, (defending ? ua.getAirDefense(current.getOwner()) : ua.getAirAttack(current.getOwner()))));
        for (int i = 0; i < rolls; i++) {
            // simulate the gains of having the best die picked.
            if (i > 1 && (lhtrBombers || ua.getChooseBestRoll())) {
                totalStrength += extraRollBonus;
                continue;
            }
            totalStrength += strength;
        }
        totalPower += Math.min(Math.max(totalStrength, 0), data.getDiceSides());
    }
    if (Properties.getLowLuck(data)) {
        // Get number of hits
        hitCount = totalPower / data.getDiceSides();
        random = new int[0];
        // We need to roll dice for the fractional part of the dice.
        final int power = totalPower % data.getDiceSides();
        if (power != 0) {
            random = bridge.getRandom(data.getDiceSides(), 1, player, DiceType.COMBAT, annotation);
            final boolean hit = power > random[0];
            if (hit) {
                hitCount++;
            }
            dice.add(new Die(random[0], power, hit ? DieType.HIT : DieType.MISS));
        }
    } else {
        random = bridge.getRandom(data.getDiceSides(), rollCount, player, DiceType.COMBAT, annotation);
        int diceIndex = 0;
        for (final Unit current : units) {
            final UnitAttachment ua = UnitAttachment.get(current.getType());
            final int strength = Math.min(data.getDiceSides(), Math.max(0, (defending ? ua.getAirDefense(current.getOwner()) : ua.getAirAttack(current.getOwner()))));
            final int rolls = AirBattle.getAirBattleRolls(current, defending);
            // lhtr heavy bombers take best of n dice for both attack and defense
            if (rolls > 1 && (lhtrBombers || ua.getChooseBestRoll())) {
                int minIndex = 0;
                int min = data.getDiceSides();
                for (int i = 0; i < rolls; i++) {
                    if (random[diceIndex + i] < min) {
                        min = random[diceIndex + i];
                        minIndex = i;
                    }
                }
                final boolean hit = strength > random[diceIndex + minIndex];
                dice.add(new Die(random[diceIndex + minIndex], strength, hit ? DieType.HIT : DieType.MISS));
                for (int i = 0; i < rolls; i++) {
                    if (i != minIndex) {
                        dice.add(new Die(random[diceIndex + i], strength, DieType.IGNORED));
                    }
                }
                if (hit) {
                    hitCount++;
                }
                diceIndex += rolls;
            } else {
                for (int i = 0; i < rolls; i++) {
                    final boolean hit = strength > random[diceIndex];
                    dice.add(new Die(random[diceIndex], strength, hit ? DieType.HIT : DieType.MISS));
                    if (hit) {
                        hitCount++;
                    }
                    diceIndex++;
                }
            }
        }
    }
    final double expectedHits = ((double) totalPower) / data.getDiceSides();
    final DiceRoll diceRoll = new DiceRoll(dice, hitCount, expectedHits);
    bridge.getHistoryWriter().addChildToEvent(annotation + " : " + MyFormatter.asDice(random), diceRoll);
    return diceRoll;
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) GameData(games.strategy.engine.data.GameData) ArrayList(java.util.ArrayList) Unit(games.strategy.engine.data.Unit) UnitAttachment(games.strategy.triplea.attachments.UnitAttachment)

Example 47 with UnitAttachment

use of games.strategy.triplea.attachments.UnitAttachment in project triplea by triplea-game.

the class DiceRoll method getTotalPowerAndRolls.

private static Tuple<Integer, Integer> getTotalPowerAndRolls(final Map<Unit, Tuple<Integer, Integer>> unitPowerAndRollsMap, final GameData data) {
    final int diceSides = data.getDiceSides();
    final boolean lhtrBombers = Properties.getLhtrHeavyBombers(data);
    // bonus is normally 1 for most games
    final int extraRollBonus = Math.max(1, data.getDiceSides() / 6);
    int totalPower = 0;
    int totalRolls = 0;
    for (final Entry<Unit, Tuple<Integer, Integer>> entry : unitPowerAndRollsMap.entrySet()) {
        int unitStrength = Math.min(Math.max(0, entry.getValue().getFirst()), diceSides);
        final int unitRolls = entry.getValue().getSecond();
        if (unitStrength <= 0 || unitRolls <= 0) {
            continue;
        }
        if (unitRolls == 1) {
            totalPower += unitStrength;
            totalRolls += unitRolls;
        } else {
            final UnitAttachment ua = UnitAttachment.get(entry.getKey().getType());
            if (lhtrBombers || ua.getChooseBestRoll()) {
                // LHTR means pick the best dice roll, which doesn't really make sense in LL. So instead, we will just add
                // +1 onto the power to
                // simulate the gains of having the best die picked.
                unitStrength += extraRollBonus * (unitRolls - 1);
                totalPower += Math.min(unitStrength, diceSides);
                totalRolls += unitRolls;
            } else {
                totalPower += unitRolls * unitStrength;
                totalRolls += unitRolls;
            }
        }
    }
    return Tuple.of(totalPower, totalRolls);
}
Also used : UnitAttachment(games.strategy.triplea.attachments.UnitAttachment) Unit(games.strategy.engine.data.Unit) Tuple(games.strategy.util.Tuple)

Example 48 with UnitAttachment

use of games.strategy.triplea.attachments.UnitAttachment in project triplea by triplea-game.

the class AbstractPlaceDelegate method canWeConsumeUnits.

protected boolean canWeConsumeUnits(final Collection<Unit> units, final Territory to, final boolean actuallyDoIt, final CompositeChange change) {
    boolean weCanConsume = true;
    final Collection<Unit> unitsAtStartOfTurnInTo = unitsAtStartOfStepInTerritory(to);
    final Collection<Unit> removedUnits = new ArrayList<>();
    final Collection<Unit> unitsWhichConsume = CollectionUtils.getMatches(units, Matches.unitConsumesUnitsOnCreation());
    for (final Unit unit : unitsWhichConsume) {
        if (Matches.unitWhichConsumesUnitsHasRequiredUnits(unitsAtStartOfTurnInTo).negate().test(unit)) {
            weCanConsume = false;
        }
        if (!weCanConsume) {
            break;
        }
        // remove units which are now consumed, then test the rest of the consuming units on the diminishing pile of units
        // which were in the
        // territory at start of turn
        final UnitAttachment ua = UnitAttachment.get(unit.getType());
        final IntegerMap<UnitType> requiredUnitsMap = ua.getConsumesUnits();
        final Collection<UnitType> requiredUnits = requiredUnitsMap.keySet();
        for (final UnitType ut : requiredUnits) {
            final int requiredNumber = requiredUnitsMap.getInt(ut);
            final Predicate<Unit> unitIsOwnedByAndOfTypeAndNotDamaged = Matches.unitIsOwnedBy(unit.getOwner()).and(Matches.unitIsOfType(ut)).and(Matches.unitHasNotTakenAnyBombingUnitDamage()).and(Matches.unitHasNotTakenAnyDamage()).and(Matches.unitIsNotDisabled());
            final Collection<Unit> unitsBeingRemoved = CollectionUtils.getNMatches(unitsAtStartOfTurnInTo, requiredNumber, unitIsOwnedByAndOfTypeAndNotDamaged);
            unitsAtStartOfTurnInTo.removeAll(unitsBeingRemoved);
            // if we should actually do it, not just test, then add to bridge
            if (actuallyDoIt && change != null) {
                final Change remove = ChangeFactory.removeUnits(to, unitsBeingRemoved);
                change.add(remove);
                removedUnits.addAll(unitsBeingRemoved);
            }
        }
    }
    if (weCanConsume && actuallyDoIt && change != null && !change.isEmpty()) {
        bridge.getHistoryWriter().startEvent("Units in " + to.getName() + " being upgraded or consumed: " + MyFormatter.unitsToTextNoOwner(removedUnits), removedUnits);
    }
    return weCanConsume;
}
Also used : UnitAttachment(games.strategy.triplea.attachments.UnitAttachment) UnitType(games.strategy.engine.data.UnitType) ArrayList(java.util.ArrayList) CompositeChange(games.strategy.engine.data.CompositeChange) Change(games.strategy.engine.data.Change) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit)

Example 49 with UnitAttachment

use of games.strategy.triplea.attachments.UnitAttachment in project triplea by triplea-game.

the class AirBattle method territoryCouldPossiblyHaveAirBattleDefenders.

static boolean territoryCouldPossiblyHaveAirBattleDefenders(final Territory territory, final PlayerID attacker, final GameData data, final boolean bombing) {
    final boolean canScrambleToAirBattle = Properties.getCanScrambleIntoAirBattles(data);
    final Predicate<Unit> defendingAirMatch = bombing ? defendingBombingRaidInterceptors(attacker, data) : defendingGroundSeaBattleInterceptors(attacker, data);
    int maxScrambleDistance = 0;
    if (canScrambleToAirBattle) {
        for (final UnitType unitType : data.getUnitTypeList()) {
            final UnitAttachment ua = UnitAttachment.get(unitType);
            if (ua.getCanScramble() && maxScrambleDistance < ua.getMaxScrambleDistance()) {
                maxScrambleDistance = ua.getMaxScrambleDistance();
            }
        }
    } else {
        return territory.getUnits().anyMatch(defendingAirMatch);
    }
    // should we check if the territory also has an air base?
    return territory.getUnits().anyMatch(defendingAirMatch) || data.getMap().getNeighbors(territory, maxScrambleDistance).stream().anyMatch(Matches.territoryHasUnitsThatMatch(defendingAirMatch));
}
Also used : UnitAttachment(games.strategy.triplea.attachments.UnitAttachment) UnitType(games.strategy.engine.data.UnitType) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit)

Example 50 with UnitAttachment

use of games.strategy.triplea.attachments.UnitAttachment in project triplea by triplea-game.

the class AirMovementValidator method carrierCapacity.

/**
 * Does not, and is not supposed to, account for any units already on this carrier (like allied/cargo fighters).
 * Instead this method only adds up the total capacity of each unit, and accounts for damaged carriers with special
 * properties and restrictions.
 */
public static int carrierCapacity(final Unit unit, final Territory territoryUnitsAreCurrentlyIn) {
    if (Matches.unitIsCarrier().test(unit)) {
        // here we check to see if the unit can no longer carry units
        if (Matches.unitHasWhenCombatDamagedEffect(UnitAttachment.UNITSMAYNOTLANDONCARRIER).test(unit)) {
            // and we must check to make sure we let any allied air that are cargo stay here
            if (Matches.unitHasWhenCombatDamagedEffect(UnitAttachment.UNITSMAYNOTLEAVEALLIEDCARRIER).test(unit)) {
                int cargo = 0;
                final Collection<Unit> airCargo = territoryUnitsAreCurrentlyIn.getUnits().getMatches(Matches.unitIsAir().and(Matches.unitCanLandOnCarrier()));
                for (final Unit airUnit : airCargo) {
                    final TripleAUnit taUnit = (TripleAUnit) airUnit;
                    if (taUnit.getTransportedBy() != null && taUnit.getTransportedBy().equals(unit)) {
                        // capacity = are cargo only
                        cargo += UnitAttachment.get(taUnit.getType()).getCarrierCost();
                    }
                }
                return cargo;
            }
            // capacity = zero 0
            return 0;
        }
        final UnitAttachment ua = UnitAttachment.get(unit.getType());
        return ua.getCarrierCapacity();
    }
    return 0;
}
Also used : UnitAttachment(games.strategy.triplea.attachments.UnitAttachment) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit) TripleAUnit(games.strategy.triplea.TripleAUnit)

Aggregations

UnitAttachment (games.strategy.triplea.attachments.UnitAttachment)60 Unit (games.strategy.engine.data.Unit)45 ArrayList (java.util.ArrayList)25 TripleAUnit (games.strategy.triplea.TripleAUnit)23 UnitType (games.strategy.engine.data.UnitType)20 GameData (games.strategy.engine.data.GameData)19 Territory (games.strategy.engine.data.Territory)19 PlayerID (games.strategy.engine.data.PlayerID)12 CompositeChange (games.strategy.engine.data.CompositeChange)8 TerritoryAttachment (games.strategy.triplea.attachments.TerritoryAttachment)7 IntegerMap (games.strategy.util.IntegerMap)6 Collection (java.util.Collection)6 Set (java.util.Set)6 Change (games.strategy.engine.data.Change)5 Resource (games.strategy.engine.data.Resource)5 Tuple (games.strategy.util.Tuple)5 HashSet (java.util.HashSet)5 ITestDelegateBridge (games.strategy.engine.data.ITestDelegateBridge)4 Route (games.strategy.engine.data.Route)4 List (java.util.List)4