Search in sources :

Example 1 with WeakAi

use of games.strategy.triplea.ai.weak.WeakAi in project triplea by triplea-game.

the class BattleCalculator method selectCasualties.

/**
 * @param battleId
 *        may be null if we are not in a battle (eg, if this is an aa fire due to moving).
 */
public static CasualtyDetails selectCasualties(final String step, final PlayerID player, final Collection<Unit> targetsToPickFrom, final Collection<Unit> friendlyUnits, final PlayerID enemyPlayer, final Collection<Unit> enemyUnits, final boolean amphibious, final Collection<Unit> amphibiousLandAttackers, final Territory battlesite, final Collection<TerritoryEffect> territoryEffects, final IDelegateBridge bridge, final String text, final DiceRoll dice, final boolean defending, final GUID battleId, final boolean headLess, final int extraHits, final boolean allowMultipleHitsPerUnit) {
    if (targetsToPickFrom.isEmpty()) {
        return new CasualtyDetails();
    }
    if (!friendlyUnits.containsAll(targetsToPickFrom)) {
        throw new IllegalStateException("friendlyUnits should but does not contain all units from targetsToPickFrom");
    }
    final GameData data = bridge.getData();
    final boolean isEditMode = BaseEditDelegate.getEditMode(data);
    final ITripleAPlayer tripleaPlayer = player.isNull() ? new WeakAi(player.getName(), TripleA.WEAK_COMPUTER_PLAYER_TYPE) : (ITripleAPlayer) bridge.getRemotePlayer(player);
    final Map<Unit, Collection<Unit>> dependents = headLess ? Collections.emptyMap() : getDependents(targetsToPickFrom);
    if (isEditMode && !headLess) {
        final CasualtyDetails editSelection = tripleaPlayer.selectCasualties(targetsToPickFrom, dependents, 0, text, dice, player, friendlyUnits, enemyPlayer, enemyUnits, amphibious, amphibiousLandAttackers, new CasualtyList(), battleId, battlesite, allowMultipleHitsPerUnit);
        final List<Unit> killed = editSelection.getKilled();
        // if partial retreat is possible, kill amphibious units first
        if (isPartialAmphibiousRetreat(data)) {
            killAmphibiousFirst(killed, targetsToPickFrom);
        }
        return editSelection;
    }
    if (dice.getHits() == 0) {
        return new CasualtyDetails(Collections.emptyList(), Collections.emptyList(), true);
    }
    int hitsRemaining = dice.getHits();
    if (isTransportCasualtiesRestricted(data)) {
        hitsRemaining = extraHits;
    }
    if (!isEditMode && allTargetsOneTypeOneHitPoint(targetsToPickFrom, dependents)) {
        final List<Unit> killed = new ArrayList<>();
        final Iterator<Unit> iter = targetsToPickFrom.iterator();
        for (int i = 0; i < hitsRemaining; i++) {
            if (i >= targetsToPickFrom.size()) {
                break;
            }
            killed.add(iter.next());
        }
        return new CasualtyDetails(killed, Collections.emptyList(), true);
    }
    // Create production cost map, Maybe should do this elsewhere, but in case prices change, we do it here.
    final IntegerMap<UnitType> costs = TuvUtils.getCostsForTuv(player, data);
    final Tuple<CasualtyList, List<Unit>> defaultCasualtiesAndSortedTargets = getDefaultCasualties(targetsToPickFrom, hitsRemaining, defending, player, enemyUnits, amphibious, amphibiousLandAttackers, battlesite, costs, territoryEffects, data, allowMultipleHitsPerUnit, true);
    final CasualtyList defaultCasualties = defaultCasualtiesAndSortedTargets.getFirst();
    final List<Unit> sortedTargetsToPickFrom = defaultCasualtiesAndSortedTargets.getSecond();
    if (sortedTargetsToPickFrom.size() != targetsToPickFrom.size() || !targetsToPickFrom.containsAll(sortedTargetsToPickFrom) || !sortedTargetsToPickFrom.containsAll(targetsToPickFrom)) {
        throw new IllegalStateException("sortedTargetsToPickFrom must contain the same units as targetsToPickFrom list");
    }
    final int totalHitpoints = (allowMultipleHitsPerUnit ? getTotalHitpointsLeft(sortedTargetsToPickFrom) : sortedTargetsToPickFrom.size());
    final CasualtyDetails casualtySelection;
    if (hitsRemaining >= totalHitpoints) {
        casualtySelection = new CasualtyDetails(defaultCasualties, true);
    } else {
        casualtySelection = tripleaPlayer.selectCasualties(sortedTargetsToPickFrom, dependents, hitsRemaining, text, dice, player, friendlyUnits, enemyPlayer, enemyUnits, amphibious, amphibiousLandAttackers, defaultCasualties, battleId, battlesite, allowMultipleHitsPerUnit);
    }
    List<Unit> killed = casualtySelection.getKilled();
    // if partial retreat is possible, kill amphibious units first
    if (isPartialAmphibiousRetreat(data)) {
        killed = killAmphibiousFirst(killed, sortedTargetsToPickFrom);
    }
    final List<Unit> damaged = casualtySelection.getDamaged();
    int numhits = killed.size();
    if (!allowMultipleHitsPerUnit) {
        damaged.clear();
    } else {
        for (final Unit unit : killed) {
            final UnitAttachment ua = UnitAttachment.get(unit.getType());
            final int damageToUnit = Collections.frequency(damaged, unit);
            // allowed damage
            numhits += Math.max(0, Math.min(damageToUnit, (ua.getHitPoints() - (1 + unit.getHits()))));
            // remove from damaged list, since they will die
            damaged.removeIf(unit::equals);
        }
    }
    // check right number
    if (!isEditMode && !(numhits + damaged.size() == (hitsRemaining > totalHitpoints ? totalHitpoints : hitsRemaining))) {
        tripleaPlayer.reportError("Wrong number of casualties selected");
        if (headLess) {
            System.err.println("Possible Infinite Loop: Wrong number of casualties selected: number of hits on units " + (numhits + damaged.size()) + " != number of hits to take " + (hitsRemaining > totalHitpoints ? totalHitpoints : hitsRemaining) + ", for " + casualtySelection.toString());
        }
        return selectCasualties(step, player, sortedTargetsToPickFrom, friendlyUnits, enemyPlayer, enemyUnits, amphibious, amphibiousLandAttackers, battlesite, territoryEffects, bridge, text, dice, defending, battleId, headLess, extraHits, allowMultipleHitsPerUnit);
    }
    // check we have enough of each type
    if (!sortedTargetsToPickFrom.containsAll(killed) || !sortedTargetsToPickFrom.containsAll(damaged)) {
        tripleaPlayer.reportError("Cannot remove enough units of those types");
        if (headLess) {
            System.err.println("Possible Infinite Loop: Cannot remove enough units of those types: targets " + MyFormatter.unitsToTextNoOwner(sortedTargetsToPickFrom) + ", for " + casualtySelection.toString());
        }
        return selectCasualties(step, player, sortedTargetsToPickFrom, friendlyUnits, enemyPlayer, enemyUnits, amphibious, amphibiousLandAttackers, battlesite, territoryEffects, bridge, text, dice, defending, battleId, headLess, extraHits, allowMultipleHitsPerUnit);
    }
    return casualtySelection;
}
Also used : GameData(games.strategy.engine.data.GameData) ArrayList(java.util.ArrayList) Unit(games.strategy.engine.data.Unit) ITripleAPlayer(games.strategy.triplea.player.ITripleAPlayer) UnitAttachment(games.strategy.triplea.attachments.UnitAttachment) WeakAi(games.strategy.triplea.ai.weak.WeakAi) CasualtyList(games.strategy.triplea.delegate.dataObjects.CasualtyList) UnitType(games.strategy.engine.data.UnitType) Collection(java.util.Collection) CasualtyDetails(games.strategy.triplea.delegate.dataObjects.CasualtyDetails) ArrayList(java.util.ArrayList) CasualtyList(games.strategy.triplea.delegate.dataObjects.CasualtyList) List(java.util.List)

