Search in sources :

Example 31 with ProTerritory

use of games.strategy.triplea.ai.pro.data.ProTerritory in project triplea by triplea-game.

the class ProNonCombatMoveAi method moveInfraUnits.

private Map<Territory, ProTerritory> moveInfraUnits(Map<Territory, ProTerritory> factoryMoveMap, final Map<Unit, Set<Territory>> infraUnitMoveMap) {
    ProLogger.info("Determine where to move infra units");
    final Map<Territory, ProTerritory> moveMap = territoryManager.getDefendOptions().getTerritoryMap();
    // Move factory units
    if (factoryMoveMap == null) {
        ProLogger.debug("Creating factory move map");
        // Determine and store where to move factories
        factoryMoveMap = new HashMap<>();
        for (final Iterator<Unit> it = infraUnitMoveMap.keySet().iterator(); it.hasNext(); ) {
            final Unit u = it.next();
            // Only check factory units
            if (Matches.unitCanProduceUnits().test(u)) {
                Territory maxValueTerritory = null;
                double maxValue = 0;
                for (final Territory t : infraUnitMoveMap.get(u)) {
                    if (!moveMap.get(t).isCanHold()) {
                        continue;
                    }
                    // Check if territory is safe after all current moves
                    if (moveMap.get(t).getBattleResult() == null) {
                        final List<Unit> defendingUnits = moveMap.get(t).getAllDefenders();
                        moveMap.get(t).setBattleResult(calc.calculateBattleResults(t, moveMap.get(t).getMaxEnemyUnits(), defendingUnits, moveMap.get(t).getMaxEnemyBombardUnits()));
                    }
                    final ProBattleResult result = moveMap.get(t).getBattleResult();
                    if (result.getWinPercentage() >= ProData.minWinPercentage || result.getTuvSwing() > 0) {
                        moveMap.get(t).setCanHold(false);
                        continue;
                    }
                    // Find value by checking if territory is not conquered and doesn't already have a factory
                    final List<Unit> units = new ArrayList<>(moveMap.get(t).getCantMoveUnits());
                    units.addAll(moveMap.get(t).getUnits());
                    final int production = TerritoryAttachment.get(t).getProduction();
                    double value = 0.1 * moveMap.get(t).getValue();
                    if (ProMatches.territoryIsNotConqueredOwnedLand(player, data).test(t) && units.stream().noneMatch(Matches.unitCanProduceUnitsAndIsInfrastructure())) {
                        value = moveMap.get(t).getValue() * production + 0.01 * production;
                    }
                    ProLogger.trace(t.getName() + " has value=" + value + ", strategicValue=" + moveMap.get(t).getValue() + ", production=" + production);
                    if (value > maxValue) {
                        maxValue = value;
                        maxValueTerritory = t;
                    }
                }
                if (maxValueTerritory != null) {
                    ProLogger.debug(u.getType().getName() + " moved to " + maxValueTerritory.getName() + " with value=" + maxValue);
                    moveMap.get(maxValueTerritory).addUnit(u);
                    if (factoryMoveMap.containsKey(maxValueTerritory)) {
                        factoryMoveMap.get(maxValueTerritory).addUnit(u);
                    } else {
                        final ProTerritory patd = new ProTerritory(maxValueTerritory);
                        patd.addUnit(u);
                        factoryMoveMap.put(maxValueTerritory, patd);
                    }
                    it.remove();
                }
            }
        }
    } else {
        ProLogger.debug("Using stored factory move map");
        // Transfer stored factory moves to move map
        for (final Territory t : factoryMoveMap.keySet()) {
            moveMap.get(t).addUnits(factoryMoveMap.get(t).getUnits());
        }
    }
    ProLogger.debug("Move infra AA units");
    // Move AA units
    for (final Iterator<Unit> it = infraUnitMoveMap.keySet().iterator(); it.hasNext(); ) {
        final Unit u = it.next();
        final Territory currentTerritory = unitTerritoryMap.get(u);
        // Only check AA units whose territory can't be held and don't have factories
        if (Matches.unitIsAaForAnything().test(u) && !moveMap.get(currentTerritory).isCanHold() && !ProMatches.territoryHasInfraFactoryAndIsLand().test(currentTerritory)) {
            Territory maxValueTerritory = null;
            double maxValue = 0;
            for (final Territory t : infraUnitMoveMap.get(u)) {
                if (!moveMap.get(t).isCanHold()) {
                    continue;
                }
                // Consider max stack of 1 AA in classic
                final Route r = data.getMap().getRoute_IgnoreEnd(currentTerritory, t, ProMatches.territoryCanMoveLandUnitsThrough(player, data, u, currentTerritory, false, new ArrayList<>()));
                final MoveValidationResult mvr = MoveValidator.validateMove(Collections.singletonList(u), r, player, new ArrayList<>(), new HashMap<>(), true, null, data);
                if (!mvr.isMoveValid()) {
                    continue;
                }
                // Find value and try to move to territory that doesn't already have AA
                final List<Unit> units = new ArrayList<>(moveMap.get(t).getCantMoveUnits());
                units.addAll(moveMap.get(t).getUnits());
                final boolean hasAa = units.stream().anyMatch(Matches.unitIsAaForAnything());
                double value = moveMap.get(t).getValue();
                if (hasAa) {
                    value *= 0.01;
                }
                ProLogger.trace(t.getName() + " has value=" + value);
                if (value > maxValue) {
                    maxValue = value;
                    maxValueTerritory = t;
                }
            }
            if (maxValueTerritory != null) {
                ProLogger.debug(u.getType().getName() + " moved to " + maxValueTerritory.getName() + " with value=" + maxValue);
                moveMap.get(maxValueTerritory).addUnit(u);
                it.remove();
            }
        }
    }
    return factoryMoveMap;
}
Also used : ProPlaceTerritory(games.strategy.triplea.ai.pro.data.ProPlaceTerritory) ProPurchaseTerritory(games.strategy.triplea.ai.pro.data.ProPurchaseTerritory) ProTerritory(games.strategy.triplea.ai.pro.data.ProTerritory) Territory(games.strategy.engine.data.Territory) ProTerritory(games.strategy.triplea.ai.pro.data.ProTerritory) ArrayList(java.util.ArrayList) ProBattleResult(games.strategy.triplea.ai.pro.data.ProBattleResult) TripleAUnit(games.strategy.triplea.TripleAUnit) Unit(games.strategy.engine.data.Unit) MoveValidationResult(games.strategy.triplea.delegate.dataObjects.MoveValidationResult) Route(games.strategy.engine.data.Route)

