use of games.strategy.triplea.attachments.PoliticalActionAttachment 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));
}
use of games.strategy.triplea.attachments.PoliticalActionAttachment in project triplea by triplea-game.
the class ProPoliticsAi method doActions.
void doActions(final List<PoliticalActionAttachment> actions) {
final GameData data = ProData.getData();
final PoliticsDelegate politicsDelegate = DelegateFinder.politicsDelegate(data);
for (final PoliticalActionAttachment action : actions) {
ProLogger.debug("Performing action: " + action);
politicsDelegate.attemptAction(action);
}
}
use of games.strategy.triplea.attachments.PoliticalActionAttachment 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;
}
Aggregations