mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-14 09:48:02 +00:00
Merge branch 'aicleanup' into 'master'
Minor cleanup See merge request core-developers/forge!4705
This commit is contained in:
@@ -427,8 +427,7 @@ public class AiAttackController {
|
||||
// total attack = biggest creature + exalted, *2 if Rafiq is in play
|
||||
int humanBasePower = getAttack(this.oppList.get(0)) + humanExaltedBonus;
|
||||
if (finestHour) {
|
||||
// For Finest Hour, one creature could attack and get the
|
||||
// bonus TWICE
|
||||
// For Finest Hour, one creature could attack and get the bonus TWICE
|
||||
humanBasePower = humanBasePower + humanExaltedBonus;
|
||||
}
|
||||
final int totalExaltedAttack = opp.isCardInPlay("Rafiq of the Many") ? 2 * humanBasePower
|
||||
@@ -935,12 +934,9 @@ public class AiAttackController {
|
||||
|
||||
// *********************
|
||||
// if outnumber and superior ratio work out whether attritional all out
|
||||
// attacking will work
|
||||
// attritional attack will expect some creatures to die but to achieve
|
||||
// victory by sheer weight
|
||||
// of numbers attacking turn after turn. It's not calculate very
|
||||
// carefully, the accuracy
|
||||
// can probably be improved
|
||||
// attacking will work attritional attack will expect some creatures to die but to achieve
|
||||
// victory by sheer weight of numbers attacking turn after turn. It's not calculate very
|
||||
// carefully, the accuracy can probably be improved
|
||||
// *********************
|
||||
boolean doAttritionalAttack = false;
|
||||
// get list of attackers ordered from low power to high
|
||||
@@ -974,7 +970,6 @@ public class AiAttackController {
|
||||
doAttritionalAttack = true;
|
||||
}
|
||||
}
|
||||
// System.out.println(doAttritionalAttack + " = do attritional attack");
|
||||
// *********************
|
||||
// end attritional attack calculation
|
||||
// *********************
|
||||
@@ -1024,11 +1019,9 @@ public class AiAttackController {
|
||||
// end see how long until unblockable attackers will be fatal
|
||||
// *****************
|
||||
|
||||
|
||||
// decide on attack aggression based on a comparison of forces, life
|
||||
// totals and other considerations
|
||||
// some bad "magic numbers" here, TODO replace with nice descriptive
|
||||
// variable names
|
||||
// totals and other considerations some bad "magic numbers" here
|
||||
// TODO replace with nice descriptive variable names
|
||||
if (ratioDiff > 0 && doAttritionalAttack) {
|
||||
this.aiAggression = 5; // attack at all costs
|
||||
} else if ((ratioDiff >= 1 && this.attackers.size() > 1 && (humanLifeToDamageRatio < 2 || outNumber > 0))
|
||||
@@ -1223,9 +1216,8 @@ public class AiAttackController {
|
||||
}
|
||||
|
||||
// look at the attacker in relation to the blockers to establish a
|
||||
// number of factors about the attacking
|
||||
// context that will be relevant to the attackers decision according to
|
||||
// the selected strategy
|
||||
// number of factors about the attacking context that will be relevant
|
||||
// to the attackers decision according to the selected strategy
|
||||
for (final Card defender : validBlockers) {
|
||||
// if both isWorthLessThanAllKillers and canKillAllDangerous are false there's nothing more to check
|
||||
if (isWorthLessThanAllKillers || canKillAllDangerous || numberOfPossibleBlockers < 2) {
|
||||
@@ -1303,10 +1295,7 @@ public class AiAttackController {
|
||||
|| (numberOfPossibleBlockers == 2 && CombatUtil.canAttackerBeBlockedWithAmount(attacker, 2, combat))) {
|
||||
canBeBlocked = true;
|
||||
}
|
||||
/*System.out.println(attacker + " canBeKilledByOne: " + canBeKilledByOne + " canKillAll: "
|
||||
+ canKillAll + " isWorthLessThanAllKillers: " + isWorthLessThanAllKillers + " canBeBlocked: " + canBeBlocked);*/
|
||||
// decide if the creature should attack based on the prevailing strategy
|
||||
// choice in aiAggression
|
||||
// decide if the creature should attack based on the prevailing strategy choice in aiAggression
|
||||
switch (this.aiAggression) {
|
||||
case 6: // Exalted: expecting to at least kill a creature of equal value or not be blocked
|
||||
if ((canKillAll && isWorthLessThanAllKillers) || !canBeBlocked) {
|
||||
@@ -1441,7 +1430,7 @@ public class AiAttackController {
|
||||
public String toProtectAttacker(SpellAbility sa) {
|
||||
//AiAttackController is created with the selected attacker as the only entry in "attackers"
|
||||
if (sa.getApi() != ApiType.Protection || oppList.isEmpty() || getPossibleBlockers(oppList, attackers).isEmpty()) {
|
||||
return null; //not protection sa or attacker is already unblockable
|
||||
return null; //not protection sa or attacker is already unblockable
|
||||
}
|
||||
final List<String> choices = ProtectEffect.getProtectionList(sa);
|
||||
String color = ComputerUtilCard.getMostProminentColor(getPossibleBlockers(oppList, attackers)), artifact = null;
|
||||
@@ -1451,7 +1440,7 @@ public class AiAttackController {
|
||||
if (!choices.contains(color)) {
|
||||
color = null;
|
||||
}
|
||||
for (Card c : oppList) { //find a blocker that ignores the currently selected protection
|
||||
for (Card c : oppList) { //find a blocker that ignores the currently selected protection
|
||||
if (artifact != null && !c.isArtifact()) {
|
||||
artifact = null;
|
||||
}
|
||||
@@ -1484,7 +1473,7 @@ public class AiAttackController {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (color == null && artifact == null) { //nothing can make the attacker unblockable
|
||||
if (color == null && artifact == null) { //nothing can make the attacker unblockable
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1562,4 +1551,4 @@ public class AiAttackController {
|
||||
return true;
|
||||
}
|
||||
|
||||
} // end class ComputerUtil_Attack2
|
||||
}
|
||||
|
||||
@@ -366,8 +366,7 @@ public class AiBlockController {
|
||||
final int damageNeeded = ComputerUtilCombat.getDamageToKill(attacker)
|
||||
+ ComputerUtilCombat.predictToughnessBonusOfAttacker(attacker, blocker, combat, false);
|
||||
// if the total damage of the blockgang was not enough
|
||||
// without but is enough with this blocker finish the
|
||||
// blockgang
|
||||
// without but is enough with this blocker finish the blockgang
|
||||
if (ComputerUtilCombat.totalFirstStrikeDamageOfBlockers(attacker, blockGang) < damageNeeded
|
||||
|| CombatUtil.needsBlockers(attacker) > blockGang.size()) {
|
||||
blockGang.add(blocker);
|
||||
@@ -454,8 +453,7 @@ public class AiBlockController {
|
||||
|| (lifeInDanger && ComputerUtilCombat.lifeInDanger(ai, combat)))
|
||||
// or life is in danger
|
||||
&& CombatUtil.canBlock(attacker, blocker, combat)) {
|
||||
// this is needed for attackers that can't be blocked by
|
||||
// more than 1
|
||||
// this is needed for attackers that can't be blocked by more than 1
|
||||
currentAttackers.remove(attacker);
|
||||
combat.addBlocker(attacker, blocker);
|
||||
if (CombatUtil.canBlock(attacker, leader, combat)) {
|
||||
@@ -510,8 +508,7 @@ public class AiBlockController {
|
||||
// or life is in danger
|
||||
&& CombatUtil.canBlock(attacker, secondBlocker, combat)
|
||||
&& CombatUtil.canBlock(attacker, thirdBlocker, combat)) {
|
||||
// this is needed for attackers that can't be blocked by
|
||||
// more than 1
|
||||
// this is needed for attackers that can't be blocked by more than 1
|
||||
currentAttackers.remove(attacker);
|
||||
combat.addBlocker(attacker, thirdBlocker);
|
||||
if (CombatUtil.canBlock(attacker, secondBlocker, combat)) {
|
||||
@@ -736,8 +733,7 @@ public class AiBlockController {
|
||||
List<Card> tramplingAttackers = CardLists.getKeyword(attackers, Keyword.TRAMPLE);
|
||||
tramplingAttackers = CardLists.filter(tramplingAttackers, Predicates.not(rampagesOrNeedsManyToBlock));
|
||||
|
||||
// TODO - should check here for a "rampage-like" trigger that replaced
|
||||
// the keyword:
|
||||
// TODO - should check here for a "rampage-like" trigger that replaced the keyword:
|
||||
// "Whenever CARDNAME becomes blocked, it gets +1/+1 until end of turn for each creature blocking it."
|
||||
|
||||
for (final Card attacker : tramplingAttackers) {
|
||||
@@ -1036,27 +1032,21 @@ public class AiBlockController {
|
||||
} else {
|
||||
lifeInDanger = false;
|
||||
}
|
||||
// if life is still in danger
|
||||
// Reinforce blockers blocking attackers with trample if life is
|
||||
// still
|
||||
// in danger
|
||||
// Reinforce blockers blocking attackers with trample if life is still in danger
|
||||
if (lifeInDanger && ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
||||
reinforceBlockersAgainstTrample(combat);
|
||||
} else {
|
||||
lifeInDanger = false;
|
||||
}
|
||||
// Support blockers not destroying the attacker with more blockers
|
||||
// to
|
||||
// try to kill the attacker
|
||||
// to try to kill the attacker
|
||||
if (!lifeInDanger) {
|
||||
reinforceBlockersToKill(combat);
|
||||
}
|
||||
|
||||
// == 2. If the AI life would still be in danger make a safer
|
||||
// approach ==
|
||||
// == 2. If the AI life would still be in danger make a safer approach ==
|
||||
if (lifeInDanger && ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
||||
clearBlockers(combat, possibleBlockers); // reset every block
|
||||
// assignment
|
||||
clearBlockers(combat, possibleBlockers); // reset every block assignment
|
||||
makeTradeBlocks(combat); // choose necessary trade blocks
|
||||
// if life is in danger
|
||||
makeGoodBlocks(combat);
|
||||
@@ -1066,8 +1056,7 @@ public class AiBlockController {
|
||||
} else {
|
||||
lifeInDanger = false;
|
||||
}
|
||||
// Reinforce blockers blocking attackers with trample if life is
|
||||
// still in danger
|
||||
// Reinforce blockers blocking attackers with trample if life is still in danger
|
||||
if (lifeInDanger && ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
||||
reinforceBlockersAgainstTrample(combat);
|
||||
} else {
|
||||
@@ -1077,11 +1066,9 @@ public class AiBlockController {
|
||||
reinforceBlockersToKill(combat);
|
||||
}
|
||||
|
||||
// == 3. If the AI life would be in serious danger make an even
|
||||
// safer approach ==
|
||||
// == 3. If the AI life would be in serious danger make an even safer approach ==
|
||||
if (lifeInDanger && ComputerUtilCombat.lifeInSeriousDanger(ai, combat)) {
|
||||
clearBlockers(combat, possibleBlockers); // reset every block
|
||||
// assignment
|
||||
clearBlockers(combat, possibleBlockers); // reset every block assignment
|
||||
makeChumpBlocks(combat); // choose chump blocks
|
||||
if (ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
||||
makeTradeBlocks(combat); // choose necessary trade
|
||||
@@ -1090,15 +1077,13 @@ public class AiBlockController {
|
||||
if (!ComputerUtilCombat.lifeInDanger(ai, combat)) {
|
||||
makeGoodBlocks(combat);
|
||||
}
|
||||
// Reinforce blockers blocking attackers with trample if life is
|
||||
// still in danger
|
||||
// Reinforce blockers blocking attackers with trample if life is still in danger
|
||||
else {
|
||||
reinforceBlockersAgainstTrample(combat);
|
||||
}
|
||||
makeGangBlocks(combat);
|
||||
// Support blockers not destroying the attacker with more
|
||||
// blockers
|
||||
// to try to kill the attacker
|
||||
// blockers to try to kill the attacker
|
||||
reinforceBlockersToKill(combat);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1422,8 +1422,6 @@ public class AiController {
|
||||
private List<SpellAbility> singleSpellAbilityList(SpellAbility sa) {
|
||||
if (sa == null) { return null; }
|
||||
|
||||
// System.out.println("Chosen to play: " + sa);
|
||||
|
||||
final List<SpellAbility> abilities = Lists.newArrayList();
|
||||
abilities.add(sa);
|
||||
return abilities;
|
||||
|
||||
@@ -2253,10 +2253,8 @@ public class ComputerUtil {
|
||||
String chosen = "";
|
||||
if (kindOfType.equals("Card")) {
|
||||
// TODO
|
||||
// computer will need to choose a type
|
||||
// based on whether it needs a creature or land,
|
||||
// otherwise, lib search for most common type left
|
||||
// then, reveal chosenType to Human
|
||||
// computer will need to choose a type based on whether it needs a creature or land,
|
||||
// otherwise, lib search for most common type left then, reveal chosenType to Human
|
||||
if (game.getPhaseHandler().is(PhaseType.UNTAP) && logic == null) { // Storage Matrix
|
||||
double amount = 0;
|
||||
for (String type : CardType.getAllCardTypes()) {
|
||||
@@ -2477,8 +2475,7 @@ public class ComputerUtil {
|
||||
return opponent ? "Numbers" : "Strength";
|
||||
}
|
||||
|
||||
// TODO check for ETB to +1/+1 counters
|
||||
// or over another trigger like lifegain
|
||||
// TODO check for ETB to +1/+1 counters or over another trigger like lifegain
|
||||
|
||||
int tokenScore = ComputerUtilCard.evaluateCreature(token);
|
||||
|
||||
@@ -2556,8 +2553,7 @@ public class ComputerUtil {
|
||||
return "Taxes";
|
||||
} else {
|
||||
// ai is first voter or ally of controller
|
||||
// both are not affected, but if opponents controll creatures,
|
||||
// sacrifice is worse
|
||||
// both are not affected, but if opponents control creatures, sacrifice is worse
|
||||
return controller.getOpponents().getCreaturesInPlay().isEmpty() ? "Taxes" : "Death";
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -265,16 +265,14 @@ public class ComputerUtilCard {
|
||||
* @return a {@link forge.game.card.Card} object.
|
||||
*/
|
||||
public static Card getBestAI(final Iterable<Card> list) {
|
||||
// Get Best will filter by appropriate getBest list if ALL of the list
|
||||
// is of that type
|
||||
// Get Best will filter by appropriate getBest list if ALL of the list is of that type
|
||||
if (Iterables.all(list, CardPredicates.Presets.CREATURES)) {
|
||||
return ComputerUtilCard.getBestCreatureAI(list);
|
||||
}
|
||||
if (Iterables.all(list, CardPredicates.Presets.LANDS)) {
|
||||
return getBestLandAI(list);
|
||||
}
|
||||
// TODO - Once we get an EvaluatePermanent this should call
|
||||
// getBestPermanent()
|
||||
// TODO - Once we get an EvaluatePermanent this should call getBestPermanent()
|
||||
return ComputerUtilCard.getMostExpensivePermanentAI(list);
|
||||
}
|
||||
|
||||
@@ -410,8 +408,7 @@ public class ComputerUtilCard {
|
||||
return getWorstCreatureAI(CardLists.filter(list, CardPredicates.Presets.CREATURES));
|
||||
}
|
||||
|
||||
// Planeswalkers fall through to here, lands will fall through if there
|
||||
// aren't very many
|
||||
// Planeswalkers fall through to here, lands will fall through if there aren't very many
|
||||
return getCheapestPermanentAI(list, null, false);
|
||||
}
|
||||
|
||||
@@ -1198,7 +1195,7 @@ public class ComputerUtilCard {
|
||||
}
|
||||
String kws = params.get("AddKeyword");
|
||||
if (kws != null) {
|
||||
bonusPT += 4 * (1 + StringUtils.countMatches(kws, "&")); //treat each added keyword as a +2/+2 for now
|
||||
bonusPT += 4 * (1 + StringUtils.countMatches(kws, "&")); //treat each added keyword as a +2/+2 for now
|
||||
}
|
||||
if (bonusPT > 0) {
|
||||
threat = bonusPT * (1 + opp.getCreaturesInPlay().size()) / 10.0f;
|
||||
@@ -1212,7 +1209,7 @@ public class ComputerUtilCard {
|
||||
}
|
||||
|
||||
final float valueNow = Math.max(valueTempo, threat);
|
||||
if (valueNow < 0.2) { //hard floor to reduce ridiculous odds for instants over time
|
||||
if (valueNow < 0.2) { //hard floor to reduce ridiculous odds for instants over time
|
||||
return false;
|
||||
}
|
||||
final float chance = MyRandom.getRandom().nextFloat();
|
||||
@@ -1310,7 +1307,7 @@ public class ComputerUtilCard {
|
||||
threat *= 2;
|
||||
}
|
||||
if (c.getNetPower() == 0 && c == sa.getHostCard() && power > 0 ) {
|
||||
threat *= 4; //over-value self +attack for 0 power creatures which may be pumped further after attacking
|
||||
threat *= 4; //over-value self +attack for 0 power creatures which may be pumped further after attacking
|
||||
}
|
||||
chance += threat;
|
||||
|
||||
|
||||
@@ -609,7 +609,6 @@ public class ComputerUtilMana {
|
||||
|
||||
String manaProduced = predictManafromSpellAbility(saPayment, ai, toPay);
|
||||
|
||||
//System.out.println(manaProduced);
|
||||
payMultipleMana(cost, manaProduced, ai);
|
||||
|
||||
// remove from available lists
|
||||
|
||||
@@ -649,7 +649,6 @@ public class PlayerControllerAi extends PlayerController {
|
||||
|
||||
@Override
|
||||
public boolean playChosenSpellAbility(SpellAbility sa) {
|
||||
// System.out.println("Playing sa: " + sa);
|
||||
if (sa instanceof LandAbility) {
|
||||
if (sa.canPlay()) {
|
||||
sa.resolve();
|
||||
|
||||
@@ -31,8 +31,7 @@ public class ControlExchangeAi extends SpellAbilityAi {
|
||||
|
||||
CardCollection list =
|
||||
CardLists.getValidCards(AiAttackController.choosePreferredDefenderPlayer(ai).getCardsIn(ZoneType.Battlefield), tgt.getValidTgts(), ai, sa.getHostCard(), sa);
|
||||
// AI won't try to grab cards that are filtered out of AI decks on
|
||||
// purpose
|
||||
// AI won't try to grab cards that are filtered out of AI decks on purpose
|
||||
list = CardLists.filter(list, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(final Card c) {
|
||||
|
||||
@@ -110,8 +110,7 @@ public class ControlGainAi extends SpellAbilityAi {
|
||||
}
|
||||
}
|
||||
|
||||
// Don't steal something if I can't Attack without, or prevent it from
|
||||
// blocking at least
|
||||
// Don't steal something if I can't Attack without, or prevent it from blocking at least
|
||||
if (lose.contains("EOT")
|
||||
&& ai.getGame().getPhaseHandler().getPhase().isAfter(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
||||
&& !sa.isTrigger()) {
|
||||
@@ -211,6 +210,7 @@ public class ControlGainAi extends SpellAbilityAi {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO check life of controller and consider stealing from another opponent so the risk of your army disappearing is spread out
|
||||
while (t == null) {
|
||||
// filter by MustTarget requirement
|
||||
CardCollection originalList = new CardCollection(list);
|
||||
@@ -264,7 +264,6 @@ public class ControlGainAi extends SpellAbilityAi {
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -120,8 +120,7 @@ public class CountersMultiplyAi extends SpellAbilityAi {
|
||||
|
||||
CardCollection list = CardLists.getTargetableCards(game.getCardsIn(ZoneType.Battlefield), sa);
|
||||
|
||||
// pre filter targetable cards with counters and can receive one of
|
||||
// them
|
||||
// pre filter targetable cards with counters and can receive one of them
|
||||
list = CardLists.filter(list, new Predicate<Card>() {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -40,7 +40,6 @@ import forge.game.keyword.Keyword;
|
||||
import forge.game.phase.PhaseHandler;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerPredicates;
|
||||
import forge.game.spellability.AbilitySub;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.TargetChoices;
|
||||
@@ -795,8 +794,7 @@ public class DamageDealAi extends DamageAiBase {
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: Improve Damage, we shouldn't just target the player just
|
||||
// because we can
|
||||
// TODO: Improve Damage, we shouldn't just target the player just because we can
|
||||
if (sa.canTarget(enemy) && tcs.size() < tgt.getMaxTargets(source, sa)) {
|
||||
if (((phase.is(PhaseType.END_OF_TURN) && phase.getNextTurn().equals(ai))
|
||||
|| (SpellAbilityAi.isSorcerySpeed(sa) && phase.is(PhaseType.MAIN2))
|
||||
@@ -1041,7 +1039,7 @@ public class DamageDealAi extends DamageAiBase {
|
||||
saTgt = saTgt.getParent();
|
||||
}
|
||||
|
||||
Player opponent = ai.getOpponents().min(PlayerPredicates.compareByLife());
|
||||
Player opponent = ai.getWeakestOpponent();
|
||||
|
||||
// TODO: somehow account for the possible cost reduction?
|
||||
int dmg = ComputerUtilMana.determineLeftoverMana(sa, ai, saTgt.getParam("XColor"));
|
||||
|
||||
@@ -45,9 +45,8 @@ public class DigAi extends SpellAbilityAi {
|
||||
sa.resetTargets();
|
||||
if (!opp.canBeTargetedBy(sa)) {
|
||||
return false;
|
||||
} else {
|
||||
sa.getTargets().add(opp);
|
||||
}
|
||||
sa.getTargets().add(opp);
|
||||
libraryOwner = opp;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,9 +30,8 @@ public class DigMultipleAi extends SpellAbilityAi {
|
||||
sa.resetTargets();
|
||||
if (!opp.canBeTargetedBy(sa)) {
|
||||
return false;
|
||||
} else {
|
||||
sa.getTargets().add(opp);
|
||||
}
|
||||
sa.getTargets().add(opp);
|
||||
libraryOwner = opp;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,9 +61,8 @@ public class DigUntilAi extends SpellAbilityAi {
|
||||
sa.resetTargets();
|
||||
if (!sa.canTarget(opp)) {
|
||||
return false;
|
||||
} else {
|
||||
sa.getTargets().add(opp);
|
||||
}
|
||||
sa.getTargets().add(opp);
|
||||
libraryOwner = opp;
|
||||
} else {
|
||||
if (sa.hasParam("Valid")) {
|
||||
|
||||
@@ -443,7 +443,7 @@ public class DrawAi extends SpellAbilityAi {
|
||||
continue;
|
||||
}
|
||||
|
||||
// use xPaid abilties only for itself
|
||||
// use xPaid abilities only for itself
|
||||
if (xPaid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -13,8 +13,7 @@ public class GameLossAi extends SpellAbilityAi {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only one SA Lose the Game card right now, which is Door to
|
||||
// Nothingness
|
||||
// Only one SA Lose the Game card right now, which is Door to Nothingness
|
||||
|
||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||
if (tgt != null) {
|
||||
|
||||
@@ -266,8 +266,7 @@ public class LifeGainAi extends SpellAbilityAi {
|
||||
}
|
||||
if (!hasTgt && mandatory) {
|
||||
// need to target something but its neither negative against
|
||||
// opponents,
|
||||
// nor posive against allies
|
||||
// opponents, nor positive against allies
|
||||
|
||||
// hurting ally is probably better than healing opponent
|
||||
// look for Lifegain not Negative (case of lifegain negated)
|
||||
@@ -295,8 +294,7 @@ public class LifeGainAi extends SpellAbilityAi {
|
||||
sa.getTargets().add(ally);
|
||||
hasTgt = true;
|
||||
}
|
||||
// better heal opponent which most life then the one with the
|
||||
// lowest
|
||||
// better heal opponent which most life then the one with the lowest
|
||||
if (!hasTgt) {
|
||||
Player opp = opps.max(PlayerPredicates.compareByLife());
|
||||
sa.getTargets().add(opp);
|
||||
|
||||
@@ -60,7 +60,6 @@ public class LifeLoseAi extends SpellAbilityAi {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
@@ -123,12 +122,11 @@ public class LifeLoseAi extends SpellAbilityAi {
|
||||
return false;
|
||||
}
|
||||
|
||||
final PlayerCollection tgtPlayers = getPlayers(ai, sa);
|
||||
|
||||
if (ComputerUtil.playImmediately(ai, sa)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final PlayerCollection tgtPlayers = getPlayers(ai, sa);
|
||||
PlayerCollection filteredPlayer = tgtPlayers
|
||||
.filter(Predicates.and(PlayerPredicates.isOpponentOf(ai), PlayerPredicates.lifeLessOrEqualTo(amount)));
|
||||
// killing opponents asap
|
||||
|
||||
@@ -21,6 +21,7 @@ import forge.game.phase.PhaseHandler;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerActionConfirmMode;
|
||||
import forge.game.player.PlayerPredicates;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.TargetRestrictions;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -214,13 +215,7 @@ public class MillAi extends SpellAbilityAi {
|
||||
}
|
||||
|
||||
// get targeted or defined Player with largest library
|
||||
// TODO in Java 8 find better way
|
||||
final Player m = Collections.max(list, new Comparator<Player>() {
|
||||
@Override
|
||||
public int compare(Player arg0, Player arg1) {
|
||||
return arg0.getCardsIn(ZoneType.Library).size() - arg1.getCardsIn(ZoneType.Library).size();
|
||||
}
|
||||
});
|
||||
final Player m = Collections.max(list, PlayerPredicates.compareByZoneSize(ZoneType.Library));
|
||||
|
||||
int cardsToDiscard = m.getCardsIn(ZoneType.Library).size();
|
||||
|
||||
|
||||
@@ -49,14 +49,6 @@ import forge.game.zone.ZoneType;
|
||||
*/
|
||||
public class RegenerateAi extends SpellAbilityAi {
|
||||
|
||||
// Ex: A:SP$Regenerate | Cost$W | ValidTgts$ Creature | TgtPrompt$ Select target creature | SpellDescription$Regenerate
|
||||
// target creature.
|
||||
// http://www.slightlymagic.net/wiki/Forge_AbilityFactory#Regenerate
|
||||
|
||||
// **************************************************************
|
||||
// ********************* Regenerate ****************************
|
||||
// **************************************************************
|
||||
|
||||
@Override
|
||||
protected boolean checkApiLogic(final Player ai, final SpellAbility sa) {
|
||||
final Game game = ai.getGame();
|
||||
@@ -65,8 +57,7 @@ public class RegenerateAi extends SpellAbilityAi {
|
||||
boolean chance = false;
|
||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||
if (tgt == null) {
|
||||
// As far as I can tell these Defined Cards will only have one of
|
||||
// them
|
||||
// As far as I can tell these Defined Cards will only have one of them
|
||||
final List<Card> list = AbilityUtils.getDefinedCards(hostCard, sa.getParam("Defined"), sa);
|
||||
|
||||
if (!game.getStack().isEmpty()) {
|
||||
@@ -105,8 +96,7 @@ public class RegenerateAi extends SpellAbilityAi {
|
||||
}
|
||||
|
||||
if (!game.getStack().isEmpty()) {
|
||||
// check stack for something on the stack will kill anything i
|
||||
// control
|
||||
// check stack for something on the stack will kill anything i control
|
||||
final List<GameObject> objects = ComputerUtil.predictThreatenedObjects(sa.getActivatingPlayer(), sa, true);
|
||||
|
||||
final List<Card> threatenedTargets = new ArrayList<>();
|
||||
@@ -191,8 +181,7 @@ public class RegenerateAi extends SpellAbilityAi {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO see if something on the stack is about to kill something i
|
||||
// can target
|
||||
// TODO see if something on the stack is about to kill something i can target
|
||||
|
||||
// choose my best X without regen
|
||||
if (CardLists.getNotType(compTargetables, "Creature").isEmpty()) {
|
||||
|
||||
@@ -121,11 +121,9 @@ public class ScryAi extends SpellAbilityAi {
|
||||
return false;
|
||||
}
|
||||
|
||||
double chance = .4; // 40 percent chance of milling with instant speed
|
||||
// stuff
|
||||
double chance = .4; // 40 percent chance of milling with instant speed stuff
|
||||
if (SpellAbilityAi.isSorcerySpeed(sa)) {
|
||||
chance = .667; // 66.7% chance for sorcery speed (since it will
|
||||
// never activate EOT)
|
||||
chance = .667; // 66.7% chance for sorcery speed (since it will never activate EOT)
|
||||
}
|
||||
boolean randomReturn = MyRandom.getRandom().nextFloat() <= Math.pow(chance, sa.getActivationsThisTurn() + 1);
|
||||
|
||||
|
||||
@@ -54,8 +54,7 @@ public class SetStateAi extends SpellAbilityAi {
|
||||
|
||||
@Override
|
||||
public boolean chkAIDrawback(SpellAbility sa, Player aiPlayer) {
|
||||
// Gross generalization, but this always considers alternate
|
||||
// states more powerful
|
||||
// Gross generalization, but this always considers alternate states more powerful
|
||||
return !sa.getHostCard().isInAlternateState();
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,7 @@ public class ShuffleAi extends SpellAbilityAi {
|
||||
return aiPlayer.getGame().getPhaseHandler().is(PhaseType.MAIN2, aiPlayer);
|
||||
}
|
||||
|
||||
// not really sure when the compy would use this; maybe only after a
|
||||
// human
|
||||
// not really sure when the compy would use this; maybe only after a human
|
||||
// deliberately put a card on top of their library
|
||||
return false;
|
||||
/*
|
||||
|
||||
@@ -19,8 +19,7 @@ public class TapOrUntapAi extends TapAiBase {
|
||||
|
||||
if (!sa.usesTargeting()) {
|
||||
// assume we are looking to tap human's stuff
|
||||
// TODO - check for things with untap abilities, and don't tap
|
||||
// those.
|
||||
// TODO - check for things with untap abilities, and don't tap those.
|
||||
|
||||
boolean bFlag = false;
|
||||
for (final Card c : AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa)) {
|
||||
|
||||
@@ -544,7 +544,6 @@ public final class CardRules implements ICardCharacteristics {
|
||||
@Override
|
||||
public final ManaCostShard next() {
|
||||
final String unparsed = st.nextToken();
|
||||
// System.out.println(unparsed);
|
||||
if (StringUtils.isNumeric(unparsed)) {
|
||||
this.genericCost += Integer.parseInt(unparsed);
|
||||
return null;
|
||||
@@ -560,7 +559,7 @@ public final class CardRules implements ICardCharacteristics {
|
||||
*/
|
||||
@Override
|
||||
public void remove() {
|
||||
} // unsuported
|
||||
} // unsupported
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@ public class ManaCostParser implements IParserManaCost {
|
||||
*/
|
||||
public ManaCostParser(final String cost) {
|
||||
this.cost = cost.split(" ");
|
||||
// System.out.println(cost);
|
||||
this.nextToken = 0;
|
||||
this.genericCost = 0;
|
||||
}
|
||||
@@ -66,7 +65,6 @@ public class ManaCostParser implements IParserManaCost {
|
||||
@Override
|
||||
public final ManaCostShard next() {
|
||||
final String unparsed = this.cost[this.nextToken++];
|
||||
// System.out.println(unparsed);
|
||||
if (StringUtils.isNumeric(unparsed)) {
|
||||
this.genericCost += Integer.parseInt(unparsed);
|
||||
return null;
|
||||
|
||||
@@ -1233,7 +1233,6 @@ public class AbilityUtils {
|
||||
}
|
||||
else if (defined.startsWith("PlayerNamed_")) {
|
||||
for (Player p : game.getPlayersInTurnOrder()) {
|
||||
//System.out.println("Named player " + defined.substring(12));
|
||||
if (p.getName().equals(defined.substring(12))) {
|
||||
players.add(p);
|
||||
}
|
||||
|
||||
@@ -220,7 +220,6 @@ public class CardFactory {
|
||||
return getCard(cp, owner, owner == null ? -1 : owner.getGame().nextCardId(), game);
|
||||
}
|
||||
public final static Card getCard(final IPaperCard cp, final Player owner, final int cardId, final Game game) {
|
||||
//System.out.println(cardName);
|
||||
CardRules cardRules = cp.getRules();
|
||||
final Card c = readCard(cardRules, cp, cardId, game);
|
||||
c.setRules(cardRules);
|
||||
|
||||
@@ -2681,11 +2681,6 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
//getZone(ZoneType.Command).add(c);
|
||||
}
|
||||
|
||||
//DBG
|
||||
//System.out.println("CurrentPlanes: " + currentPlanes);
|
||||
//System.out.println("ActivePlanes: " + game.getActivePlanes());
|
||||
//System.out.println("CommandPlanes: " + getZone(ZoneType.Command).getCards());
|
||||
|
||||
game.setActivePlanes(currentPlanes);
|
||||
//Run PlaneswalkedTo triggers here.
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||
@@ -2710,11 +2705,6 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
game.getAction().moveTo(ZoneType.PlanarDeck, plane,-1, null);
|
||||
}
|
||||
currentPlanes.clear();
|
||||
|
||||
//DBG
|
||||
//System.out.println("CurrentPlanes: " + currentPlanes);
|
||||
//System.out.println("ActivePlanes: " + game.getActivePlanes());
|
||||
//System.out.println("CommandPlanes: " + getZone(ZoneType.Command).getCards());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,7 +40,6 @@ public class SealedDeckBuilder extends LimitedDeckBuilder {
|
||||
for (int i = 0; i < limit; i++) {
|
||||
PaperCard cp = initialRanked.get(i);
|
||||
colorChooserList.add(cp);
|
||||
//System.out.println(cp.getName() + " " + cp.getRules().getManaCost().toString());
|
||||
}
|
||||
|
||||
Iterable<CardRules> rules = Iterables.transform(colorChooserList, PaperCard.FN_GET_RULES);
|
||||
|
||||
@@ -154,7 +154,6 @@ public class QuestBazaarManager {
|
||||
for (int iSlot = 0; iSlot < QuestController.MAX_PET_SLOTS; iSlot++) {
|
||||
|
||||
for (final QuestPetController pet : qCtrl.getPetsStorage().getAllPets(iSlot)) {
|
||||
//System.out.println("Pet: " + pet.getName());
|
||||
itemSet.put(pet.getName(), pet);
|
||||
}
|
||||
}
|
||||
@@ -168,7 +167,6 @@ public class QuestBazaarManager {
|
||||
|
||||
for (final String itemName : thisStall.getItems()) {
|
||||
final IQuestBazaarItem item = itemSet.get(itemName);
|
||||
//System.out.println(itemName);
|
||||
set.add(item);
|
||||
}
|
||||
itemsOnStalls.put(thisStall.getName(), set);
|
||||
|
||||
@@ -413,7 +413,6 @@ public abstract class GuiDownloadService implements Runnable {
|
||||
protected static void addMissingItems(Map<String, String> list, String nameUrlFile, String dir, boolean includeParent) {
|
||||
for (Pair<String, String> nameUrlPair : FileUtil.readNameUrlFile(nameUrlFile)) {
|
||||
File f = new File(includeParent? dir+FileUtil.getParent(nameUrlPair.getRight()) : dir , decodeURL(nameUrlPair.getLeft()));
|
||||
//System.out.println(f.getAbsolutePath());
|
||||
if (!f.exists()) {
|
||||
list.put(f.getAbsolutePath(), nameUrlPair.getRight());
|
||||
}
|
||||
|
||||
@@ -95,7 +95,6 @@ public class GuiDownloadSetPicturesLQ extends GuiDownloadService {
|
||||
if (fullborder.exists())
|
||||
return; //don't add on download if you have an existing fullborder image in this set...
|
||||
|
||||
// System.out.println(filename);
|
||||
if (!destFile.exists()) {
|
||||
downloads.put(destFile.getAbsolutePath(), ForgeConstants.URL_PIC_DOWNLOAD + urlPath);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user