Example 32 with ProTerritory

use of games.strategy.triplea.ai.pro.data.ProTerritory in project triplea by triplea-game.

the class ProPoliticsAi method politicalActions.

List<PoliticalActionAttachment> politicalActions() {
    final GameData data = ProData.getData();
    final PlayerID player = ProData.getPlayer();
    final float numPlayers = data.getPlayerList().getPlayers().size();
    final double round = data.getSequence().getRound();
    final ProTerritoryManager territoryManager = new ProTerritoryManager(calc);
    final PoliticsDelegate politicsDelegate = DelegateFinder.politicsDelegate(data);
    ProLogger.info("Politics for " + player.getName());
    // Find valid war actions
    final List<PoliticalActionAttachment> actionChoicesTowardsWar = AiPoliticalUtils.getPoliticalActionsTowardsWar(player, politicsDelegate.getTestedConditions(), data);
    ProLogger.trace("War options: " + actionChoicesTowardsWar);
    final List<PoliticalActionAttachment> validWarActions = CollectionUtils.getMatches(actionChoicesTowardsWar, Matches.abstractUserActionAttachmentCanBeAttempted(politicsDelegate.getTestedConditions()));
    ProLogger.trace("Valid War options: " + validWarActions);
    // Divide war actions into enemy and neutral
    final Map<PoliticalActionAttachment, List<PlayerID>> enemyMap = new HashMap<>();
    final Map<PoliticalActionAttachment, List<PlayerID>> neutralMap = new HashMap<>();
    for (final PoliticalActionAttachment action : validWarActions) {
        final List<PlayerID> warPlayers = new ArrayList<>();
        for (final String relationshipChange : action.getRelationshipChange()) {
            final String[] s = relationshipChange.split(":");
            final PlayerID player1 = data.getPlayerList().getPlayerId(s[0]);
            final PlayerID player2 = data.getPlayerList().getPlayerId(s[1]);
            final RelationshipType oldRelation = data.getRelationshipTracker().getRelationshipType(player1, player2);
            final RelationshipType newRelation = data.getRelationshipTypeList().getRelationshipType(s[2]);
            if (!oldRelation.equals(newRelation) && Matches.relationshipTypeIsAtWar().test(newRelation) && (player1.equals(player) || player2.equals(player))) {
                PlayerID warPlayer = player2;
                if (warPlayer.equals(player)) {
                    warPlayer = player1;
                }
                warPlayers.add(warPlayer);
            }
        }
        if (!warPlayers.isEmpty()) {
            if (ProUtils.isNeutralPlayer(warPlayers.get(0))) {
                neutralMap.put(action, warPlayers);
            } else {
                enemyMap.put(action, warPlayers);
            }
        }
    }
    ProLogger.debug("Neutral options: " + neutralMap);
    ProLogger.debug("Enemy options: " + enemyMap);
    final List<PoliticalActionAttachment> results = new ArrayList<>();
    if (!enemyMap.isEmpty()) {
        // Find all attack options
        territoryManager.populatePotentialAttackOptions();
        final List<ProTerritory> attackOptions = territoryManager.removePotentialTerritoriesThatCantBeConquered();
        ProLogger.trace(player.getName() + ", numAttackOptions=" + attackOptions.size() + ", options=" + attackOptions);
        // Find attack options per war action
        final Map<PoliticalActionAttachment, Double> attackPercentageMap = new HashMap<>();
        for (final PoliticalActionAttachment action : enemyMap.keySet()) {
            int count = 0;
            final List<PlayerID> enemyPlayers = enemyMap.get(action);
            for (final ProTerritory patd : attackOptions) {
                if (Matches.isTerritoryOwnedBy(enemyPlayers).test(patd.getTerritory()) || Matches.territoryHasUnitsThatMatch(Matches.unitOwnedBy(enemyPlayers)).test(patd.getTerritory())) {
                    count++;
                }
            }
            final double attackPercentage = count / (attackOptions.size() + 1.0);
            attackPercentageMap.put(action, attackPercentage);
            ProLogger.trace(enemyPlayers + ", count=" + count + ", attackPercentage=" + attackPercentage);
        }
        // Decide whether to declare war on an enemy
        final List<PoliticalActionAttachment> options = new ArrayList<>(attackPercentageMap.keySet());
        Collections.shuffle(options);
        for (final PoliticalActionAttachment action : options) {
            // 0, .05, .1, .15, etc
            final double roundFactor = (round - 1) * .05;
            final double warChance = roundFactor + attackPercentageMap.get(action) * (1 + 10 * roundFactor);
            final double random = Math.random();
            ProLogger.trace(enemyMap.get(action) + ", warChance=" + warChance + ", random=" + random);
            if (random <= warChance) {
                results.add(action);
                ProLogger.debug("---Declared war on " + enemyMap.get(action));
                break;
            }
        }
    } else if (!neutralMap.isEmpty()) {
        // Decide whether to declare war on a neutral
        final List<PoliticalActionAttachment> options = new ArrayList<>(neutralMap.keySet());
        Collections.shuffle(options);
        final double random = Math.random();
        final double warChance = .01;
        ProLogger.debug("warChance=" + warChance + ", random=" + random);
        if (random <= warChance) {
            results.add(options.get(0));
            ProLogger.debug("Declared war on " + enemyMap.get(options.get(0)));
        }
    }
    // Old code used for non-war actions
    if (Math.random() < .5) {
        final List<PoliticalActionAttachment> actionChoicesOther = AiPoliticalUtils.getPoliticalActionsOther(player, politicsDelegate.getTestedConditions(), data);
        if (actionChoicesOther != null && !actionChoicesOther.isEmpty()) {
            Collections.shuffle(actionChoicesOther);
            int i = 0;
            final double random = Math.random();
            final int maxOtherActionsPerTurn = (random < .3 ? 0 : (random < .6 ? 1 : (random < .9 ? 2 : (random < .99 ? 3 : (int) numPlayers))));
            final Iterator<PoliticalActionAttachment> actionOtherIter = actionChoicesOther.iterator();
            while (actionOtherIter.hasNext() && maxOtherActionsPerTurn > 0) {
                final PoliticalActionAttachment action = actionOtherIter.next();
                if (!Matches.abstractUserActionAttachmentCanBeAttempted(politicsDelegate.getTestedConditions()).test(action)) {
                    continue;
                }
                if (action.getCostPu() > 0 && action.getCostPu() > player.getResources().getQuantity(Constants.PUS)) {
                    continue;
                }
                i++;
                if (i > maxOtherActionsPerTurn) {
                    break;
                }
                results.add(action);
            }
        }
    }
    doActions(results);
    return results;
}
Also used : PlayerID(games.strategy.engine.data.PlayerID) GameData(games.strategy.engine.data.GameData) HashMap(java.util.HashMap) ProTerritoryManager(games.strategy.triplea.ai.pro.data.ProTerritoryManager) ProTerritory(games.strategy.triplea.ai.pro.data.ProTerritory) ArrayList(java.util.ArrayList) RelationshipType(games.strategy.engine.data.RelationshipType) PoliticsDelegate(games.strategy.triplea.delegate.PoliticsDelegate) PoliticalActionAttachment(games.strategy.triplea.attachments.PoliticalActionAttachment) ArrayList(java.util.ArrayList) List(java.util.List)

Aggregations

ProTerritory (games.strategy.triplea.ai.pro.data.ProTerritory)32 Territory (games.strategy.engine.data.Territory)31 Unit (games.strategy.engine.data.Unit)29 ArrayList (java.util.ArrayList)26 TripleAUnit (games.strategy.triplea.TripleAUnit)24 HashSet (java.util.HashSet)16 ProBattleResult (games.strategy.triplea.ai.pro.data.ProBattleResult)11 ProPurchaseTerritory (games.strategy.triplea.ai.pro.data.ProPurchaseTerritory)11 Set (java.util.Set)11 ProPlaceTerritory (games.strategy.triplea.ai.pro.data.ProPlaceTerritory)10 GameData (games.strategy.engine.data.GameData)9 HashMap (java.util.HashMap)9 ProOtherMoveOptions (games.strategy.triplea.ai.pro.data.ProOtherMoveOptions)8 LinkedHashSet (java.util.LinkedHashSet)7 Route (games.strategy.engine.data.Route)6 List (java.util.List)6 Map (java.util.Map)6 TerritoryAttachment (games.strategy.triplea.attachments.TerritoryAttachment)5 ProTransport (games.strategy.triplea.ai.pro.data.ProTransport)4 Collection (java.util.Collection)4