Search in sources :

Example 1 with UnitSupportAttachment

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

the class BattleCalculator method getRolls.

private static int getRolls(final Unit unit, final PlayerID id, final boolean defend, final boolean bombing, final Set<List<UnitSupportAttachment>> supportRulesFriendly, final IntegerMap<UnitSupportAttachment> supportLeftFriendlyCopy, final Set<List<UnitSupportAttachment>> supportRulesEnemy, final IntegerMap<UnitSupportAttachment> supportLeftEnemyCopy, final Collection<TerritoryEffect> territoryEffects) {
    final UnitAttachment unitAttachment = UnitAttachment.get(unit.getType());
    int rolls;
    if (defend) {
        rolls = unitAttachment.getDefenseRolls(id);
    } else {
        rolls = unitAttachment.getAttackRolls(id);
    }
    final Map<UnitSupportAttachment, LinkedIntegerMap<Unit>> dummyEmptyMap = new HashMap<>();
    rolls += DiceRoll.getSupport(unit, supportRulesFriendly, supportLeftFriendlyCopy, dummyEmptyMap, null, false, true);
    rolls += DiceRoll.getSupport(unit, supportRulesEnemy, supportLeftEnemyCopy, dummyEmptyMap, null, false, true);
    rolls = Math.max(0, rolls);
    // if we are strategic bombing, we do not care what the strength of the unit is...
    if (bombing) {
        return rolls;
    }
    int strength;
    if (defend) {
        strength = unitAttachment.getDefense(unit.getOwner());
    } else {
        strength = unitAttachment.getAttack(unit.getOwner());
    }
    // TODO: we should add in isMarine bonus too...
    strength += DiceRoll.getSupport(unit, supportRulesFriendly, supportLeftFriendlyCopy, dummyEmptyMap, null, true, false);
    strength += DiceRoll.getSupport(unit, supportRulesEnemy, supportLeftEnemyCopy, dummyEmptyMap, null, true, false);
    strength += TerritoryEffectHelper.getTerritoryCombatBonus(unit.getType(), territoryEffects, defend);
    if (strength <= 0) {
        rolls = 0;
    }
    return rolls;
}
Also used : UnitAttachment(games.strategy.triplea.attachments.UnitAttachment) LinkedIntegerMap(games.strategy.util.LinkedIntegerMap) HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) UnitSupportAttachment(games.strategy.triplea.attachments.UnitSupportAttachment)

Example 2 with UnitSupportAttachment

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

the class DiceRoll method getSupport.

/**
 * Fills a set and map with the support possibly given by these units.
 *
 * @param supportsAvailable
 *        an empty set that will be filled with all support rules grouped into lists of non-stacking rules
 * @param supportLeft
 *        an empty map that will be filled with all the support that can be given in the form of counters
 * @param supportUnitsLeft
 *        an empty map that will be filled with all the support that can be given in the form of counters
 * @param defence
 *        are the receiving units defending?
 * @param allies
 *        are the receiving units allied to the giving units?
 */
public static void getSupport(final List<Unit> unitsGivingTheSupport, final Set<List<UnitSupportAttachment>> supportsAvailable, final IntegerMap<UnitSupportAttachment> supportLeft, final Map<UnitSupportAttachment, LinkedIntegerMap<Unit>> supportUnitsLeft, final GameData data, final boolean defence, final boolean allies) {
    if (unitsGivingTheSupport == null || unitsGivingTheSupport.isEmpty()) {
        return;
    }
    for (final UnitSupportAttachment rule : UnitSupportAttachment.get(data)) {
        if (rule.getPlayers().isEmpty()) {
            continue;
        }
        if (!((defence && rule.getDefence()) || (!defence && rule.getOffence()))) {
            continue;
        }
        if (!((allies && rule.getAllied()) || (!allies && rule.getEnemy()))) {
            continue;
        }
        final Predicate<Unit> canSupport = Matches.unitIsOfType((UnitType) rule.getAttachedTo()).and(Matches.unitOwnedBy(rule.getPlayers()));
        final List<Unit> supporters = CollectionUtils.getMatches(unitsGivingTheSupport, canSupport);
        int numSupport = supporters.size();
        if (numSupport <= 0) {
            continue;
        }
        final List<Unit> impArtTechUnits = new ArrayList<>();
        if (rule.getImpArtTech()) {
            impArtTechUnits.addAll(CollectionUtils.getMatches(supporters, Matches.unitOwnerHasImprovedArtillerySupportTech()));
        }
        numSupport += impArtTechUnits.size();
        supportLeft.put(rule, numSupport * rule.getNumber());
        supportUnitsLeft.put(rule, new LinkedIntegerMap<>(supporters, rule.getNumber()));
        supportUnitsLeft.get(rule).addAll(impArtTechUnits, rule.getNumber());
        final Iterator<List<UnitSupportAttachment>> iter2 = supportsAvailable.iterator();
        List<UnitSupportAttachment> ruleType = null;
        boolean found = false;
        final String bonusType = rule.getBonusType();
        while (iter2.hasNext()) {
            ruleType = iter2.next();
            if (ruleType.get(0).getBonusType().equals(bonusType)) {
                found = true;
                break;
            }
        }
        if (!found) {
            ruleType = new ArrayList<>();
            supportsAvailable.add(ruleType);
        }
        if (ruleType != null) {
            ruleType.add(rule);
        }
    }
    sortSupportRules(supportsAvailable, defence, allies);
}
Also used : UnitSupportAttachment(games.strategy.triplea.attachments.UnitSupportAttachment) ArrayList(java.util.ArrayList) Unit(games.strategy.engine.data.Unit) UnitType(games.strategy.engine.data.UnitType) ArrayList(java.util.ArrayList) List(java.util.List)

