mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 02:30:08 -08:00
tests: added tests for Chandra Ablaze card and some AI logic;
This commit is contained in:
parent
d28b9e6d05
commit
ebe04dc3a6
3 changed files with 163 additions and 18 deletions
|
|
@ -169,6 +169,7 @@ public class ComputerPlayer extends PlayerImpl {
|
||||||
|
|
||||||
if (target.getOriginalTarget() instanceof TargetDiscard) {
|
if (target.getOriginalTarget() instanceof TargetDiscard) {
|
||||||
findPlayables(game);
|
findPlayables(game);
|
||||||
|
// discard not playable first
|
||||||
if (!unplayable.isEmpty()) {
|
if (!unplayable.isEmpty()) {
|
||||||
for (int i = unplayable.size() - 1; i >= 0; i--) {
|
for (int i = unplayable.size() - 1; i >= 0; i--) {
|
||||||
if (target.canTarget(abilityControllerId, unplayable.values().toArray(new Card[0])[i].getId(), null, game)) {
|
if (target.canTarget(abilityControllerId, unplayable.values().toArray(new Card[0])[i].getId(), null, game)) {
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,8 @@ public final class ChandraAblaze extends CardImpl {
|
||||||
this.setStartingLoyalty(5);
|
this.setStartingLoyalty(5);
|
||||||
|
|
||||||
// +1: Discard a card. If a red card is discarded this way, Chandra Ablaze deals 4 damage to any target.
|
// +1: Discard a card. If a red card is discarded this way, Chandra Ablaze deals 4 damage to any target.
|
||||||
LoyaltyAbility ability = new LoyaltyAbility(new ChandraAblazeEffect1(), 1);
|
LoyaltyAbility ability = new LoyaltyAbility(new ChandraAblazeDiscardCardEffect(), 1);
|
||||||
ability.addEffect(new ChandraAblazeEffect2());
|
ability.addEffect(new ChandraAblazeDamageEffect());
|
||||||
ability.addTarget(new TargetAnyTarget());
|
ability.addTarget(new TargetAnyTarget());
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
|
|
||||||
|
|
@ -54,7 +54,7 @@ public final class ChandraAblaze extends CardImpl {
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
|
|
||||||
// -7: Cast any number of red instant and/or sorcery cards from your graveyard without paying their mana costs.
|
// -7: Cast any number of red instant and/or sorcery cards from your graveyard without paying their mana costs.
|
||||||
ability = new LoyaltyAbility(new ChandraAblazeEffect5(), -7);
|
ability = new LoyaltyAbility(new ChandraAblazeCastCardsEffect(), -7);
|
||||||
this.addAbility(ability);
|
this.addAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -68,20 +68,20 @@ public final class ChandraAblaze extends CardImpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChandraAblazeEffect1 extends OneShotEffect {
|
class ChandraAblazeDiscardCardEffect extends OneShotEffect {
|
||||||
|
|
||||||
public ChandraAblazeEffect1() {
|
public ChandraAblazeDiscardCardEffect() {
|
||||||
super(Outcome.Discard);
|
super(Outcome.Discard);
|
||||||
this.staticText = "Discard a card";
|
this.staticText = "Discard a card";
|
||||||
}
|
}
|
||||||
|
|
||||||
private ChandraAblazeEffect1(final ChandraAblazeEffect1 effect) {
|
private ChandraAblazeDiscardCardEffect(final ChandraAblazeDiscardCardEffect effect) {
|
||||||
super(effect);
|
super(effect);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChandraAblazeEffect1 copy() {
|
public ChandraAblazeDiscardCardEffect copy() {
|
||||||
return new ChandraAblazeEffect1(this);
|
return new ChandraAblazeDiscardCardEffect(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -107,20 +107,20 @@ class ChandraAblazeEffect1 extends OneShotEffect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChandraAblazeEffect2 extends OneShotEffect {
|
class ChandraAblazeDamageEffect extends OneShotEffect {
|
||||||
|
|
||||||
public ChandraAblazeEffect2() {
|
public ChandraAblazeDamageEffect() {
|
||||||
super(Outcome.Damage);
|
super(Outcome.Damage);
|
||||||
this.staticText = "If a red card is discarded this way, {this} deals 4 damage to any target";
|
this.staticText = "If a red card is discarded this way, {this} deals 4 damage to any target";
|
||||||
}
|
}
|
||||||
|
|
||||||
private ChandraAblazeEffect2(final ChandraAblazeEffect2 effect) {
|
private ChandraAblazeDamageEffect(final ChandraAblazeDamageEffect effect) {
|
||||||
super(effect);
|
super(effect);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChandraAblazeEffect2 copy() {
|
public ChandraAblazeDamageEffect copy() {
|
||||||
return new ChandraAblazeEffect2(this);
|
return new ChandraAblazeDamageEffect(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -143,7 +143,7 @@ class ChandraAblazeEffect2 extends OneShotEffect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChandraAblazeEffect5 extends OneShotEffect {
|
class ChandraAblazeCastCardsEffect extends OneShotEffect {
|
||||||
|
|
||||||
private static final FilterCard filter = new FilterInstantOrSorceryCard();
|
private static final FilterCard filter = new FilterInstantOrSorceryCard();
|
||||||
|
|
||||||
|
|
@ -151,18 +151,18 @@ class ChandraAblazeEffect5 extends OneShotEffect {
|
||||||
filter.add(new ColorPredicate(ObjectColor.RED));
|
filter.add(new ColorPredicate(ObjectColor.RED));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChandraAblazeEffect5() {
|
public ChandraAblazeCastCardsEffect() {
|
||||||
super(Outcome.PlayForFree);
|
super(Outcome.PlayForFree);
|
||||||
this.staticText = "Cast any number of red instant and/or sorcery cards from your graveyard without paying their mana costs";
|
this.staticText = "Cast any number of red instant and/or sorcery cards from your graveyard without paying their mana costs";
|
||||||
}
|
}
|
||||||
|
|
||||||
private ChandraAblazeEffect5(final ChandraAblazeEffect5 effect) {
|
private ChandraAblazeCastCardsEffect(final ChandraAblazeCastCardsEffect effect) {
|
||||||
super(effect);
|
super(effect);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChandraAblazeEffect5 copy() {
|
public ChandraAblazeCastCardsEffect copy() {
|
||||||
return new ChandraAblazeEffect5(this);
|
return new ChandraAblazeCastCardsEffect(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,144 @@
|
||||||
|
package org.mage.test.cards.single.zen;
|
||||||
|
|
||||||
|
import mage.constants.PhaseStep;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mage.test.serverside.base.CardTestPlayerBaseWithAIHelps;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author JayDi85
|
||||||
|
*/
|
||||||
|
public class ChandraAblazeTest extends CardTestPlayerBaseWithAIHelps {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_PlusOneAbility_Manual() {
|
||||||
|
// +1: Discard a card. If a red card is discarded this way, Chandra Ablaze deals 4 damage to any target.
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Chandra Ablaze", 1);
|
||||||
|
addCard(Zone.HAND, playerA, "Lightning Bolt", 1);
|
||||||
|
//
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears", 1);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
|
||||||
|
|
||||||
|
// activate +1 and kill lion
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "+1:");
|
||||||
|
addTarget(playerA, "Silvercoat Lion"); // damage
|
||||||
|
setChoice(playerA, "Lightning Bolt"); // discard
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertGraveyardCount(playerB, "Silvercoat Lion", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_PlusOneAbility_AI_ChooseBetterTarget() {
|
||||||
|
// +1: Discard a card. If a red card is discarded this way, Chandra Ablaze deals 4 damage to any target.
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Chandra Ablaze", 1);
|
||||||
|
addCard(Zone.HAND, playerA, "Lightning Bolt", 1);
|
||||||
|
//
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears", 1);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
|
||||||
|
|
||||||
|
// AI must choose better action (kill lion)
|
||||||
|
aiPlayPriority(1, PhaseStep.PRECOMBAT_MAIN, playerA);
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertGraveyardCount(playerB, "Silvercoat Lion", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore // TODO: current choose logic uses first target, enable after new logic implemented (by simulations or improved choice)
|
||||||
|
public void test_PlusOneAbility_AI_ChooseBetterDiscardCard() {
|
||||||
|
// +1: Discard a card. If a red card is discarded this way, Chandra Ablaze deals 4 damage to any target.
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Chandra Ablaze", 1);
|
||||||
|
addCard(Zone.HAND, playerA, "Glittermonger", 10); // green
|
||||||
|
addCard(Zone.HAND, playerA, "Lightning Bolt", 1); // put after green, so AI must choose better, not first
|
||||||
|
//
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Grizzly Bears", 1);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
|
||||||
|
|
||||||
|
// AI must choose better discard card (bolt as red, not green)
|
||||||
|
aiPlayPriority(1, PhaseStep.PRECOMBAT_MAIN, playerA);
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertGraveyardCount(playerB, "Silvercoat Lion", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_PlusTwoAbility_Manual() {
|
||||||
|
// -2: Each player discards their hand, then draws three cards.
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Chandra Ablaze", 1);
|
||||||
|
//
|
||||||
|
addCard(Zone.HAND, playerA, "Grizzly Bears", 5);
|
||||||
|
addCard(Zone.HAND, playerB, "Silvercoat Lion", 1);
|
||||||
|
|
||||||
|
// activate -2 and discard all
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "-2:");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertHandCount(playerA, 3);
|
||||||
|
assertHandCount(playerB, 3);
|
||||||
|
|
||||||
|
assertGraveyardCount(playerA, "Grizzly Bears", 5);
|
||||||
|
assertGraveyardCount(playerB, "Silvercoat Lion", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_PlusTwoAbility_AI_MustNotSeeOpponentHand_KeepBetterHand() {
|
||||||
|
// AI must calc battlefield score by visible data, so it do not know opponent's hand,
|
||||||
|
// but it is still able to cheat by look ahead in library (e.g. it "see" result of draw actions)
|
||||||
|
|
||||||
|
// -2: Each player discards their hand, then draws three cards.
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Chandra Ablaze", 1);
|
||||||
|
//
|
||||||
|
// TODO: it's another bug - AI can play land in some actions chain and can't play on another,
|
||||||
|
// comment and research AI logs (possible reason: AI don't wait stack resolve)
|
||||||
|
addCard(Zone.HAND, playerA, "Mountain", 1);
|
||||||
|
//
|
||||||
|
addCard(Zone.HAND, playerA, "Grizzly Bears", 5);
|
||||||
|
addCard(Zone.HAND, playerB, "Silvercoat Lion", 1);
|
||||||
|
|
||||||
|
// must not call any abilities
|
||||||
|
aiPlayPriority(1, PhaseStep.PRECOMBAT_MAIN, playerA);
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
// must keep better hand
|
||||||
|
assertHandCount(playerA, "Grizzly Bears", 5);
|
||||||
|
assertHandCount(playerB, "Silvercoat Lion", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_PlusTwoAbility_AI_MustNotSeeOpponentHand_KeepWorseHand() {
|
||||||
|
// -2: Each player discards their hand, then draws three cards.
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Chandra Ablaze", 1);
|
||||||
|
addCard(Zone.HAND, playerA, "Mountain", 1); // see prev test comments
|
||||||
|
//
|
||||||
|
addCard(Zone.HAND, playerA, "Grizzly Bears", 1);
|
||||||
|
addCard(Zone.HAND, playerB, "Silvercoat Lion", 5);
|
||||||
|
|
||||||
|
// must not call any abilities
|
||||||
|
aiPlayPriority(1, PhaseStep.PRECOMBAT_MAIN, playerA);
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
// must keep worse hand
|
||||||
|
assertHandCount(playerA, "Grizzly Bears", 1);
|
||||||
|
assertHandCount(playerB, "Silvercoat Lion", 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue