Performance: improve deduping

This commit is contained in:
tool4EvEr
2023-01-08 23:14:47 +01:00
parent fb3f14db71
commit f783d5a198
9 changed files with 33 additions and 24 deletions

View File

@@ -1646,7 +1646,8 @@ public class AiController {
}
private final SpellAbility getSpellAbilityToPlay() {
final CardCollection cards = ComputerUtilAbility.getAvailableCards(game, player);
CardCollection cards = ComputerUtilAbility.getAvailableCards(game, player);
cards = ComputerUtilCard.dedupeCards(cards);
List<SpellAbility> saList = Lists.newArrayList();
SpellAbility top = null;

View File

@@ -2052,6 +2052,25 @@ public class ComputerUtilCard {
return false;
}
public static CardCollection dedupeCards(CardCollection cc) {
CardCollection deduped = new CardCollection();
for (Card c : cc) {
boolean unique = true;
if (c.isInZone(ZoneType.Hand)) {
for (Card d : deduped) {
if (d.isInZone(ZoneType.Hand) && d.getOwner().equals(c.getOwner()) && d.getName().equals(c.getName())) {
unique = false;
break;
}
}
}
if (unique) {
deduped.add(c);
}
}
return deduped;
}
// Determine if the AI has an AI:RemoveDeck:All or an AI:RemoveDeck:Random hint specified.
// Includes a NPE guard on getRules() which might otherwise be tripped on some cards (e.g. tokens).
public static boolean isCardRemAIDeck(final Card card) {

View File

@@ -200,8 +200,8 @@ public class ComputerUtilCombat {
return 0;
}
damage += predictPowerBonusOfAttacker(attacker, null, combat, withoutAbilities);
if (!attacker.hasKeyword(Keyword.INFECT)) {
damage += predictPowerBonusOfAttacker(attacker, null, combat, withoutAbilities);
sum = predictDamageTo(attacked, damage, attacker, true);
if (attacker.hasDoubleStrike()) {
sum *= 2;
@@ -2480,8 +2480,7 @@ public class ComputerUtilCombat {
// intern toxic effect
poison += attacker.getKeywordMagnitude(Keyword.TOXIC);
}
if (attacker.hasDoubleStrike())
{
if (attacker.hasDoubleStrike()) {
poison *= 2;
}
return poison;

View File

@@ -116,6 +116,9 @@ public class CreatureEvaluator implements Function<Card, Integer> {
else if (c.hasKeyword(Keyword.WITHER)) {
value += addValue(power * 10, "Wither");
}
else if (c.hasKeyword(Keyword.TOXIC)) {
value += addValue(power * 10, "Toxic");
}
value += addValue(c.getKeywordMagnitude(Keyword.RAMPAGE), "rampage");
value += addValue(c.getKeywordMagnitude(Keyword.AFFLICT) * 5, "afflict");
}

View File

@@ -1066,9 +1066,7 @@ public abstract class GameState {
}
top.addMergedCard(bottom);
if (top.getMutatedTimestamp() != -1) {
top.removeCloneState(top.getMutatedTimestamp());
}
top.removeMutatedStates();
final long ts = game.getNextTimestamp();
top.setMutatedTimestamp(ts);

View File

@@ -73,7 +73,7 @@ public class MultiTargetSelector {
public void reset() {
for (PossibleTargetSelector selector : selectors) {
selector.reset();
selector.reset();
}
currentIndex = -1;
}

View File

@@ -2,7 +2,6 @@ package forge.ai.simulation;
import forge.util.MyRandom;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import java.util.Set;
@@ -10,6 +9,7 @@ import java.util.Set;
import forge.ai.AiPlayDecision;
import forge.ai.ComputerUtil;
import forge.ai.ComputerUtilAbility;
import forge.ai.ComputerUtilCard;
import forge.ai.ComputerUtilCost;
import forge.ai.ability.ChangeZoneAi;
import forge.ai.ability.ExploreAi;
@@ -66,8 +66,8 @@ public class SpellAbilityPicker {
private List<SpellAbility> getCandidateSpellsAndAbilities() {
CardCollection cards = ComputerUtilAbility.getAvailableCards(game, player);
cards = ComputerUtilCard.dedupeCards(cards);
List<SpellAbility> all = ComputerUtilAbility.getSpellAbilities(cards, player);
HashMap<String, Card> landsDeDupe = new HashMap<>();
List<SpellAbility> candidateSAs = ComputerUtilAbility.getOriginalAndAltCostAbilities(all, player);
int writeIndex = 0;
for (int i = 0; i < candidateSAs.size(); i++) {
@@ -75,16 +75,6 @@ public class SpellAbilityPicker {
if (sa.isManaAbility()) {
continue;
}
// Skip identical lands.
if (sa instanceof LandAbility) {
Card land = sa.getHostCard();
Card previousLand = landsDeDupe.get(sa.getHostCard().getName());
if (previousLand != null && previousLand.getZone() == land.getZone() &&
previousLand.getOwner() == land.getOwner()) {
continue;
}
landsDeDupe.put(land.getName(), land);
}
sa.setActivatingPlayer(player, true);
AiPlayDecision opinion = canPlayAndPayForSim(sa);

View File

@@ -66,9 +66,7 @@ public class MutateEffect extends SpellAbilityEffect {
}
// First remove current mutated states
if (target.getMutatedTimestamp() != -1) {
target.removeCloneState(target.getMutatedTimestamp());
}
target.removeMutatedStates();
// Now add all abilities from bottom cards
final Long ts = game.getNextTimestamp();
target.setMutatedTimestamp(ts);

View File

@@ -1240,7 +1240,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
}
public final void removeMutatedStates() {
if (getMutatedTimestamp() != -1) {
if (isMutated()) {
removeCloneState(getMutatedTimestamp());
}
}
@@ -5801,6 +5801,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
}
return getCastSA().isMadness();
}
public boolean wasDiscarded() { return discarded; }
public void setDiscarded(boolean state) { discarded = state; }