Example 3 with UnitSupportAttachment

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

the class ProTransportUtils method getUnitsToTransportFromTerritories.

// TODO: this needs fixed to consider whether a valid route exists to load all units
public static List<Unit> getUnitsToTransportFromTerritories(final PlayerID player, final Unit transport, final Set<Territory> territoriesToLoadFrom, final List<Unit> unitsToIgnore, final Predicate<Unit> validUnitMatch) {
    final List<Unit> selectedUnits = new ArrayList<>();
    // Get units if transport already loaded
    if (TransportTracker.isTransporting(transport)) {
        selectedUnits.addAll(TransportTracker.transporting(transport));
    } else {
        // Get all units that can be transported
        final List<Unit> units = new ArrayList<>();
        for (final Territory loadFrom : territoriesToLoadFrom) {
            units.addAll(loadFrom.getUnits().getMatches(validUnitMatch));
        }
        units.removeAll(unitsToIgnore);
        // Sort units by attack
        units.sort((o1, o2) -> {
            // Very rough way to add support power
            final Set<UnitSupportAttachment> supportAttachments1 = UnitSupportAttachment.get(o1.getType());
            int maxSupport1 = 0;
            for (final UnitSupportAttachment usa : supportAttachments1) {
                if (usa.getAllied() && usa.getOffence() && usa.getBonus() > maxSupport1) {
                    maxSupport1 = usa.getBonus();
                }
            }
            final int attack1 = UnitAttachment.get(o1.getType()).getAttack(player) + maxSupport1;
            final Set<UnitSupportAttachment> supportAttachments2 = UnitSupportAttachment.get(o2.getType());
            int maxSupport2 = 0;
            for (final UnitSupportAttachment usa : supportAttachments2) {
                if (usa.getAllied() && usa.getOffence() && usa.getBonus() > maxSupport2) {
                    maxSupport2 = usa.getBonus();
                }
            }
            final int attack2 = UnitAttachment.get(o2.getType()).getAttack(player) + maxSupport2;
            return attack2 - attack1;
        });
        // Get best units that can be loaded
        selectedUnits.addAll(selectUnitsToTransportFromList(transport, units));
    }
    return selectedUnits;
}
Also used : Territory(games.strategy.engine.data.Territory) ProTerritory(games.strategy.triplea.ai.pro.data.ProTerritory) UnitSupportAttachment(games.strategy.triplea.attachments.UnitSupportAttachment) ArrayList(java.util.ArrayList) Unit(games.strategy.engine.data.Unit)

Example 4 with UnitSupportAttachment

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

the class ProPurchaseOption method calculateSupportFactor.

