mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 02:30:08 -08:00
AI: fixed that computer can stop to use some equip and level up abilities, fixed small memory leaks (related to #11285, #4520)
This commit is contained in:
parent
10ccab3caa
commit
0d9121bf10
6 changed files with 24 additions and 48 deletions
|
|
@ -5,7 +5,9 @@ import mage.abilities.Ability;
|
|||
import mage.game.Game;
|
||||
|
||||
/**
|
||||
* Interface for ai optimizer that cuts the tree of decision.
|
||||
* AI: interface for ai optimizer that cuts the tree of decision.
|
||||
*
|
||||
* Warning, it's a static objects for all AI instances, don't store any data in it
|
||||
*
|
||||
* @author ayratn
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -8,54 +8,27 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Base class for tree optimizers.
|
||||
* AI: base class for tree optimizers.
|
||||
*
|
||||
* @author ayratn
|
||||
*/
|
||||
public abstract class BaseTreeOptimizer implements TreeOptimizer {
|
||||
|
||||
/**
|
||||
* List of abilities that should be removed because of optimization.
|
||||
*
|
||||
*/
|
||||
protected List<Ability> toRemove;
|
||||
|
||||
/**
|
||||
* Inner method for filtering actions.
|
||||
* Should be implemented by classes.
|
||||
* Filter and ignore bad actions
|
||||
*
|
||||
* @param game
|
||||
* @param actions
|
||||
* @param actionsToRemove that must be removed/ignored from a possible AI actions
|
||||
*/
|
||||
abstract void filter(Game game, List<Ability> actions);
|
||||
abstract void filter(Game game, List<Ability> actions, List<Ability> actionsToRemove);
|
||||
|
||||
/**
|
||||
* Template method for optimization.
|
||||
*
|
||||
* @param game
|
||||
* @param actions
|
||||
*/
|
||||
@Override
|
||||
public final void optimize(Game game, List<Ability> actions) {
|
||||
filter(game, actions);
|
||||
|
||||
if (toRemove != null) {
|
||||
for (Ability r : toRemove) {
|
||||
actions.remove(r);
|
||||
}
|
||||
List<Ability> actionsToRemove = new ArrayList<>();
|
||||
filter(game, actions, actionsToRemove);
|
||||
for (Ability r : actionsToRemove) {
|
||||
actions.remove(r);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark an ability to be removed
|
||||
* Not thread-safe for performance reasons.
|
||||
*
|
||||
* @param ability
|
||||
*/
|
||||
protected void removeAbility(Ability ability) {
|
||||
if (toRemove == null) {
|
||||
toRemove = new ArrayList<>();
|
||||
}
|
||||
toRemove.add(ability);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,17 +5,18 @@ import mage.abilities.Ability;
|
|||
import mage.game.Game;
|
||||
|
||||
/**
|
||||
* Removes abilities that require only discard a card for activation.
|
||||
* AI: removes abilities that require only discard a card for activation.
|
||||
*
|
||||
* @author magenoxx_at_gmail.com
|
||||
*/
|
||||
public class DiscardCardOptimizer extends BaseTreeOptimizer {
|
||||
|
||||
@Override
|
||||
public void filter(Game game, List<Ability> actions) {
|
||||
public void filter(Game game, List<Ability> actions, List<Ability> actionsToRemove) {
|
||||
for (Ability ability : actions) {
|
||||
// TODO: add more discard restictions here? See ExileSourceUnlessPaysEffect for a possible list
|
||||
if (ability.toString().startsWith("Discard card")) {
|
||||
removeAbility(ability);
|
||||
actionsToRemove.add(ability);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,21 +7,21 @@ import mage.game.Game;
|
|||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
* Make sure that AI won't equip the same creature equip already attached to.
|
||||
* AI: make sure that AI won't equip the same creature equip already attached to.
|
||||
*
|
||||
* @author ayratn
|
||||
*/
|
||||
public class EquipOptimizer extends BaseTreeOptimizer {
|
||||
|
||||
@Override
|
||||
public void filter(Game game, List<Ability> actions) {
|
||||
public void filter(Game game, List<Ability> actions, List<Ability> actionsToRemove) {
|
||||
for (Ability ability : actions) {
|
||||
if (ability instanceof EquipAbility) {
|
||||
Permanent permanent = game.getPermanent(ability.getFirstTarget());
|
||||
if (permanent != null) {
|
||||
// check that equipment is not already attached to {this}
|
||||
if (permanent.getAttachments().contains(ability.getSourceId())) {
|
||||
removeAbility(ability);
|
||||
actionsToRemove.add(ability);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import mage.game.permanent.PermanentCard;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Make sure that AI won't level up whenever there are maximum possible level up counters.
|
||||
* AI: make sure that AI won't level up whenever there are maximum possible level up counters.
|
||||
*
|
||||
* @author ayratn
|
||||
*/
|
||||
|
|
@ -23,7 +23,7 @@ public class LevelUpOptimizer extends BaseTreeOptimizer {
|
|||
* @param actions
|
||||
*/
|
||||
@Override
|
||||
public void filter(Game game, List<Ability> actions) {
|
||||
public void filter(Game game, List<Ability> actions, List<Ability> actionsToRemove) {
|
||||
for (Ability ability : actions) {
|
||||
if (ability instanceof LevelUpAbility) {
|
||||
Permanent permanent = game.getPermanent(ability.getSourceId());
|
||||
|
|
@ -31,7 +31,7 @@ public class LevelUpOptimizer extends BaseTreeOptimizer {
|
|||
PermanentCard leveler = (PermanentCard) permanent;
|
||||
// check already existing Level counters and compare to maximum that make sense
|
||||
if (permanent.getCounters(game).getCount(CounterType.LEVEL) >= leveler.getMaxLevelCounters()) {
|
||||
removeAbility(ability);
|
||||
actionsToRemove.add(ability);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,18 +8,18 @@ import mage.game.Game;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Removes abilities that require only discard a card for activation.
|
||||
* AI: removes abilities that AI don't know how to use
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class OutcomeOptimizer extends BaseTreeOptimizer {
|
||||
|
||||
@Override
|
||||
public void filter(Game game, List<Ability> actions) {
|
||||
public void filter(Game game, List<Ability> actions, List<Ability> actionsToRemove) {
|
||||
for (Ability ability : actions) {
|
||||
for (Effect effect : ability.getEffects()) {
|
||||
if (ability.getCustomOutcome() == Outcome.AIDontUseIt || effect.getOutcome() == Outcome.AIDontUseIt) {
|
||||
removeAbility(ability);
|
||||
actionsToRemove.add(ability);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue