mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-12 08:48:39 +00:00
Added test that ensures all lands can be played
This commit is contained in:
@@ -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()) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user