AI: purged whole targeting code and replaced with simple and shared logic (part of #13638) (#13766)

- refactor: removed outdated/unused code from AI, battlefield score, targeting, etc;
- ai: removed all targeting and filters related logic from ComputerPlayer;
- ai: improved targeting with shared and simple logic due effect's outcome and possible targets priority;
- ai: improved get amount selection (now AI will not choose big and useless values);
- ai: improved spell selection on free cast (now AI will try to cast spells with valid targets only);
- tests: improved result table with first bad dialog info for fast access (part of #13638);
This commit is contained in:
Oleg Agafonov 2025-06-18 20:03:58 +03:00 committed by GitHub
parent 1fe0d92c86
commit ffe902d25e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 777 additions and 1615 deletions

View file

@ -47,23 +47,23 @@ public enum Outcome {
private final boolean good;
// no different between own or opponent targets (example: copy must choose from all permanents)
private boolean canTargetAll;
private boolean anyTargetHasSameValue;
Outcome(boolean good) {
this.good = good;
}
Outcome(boolean good, boolean canTargetAll) {
Outcome(boolean good, boolean anyTargetHasSameValue) {
this.good = good;
this.canTargetAll = canTargetAll;
this.anyTargetHasSameValue = anyTargetHasSameValue;
}
public boolean isGood() {
return good;
}
public boolean isCanTargetAll() {
return canTargetAll;
public boolean anyTargetHasSameValue() {
return anyTargetHasSameValue;
}
public static Outcome inverse(Outcome outcome) {

View file

@ -4,6 +4,8 @@ import mage.constants.CardType;
import mage.filter.predicate.Predicates;
/**
* Warning, it's a filter for damage effects only (ignore lands, artifacts and other non-damageable objects)
*
* @author TheElk801
*/
public class FilterAnyTarget extends FilterPermanentOrPlayer {

View file

@ -28,6 +28,7 @@ public interface Target extends Copyable<Target>, Serializable {
*/
boolean isChosen(Game game);
@Deprecated // TODO: replace usage in cards by full version from choose methods
boolean isChoiceCompleted(Game game);
boolean isChoiceCompleted(UUID abilityControllerId, Ability source, Game game);
@ -84,7 +85,7 @@ public interface Target extends Copyable<Target>, Serializable {
/**
* @param id
* @param source WARNING, it can be null for AI or other calls from events (TODO: introduce normal source in AI ComputerPlayer)
* @param source WARNING, it can be null for AI or other calls from events
* @param game
* @return
*/

View file

@ -261,7 +261,6 @@ public abstract class TargetImpl implements Target {
}
@Override
@Deprecated // TODO: replace usage in cards by full version from choose methods
public boolean isChoiceCompleted(Game game) {
return isChoiceCompleted(null, null, game);
}

View file

@ -3,6 +3,8 @@ package mage.target.common;
import mage.filter.common.FilterAnyTarget;
/**
* Warning, it's a target for damage effects only (ignore lands, artifacts and other non-damageable objects)
*
* @author JRHerlehy Created on 4/8/18.
*/
public class TargetAnyTarget extends TargetPermanentOrPlayer {

View file

@ -18,6 +18,7 @@ import java.util.Set;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public class TargetCardInGraveyardBattlefieldOrStack extends TargetCard {
@ -97,7 +98,7 @@ public class TargetCardInGraveyardBattlefieldOrStack extends TargetCard {
@Override
public boolean canTarget(UUID id, Game game) {
return this.canTarget(null, id, null, game);
return this.canTarget(null, id, null, game); // wtf
}
@Override