use of games.strategy.engine.delegate.IDelegateBridge in project triplea by triplea-game.
the class ProPurchaseUtils method canUnitsBePlaced.
public static boolean canUnitsBePlaced(final List<Unit> units, final PlayerID player, final Territory t, final boolean isBid) {
final GameData data = ProData.getData();
AbstractPlaceDelegate placeDelegate = (AbstractPlaceDelegate) data.getDelegateList().getDelegate("place");
if (isBid) {
placeDelegate = (AbstractPlaceDelegate) data.getDelegateList().getDelegate("placeBid");
}
final IDelegateBridge bridge = new ProDummyDelegateBridge(ProData.getProAi(), player, data);
placeDelegate.setDelegateBridgeAndPlayer(bridge);
final String s = placeDelegate.canUnitsBePlaced(t, units, player);
return s == null;
}
use of games.strategy.engine.delegate.IDelegateBridge in project triplea by triplea-game.
the class BattleDelegate method setupTerritoriesAbandonedToTheEnemy.
/**
* Setup the battles where we have abandoned a contested territory during combat move to the enemy.
* The enemy then takes over the territory in question.
*/
private static void setupTerritoriesAbandonedToTheEnemy(final BattleTracker battleTracker, final IDelegateBridge bridge) {
final GameData data = bridge.getData();
if (!Properties.getAbandonedTerritoriesMayBeTakenOverImmediately(data)) {
return;
}
final PlayerID player = bridge.getPlayerId();
final List<Territory> battleTerritories = CollectionUtils.getMatches(data.getMap().getTerritories(), Matches.territoryIsNotUnownedWater().and(Matches.territoryHasEnemyUnitsThatCanCaptureItAndIsOwnedByTheirEnemy(player, data)));
// all territories that contain enemy units, where the territory is owned by an enemy of these units
for (final Territory territory : battleTerritories) {
final List<Unit> abandonedToUnits = territory.getUnits().getMatches(Matches.enemyUnit(player, data));
final PlayerID abandonedToPlayer = AbstractBattle.findPlayerWithMostUnits(abandonedToUnits);
// now make sure to add any units that must move with these units, so that they get included as dependencies
final Map<Unit, Collection<Unit>> transportMap = TransportTracker.transporting(territory.getUnits());
abandonedToUnits.addAll(transportMap.entrySet().stream().filter(e -> abandonedToUnits.contains(e.getKey())).map(Entry::getValue).flatMap(Collection::stream).filter(Util.not(abandonedToUnits::contains)).collect(Collectors.toSet()));
// either we have abandoned the territory (so there are no more units that are enemy units of our enemy units)
// or we are possibly bombing the territory (so we may have units there still)
final Set<Unit> enemyUnitsOfAbandonedToUnits = abandonedToUnits.stream().map(Unit::getOwner).map(p -> Matches.unitIsEnemyOf(data, p).and(Matches.unitIsNotAir()).and(Matches.unitIsNotInfrastructure())).map(territory.getUnits()::getMatches).flatMap(Collection::stream).collect(Collectors.toSet());
// only look at bombing battles, because otherwise the normal attack will determine the ownership of the territory
final IBattle bombingBattle = battleTracker.getPendingBattle(territory, true, null);
if (bombingBattle != null) {
enemyUnitsOfAbandonedToUnits.removeAll(bombingBattle.getAttackingUnits());
}
if (!enemyUnitsOfAbandonedToUnits.isEmpty()) {
continue;
}
final IBattle nonFightingBattle = battleTracker.getPendingBattle(territory, false, BattleType.NORMAL);
if (nonFightingBattle != null) {
throw new IllegalStateException("Should not be possible to have a normal battle in: " + territory.getName() + " and have abandoned or only bombing there too.");
}
bridge.getHistoryWriter().startEvent(player.getName() + " has abandoned " + territory.getName() + " to " + abandonedToPlayer.getName(), abandonedToUnits);
battleTracker.takeOver(territory, abandonedToPlayer, bridge, null, abandonedToUnits);
// TODO: if there are multiple defending unit owners, allow picking which one takes over the territory
}
}
use of games.strategy.engine.delegate.IDelegateBridge in project triplea by triplea-game.
the class BattleTracker method fightDefenselessBattles.
/**
* Kill undefended transports. Done first to remove potentially dependent sea battles
* Which could block amphibious assaults later
*/
public void fightDefenselessBattles(final IDelegateBridge bridge) {
final GameData gameData = bridge.getData();
// Here and below parameter "false" to getPendingBattleSites & getPendingBattle denote non-SBR battles
for (final Territory territory : getPendingBattleSites(false)) {
final IBattle battle = getPendingBattle(territory, false, BattleType.NORMAL);
final List<Unit> defenders = new ArrayList<>(battle.getDefendingUnits());
final List<Unit> sortedUnitsList = getSortedDefendingUnits(bridge, gameData, territory, defenders);
if (getDependentOn(battle).isEmpty() && DiceRoll.getTotalPower(DiceRoll.getUnitPowerAndRollsForNormalBattles(sortedUnitsList, defenders, false, false, gameData, territory, TerritoryEffectHelper.getEffects(territory), false, null), gameData) == 0) {
battle.fight(bridge);
}
}
getPendingBattleSites(false).stream().map(territory -> getPendingBattle(territory, false, BattleType.NORMAL)).filter(NonFightingBattle.class::isInstance).filter(battle -> getDependentOn(battle).isEmpty()).forEach(battle -> battle.fight(bridge));
}
use of games.strategy.engine.delegate.IDelegateBridge in project triplea by triplea-game.
the class TriggerAttachment method triggerProductionFrontierEditChange.
public static void triggerProductionFrontierEditChange(final Set<TriggerAttachment> satisfiedTriggers, final IDelegateBridge bridge, final String beforeOrAfter, final String stepName, final boolean useUses, final boolean testUses, final boolean testChance, final boolean testWhen) {
final GameData data = bridge.getData();
Collection<TriggerAttachment> trigs = CollectionUtils.getMatches(satisfiedTriggers, prodFrontierEditMatch());
if (testWhen) {
trigs = CollectionUtils.getMatches(trigs, whenOrDefaultMatch(beforeOrAfter, stepName));
}
if (testUses) {
trigs = CollectionUtils.getMatches(trigs, availableUses);
}
final CompositeChange change = new CompositeChange();
for (final TriggerAttachment triggerAttachment : trigs) {
if (testChance && !triggerAttachment.testChance(bridge)) {
continue;
}
if (useUses) {
triggerAttachment.use(bridge);
}
triggerAttachment.getProductionRule().stream().map(s -> s.split(":")).forEach(array -> {
final ProductionFrontier front = data.getProductionFrontierList().getProductionFrontier(array[0]);
final String rule = array[1];
final String ruleName = rule.replaceFirst("^-", "");
final ProductionRule productionRule = data.getProductionRuleList().getProductionRule(ruleName);
final boolean ruleAdded = !rule.startsWith("-");
if (ruleAdded) {
if (!front.getRules().contains(productionRule)) {
change.add(ChangeFactory.addProductionRule(productionRule, front));
bridge.getHistoryWriter().startEvent(MyFormatter.attachmentNameToText(triggerAttachment.getName()) + ": " + productionRule.getName() + " added to " + front.getName());
}
} else {
if (front.getRules().contains(productionRule)) {
change.add(ChangeFactory.removeProductionRule(productionRule, front));
bridge.getHistoryWriter().startEvent(MyFormatter.attachmentNameToText(triggerAttachment.getName()) + ": " + productionRule.getName() + " removed from " + front.getName());
}
}
});
}
if (!change.isEmpty()) {
// TODO: we should sort the frontier list if we make changes to it...
bridge.addChange(change);
}
}
use of games.strategy.engine.delegate.IDelegateBridge in project triplea by triplea-game.
the class ProAi method purchase.
@Override
protected void purchase(final boolean purchaseForBid, final int pusToSpend, final IPurchaseDelegate purchaseDelegate, final GameData data, final PlayerID player) {
final long start = System.currentTimeMillis();
BattleCalculator.clearOolCache();
ProLogUi.notifyStartOfRound(data.getSequence().getRound(), player.getName());
initializeData();
if (pusToSpend <= 0) {
return;
}
if (purchaseForBid) {
calc.setData(data);
storedPurchaseTerritories = purchaseAi.bid(pusToSpend, purchaseDelegate, data);
} else {
// Repair factories
purchaseAi.repair(pusToSpend, purchaseDelegate, data, player);
// Check if any place territories exist
final Map<Territory, ProPurchaseTerritory> purchaseTerritories = ProPurchaseUtils.findPurchaseTerritories(player);
final List<Territory> possibleFactoryTerritories = CollectionUtils.getMatches(data.getMap().getTerritories(), ProMatches.territoryHasNoInfraFactoryAndIsNotConqueredOwnedLand(player, data));
if (purchaseTerritories.isEmpty() && possibleFactoryTerritories.isEmpty()) {
ProLogger.info("No possible place or factory territories owned so exiting purchase logic");
return;
}
ProLogger.info("Starting simulation for purchase phase");
// Setup data copy and delegates
GameData dataCopy;
try {
data.acquireReadLock();
dataCopy = GameDataUtils.cloneGameData(data, true);
} catch (final Throwable t) {
ProLogger.log(Level.WARNING, "Error trying to clone game data for simulating phases", t);
return;
} finally {
data.releaseReadLock();
}
calc.setData(dataCopy);
final PlayerID playerCopy = dataCopy.getPlayerList().getPlayerId(player.getName());
final IMoveDelegate moveDel = DelegateFinder.moveDelegate(dataCopy);
final IDelegateBridge bridge = new ProDummyDelegateBridge(this, playerCopy, dataCopy);
moveDel.setDelegateBridgeAndPlayer(bridge);
// Determine turn sequence
final List<GameStep> gameSteps = new ArrayList<>();
for (final GameStep gameStep : dataCopy.getSequence()) {
gameSteps.add(gameStep);
}
// Simulate the next phases until place/end of turn is reached then use simulated data for purchase
final int nextStepIndex = dataCopy.getSequence().getStepIndex() + 1;
for (int i = nextStepIndex; i < gameSteps.size(); i++) {
final GameStep step = gameSteps.get(i);
if (!playerCopy.equals(step.getPlayerId())) {
continue;
}
dataCopy.getSequence().setRoundAndStep(dataCopy.getSequence().getRound(), step.getDisplayName(), step.getPlayerId());
final String stepName = step.getName();
ProLogger.info("Simulating phase: " + stepName);
if (stepName.endsWith("NonCombatMove")) {
ProData.initializeSimulation(this, dataCopy, playerCopy);
final Map<Territory, ProTerritory> factoryMoveMap = nonCombatMoveAi.simulateNonCombatMove(moveDel);
if (storedFactoryMoveMap == null) {
storedFactoryMoveMap = ProSimulateTurnUtils.transferMoveMap(factoryMoveMap, data, player);
}
} else if (stepName.endsWith("CombatMove") && !stepName.endsWith("AirborneCombatMove")) {
ProData.initializeSimulation(this, dataCopy, playerCopy);
final Map<Territory, ProTerritory> moveMap = combatMoveAi.doCombatMove(moveDel);
if (storedCombatMoveMap == null) {
storedCombatMoveMap = ProSimulateTurnUtils.transferMoveMap(moveMap, data, player);
}
} else if (stepName.endsWith("Battle")) {
ProData.initializeSimulation(this, dataCopy, playerCopy);
ProSimulateTurnUtils.simulateBattles(dataCopy, playerCopy, bridge, calc);
} else if (stepName.endsWith("Place") || stepName.endsWith("EndTurn")) {
ProData.initializeSimulation(this, dataCopy, player);
storedPurchaseTerritories = purchaseAi.purchase(purchaseDelegate, data);
break;
} else if (stepName.endsWith("Politics")) {
ProData.initializeSimulation(this, dataCopy, player);
final PoliticsDelegate politicsDelegate = DelegateFinder.politicsDelegate(dataCopy);
politicsDelegate.setDelegateBridgeAndPlayer(bridge);
final List<PoliticalActionAttachment> actions = politicsAi.politicalActions();
if (storedPoliticalActions == null) {
storedPoliticalActions = actions;
}
}
}
}
ProLogger.info(player.getName() + " time for purchase=" + (System.currentTimeMillis() - start));
}
Aggregations