Fix for noted types for Volo's journal (#6665)

This commit is contained in:
Justin C
2024-12-07 01:13:22 +11:00
committed by GitHub
parent 95e5b7afca
commit 6c1f4c7ffe
4 changed files with 98 additions and 23 deletions

View File

@@ -2544,35 +2544,33 @@ public class ComputerUtil {
if (logic.equals("MostProminentOnBattlefield")) {
chosen = ComputerUtilCard.getMostProminentType(game.getCardsIn(ZoneType.Battlefield), valid);
}
else if (logic.equals("MostProminentComputerControls")) {
} else if (logic.equals("MostProminentComputerControls")) {
chosen = ComputerUtilCard.getMostProminentType(ai.getCardsIn(ZoneType.Battlefield), valid);
}
else if (logic.equals("MostProminentComputerControlsOrOwns")) {
} else if (logic.equals("MostProminentComputerControlsOrOwns")) {
CardCollectionView list = ai.getCardsIn(Arrays.asList(ZoneType.Battlefield, ZoneType.Hand));
if (list.isEmpty()) {
list = ai.getCardsIn(Arrays.asList(ZoneType.Library));
}
chosen = ComputerUtilCard.getMostProminentType(list, valid);
}
else if (logic.equals("MostProminentOppControls")) {
} else if (logic.equals("MostProminentOppControls")) {
CardCollection list = ai.getOpponents().getCardsIn(ZoneType.Battlefield);
chosen = ComputerUtilCard.getMostProminentType(list, valid);
if (!CardType.isACreatureType(chosen) || invalidTypes.contains(chosen)) {
list = CardLists.filterControlledBy(game.getCardsInGame(), ai.getOpponents());
chosen = ComputerUtilCard.getMostProminentType(list, valid);
}
}
else if (logic.startsWith("MostProminentInComputerDeck")) {
} else if (logic.startsWith("MostProminentInComputerDeck")) {
boolean includeTokens = !logic.endsWith("NonToken");
chosen = ComputerUtilCard.getMostProminentType(ai.getAllCards(), valid, includeTokens);
}
else if (logic.equals("MostProminentInComputerGraveyard")) {
} else if (logic.equals("MostProminentInComputerGraveyard")) {
chosen = ComputerUtilCard.getMostProminentType(ai.getCardsIn(ZoneType.Graveyard), valid);
}
}
if (!CardType.isACreatureType(chosen) || invalidTypes.contains(chosen)) {
chosen = "Sliver";
chosen = validTypes.size() == 1 ? (String) validTypes.toArray()[0] :
ComputerUtilCard.getMostProminentType(ai.getAllCards(), validTypes, false);
//chosen = "Sliver";
}
} else if (kindOfType.equals("Basic Land")) {

View File

@@ -875,12 +875,14 @@ public class ComputerUtilCard {
int max = 0;
String maxType = "";
// Iterate through typesInDeck and consider only valid types
for (final Entry<String, Integer> entry : typesInDeck.entrySet()) {
final String type = entry.getKey();
if (max < entry.getValue()) {
max = entry.getValue();
maxType = type;
// consider the types that are in the valid list
if ((valid.isEmpty() || valid.contains(type)) && max < entry.getValue()) {
max = entry.getValue();
maxType = type;
}
}

View File

@@ -38,7 +38,7 @@ public class ChooseTypeEffect extends SpellAbilityEffect {
public void resolve(SpellAbility sa) {
final Card card = sa.getHostCard();
final String type = sa.getParam("Type");
final List<String> invalidTypes = sa.hasParam("InvalidTypes") ? Arrays.asList(sa.getParam("InvalidTypes").split(",")) : new ArrayList<>();
final List<String> invalidTypes = getInvalidTypes(sa);
final List<String> validTypes = new ArrayList<>();
final List<Player> tgtPlayers = getTargetPlayers(sa);
final boolean secret = sa.hasParam("Secretly");
@@ -154,4 +154,10 @@ public class ChooseTypeEffect extends SpellAbilityEffect {
throw new InvalidParameterException(sa.getHostCard() + "'s ability resulted in no types to choose from");
}
}
private static List<String> getInvalidTypes(SpellAbility sa) {
return sa.hasParam("InvalidTypes") ?
Arrays.asList(sa.getParam("InvalidTypes").split(",")) :
new ArrayList<>();
}
}

View File

@@ -1,12 +1,6 @@
package forge.ai.simulation;
import java.util.List;
import org.testng.AssertJUnit;
import org.testng.annotations.Test;
import com.google.common.collect.Lists;
import forge.ai.ComputerUtilAbility;
import forge.card.CardStateName;
import forge.card.MagicColor;
@@ -14,12 +8,19 @@ import forge.game.Game;
import forge.game.ability.ApiType;
import forge.game.card.Card;
import forge.game.card.CardCollection;
import forge.game.card.CardCollectionView;
import forge.game.card.CounterEnumType;
import forge.game.keyword.Keyword;
import forge.game.phase.PhaseType;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
import org.testng.AssertJUnit;
import org.testng.annotations.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class GameSimulationTest extends SimulationTest {
@@ -154,7 +155,7 @@ public class GameSimulationTest extends SimulationTest {
@Test
public void testEtbTriggers() {
Game game = initAndCreateGame();
Player p0 = game.getPlayers().get(0);
Player p0 = game.getPlayers().get(0);
Player p = game.getPlayers().get(1);
addCard("Black Knight", p);
addCards("Swamp", 5, p);
@@ -1391,7 +1392,7 @@ public class GameSimulationTest extends SimulationTest {
p.setLife(-1, null);
game.getAction().checkStateEffects(true);
assert (deathsShadow.getNetPower() == 13); // on negative life, should
// always be 13/13
// always be 13/13
}
@Test
@@ -2548,4 +2549,72 @@ public class GameSimulationTest extends SimulationTest {
// spell should fizzle so no card was drawn
AssertJUnit.assertEquals(0, game.getPlayers().get(0).getCardsIn(ZoneType.Hand).size());
}
/**
* blah
*/
@Test
public void testVoloJournal() {
Game game = initAndCreateGame();
Player p0 = game.getPlayers().get(0);
Player p = game.getPlayers().get(1);
addCards("Island", 7, p);
addCards("Mountain", 2, p);
addCards("Forest", 2, p);
Card c = addCardToZone("Volo, Itinerant Scholar", p, ZoneType.Hand);
Card[] cards = {
addCardToZone("Cathartic Adept", p, ZoneType.Hand),
addCardToZone("Cathartic Adept", p, ZoneType.Hand),
addCardToZone("Drowner Initiate", p, ZoneType.Hand),
addCardToZone("Atog", p, ZoneType.Hand),
addCardToZone("Atog", p, ZoneType.Hand)
};
game.getPhaseHandler().devModeSet(PhaseType.MAIN1, p);
game.getAction().checkStateEffects(true);
SpellAbility playVoloSA = c.getFirstSpellAbility();
playVoloSA.setActivatingPlayer(p);
GameSimulator sim = createSimulator(game, p);
sim.simulateSpellAbility(playVoloSA);
Game simGame = sim.getSimulatedGameState();
for (Card card : cards) {
SpellAbility a1 = card.getSpellAbilities().get(0);
a1.setActivatingPlayer(p);
sim.simulateSpellAbility(a1);
}
Player simP = simGame.getPlayer(p.getId());
CardCollectionView btlf = simP.getCardsIn(ZoneType.Battlefield);
List<String> words = List.of(new String[]{"Human", "Wizard", "Atog", "Merfolk"});
for (Card card : btlf) {
if (card.getName().equals("Volo's Journal")) {
// All words are present in the iterable
AssertJUnit.assertTrue(areWordsInIterable(words, card.getNotedTypes()));
}
}
}
protected boolean areWordsInIterable(List<String> words, Iterable<String> iterable) {
// Create a frequency map for the words in the iterable
Map<String, Integer> frequencyMap = new HashMap<>();
for (String item : iterable) {
frequencyMap.put(item, frequencyMap.getOrDefault(item, 0) + 1);
}
// Check if each word in the list appears exactly once
for (String word : words) {
if (frequencyMap.getOrDefault(word, 0) != 1) {
return false; // If the word doesn't appear exactly once, return false
}
}
return true; // All words appear exactly once
}
}