...
 
Commits (235)
......@@ -6,7 +6,7 @@
<parent>
<artifactId>forge</artifactId>
<groupId>forge</groupId>
<version>1.6.28-SNAPSHOT</version>
<version>1.6.29-SNAPSHOT</version>
</parent>
<artifactId>forge-ai</artifactId>
......
package forge.ai;
public enum AIOption {
USE_SIMULATION;
USE_SIMULATION
}
......@@ -81,7 +81,7 @@ public class AiAttackController {
this.defendingOpponent = choosePreferredDefenderPlayer();
this.oppList = getOpponentCreatures(this.defendingOpponent);
this.myList = ai.getCreaturesInPlay();
this.attackers = new ArrayList<Card>();
this.attackers = new ArrayList<>();
for (Card c : myList) {
if (CombatUtil.canAttack(c, this.defendingOpponent)) {
attackers.add(c);
......@@ -95,7 +95,7 @@ public class AiAttackController {
this.defendingOpponent = choosePreferredDefenderPlayer();
this.oppList = getOpponentCreatures(this.defendingOpponent);
this.myList = ai.getCreaturesInPlay();
this.attackers = new ArrayList<Card>();
this.attackers = new ArrayList<>();
if (CombatUtil.canAttack(attacker, this.defendingOpponent)) {
attackers.add(attacker);
}
......@@ -103,8 +103,7 @@ public class AiAttackController {
} // overloaded constructor to evaluate single specified attacker
public static List<Card> getOpponentCreatures(final Player defender) {
List<Card> defenders = new ArrayList<Card>();
defenders.addAll(defender.getCreaturesInPlay());
List<Card> defenders = new ArrayList<>(defender.getCreaturesInPlay());
Predicate<Card> canAnimate = new Predicate<Card>() {
@Override
public boolean apply(Card c) {
......@@ -151,7 +150,7 @@ public class AiAttackController {
*
*/
public final static List<Card> sortAttackers(final List<Card> in) {
final List<Card> list = new ArrayList<Card>();
final List<Card> list = new ArrayList<>();
// Cards with triggers should come first (for Battle Cry)
for (final Card attacker : in) {
......@@ -256,7 +255,7 @@ public class AiAttackController {
}
public final static List<Card> getPossibleBlockers(final List<Card> blockers, final List<Card> attackers) {
List<Card> possibleBlockers = new ArrayList<Card>(blockers);
List<Card> possibleBlockers = new ArrayList<>(blockers);
possibleBlockers = CardLists.filter(possibleBlockers, new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
......@@ -267,7 +266,7 @@ public class AiAttackController {
}
public final static boolean canBlockAnAttacker(final Card c, final List<Card> attackers, final boolean nextTurn) {
final List<Card> attackerList = new ArrayList<Card>(attackers);
final List<Card> attackerList = new ArrayList<>(attackers);
if (!c.isCreature()) {
return false;
}
......@@ -280,7 +279,7 @@ public class AiAttackController {
}
public final static Card getCardCanBlockAnAttacker(final Card c, final List<Card> attackers, final boolean nextTurn) {
final List<Card> attackerList = new ArrayList<Card>(attackers);
final List<Card> attackerList = new ArrayList<>(attackers);
if (!c.isCreature()) {
return null;
}
......@@ -295,9 +294,9 @@ public class AiAttackController {
// this checks to make sure that the computer player doesn't lose when the human player attacks
// this method is used by getAttackers()
public final List<Card> notNeededAsBlockers(final Player ai, final List<Card> attackers) {
final List<Card> notNeededAsBlockers = new ArrayList<Card>(attackers);
final List<Card> notNeededAsBlockers = new ArrayList<>(attackers);
int fixedBlockers = 0;
final List<Card> vigilantes = new ArrayList<Card>();
final List<Card> vigilantes = new ArrayList<>();
//check for time walks
if (ai.getGame().getPhaseHandler().getNextTurn().equals(ai)) {
return attackers;
......@@ -336,7 +335,7 @@ public class AiAttackController {
}
}
List<Card> opponentsAttackers = new ArrayList<Card>(oppList);
List<Card> opponentsAttackers = new ArrayList<>(oppList);
opponentsAttackers = CardLists.filter(opponentsAttackers, new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
......@@ -548,8 +547,7 @@ public class AiAttackController {
remainingAttackers.removeAll(unblockedAttackers);
for (Card blocker : this.blockers) {
if (blocker.hasKeyword("CARDNAME can block any number of creatures.")
|| blocker.hasKeyword("CARDNAME can block an additional ninety-nine creatures each combat.")) {
if (blocker.canBlockAny()) {
for (Card attacker : this.attackers) {
if (CombatUtil.canBlock(attacker, blocker)) {
remainingAttackers.remove(attacker);
......@@ -565,14 +563,19 @@ public class AiAttackController {
if (remainingAttackers.isEmpty() || maxBlockersAfterCrew == 0) {
break;
}
if (blocker.hasKeyword("CARDNAME can block an additional creature each combat.")) {
blockedAttackers.add(remainingAttackers.get(0));
remainingAttackers.remove(0);
maxBlockersAfterCrew--;
if (remainingAttackers.isEmpty()) {
break;
int numExtraBlocks = blocker.canBlockAdditional();
if (numExtraBlocks > 0) {
while (numExtraBlocks-- > 0 && !remainingAttackers.isEmpty()) {
blockedAttackers.add(remainingAttackers.get(0));
remainingAttackers.remove(0);
maxBlockersAfterCrew--;
}
}
if (remainingAttackers.isEmpty()) {
break;
}
blockedAttackers.add(remainingAttackers.get(0));
remainingAttackers.remove(0);
maxBlockersAfterCrew--;
......@@ -681,7 +684,7 @@ public class AiAttackController {
// Determine who will be attacked
GameEntity defender = this.chooseDefender(combat, bAssault);
List<Card> attackersLeft = new ArrayList<Card>(this.attackers);
List<Card> attackersLeft = new ArrayList<>(this.attackers);
// TODO probably use AttackConstraints instead of only GlobalAttackRestrictions?
GlobalAttackRestrictions restrict = GlobalAttackRestrictions.getGlobalRestrictions(ai, combat.getDefenders());
......@@ -821,12 +824,12 @@ public class AiAttackController {
int humanForcesForAttritionalAttack = 0;
// examine the potential forces
final List<Card> nextTurnAttackers = new ArrayList<Card>();
final List<Card> nextTurnAttackers = new ArrayList<>();
int candidateCounterAttackDamage = 0;
final Player opp = this.defendingOpponent;
// get the potential damage and strength of the AI forces
final List<Card> candidateAttackers = new ArrayList<Card>();
final List<Card> candidateAttackers = new ArrayList<>();
int candidateUnblockedDamage = 0;
for (final Card pCard : this.myList) {
// if the creature can attack then it's a potential attacker this
......@@ -885,7 +888,7 @@ public class AiAttackController {
final int outNumber = computerForces - humanForces;
for (Card blocker : this.blockers) {
if (blocker.hasKeyword("CARDNAME can block any number of creatures.")) {
if (blocker.canBlockAny()) {
aiLifeToPlayerDamageRatio--;
}
}
......@@ -908,7 +911,7 @@ public class AiAttackController {
// get player life total
int humanLife = opp.getLife();
// get the list of attackers up to the first blocked one
final List<Card> attritionalAttackers = new ArrayList<Card>();
final List<Card> attritionalAttackers = new ArrayList<>();
for (int x = 0; x < (this.attackers.size() - humanForces); x++) {
attritionalAttackers.add(this.attackers.get(x));
}
......@@ -1021,7 +1024,7 @@ public class AiAttackController {
} // stay at home to block
if ( LOG_AI_ATTACKS )
System.out.println(String.valueOf(this.aiAggression) + " = ai aggression");
System.out.println(this.aiAggression + " = ai aggression");
// ****************
// Evaluation the end
......@@ -1457,7 +1460,7 @@ public class AiAttackController {
if (artifact != null) {
return artifact;
}
return null; //should never get here
return null;//should never get here
}
private void doLightmineFieldAttackLogic(List<Card> attackersLeft, int numForcedAttackers, boolean playAggro) {
......
......@@ -148,9 +148,7 @@ public class AiBlockController {
final CardCollection attackers = combat.getAttackersOf(defender);
// Begin with the attackers that pose the biggest threat
CardLists.sortByPowerDesc(attackers);
for (final Card c : attackers) {
sortedAttackers.add(c);
}
sortedAttackers.addAll(attackers);
} else if (defender instanceof Player && defender.equals(ai)) {
firstAttacker = combat.getAttackersOf(defender);
}
......@@ -163,9 +161,7 @@ public class AiBlockController {
}
} else {
// add creatures attacking the Player to the back of the list
for (final Card c : firstAttacker) {
sortedAttackers.add(c);
}
sortedAttackers.addAll(firstAttacker);
}
return sortedAttackers;
}
......@@ -481,8 +477,7 @@ public class AiBlockController {
final int damageNeeded = ComputerUtilCombat.getDamageToKill(attacker)
+ ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, secondBlocker, combat, false);
List<Card> usableBlockersAsThird = new ArrayList<>();
usableBlockersAsThird.addAll(usableBlockers);
List<Card> usableBlockersAsThird = new ArrayList<>(usableBlockers);
usableBlockersAsThird.remove(secondBlocker);
// loop over the remaining blockers in search of a good third blocker candidate
......@@ -859,7 +854,7 @@ public class AiBlockController {
damageToPW += ComputerUtilCombat.predictDamageTo((Card) def, pwatkr.getNetCombatDamage(), pwatkr, true);
}
}
if ((!onlyIfLethal && damageToPW > 0) || damageToPW >= ((Card) def).getCounters(CounterType.LOYALTY)) {
if ((!onlyIfLethal && damageToPW > 0) || damageToPW >= def.getCounters(CounterType.LOYALTY)) {
threatenedPWs.add((Card) def);
}
}
......@@ -879,7 +874,7 @@ public class AiBlockController {
if (!chumpPWDefenders.isEmpty()) {
for (final Card attacker : attackers) {
GameEntity def = combat.getDefenderByAttacker(attacker);
if (def instanceof Card && threatenedPWs.contains((Card) def)) {
if (def instanceof Card && threatenedPWs.contains(def)) {
if (attacker.hasKeyword(Keyword.TRAMPLE)) {
// don't bother trying to chump a trampling creature
continue;
......@@ -914,7 +909,7 @@ public class AiBlockController {
pwDefenders.addAll(combat.getBlockers(pwAtk));
} else {
isFullyBlocked = false;
damageToPW += ComputerUtilCombat.predictDamageTo((Card) pw, pwAtk.getNetCombatDamage(), pwAtk, true);
damageToPW += ComputerUtilCombat.predictDamageTo(pw, pwAtk.getNetCombatDamage(), pwAtk, true);
}
}
if (!isFullyBlocked && damageToPW >= pw.getCounters(CounterType.LOYALTY)) {
......@@ -1329,13 +1324,9 @@ public class AiBlockController {
&& ((Card) combat.getDefenderByAttacker(attacker)).isPlaneswalker();
boolean wantToTradeDownToSavePW = chanceToTradeDownToSaveWalker > 0;
if (((evalBlk <= evalAtk + 1) || (wantToSavePlaneswalker && wantToTradeDownToSavePW)) // "1" accounts for tapped.
return ((evalBlk <= evalAtk + 1) || (wantToSavePlaneswalker && wantToTradeDownToSavePW)) // "1" accounts for tapped.
&& powerParityOrHigher
&& (creatureParityOrAllowedDiff || wantToTradeWithCreatInHand)
&& (MyRandom.percentTrue(chance) || wantToSavePlaneswalker)) {
return true;
}
return false;
&& (MyRandom.percentTrue(chance) || wantToSavePlaneswalker);
}
}
......@@ -137,7 +137,7 @@ public class AiCardMemory {
Set<Card> memorySet = getMemorySet(set);
return memorySet == null ? false : memorySet.contains(c);
return memorySet != null && memorySet.contains(c);
}
/**
......@@ -291,7 +291,7 @@ public class AiCardMemory {
* @return true, if the given memory set contains no remembered cards.
*/
public boolean isMemorySetEmpty(MemorySet set) {
return set == null ? true : getMemorySet(set).isEmpty();
return set == null || getMemorySet(set).isEmpty();
}
/**
......
......@@ -1645,7 +1645,6 @@ public class AiController {
// For non-converted triggers (such as Cumulative Upkeep) that don't have costs or targets to worry about
return true;
}
return false;
}
......@@ -1690,16 +1689,11 @@ public class AiController {
left = AbilityUtils.calculateAmount(hostCard, svarToCheck, sa);
}
System.out.println("aiShouldRun?" + left + comparator + compareTo);
if (Expressions.compare(left, comparator, compareTo)) {
return true;
}
return Expressions.compare(left, comparator, compareTo);
} else if (effect.getMapParams().containsKey("AICheckDredge")) {
return player.getCardsIn(ZoneType.Library).size() > 8 || player.isCardInPlay("Laboratory Maniac");
} else if (sa != null && doTrigger(sa, false)) {
return true;
}
} else return sa != null && doTrigger(sa, false);
return false;
}
public List<SpellAbility> chooseSaToActivateFromOpeningHand(List<SpellAbility> usableFromOpeningHand) {
......@@ -2078,9 +2072,7 @@ public class AiController {
// AI-specific restrictions specified as activation parameters in spell abilities
if (sa.hasParam("AILifeThreshold")) {
if (player.getLife() <= Integer.parseInt(sa.getParam("AILifeThreshold"))) {
return false;
}
return player.getLife() > Integer.parseInt(sa.getParam("AILifeThreshold"));
}
return true;
......
......@@ -56,7 +56,7 @@ public class AiCostDecision extends CostDecisionMakerBase {
@Override
public PaymentDecision visit(CostChooseCreatureType cost) {
String choice = player.getController().chooseSomeType("Creature", ability, CardType.getAllCreatureTypes(),
Lists.<String>newArrayList());
Lists.newArrayList());
return PaymentDecision.type(choice);
}
......@@ -475,7 +475,7 @@ public class AiCostDecision extends CostDecisionMakerBase {
if (ability.getPayCosts().hasTapCost() && typeList.contains(ability.getHostCard())) {
c--;
}
source.setSVar("ChosenX", "Number$" + Integer.toString(c));
source.setSVar("ChosenX", "Number$" + c);
} else {
if (!isVehicle) {
c = AbilityUtils.calculateAmount(source, amount, ability);
......@@ -809,7 +809,7 @@ public class AiCostDecision extends CostDecisionMakerBase {
final String sVar = ability.getSVar(amount);
if (sVar.equals("XChoice")) {
c = AbilityUtils.calculateAmount(source, "ChosenX", ability);
source.setSVar("ChosenX", "Number$" + String.valueOf(c));
source.setSVar("ChosenX", "Number$" + c);
} else if (amount.equals("All")) {
c = source.getCounters(cost.counter);
} else if (sVar.equals("Targeted$CardManaCost")) {
......@@ -865,7 +865,7 @@ public class AiCostDecision extends CostDecisionMakerBase {
}
typeList = CardLists.filter(typeList, Presets.TAPPED);
c = typeList.size();
source.setSVar("ChosenX", "Number$" + Integer.toString(c));
source.setSVar("ChosenX", "Number$" + c);
} else {
c = AbilityUtils.calculateAmount(source, amount, ability);
}
......
......@@ -17,5 +17,5 @@ public enum AiPlayDecision {
WouldBecomeZeroToughnessCreature,
WouldDestroyWorldEnchantment,
BadEtbEffects,
CurseEffects;
CurseEffects
}
\ No newline at end of file
......@@ -39,7 +39,7 @@ import java.util.Map;
* @version $Id: AIProfile.java 20169 2013-03-08 08:24:17Z Agetian $
*/
public class AiProfileUtil {
private static Map<String, Map<AiProps, String>> loadedProfiles = new HashMap<String, Map<AiProps, String>>();
private static Map<String, Map<AiProps, String>> loadedProfiles = new HashMap<>();
private static String AI_PROFILE_DIR;
private static final String AI_PROFILE_EXT = ".ai";
......@@ -74,7 +74,7 @@ public class AiProfileUtil {
* @param profileName a profile to load.
*/
private static final Map<AiProps, String> loadProfile(final String profileName) {
Map<AiProps, String> profileMap = new HashMap<AiProps, String>();
Map<AiProps, String> profileMap = new HashMap<>();
List<String> lines = FileUtil.readFile(buildFileName(profileName));
for (String line : lines) {
......@@ -122,7 +122,7 @@ public class AiProfileUtil {
*/
public static List<String> getAvailableProfiles()
{
final List<String> availableProfiles = new ArrayList<String>();
final List<String> availableProfiles = new ArrayList<>();
final File dir = new File(AI_PROFILE_DIR);