mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 03:38:01 +00:00
Fix for noted types for Volo's journal (#6665)
This commit is contained in:
@@ -2544,35 +2544,33 @@ public class ComputerUtil {
|
|||||||
|
|
||||||
if (logic.equals("MostProminentOnBattlefield")) {
|
if (logic.equals("MostProminentOnBattlefield")) {
|
||||||
chosen = ComputerUtilCard.getMostProminentType(game.getCardsIn(ZoneType.Battlefield), valid);
|
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);
|
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));
|
CardCollectionView list = ai.getCardsIn(Arrays.asList(ZoneType.Battlefield, ZoneType.Hand));
|
||||||
if (list.isEmpty()) {
|
if (list.isEmpty()) {
|
||||||
list = ai.getCardsIn(Arrays.asList(ZoneType.Library));
|
list = ai.getCardsIn(Arrays.asList(ZoneType.Library));
|
||||||
}
|
}
|
||||||
chosen = ComputerUtilCard.getMostProminentType(list, valid);
|
chosen = ComputerUtilCard.getMostProminentType(list, valid);
|
||||||
}
|
} else if (logic.equals("MostProminentOppControls")) {
|
||||||
else if (logic.equals("MostProminentOppControls")) {
|
|
||||||
CardCollection list = ai.getOpponents().getCardsIn(ZoneType.Battlefield);
|
CardCollection list = ai.getOpponents().getCardsIn(ZoneType.Battlefield);
|
||||||
chosen = ComputerUtilCard.getMostProminentType(list, valid);
|
chosen = ComputerUtilCard.getMostProminentType(list, valid);
|
||||||
if (!CardType.isACreatureType(chosen) || invalidTypes.contains(chosen)) {
|
if (!CardType.isACreatureType(chosen) || invalidTypes.contains(chosen)) {
|
||||||
list = CardLists.filterControlledBy(game.getCardsInGame(), ai.getOpponents());
|
list = CardLists.filterControlledBy(game.getCardsInGame(), ai.getOpponents());
|
||||||
chosen = ComputerUtilCard.getMostProminentType(list, valid);
|
chosen = ComputerUtilCard.getMostProminentType(list, valid);
|
||||||
}
|
}
|
||||||
}
|
} else if (logic.startsWith("MostProminentInComputerDeck")) {
|
||||||
else if (logic.startsWith("MostProminentInComputerDeck")) {
|
|
||||||
boolean includeTokens = !logic.endsWith("NonToken");
|
boolean includeTokens = !logic.endsWith("NonToken");
|
||||||
chosen = ComputerUtilCard.getMostProminentType(ai.getAllCards(), valid, includeTokens);
|
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);
|
chosen = ComputerUtilCard.getMostProminentType(ai.getCardsIn(ZoneType.Graveyard), valid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CardType.isACreatureType(chosen) || invalidTypes.contains(chosen)) {
|
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")) {
|
} else if (kindOfType.equals("Basic Land")) {
|
||||||
|
|||||||
@@ -875,12 +875,14 @@ public class ComputerUtilCard {
|
|||||||
int max = 0;
|
int max = 0;
|
||||||
String maxType = "";
|
String maxType = "";
|
||||||
|
|
||||||
|
// Iterate through typesInDeck and consider only valid types
|
||||||
for (final Entry<String, Integer> entry : typesInDeck.entrySet()) {
|
for (final Entry<String, Integer> entry : typesInDeck.entrySet()) {
|
||||||
final String type = entry.getKey();
|
final String type = entry.getKey();
|
||||||
|
|
||||||
if (max < entry.getValue()) {
|
// consider the types that are in the valid list
|
||||||
max = entry.getValue();
|
if ((valid.isEmpty() || valid.contains(type)) && max < entry.getValue()) {
|
||||||
maxType = type;
|
max = entry.getValue();
|
||||||
|
maxType = type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public class ChooseTypeEffect extends SpellAbilityEffect {
|
|||||||
public void resolve(SpellAbility sa) {
|
public void resolve(SpellAbility sa) {
|
||||||
final Card card = sa.getHostCard();
|
final Card card = sa.getHostCard();
|
||||||
final String type = sa.getParam("Type");
|
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<String> validTypes = new ArrayList<>();
|
||||||
final List<Player> tgtPlayers = getTargetPlayers(sa);
|
final List<Player> tgtPlayers = getTargetPlayers(sa);
|
||||||
final boolean secret = sa.hasParam("Secretly");
|
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");
|
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<>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
package forge.ai.simulation;
|
package forge.ai.simulation;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.testng.AssertJUnit;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import forge.ai.ComputerUtilAbility;
|
import forge.ai.ComputerUtilAbility;
|
||||||
import forge.card.CardStateName;
|
import forge.card.CardStateName;
|
||||||
import forge.card.MagicColor;
|
import forge.card.MagicColor;
|
||||||
@@ -14,12 +8,19 @@ import forge.game.Game;
|
|||||||
import forge.game.ability.ApiType;
|
import forge.game.ability.ApiType;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardCollection;
|
import forge.game.card.CardCollection;
|
||||||
|
import forge.game.card.CardCollectionView;
|
||||||
import forge.game.card.CounterEnumType;
|
import forge.game.card.CounterEnumType;
|
||||||
import forge.game.keyword.Keyword;
|
import forge.game.keyword.Keyword;
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.zone.ZoneType;
|
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 {
|
public class GameSimulationTest extends SimulationTest {
|
||||||
|
|
||||||
@@ -154,7 +155,7 @@ public class GameSimulationTest extends SimulationTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testEtbTriggers() {
|
public void testEtbTriggers() {
|
||||||
Game game = initAndCreateGame();
|
Game game = initAndCreateGame();
|
||||||
Player p0 = game.getPlayers().get(0);
|
Player p0 = game.getPlayers().get(0);
|
||||||
Player p = game.getPlayers().get(1);
|
Player p = game.getPlayers().get(1);
|
||||||
addCard("Black Knight", p);
|
addCard("Black Knight", p);
|
||||||
addCards("Swamp", 5, p);
|
addCards("Swamp", 5, p);
|
||||||
@@ -1391,7 +1392,7 @@ public class GameSimulationTest extends SimulationTest {
|
|||||||
p.setLife(-1, null);
|
p.setLife(-1, null);
|
||||||
game.getAction().checkStateEffects(true);
|
game.getAction().checkStateEffects(true);
|
||||||
assert (deathsShadow.getNetPower() == 13); // on negative life, should
|
assert (deathsShadow.getNetPower() == 13); // on negative life, should
|
||||||
// always be 13/13
|
// always be 13/13
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -2548,4 +2549,72 @@ public class GameSimulationTest extends SimulationTest {
|
|||||||
// spell should fizzle so no card was drawn
|
// spell should fizzle so no card was drawn
|
||||||
AssertJUnit.assertEquals(0, game.getPlayers().get(0).getCardsIn(ZoneType.Hand).size());
|
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
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user