mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 10:48:00 +00:00
Performance: improve deduping
This commit is contained in:
@@ -1646,7 +1646,8 @@ public class AiController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final SpellAbility getSpellAbilityToPlay() {
|
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();
|
List<SpellAbility> saList = Lists.newArrayList();
|
||||||
|
|
||||||
SpellAbility top = null;
|
SpellAbility top = null;
|
||||||
|
|||||||
@@ -2052,6 +2052,25 @@ public class ComputerUtilCard {
|
|||||||
return false;
|
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.
|
// 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).
|
// Includes a NPE guard on getRules() which might otherwise be tripped on some cards (e.g. tokens).
|
||||||
public static boolean isCardRemAIDeck(final Card card) {
|
public static boolean isCardRemAIDeck(final Card card) {
|
||||||
|
|||||||
@@ -200,8 +200,8 @@ public class ComputerUtilCombat {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
damage += predictPowerBonusOfAttacker(attacker, null, combat, withoutAbilities);
|
|
||||||
if (!attacker.hasKeyword(Keyword.INFECT)) {
|
if (!attacker.hasKeyword(Keyword.INFECT)) {
|
||||||
|
damage += predictPowerBonusOfAttacker(attacker, null, combat, withoutAbilities);
|
||||||
sum = predictDamageTo(attacked, damage, attacker, true);
|
sum = predictDamageTo(attacked, damage, attacker, true);
|
||||||
if (attacker.hasDoubleStrike()) {
|
if (attacker.hasDoubleStrike()) {
|
||||||
sum *= 2;
|
sum *= 2;
|
||||||
@@ -2480,8 +2480,7 @@ public class ComputerUtilCombat {
|
|||||||
// intern toxic effect
|
// intern toxic effect
|
||||||
poison += attacker.getKeywordMagnitude(Keyword.TOXIC);
|
poison += attacker.getKeywordMagnitude(Keyword.TOXIC);
|
||||||
}
|
}
|
||||||
if (attacker.hasDoubleStrike())
|
if (attacker.hasDoubleStrike()) {
|
||||||
{
|
|
||||||
poison *= 2;
|
poison *= 2;
|
||||||
}
|
}
|
||||||
return poison;
|
return poison;
|
||||||
|
|||||||
@@ -116,6 +116,9 @@ public class CreatureEvaluator implements Function<Card, Integer> {
|
|||||||
else if (c.hasKeyword(Keyword.WITHER)) {
|
else if (c.hasKeyword(Keyword.WITHER)) {
|
||||||
value += addValue(power * 10, "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.RAMPAGE), "rampage");
|
||||||
value += addValue(c.getKeywordMagnitude(Keyword.AFFLICT) * 5, "afflict");
|
value += addValue(c.getKeywordMagnitude(Keyword.AFFLICT) * 5, "afflict");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1066,9 +1066,7 @@ public abstract class GameState {
|
|||||||
}
|
}
|
||||||
top.addMergedCard(bottom);
|
top.addMergedCard(bottom);
|
||||||
|
|
||||||
if (top.getMutatedTimestamp() != -1) {
|
top.removeMutatedStates();
|
||||||
top.removeCloneState(top.getMutatedTimestamp());
|
|
||||||
}
|
|
||||||
|
|
||||||
final long ts = game.getNextTimestamp();
|
final long ts = game.getNextTimestamp();
|
||||||
top.setMutatedTimestamp(ts);
|
top.setMutatedTimestamp(ts);
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ public class MultiTargetSelector {
|
|||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
for (PossibleTargetSelector selector : selectors) {
|
for (PossibleTargetSelector selector : selectors) {
|
||||||
selector.reset();
|
selector.reset();
|
||||||
}
|
}
|
||||||
currentIndex = -1;
|
currentIndex = -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package forge.ai.simulation;
|
|||||||
|
|
||||||
import forge.util.MyRandom;
|
import forge.util.MyRandom;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -10,6 +9,7 @@ import java.util.Set;
|
|||||||
import forge.ai.AiPlayDecision;
|
import forge.ai.AiPlayDecision;
|
||||||
import forge.ai.ComputerUtil;
|
import forge.ai.ComputerUtil;
|
||||||
import forge.ai.ComputerUtilAbility;
|
import forge.ai.ComputerUtilAbility;
|
||||||
|
import forge.ai.ComputerUtilCard;
|
||||||
import forge.ai.ComputerUtilCost;
|
import forge.ai.ComputerUtilCost;
|
||||||
import forge.ai.ability.ChangeZoneAi;
|
import forge.ai.ability.ChangeZoneAi;
|
||||||
import forge.ai.ability.ExploreAi;
|
import forge.ai.ability.ExploreAi;
|
||||||
@@ -66,8 +66,8 @@ public class SpellAbilityPicker {
|
|||||||
|
|
||||||
private List<SpellAbility> getCandidateSpellsAndAbilities() {
|
private List<SpellAbility> getCandidateSpellsAndAbilities() {
|
||||||
CardCollection cards = ComputerUtilAbility.getAvailableCards(game, player);
|
CardCollection cards = ComputerUtilAbility.getAvailableCards(game, player);
|
||||||
|
cards = ComputerUtilCard.dedupeCards(cards);
|
||||||
List<SpellAbility> all = ComputerUtilAbility.getSpellAbilities(cards, player);
|
List<SpellAbility> all = ComputerUtilAbility.getSpellAbilities(cards, player);
|
||||||
HashMap<String, Card> landsDeDupe = new HashMap<>();
|
|
||||||
List<SpellAbility> candidateSAs = ComputerUtilAbility.getOriginalAndAltCostAbilities(all, player);
|
List<SpellAbility> candidateSAs = ComputerUtilAbility.getOriginalAndAltCostAbilities(all, player);
|
||||||
int writeIndex = 0;
|
int writeIndex = 0;
|
||||||
for (int i = 0; i < candidateSAs.size(); i++) {
|
for (int i = 0; i < candidateSAs.size(); i++) {
|
||||||
@@ -75,16 +75,6 @@ public class SpellAbilityPicker {
|
|||||||
if (sa.isManaAbility()) {
|
if (sa.isManaAbility()) {
|
||||||
continue;
|
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);
|
sa.setActivatingPlayer(player, true);
|
||||||
|
|
||||||
AiPlayDecision opinion = canPlayAndPayForSim(sa);
|
AiPlayDecision opinion = canPlayAndPayForSim(sa);
|
||||||
|
|||||||
@@ -66,9 +66,7 @@ public class MutateEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// First remove current mutated states
|
// First remove current mutated states
|
||||||
if (target.getMutatedTimestamp() != -1) {
|
target.removeMutatedStates();
|
||||||
target.removeCloneState(target.getMutatedTimestamp());
|
|
||||||
}
|
|
||||||
// Now add all abilities from bottom cards
|
// Now add all abilities from bottom cards
|
||||||
final Long ts = game.getNextTimestamp();
|
final Long ts = game.getNextTimestamp();
|
||||||
target.setMutatedTimestamp(ts);
|
target.setMutatedTimestamp(ts);
|
||||||
|
|||||||
@@ -1240,7 +1240,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final void removeMutatedStates() {
|
public final void removeMutatedStates() {
|
||||||
if (getMutatedTimestamp() != -1) {
|
if (isMutated()) {
|
||||||
removeCloneState(getMutatedTimestamp());
|
removeCloneState(getMutatedTimestamp());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5801,6 +5801,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
}
|
}
|
||||||
return getCastSA().isMadness();
|
return getCastSA().isMadness();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean wasDiscarded() { return discarded; }
|
public boolean wasDiscarded() { return discarded; }
|
||||||
public void setDiscarded(boolean state) { discarded = state; }
|
public void setDiscarded(boolean state) { discarded = state; }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user