Example 2 with WeakAi

use of games.strategy.triplea.ai.weak.WeakAi in project triplea by triplea-game.

the class TripleA method createPlayers.

@Override
public Set<IGamePlayer> createPlayers(final Map<String, String> playerNames) {
    final Set<IGamePlayer> players = new HashSet<>();
    for (final String name : playerNames.keySet()) {
        final String type = playerNames.get(name);
        if (type.equals(WEAK_COMPUTER_PLAYER_TYPE)) {
            players.add(new WeakAi(name, type));
        } else if (type.equals(FAST_COMPUTER_PLAYER_TYPE)) {
            players.add(new FastAi(name, type));
        } else if (type.equals(PRO_COMPUTER_PLAYER_TYPE)) {
            players.add(new ProAi(name, type));
        } else if (type.equals(DOESNOTHINGAI_COMPUTER_PLAYER_TYPE)) {
            players.add(new DoesNothingAi(name, type));
        } else if (type.equals(HUMAN_PLAYER_TYPE) || type.equals(CLIENT_PLAYER_TYPE)) {
            final TripleAPlayer player = new TripleAPlayer(name, type);
            players.add(player);
        } else {
            throw new IllegalStateException("Player type not recognized:" + type);
        }
    }
    return players;
}
Also used : IGamePlayer(games.strategy.engine.gamePlayer.IGamePlayer) WeakAi(games.strategy.triplea.ai.weak.WeakAi) ITripleAPlayer(games.strategy.triplea.player.ITripleAPlayer) DoesNothingAi(games.strategy.triplea.ai.weak.DoesNothingAi) FastAi(games.strategy.triplea.ai.fast.FastAi) ProAi(games.strategy.triplea.ai.pro.ProAi) HashSet(java.util.HashSet)

Aggregations

WeakAi (games.strategy.triplea.ai.weak.WeakAi)2 ITripleAPlayer (games.strategy.triplea.player.ITripleAPlayer)2 GameData (games.strategy.engine.data.GameData)1 Unit (games.strategy.engine.data.Unit)1 UnitType (games.strategy.engine.data.UnitType)1 IGamePlayer (games.strategy.engine.gamePlayer.IGamePlayer)1 FastAi (games.strategy.triplea.ai.fast.FastAi)1 ProAi (games.strategy.triplea.ai.pro.ProAi)1 DoesNothingAi (games.strategy.triplea.ai.weak.DoesNothingAi)1 UnitAttachment (games.strategy.triplea.attachments.UnitAttachment)1 CasualtyDetails (games.strategy.triplea.delegate.dataObjects.CasualtyDetails)1 CasualtyList (games.strategy.triplea.delegate.dataObjects.CasualtyList)1 ArrayList (java.util.ArrayList)1 Collection (java.util.Collection)1 HashSet (java.util.HashSet)1 List (java.util.List)1