// TODO: doesn't consider enemy support
private double calculateSupportFactor(final List<Unit> ownedLocalUnits, final List<Unit> unitsToPlace, final GameData data, final boolean defense) {
    if ((!isAttackSupport && !defense) || (!isDefenseSupport && defense)) {
        return 0;
    }
    final List<Unit> units = new ArrayList<>(ownedLocalUnits);
    units.addAll(unitsToPlace);
    units.addAll(unitType.create(1, player, true));
    final Set<List<UnitSupportAttachment>> supportsAvailable = new HashSet<>();
    final IntegerMap<UnitSupportAttachment> supportLeft = new IntegerMap<>();
    DiceRoll.getSupport(units, supportsAvailable, supportLeft, new HashMap<>(), data, defense, true);
    double totalSupportFactor = 0;
    for (final UnitSupportAttachment usa : unitSupportAttachments) {
        for (final List<UnitSupportAttachment> bonusType : supportsAvailable) {
            if (!bonusType.contains(usa)) {
                continue;
            }
            // Find number of support provided and supportable units
            int numAddedSupport = usa.getNumber();
            if (usa.getImpArtTech() && TechTracker.hasImprovedArtillerySupport(player)) {
                numAddedSupport *= 2;
            }
            int numSupportProvided = -numAddedSupport;
            final Set<Unit> supportableUnits = new HashSet<>();
            for (final UnitSupportAttachment usa2 : bonusType) {
                numSupportProvided += supportLeft.getInt(usa2);
                supportableUnits.addAll(CollectionUtils.getMatches(units, Matches.unitIsOfTypes(usa2.getUnitType())));
            }
            final int numSupportableUnits = supportableUnits.size();
            // Find ratio of supportable to support units (optimal 2 to 1)
            final int numExtraSupportableUnits = Math.max(0, numSupportableUnits - numSupportProvided);
            // Ranges from 0 to 1
            final double ratio = Math.min(1, 2.0 * numExtraSupportableUnits / (numSupportableUnits + numAddedSupport));
            // Find approximate strength bonus provided
            double bonus = 0;
            if (usa.getStrength()) {
                bonus += usa.getBonus();
            }
            if (usa.getRoll()) {
                bonus += (usa.getBonus() * data.getDiceSides() * 0.75);
            }
            // Find support factor value
            final double supportFactor = Math.pow(numAddedSupport * 0.9, 0.9) * bonus * ratio;
            totalSupportFactor += supportFactor;
            ProLogger.trace(unitType.getName() + ", bonusType=" + usa.getBonusType() + ", supportFactor=" + supportFactor + ", numSupportProvided=" + numSupportProvided + ", numSupportableUnits=" + numSupportableUnits + ", numAddedSupport=" + numAddedSupport + ", ratio=" + ratio + ", bonus=" + bonus);
        }
    }
    ProLogger.debug(unitType.getName() + ", defense=" + defense + ", totalSupportFactor=" + totalSupportFactor);
    return totalSupportFactor;
}
Also used : IntegerMap(games.strategy.util.IntegerMap) UnitSupportAttachment(games.strategy.triplea.attachments.UnitSupportAttachment) ArrayList(java.util.ArrayList) Unit(games.strategy.engine.data.Unit) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet)

Example 5 with UnitSupportAttachment

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

the class DiceRoll method getSupport.

/**
 * Returns the support for this unit type, and decrements the supportLeft counters.
 *
 * @return the bonus given to the unit
 */
public static int getSupport(final Unit unit, final Set<List<UnitSupportAttachment>> supportsAvailable, final IntegerMap<UnitSupportAttachment> supportLeft, final Map<UnitSupportAttachment, LinkedIntegerMap<Unit>> supportUnitsLeft, final Map<Unit, IntegerMap<Unit>> unitSupportMap, final boolean strength, final boolean rolls) {
    int givenSupport = 0;
    for (final List<UnitSupportAttachment> bonusType : supportsAvailable) {
        for (final UnitSupportAttachment rule : bonusType) {
            if (!((strength && rule.getStrength()) || (rolls && rule.getRoll()))) {
                continue;
            }
            final Set<UnitType> types = rule.getUnitType();
            if (types != null && types.contains(unit.getType()) && supportLeft.getInt(rule) > 0) {
                givenSupport += rule.getBonus();
                supportLeft.add(rule, -1);
                final LinkedIntegerMap<Unit> supportersLeft = supportUnitsLeft.get(rule);
                if (supportersLeft != null) {
                    final Set<Unit> supporters = supportersLeft.keySet();
                    if (!supporters.isEmpty()) {
                        final Unit u = supporters.iterator().next();
                        supportUnitsLeft.get(rule).add(u, -1);
                        if (supportUnitsLeft.get(rule).getInt(u) <= 0) {
                            supportUnitsLeft.get(rule).removeKey(u);
                        }
                        if (unitSupportMap.containsKey(u)) {
                            unitSupportMap.get(u).add(unit, rule.getBonus());
                        } else {
                            unitSupportMap.put(u, new IntegerMap<>(unit, rule.getBonus()));
                        }
                    }
                }
                break;
            }
        }
    }
    return givenSupport;
}
Also used : UnitType(games.strategy.engine.data.UnitType) UnitSupportAttachment(games.strategy.triplea.attachments.UnitSupportAttachment) Unit(games.strategy.engine.data.Unit)

Aggregations

UnitSupportAttachment (games.strategy.triplea.attachments.UnitSupportAttachment)6 Unit (games.strategy.engine.data.Unit)5 ArrayList (java.util.ArrayList)4 List (java.util.List)3 UnitType (games.strategy.engine.data.UnitType)2 UnitAttachment (games.strategy.triplea.attachments.UnitAttachment)2 IntegerMap (games.strategy.util.IntegerMap)2 LinkedIntegerMap (games.strategy.util.LinkedIntegerMap)2 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2 Territory (games.strategy.engine.data.Territory)1 ProTerritory (games.strategy.triplea.ai.pro.data.ProTerritory)1 Tuple (games.strategy.util.Tuple)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1