Added test that ensures all lands can be played

This commit is contained in:
marthinwurer
2023-02-01 23:12:42 -07:00
committed by Chris H
parent 58f0a72c4d
commit 2d98e58b81
4 changed files with 110 additions and 17 deletions

View File

@@ -8,6 +8,7 @@ import forge.game.phase.PhaseType;
import forge.game.player.Player;
import forge.game.spellability.AbilityManaPart;
import forge.game.spellability.SpellAbility;
import forge.game.staticability.StaticAbility;
import forge.game.zone.ZoneType;
import java.util.Arrays;
@@ -173,9 +174,9 @@ public class GameStateEvaluator {
colors_produced.addAll(Arrays.asList(mp.mana(m).split(" ")));
}
}
value = 100 * max_produced;
value += 100 * max_produced;
int size = max(colors_produced.size(), colors_produced.contains("Any") ? 5 : 0);
value += size * 2;
value += size * 6;
// add a value for each activated ability that the land has that's not an activated ability.
for (SpellAbility m: c.getNonManaAbilities()) {
@@ -184,6 +185,12 @@ public class GameStateEvaluator {
value += 6;
}
// Add a value for each static ability that the land has
for (StaticAbility s : c.getStaticAbilities()) {
// More than the value of having a card in hand. See comment above
value += 6;
}
return value;
} else if (c.isEnchantingCard()) {

View File

@@ -64,7 +64,7 @@ public class SpellAbilityPicker {
print("---- choose ability (phase = " + phaseStr + ")");
}
private List<SpellAbility> getCandidateSpellsAndAbilities() {
public List<SpellAbility> getCandidateSpellsAndAbilities() {
CardCollection cards = ComputerUtilAbility.getAvailableCards(game, player);
cards = ComputerUtilCard.dedupeCards(cards);
List<SpellAbility> all = ComputerUtilAbility.getSpellAbilities(cards, player);
@@ -351,7 +351,7 @@ public class SpellAbilityPicker {
return AiPlayDecision.WillPlay;
}
private Score evaluateSa(final SimulationController controller, PhaseType phase, List<SpellAbility> saList, int saIndex) {
public Score evaluateSa(final SimulationController controller, PhaseType phase, List<SpellAbility> saList, int saIndex) {
controller.evaluateSpellAbility(saList, saIndex);
SpellAbility sa = saList.get(saIndex);

View File

@@ -33,6 +33,22 @@ import forge.model.FModel;
public class SimulationTest {
private static boolean initialized = false;
public Game resetGame() {
// need to be done after FModel.initialize, or the Localizer isn't loaded yet
List<RegisteredPlayer> players = Lists.newArrayList();
Deck d1 = new Deck();
players.add(new RegisteredPlayer(d1).setPlayer(new LobbyPlayerAi("p2", null)));
Set<AIOption> options = new HashSet<>();
options.add(AIOption.USE_SIMULATION);
players.add(new RegisteredPlayer(d1).setPlayer(new LobbyPlayerAi("p1", options)));
GameRules rules = new GameRules(GameType.Constructed);
Match match = new Match(rules, players, "Test");
Game game = new Game(players, rules, match);
game.setAge(GameStage.Play);
return game;
}
protected Game initAndCreateGame() {
if (!initialized) {
GuiBase.setInterface(new GuiDesktop());
@@ -47,19 +63,7 @@ public class SimulationTest {
initialized = true;
}
// need to be done after FModel.initialize, or the Localizer isn't loaded yet
List<RegisteredPlayer> players = Lists.newArrayList();
Deck d1 = new Deck();
players.add(new RegisteredPlayer(d1).setPlayer(new LobbyPlayerAi("p2", null)));
Set<AIOption> options = new HashSet<>();
options.add(AIOption.USE_SIMULATION);
players.add(new RegisteredPlayer(d1).setPlayer(new LobbyPlayerAi("p1", options)));
GameRules rules = new GameRules(GameType.Constructed);
Match match = new Match(rules, players, "Test");
Game game = new Game(players, rules, match);
game.setAge(GameStage.Play);
return game;
return resetGame();
}
protected GameSimulator createSimulator(Game game, Player p) {

View File

@@ -1,8 +1,12 @@
package forge.ai.simulation;
import forge.game.spellability.LandAbility;
import java.util.ArrayList;
import java.util.List;
import forge.item.PaperCard;
import forge.model.FModel;
import org.testng.AssertJUnit;
import org.testng.annotations.Test;
@@ -371,6 +375,84 @@ public class SpellAbilityPickerSimulationTest extends SimulationTest {
AssertJUnit.assertEquals(desired, sa.getTargetCard());
}
@Test
public void ensureAllLandsArePlayable() {
initAndCreateGame();
System.out.println("Adding lands to hand");
// add every land to the player's hand
// SimulationController.MAX_DEPTH = 0;
List<Card> funky = new ArrayList<>();
String previous = "";
for (PaperCard c : FModel.getMagicDb().getCommonCards().getAllCards()) {
// reset the game
Game game = resetGame();
Player p = game.getPlayers().get(1);
Player opponent = game.getPlayers().get(0);
opponent.setLife(20, null);
// add one of each basic to the battlefield so that bouncelands and similar work
addCard("Plains", p);
addCard("Island", p);
addCard("Swamp", p);
addCard("Mountain", p);
addCard("Forest", p);
// Add basics to library to ensure fetches work
addCardToZone("Plains", p, ZoneType.Library);
addCardToZone("Island", p, ZoneType.Library);
addCardToZone("Swamp", p, ZoneType.Library);
addCardToZone("Mountain", p, ZoneType.Library);
addCardToZone("Forest", p, ZoneType.Library);
game.getPhaseHandler().devModeSet(PhaseType.MAIN1, p);
game.getAction().checkStateEffects(true);
// Only add one version at a time
if (c.getName().equals(previous)) {
continue;
}
previous = c.getName();
if (c.getRules().getType().isLand()) {
// Skip glacial chasm, it's really weird.
if (c.getName().equals("Glacial Chasm")) {
System.out.println("Skipping " + c.getName());
continue;
}
addCardToZone(c.getName(), p, ZoneType.Hand);
// Once the card has been added to the hand, test it
GameStateEvaluator.Score s = new GameStateEvaluator().getScoreForGameState(game, p);
System.out.println("Starting score: " + s);
SpellAbilityPicker picker = new SpellAbilityPicker(game, p);
List<SpellAbility> candidateSAs = picker.getCandidateSpellsAndAbilities();
for (int i = 0; i < candidateSAs.size(); i++) {
SpellAbility sa = candidateSAs.get(i);
if (sa.isActivatedAbility()) {
continue;
}
GameStateEvaluator.Score value = picker.evaluateSa(new SimulationController(s), game.getPhaseHandler().getPhase(), candidateSAs, i);
System.out.println("sa: " + sa.getHostCard() + ", value: " + value);
if (!(value.value > s.value)) {
funky.add(sa.getHostCard());
}
}
}
}
// ensure that every land play has a higher evaluation than doing nothing
System.out.println(funky);
for (Card c : funky) {
GameStateEvaluator gse = new GameStateEvaluator();
Game game = resetGame();
System.out.println(c.getName() + ": " + gse.evalCard(game, game.getStartingPlayer(), c));
}
AssertJUnit.assertEquals(0, funky.size());
}
@Test
public void testPlayRememberedCardsLand() {
Game game = initAndCreateGame();