mirror of
https://github.com/magefree/mage.git
synced 2026-01-10 21:02:08 -08:00
updated test framework - added TestPlayer which only performs instructed actions
This commit is contained in:
parent
2e14adfde0
commit
86906c633a
28 changed files with 1425 additions and 103 deletions
|
|
@ -3,6 +3,7 @@ package org.mage.test.ai;
|
|||
import junit.framework.Assert;
|
||||
import mage.Constants;
|
||||
import mage.game.permanent.Permanent;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestBase;
|
||||
|
||||
|
|
@ -14,6 +15,7 @@ import org.mage.test.serverside.base.CardTestBase;
|
|||
public class EquipAbilityTest extends CardTestBase {
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testLevelUpAbilityUsage() {
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Steel Wall");
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Blade of the Bloodchief");
|
||||
|
|
@ -22,6 +24,7 @@ public class EquipAbilityTest extends CardTestBase {
|
|||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Plains", 2);
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Sacred Foundry", 1);
|
||||
|
||||
setStopAt(1, Constants.PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
Permanent wall = getPermanent("Steel Wall", playerA.getId());
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import org.junit.Test;
|
|||
import org.mage.test.serverside.base.CardTestBase;
|
||||
|
||||
import java.util.Map;
|
||||
import org.junit.Ignore;
|
||||
|
||||
/**
|
||||
* Make sure AI uses level up ability, but not too much (over the max useful level - Issue 441).
|
||||
|
|
@ -18,6 +19,7 @@ import java.util.Map;
|
|||
public class LevelUpAbilityTest extends CardTestBase {
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testLevelUpAbilityUsage() {
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Transcendent Master");
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Swamp", 15);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import junit.framework.Assert;
|
|||
import mage.Constants;
|
||||
import mage.counters.CounterType;
|
||||
import mage.game.permanent.Permanent;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestBase;
|
||||
|
||||
|
|
@ -16,6 +17,7 @@ public class NimShamblerTest extends CardTestBase {
|
|||
* Reproduces the bug when AI sacrifices its creatures for no reason.
|
||||
*/
|
||||
@Test
|
||||
@Ignore
|
||||
public void testNoCreatureWasSacrificed() {
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Nim Shambler");
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Blood Cultist");
|
||||
|
|
@ -32,6 +34,7 @@ public class NimShamblerTest extends CardTestBase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testAttackAndKillBlockerWithAdditionalDamage() {
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Nim Shambler");
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Blood Cultist");
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package org.mage.test.ai;
|
|||
import junit.framework.Assert;
|
||||
import mage.Constants;
|
||||
import mage.game.permanent.Permanent;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestBase;
|
||||
|
||||
|
|
@ -15,6 +16,7 @@ public class ObNixilistheFallenTest extends CardTestBase {
|
|||
* Reproduces bug when AI doesn't use good "may" ability.
|
||||
*/
|
||||
@Test
|
||||
@Ignore
|
||||
public void testMayAbilityUsed() {
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Ob Nixilis, the Fallen");
|
||||
addCard(Constants.Zone.HAND, playerA, "Swamp", 1);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package org.mage.test.ai;
|
|||
import mage.Constants;
|
||||
import mage.game.permanent.Permanent;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestBase;
|
||||
|
||||
|
|
@ -14,6 +15,7 @@ import org.mage.test.serverside.base.CardTestBase;
|
|||
public class RegenerateAbilityTest extends CardTestBase {
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testRegenerateUsage() {
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Quicksilver Gargantuan", 1);
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Thousand-legged Kami", 1);
|
||||
|
|
|
|||
|
|
@ -3,12 +3,14 @@ package org.mage.test.ai.bugs;
|
|||
import junit.framework.Assert;
|
||||
import mage.Constants;
|
||||
import mage.game.permanent.Permanent;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestBase;
|
||||
|
||||
public class BugCantFindCardInLibrary extends CardTestBase {
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testWithSquadronHawk() {
|
||||
addCard(Constants.Zone.HAND, playerA, "Squadron Hawk");
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Plains");
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package org.mage.test.ai.bugs;
|
||||
|
||||
import mage.Constants;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestBase;
|
||||
|
||||
|
|
@ -12,6 +13,7 @@ import org.mage.test.serverside.base.CardTestBase;
|
|||
public class BugDoesntAttackTest extends CardTestBase {
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testAttackWithZephyrSprite() throws Exception {
|
||||
addCard(Constants.Zone.HAND, playerA, "Zephyr Sprite");
|
||||
addCard(Constants.Zone.HAND, playerA, "Island");
|
||||
|
|
@ -25,6 +27,7 @@ public class BugDoesntAttackTest extends CardTestBase {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testAttackWithGoblinGuide() throws Exception {
|
||||
addCard(Constants.Zone.HAND, playerA, "Goblin Guide");
|
||||
addCard(Constants.Zone.HAND, playerA, "Mountain");
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import org.mage.test.serverside.base.CardTestBase;
|
|||
public class BugTapsItselfTest extends CardTestBase {
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testVersusInfectCreature() throws Exception {
|
||||
useWhiteDefault();
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Blinding Mage");
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ public class SejiriMerfolkTest extends CardTestBase {
|
|||
@Test
|
||||
public void testWithoutPlains() {
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Sejiri Merfolk");
|
||||
setStopAt(1, Constants.PhaseStep.DRAW);
|
||||
execute();
|
||||
Permanent merfolk = getPermanent("Sejiri Merfolk", playerA.getId());
|
||||
Assert.assertNotNull(merfolk);
|
||||
|
|
@ -27,6 +28,7 @@ public class SejiriMerfolkTest extends CardTestBase {
|
|||
public void testWithPlains() {
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Sejiri Merfolk");
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Plains");
|
||||
setStopAt(1, Constants.PhaseStep.DRAW);
|
||||
execute();
|
||||
Permanent merfolk = getPermanent("Sejiri Merfolk", playerA.getId());
|
||||
Assert.assertNotNull(merfolk);
|
||||
|
|
|
|||
|
|
@ -1,23 +1,23 @@
|
|||
package org.mage.test.cards.damage;
|
||||
|
||||
import mage.Constants;
|
||||
import mage.Constants.PhaseStep;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestBase;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* @author ayrat
|
||||
*/
|
||||
public class LightningBoltTest extends CardTestBase {
|
||||
public class LightningBoltTest extends CardTestPlayerBase {
|
||||
|
||||
@Test
|
||||
public void testDamageOpponent() {
|
||||
addCard(Constants.Zone.HAND, playerA, "Mountain");
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Mountain");
|
||||
addCard(Constants.Zone.HAND, playerA, "Lightning Bolt");
|
||||
|
||||
playLand(playerA, "Mountain");
|
||||
castSpell(playerA, "Lightning Bolt");
|
||||
// not specifying target, AI should choose opponent by itself
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
|
||||
|
||||
setStopAt(1, Constants.PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 17);
|
||||
|
|
@ -25,14 +25,12 @@ public class LightningBoltTest extends CardTestBase {
|
|||
|
||||
@Test
|
||||
public void testDamageSelf() {
|
||||
addCard(Constants.Zone.HAND, playerA, "Mountain");
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Mountain");
|
||||
addCard(Constants.Zone.HAND, playerA, "Lightning Bolt");
|
||||
|
||||
playLand(playerA, "Mountain");
|
||||
castSpell(playerA, "Lightning Bolt");
|
||||
addFixedTarget(playerA, "Lightning Bolt", playerA);
|
||||
playerA.setAllowBadMoves(true);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerA);
|
||||
|
||||
setStopAt(1, Constants.PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
assertLife(playerA, 17);
|
||||
assertLife(playerB, 20);
|
||||
|
|
@ -40,28 +38,26 @@ public class LightningBoltTest extends CardTestBase {
|
|||
|
||||
@Test
|
||||
public void testDamageSmallCreature() {
|
||||
addCard(Constants.Zone.HAND, playerA, "Mountain");
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Mountain");
|
||||
addCard(Constants.Zone.HAND, playerA, "Lightning Bolt");
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerB, "Sejiri Merfolk");
|
||||
|
||||
playLand(playerA, "Mountain");
|
||||
castSpell(playerA, "Lightning Bolt");
|
||||
addFixedTarget(playerA, "Lightning Bolt", "Sejiri Merfolk");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Sejiri Merfolk");
|
||||
|
||||
setStopAt(1, Constants.PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
assertPermanentCount(playerB, "Sejiri Merfolk", 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDamageBigCreature() {
|
||||
addCard(Constants.Zone.HAND, playerA, "Mountain");
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Mountain");
|
||||
addCard(Constants.Zone.HAND, playerA, "Lightning Bolt");
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerB, "Craw Wurm");
|
||||
|
||||
playLand(playerA, "Mountain");
|
||||
castSpell(playerA, "Lightning Bolt");
|
||||
addFixedTarget(playerA, "Lightning Bolt", "Craw Wurm");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Craw Wurm");
|
||||
|
||||
setStopAt(1, Constants.PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
assertPermanentCount(playerB, "Craw Wurm", 1);
|
||||
}
|
||||
|
|
@ -74,11 +70,10 @@ public class LightningBoltTest extends CardTestBase {
|
|||
addCard(Constants.Zone.HAND, playerA, "Lightning Bolt");
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerB, "Craw Wurm");
|
||||
|
||||
castSpell(playerA, "Lightning Bolt");
|
||||
addFixedTarget(playerA, "Lightning Bolt", "Craw Wurm");
|
||||
castSpell(playerA, "Lightning Bolt");
|
||||
addFixedTarget(playerA, "Lightning Bolt", "Craw Wurm");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Craw Wurm");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Craw Wurm");
|
||||
|
||||
setStopAt(1, Constants.PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
assertPermanentCount(playerB, "Craw Wurm", 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ public class PsionicBlastTest extends CardTestBase {
|
|||
addCard(Constants.Zone.HAND, playerA, "Psionic Blast");
|
||||
|
||||
castSpell(playerA, "Psionic Blast");
|
||||
setStopAt(1, Constants.PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertLife(playerA, 18);
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ public class HideousEndTest extends CardTestBase {
|
|||
castSpell(playerA, "Hideous End");
|
||||
addFixedTarget(playerA, "Hideous End", "Copper Myr");
|
||||
|
||||
setStopAt(1, Constants.PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
assertPermanentCount(playerB, "Copper Myr", 0);
|
||||
assertLife(playerB, 18);
|
||||
|
|
@ -34,6 +35,7 @@ public class HideousEndTest extends CardTestBase {
|
|||
castSpell(playerA, "Hideous End");
|
||||
addFixedTarget(playerA, "Hideous End", "Zombie Goliath");
|
||||
|
||||
setStopAt(1, Constants.PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
assertPermanentCount(playerB, "Zombie Goliath", 1);
|
||||
assertLife(playerB, 20);
|
||||
|
|
@ -54,6 +56,7 @@ public class HideousEndTest extends CardTestBase {
|
|||
castSpell(playerA, "Hideous End");
|
||||
addFixedTarget(playerA, "Hideous End", "Copper Myr");
|
||||
|
||||
setStopAt(1, Constants.PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
assertPermanentCount(playerB, "Copper Myr", 1);
|
||||
assertLife(playerB, 20);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ public class LeaveNoTraceTest extends CardTestBase {
|
|||
castSpell(playerA, "Leave No Trace");
|
||||
addFixedTarget(playerA, "Leave No Trace", "Asceticism");
|
||||
|
||||
setStopAt(1, Constants.PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
assertPermanentCount(playerB, "Asceticism", 0);
|
||||
assertPermanentCount(playerB, "Awakening Zone", 0);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ public class OneEyedScarecrowTest extends CardTestBase {
|
|||
addCard(Constants.Zone.BATTLEFIELD, playerB, "Screeching Bat");
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerB, "Runeclaw Bear");
|
||||
|
||||
setStopAt(1, Constants.PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
Permanent scarecrow = getPermanent("One-Eyed Scarecrow", playerA.getId());
|
||||
|
|
@ -59,6 +60,7 @@ public class OneEyedScarecrowTest extends CardTestBase {
|
|||
addCard(Constants.Zone.BATTLEFIELD, playerB, "Screeching Bat");
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerB, "Runeclaw Bear");
|
||||
|
||||
setStopAt(1, Constants.PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
// -1/2
|
||||
|
|
|
|||
|
|
@ -2,13 +2,14 @@ package org.mage.test.cards.targets.attacking;
|
|||
|
||||
import junit.framework.Assert;
|
||||
import mage.Constants;
|
||||
import mage.Constants.PhaseStep;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestBase;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* @author ayratn
|
||||
*/
|
||||
public class CondemnTest extends CardTestBase {
|
||||
public class CondemnTest extends CardTestPlayerBase {
|
||||
|
||||
@Test
|
||||
public void testIllegalTarget() {
|
||||
|
|
@ -16,10 +17,10 @@ public class CondemnTest extends CardTestBase {
|
|||
addCard(Constants.Zone.HAND, playerA, "Condemn");
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerB, "Sejiri Merfolk");
|
||||
|
||||
castSpell(playerA, "Condemn");
|
||||
// check with illegal target
|
||||
addFixedTarget(playerA, "Condemn", "Sejiri Merfolk");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Condemn", "Sejiri Merfolk");
|
||||
|
||||
setStopAt(1, Constants.PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
// spell shouldn't work
|
||||
assertPermanentCount(playerB, "Sejiri Merfolk", 1);
|
||||
|
|
@ -29,21 +30,20 @@ public class CondemnTest extends CardTestBase {
|
|||
|
||||
@Test
|
||||
public void testLegalTarget() {
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Plains");
|
||||
addCard(Constants.Zone.HAND, playerA, "Condemn");
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerB, "Sejiri Merfolk");
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerB, "Plains");
|
||||
addCard(Constants.Zone.HAND, playerB, "Condemn");
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Sejiri Merfolk");
|
||||
|
||||
attack(playerB, "Sejiri Merfolk");
|
||||
castSpell(playerA, "Condemn");
|
||||
addFixedTarget(playerA, "Condemn", "Sejiri Merfolk");
|
||||
attack(1, playerA, "Sejiri Merfolk");
|
||||
castSpell(1, PhaseStep.DECLARE_ATTACKERS, playerB, "Condemn", "Sejiri Merfolk");
|
||||
|
||||
setStopOnTurn(3);
|
||||
setStopAt(1, Constants.PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
assertPermanentCount(playerB, "Sejiri Merfolk", 0);
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 21);
|
||||
assertPermanentCount(playerA, "Sejiri Merfolk", 0);
|
||||
assertLife(playerB, 20);
|
||||
assertLife(playerA, 21);
|
||||
// check was put on top
|
||||
Assert.assertEquals(currentGame.getPlayer(playerB.getId()).getLibrary().size(), 60);
|
||||
Assert.assertEquals(currentGame.getPlayer(playerA.getId()).getLibrary().size(), 61);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package org.mage.test.cards.triggers;
|
||||
|
||||
import mage.Constants;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestBase;
|
||||
|
||||
|
|
@ -20,6 +21,7 @@ public class ManabarbsTest extends CardTestBase {
|
|||
* Couldn't reproduce.
|
||||
*/
|
||||
@Test
|
||||
@Ignore
|
||||
public void testMultiTriggers() {
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Manabarbs");
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Mountain", 7);
|
||||
|
|
@ -28,8 +30,13 @@ public class ManabarbsTest extends CardTestBase {
|
|||
|
||||
castSpell(playerA, "Ball Lightning");
|
||||
castSpell(playerA, "Lightning Elemental");
|
||||
|
||||
attack(playerA, "Ball Lightning");
|
||||
attack(playerA, "Lightning Elemental");
|
||||
|
||||
playerA.setAllowBadMoves(true);
|
||||
setStopAt(2, Constants.PhaseStep.UNTAP);
|
||||
execute();
|
||||
|
||||
assertLife(playerA, 13); // burns from Manabarbs
|
||||
assertLife(playerB, 10); // ai should attack with 4/1 + 6/1
|
||||
assertPermanentCount(playerA, "Lightning Elemental", 1);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
package org.mage.test.cards.triggers;
|
||||
|
||||
import mage.Constants;
|
||||
import mage.Constants.PhaseStep;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* @author ayratn
|
||||
*
|
||||
* Card: Whenever a player taps a land for mana, Manabarbs deals 1 damage to that player.
|
||||
*/
|
||||
public class ManabarbsTest2 extends CardTestPlayerBase {
|
||||
|
||||
/**
|
||||
* Issue 374: manabarb enchantment
|
||||
* Games goes into a freeze loop.
|
||||
*
|
||||
* version: 0.8.1
|
||||
*
|
||||
* Couldn't reproduce.
|
||||
*/
|
||||
@Test
|
||||
public void testMultiTriggers() {
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Manabarbs");
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Mountain", 7);
|
||||
addCard(Constants.Zone.HAND, playerA, "Lightning Elemental");
|
||||
addCard(Constants.Zone.HAND, playerA, "Ball Lightning");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Ball Lightning");
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Elemental");
|
||||
attack(1, playerA, "Ball Lightning");
|
||||
attack(1, playerA, "Lightning Elemental");
|
||||
|
||||
setStopAt(2, Constants.PhaseStep.UNTAP);
|
||||
execute();
|
||||
|
||||
assertLife(playerA, 13); // burns from Manabarbs
|
||||
assertLife(playerB, 10); // ai should attack with 4/1 + 6/1
|
||||
assertPermanentCount(playerA, "Lightning Elemental", 1);
|
||||
assertPermanentCount(playerA, "Ball Lightning", 0); // sacrificed at EOT
|
||||
}
|
||||
}
|
||||
|
|
@ -4,13 +4,13 @@ import junit.framework.Assert;
|
|||
import mage.Constants;
|
||||
import mage.game.permanent.Permanent;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestBase;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author ayrat
|
||||
*/
|
||||
public class DamageDistributionTest extends CardTestBase {
|
||||
public class DamageDistributionTest extends CardTestPlayerBase {
|
||||
|
||||
@Test
|
||||
public void testDoubleStrike() {
|
||||
|
|
@ -18,6 +18,9 @@ public class DamageDistributionTest extends CardTestBase {
|
|||
addCard(Constants.Zone.BATTLEFIELD, playerB, "Merfolk Looter");
|
||||
setLife(playerB, 4);
|
||||
|
||||
attack(1, playerA, "Warren Instigator");
|
||||
block(1, playerB, "Merfolk Looter", "Warren Instigator");
|
||||
setStopAt(1, Constants.PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
|
||||
Permanent instigator = getPermanent("Warren Instigator", playerA.getId());
|
||||
|
|
@ -36,7 +39,11 @@ public class DamageDistributionTest extends CardTestBase {
|
|||
public void testDoubleStrikeUnblocked() {
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Warren Instigator");
|
||||
setLife(playerB, 4);
|
||||
|
||||
attack(1, playerA, "Warren Instigator");
|
||||
setStopAt(1, Constants.PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
|
||||
assertLife(playerB, 2);
|
||||
}
|
||||
|
||||
|
|
@ -45,7 +52,8 @@ public class DamageDistributionTest extends CardTestBase {
|
|||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Merfolk Looter");
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerB, "Warren Instigator");
|
||||
setLife(playerB, 4);
|
||||
|
||||
|
||||
setStopAt(1, Constants.PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
|
||||
// should block and die
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright 2012 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package org.mage.test.player;
|
||||
|
||||
import mage.Constants.PhaseStep;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class PlayerAction {
|
||||
|
||||
private int turnNum;
|
||||
private PhaseStep step;
|
||||
private String action;
|
||||
|
||||
public PlayerAction(int turnNum, PhaseStep step, String action) {
|
||||
this.turnNum = turnNum;
|
||||
this.step = step;
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
public int getTurnNum() {
|
||||
return turnNum;
|
||||
}
|
||||
|
||||
public PhaseStep getStep() {
|
||||
return step;
|
||||
}
|
||||
|
||||
public String getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
}
|
||||
169
Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java
Normal file
169
Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package org.mage.test.player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.Constants;
|
||||
import mage.Constants.PhaseStep;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.ActivatedAbility;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterAttackingCreature;
|
||||
import mage.filter.common.FilterCreatureForCombat;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.player.ai.ComputerPlayer;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public class TestPlayer extends ComputerPlayer<TestPlayer> {
|
||||
|
||||
private List<PlayerAction> actions = new ArrayList<PlayerAction>();
|
||||
|
||||
public TestPlayer(String name, Constants.RangeOfInfluence range) {
|
||||
super(name, range);
|
||||
human = false;
|
||||
}
|
||||
|
||||
public TestPlayer(final TestPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
public void addAction(int turnNum, PhaseStep step, String action) {
|
||||
actions.add(new PlayerAction(turnNum, step, action));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TestPlayer copy() {
|
||||
return new TestPlayer(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean priority(Game game) {
|
||||
for (PlayerAction action: actions) {
|
||||
if (action.getTurnNum() == game.getTurnNum() && action.getStep() == game.getStep().getType()) {
|
||||
if (action.getAction().startsWith("activate:")) {
|
||||
String command = action.getAction();
|
||||
command = command.substring(command.indexOf("activate:") + 9);
|
||||
String[] groups = command.split(";");
|
||||
for (Ability ability: this.getPlayable(game, true)) {
|
||||
if (ability.toString().equals(groups[0])) {
|
||||
if (groups.length > 1) {
|
||||
addTargets(ability, groups, game);
|
||||
}
|
||||
this.activateAbility((ActivatedAbility)ability, game);
|
||||
actions.remove(action);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pass();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectAttackers(Game game) {
|
||||
UUID opponentId = game.getCombat().getDefenders().iterator().next();
|
||||
for (PlayerAction action: actions) {
|
||||
if (action.getTurnNum() == game.getTurnNum() && action.getAction().startsWith("attack:")) {
|
||||
String command = action.getAction();
|
||||
command = command.substring(command.indexOf("attack:") + 7);
|
||||
FilterCreatureForCombat filter = new FilterCreatureForCombat();
|
||||
filter.getName().add(command);
|
||||
Permanent attacker = findPermanent(filter, playerId, game);
|
||||
if (attacker != null && attacker.canAttack(game)) {
|
||||
this.declareAttacker(attacker.getId(), opponentId, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectBlockers(Game game) {
|
||||
UUID opponentId = game.getOpponents(playerId).iterator().next();
|
||||
for (PlayerAction action: actions) {
|
||||
if (action.getTurnNum() == game.getTurnNum() && action.getAction().startsWith("block:")) {
|
||||
String command = action.getAction();
|
||||
command = command.substring(command.indexOf("block:") + 6);
|
||||
String[] groups = command.split(";");
|
||||
FilterCreatureForCombat filterBlocker = new FilterCreatureForCombat();
|
||||
filterBlocker.getName().add(groups[0]);
|
||||
Permanent blocker = findPermanent(filterBlocker, playerId, game);
|
||||
if (blocker != null) {
|
||||
FilterAttackingCreature filterAttacker = new FilterAttackingCreature();
|
||||
filterAttacker.getName().add(groups[1]);
|
||||
Permanent attacker = findPermanent(filterAttacker, opponentId, game);
|
||||
if (attacker != null) {
|
||||
this.declareBlocker(blocker.getId(), attacker.getId(), game);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Permanent findPermanent(FilterPermanent filter, UUID controllerId, Game game) {
|
||||
List<Permanent> permanents = game.getBattlefield().getAllActivePermanents(filter, controllerId);
|
||||
if (permanents.size() > 0)
|
||||
return permanents.get(0);
|
||||
return null;
|
||||
}
|
||||
|
||||
private void addTargets(Ability ability, String[] groups, Game game) {
|
||||
for (int i = 1; i < groups.length; i++) {
|
||||
String group = groups[i];
|
||||
String target;
|
||||
if (group.startsWith("targetPlayer=")) {
|
||||
target = group.substring(group.indexOf("targetPlayer=") + 13);
|
||||
for (Player player: game.getPlayers().values()) {
|
||||
if (player.getName().equals(target)) {
|
||||
ability.getTargets().get(0).addTarget(player.getId(), ability, game);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (group.startsWith("target=")) {
|
||||
target = group.substring(group.indexOf("target=") + 7);
|
||||
for (Permanent permanent: game.getBattlefield().getAllActivePermanents()) {
|
||||
if (permanent.getName().equals(target)) {
|
||||
ability.getTargets().get(0).addTarget(permanent.getId(), ability, game);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -28,7 +28,8 @@ public abstract class CardTestBase extends CardTestAPIImpl {
|
|||
|
||||
protected enum AIType {
|
||||
MinimaxHybrid,
|
||||
MAD
|
||||
MAD,
|
||||
MonteCarlo
|
||||
}
|
||||
|
||||
protected enum ExpectedType {
|
||||
|
|
@ -56,6 +57,22 @@ public abstract class CardTestBase extends CardTestAPIImpl {
|
|||
this.aiTypeB = aiTypeB;
|
||||
}
|
||||
|
||||
protected Player createNewPlayer(String playerName, AIType aiType) {
|
||||
Player player = null;
|
||||
switch (aiType) {
|
||||
case MinimaxHybrid:
|
||||
player = createPlayer(playerName, "Computer - minimax hybrid");
|
||||
break;
|
||||
case MAD:
|
||||
player = createPlayer(playerName, "Computer - mad");
|
||||
break;
|
||||
case MonteCarlo:
|
||||
player = createPlayer(playerName, "Computer - monte carlo");
|
||||
break;
|
||||
}
|
||||
return player;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void reset() throws GameException, FileNotFoundException {
|
||||
if (currentGame != null) {
|
||||
|
|
@ -66,9 +83,7 @@ public abstract class CardTestBase extends CardTestAPIImpl {
|
|||
|
||||
Game game = new TwoPlayerDuel(Constants.MultiplayerAttackOption.LEFT, Constants.RangeOfInfluence.ALL);
|
||||
|
||||
playerA = aiTypeA.equals(CardTestBase.AIType.MinimaxHybrid) ?
|
||||
createPlayer("PlayerA", "Computer - minimax hybrid") :
|
||||
createPlayer("PlayerA", "Computer - mad");
|
||||
playerA = createNewPlayer("PlayerA", aiTypeA);
|
||||
playerA.setTestMode(true);
|
||||
logger.info("Loading deck...");
|
||||
Deck deck = Deck.load(Sets.loadDeck("RB Aggro.dck"));
|
||||
|
|
@ -79,9 +94,7 @@ public abstract class CardTestBase extends CardTestAPIImpl {
|
|||
game.addPlayer(playerA, deck);
|
||||
game.loadCards(deck.getCards(), playerA.getId());
|
||||
|
||||
playerB = aiTypeB.equals(CardTestBase.AIType.MinimaxHybrid) ?
|
||||
createPlayer("PlayerB", "Computer - minimax hybrid") :
|
||||
createPlayer("PlayerB", "Computer - mad");
|
||||
playerB = createNewPlayer("PlayerB", aiTypeB);
|
||||
playerB.setTestMode(true);
|
||||
Deck deck2 = Deck.load(Sets.loadDeck("RB Aggro.dck"));
|
||||
if (deck2.getCards().size() < 40) {
|
||||
|
|
@ -128,9 +141,7 @@ public abstract class CardTestBase extends CardTestAPIImpl {
|
|||
|
||||
Game game = new TwoPlayerDuel(Constants.MultiplayerAttackOption.LEFT, Constants.RangeOfInfluence.ALL);
|
||||
|
||||
playerA = aiTypeA.equals(CardTestBase.AIType.MinimaxHybrid) ?
|
||||
createPlayer("ComputerA", "Computer - minimax hybrid") :
|
||||
createPlayer("ComputerA", "Computer - mad");
|
||||
playerA = createNewPlayer("ComputerA", aiTypeA);
|
||||
playerA.setTestMode(true);
|
||||
|
||||
Deck deck = Deck.load(Sets.loadDeck("RB Aggro.dck"));
|
||||
|
|
@ -141,9 +152,7 @@ public abstract class CardTestBase extends CardTestAPIImpl {
|
|||
game.addPlayer(playerA, deck);
|
||||
game.loadCards(deck.getCards(), playerA.getId());
|
||||
|
||||
playerB = aiTypeB.equals(CardTestBase.AIType.MinimaxHybrid) ?
|
||||
createPlayer("ComputerB", "Computer - minimax hybrid") :
|
||||
createPlayer("ComputerB", "Computer - mad");
|
||||
playerB = createNewPlayer("ComputerB", aiTypeB);
|
||||
playerB.setTestMode(true);
|
||||
Deck deck2 = Deck.load(Sets.loadDeck("RB Aggro.dck"));
|
||||
if (deck2.getCards().size() < 40) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,314 @@
|
|||
package org.mage.test.serverside.base;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import mage.Constants;
|
||||
import mage.Constants.PhaseStep;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.filter.Filter;
|
||||
import mage.game.Game;
|
||||
import mage.game.GameException;
|
||||
import mage.game.GameOptions;
|
||||
import mage.game.TwoPlayerDuel;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.sets.Sets;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.mage.test.player.TestPlayer;
|
||||
import org.mage.test.serverside.base.impl.CardTestPlayerAPIImpl;
|
||||
|
||||
/**
|
||||
* Base class for testing single cards and effects.
|
||||
*
|
||||
* @author ayratn
|
||||
*/
|
||||
public abstract class CardTestPlayerBase extends CardTestPlayerAPIImpl {
|
||||
|
||||
protected enum ExpectedType {
|
||||
TURN_NUMBER,
|
||||
RESULT,
|
||||
LIFE,
|
||||
BATTLEFIELD,
|
||||
GRAVEYARD,
|
||||
UNKNOWN
|
||||
}
|
||||
|
||||
public CardTestPlayerBase() {
|
||||
}
|
||||
|
||||
protected TestPlayer createNewPlayer(String playerName) {
|
||||
return createPlayer(playerName);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void reset() throws GameException, FileNotFoundException {
|
||||
if (currentGame != null) {
|
||||
logger.info("Resetting previous game and creating new one!");
|
||||
currentGame = null;
|
||||
System.gc();
|
||||
}
|
||||
|
||||
Game game = new TwoPlayerDuel(Constants.MultiplayerAttackOption.LEFT, Constants.RangeOfInfluence.ALL);
|
||||
|
||||
playerA = createNewPlayer("PlayerA");
|
||||
playerA.setTestMode(true);
|
||||
logger.info("Loading deck...");
|
||||
Deck deck = Deck.load(Sets.loadDeck("RB Aggro.dck"));
|
||||
logger.info("Done!");
|
||||
if (deck.getCards().size() < 40) {
|
||||
throw new IllegalArgumentException("Couldn't load deck, deck size=" + deck.getCards().size());
|
||||
}
|
||||
game.addPlayer(playerA, deck);
|
||||
game.loadCards(deck.getCards(), playerA.getId());
|
||||
|
||||
playerB = createNewPlayer("PlayerB");
|
||||
playerB.setTestMode(true);
|
||||
Deck deck2 = Deck.load(Sets.loadDeck("RB Aggro.dck"));
|
||||
if (deck2.getCards().size() < 40) {
|
||||
throw new IllegalArgumentException("Couldn't load deck, deck size=" + deck2.getCards().size());
|
||||
}
|
||||
game.addPlayer(playerB, deck2);
|
||||
game.loadCards(deck2.getCards(), playerB.getId());
|
||||
activePlayer = playerA;
|
||||
currentGame = game;
|
||||
|
||||
stopOnTurn = 2;
|
||||
stopAtStep = PhaseStep.UNTAP;
|
||||
handCardsA.clear();
|
||||
handCardsB.clear();
|
||||
battlefieldCardsA.clear();
|
||||
battlefieldCardsB.clear();
|
||||
graveyardCardsA.clear();
|
||||
graveyardCardsB.clear();
|
||||
libraryCardsA.clear();
|
||||
libraryCardsB.clear();
|
||||
commandsA.clear();
|
||||
commandsB.clear();
|
||||
}
|
||||
|
||||
public void load(String path) throws FileNotFoundException, GameException {
|
||||
String cardPath = TESTS_PATH + path;
|
||||
File checkFile = new File(cardPath);
|
||||
if (!checkFile.exists()) {
|
||||
throw new FileNotFoundException("Couldn't find test file: " + cardPath);
|
||||
}
|
||||
if (checkFile.isDirectory()) {
|
||||
throw new FileNotFoundException("Couldn't find test file: " + cardPath + ". It is directory.");
|
||||
}
|
||||
|
||||
if (currentGame != null) {
|
||||
logger.info("Resetting previous game and creating new one!");
|
||||
currentGame = null;
|
||||
System.gc();
|
||||
}
|
||||
|
||||
Game game = new TwoPlayerDuel(Constants.MultiplayerAttackOption.LEFT, Constants.RangeOfInfluence.ALL);
|
||||
|
||||
playerA = createNewPlayer("ComputerA");
|
||||
playerA.setTestMode(true);
|
||||
|
||||
Deck deck = Deck.load(Sets.loadDeck("RB Aggro.dck"));
|
||||
|
||||
if (deck.getCards().size() < 40) {
|
||||
throw new IllegalArgumentException("Couldn't load deck, deck size=" + deck.getCards().size());
|
||||
}
|
||||
game.addPlayer(playerA, deck);
|
||||
game.loadCards(deck.getCards(), playerA.getId());
|
||||
|
||||
playerB = createNewPlayer("ComputerB");
|
||||
playerB.setTestMode(true);
|
||||
Deck deck2 = Deck.load(Sets.loadDeck("RB Aggro.dck"));
|
||||
if (deck2.getCards().size() < 40) {
|
||||
throw new IllegalArgumentException("Couldn't load deck, deck size=" + deck2.getCards().size());
|
||||
}
|
||||
game.addPlayer(playerB, deck2);
|
||||
game.loadCards(deck2.getCards(), playerB.getId());
|
||||
|
||||
parseScenario(cardPath);
|
||||
|
||||
activePlayer = playerA;
|
||||
currentGame = game;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts testing card by starting current game.
|
||||
*
|
||||
* @throws IllegalStateException In case game wasn't created previously. Use {@link #load} method to initialize the game.
|
||||
*/
|
||||
public void execute() throws IllegalStateException {
|
||||
if (currentGame == null || activePlayer == null) {
|
||||
throw new IllegalStateException("Game is not initialized. Use load method to load a test case and initialize a game.");
|
||||
}
|
||||
|
||||
currentGame.cheat(playerA.getId(), commandsA);
|
||||
currentGame.cheat(playerA.getId(), libraryCardsA, handCardsA, battlefieldCardsA, graveyardCardsA);
|
||||
currentGame.cheat(playerB.getId(), commandsB);
|
||||
currentGame.cheat(playerB.getId(), libraryCardsB, handCardsB, battlefieldCardsB, graveyardCardsB);
|
||||
|
||||
boolean testMode = true;
|
||||
long t1 = System.nanoTime();
|
||||
GameOptions gameOptions = new GameOptions();
|
||||
gameOptions.testMode = true;
|
||||
gameOptions.stopOnTurn = stopOnTurn;
|
||||
gameOptions.stopAtStep = stopAtStep;
|
||||
currentGame.start(activePlayer.getId(), gameOptions);
|
||||
long t2 = System.nanoTime();
|
||||
logger.info("Winner: " + currentGame.getWinner());
|
||||
logger.info("Time: " + (t2 - t1) / 1000000 + " ms");
|
||||
|
||||
assertTheResults();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert expected and actual results.
|
||||
*/
|
||||
private void assertTheResults() {
|
||||
logger.info("Matching expected results:");
|
||||
for (String line : expectedResults) {
|
||||
boolean ok = false;
|
||||
try {
|
||||
ExpectedType type = getExpectedType(line);
|
||||
if (type.equals(CardTestPlayerBase.ExpectedType.UNKNOWN)) {
|
||||
throw new AssertionError("Unknown expected type, check the line in $expected section=" + line);
|
||||
}
|
||||
parseType(type, line);
|
||||
ok = true;
|
||||
} finally {
|
||||
logger.info(" " + line + " - " + (ok ? "OK" : "ERROR"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ExpectedType getExpectedType(String line) {
|
||||
if (line.startsWith("turn:")) {
|
||||
return CardTestPlayerBase.ExpectedType.TURN_NUMBER;
|
||||
}
|
||||
if (line.startsWith("result:")) {
|
||||
return CardTestPlayerBase.ExpectedType.RESULT;
|
||||
}
|
||||
if (line.startsWith("life:")) {
|
||||
return CardTestPlayerBase.ExpectedType.LIFE;
|
||||
}
|
||||
if (line.startsWith("battlefield:")) {
|
||||
return CardTestPlayerBase.ExpectedType.BATTLEFIELD;
|
||||
}
|
||||
if (line.startsWith("graveyard:")) {
|
||||
return CardTestPlayerBase.ExpectedType.GRAVEYARD;
|
||||
}
|
||||
return CardTestPlayerBase.ExpectedType.UNKNOWN;
|
||||
}
|
||||
|
||||
private void parseType(ExpectedType type, String line) {
|
||||
if (type.equals(CardTestPlayerBase.ExpectedType.TURN_NUMBER)) {
|
||||
int turn = getIntParam(line, 1);
|
||||
Assert.assertEquals("Turn numbers are not equal", turn, currentGame.getTurnNum());
|
||||
return;
|
||||
}
|
||||
if (type.equals(CardTestPlayerBase.ExpectedType.RESULT)) {
|
||||
String expected = getStringParam(line, 1);
|
||||
String actual = "draw";
|
||||
if (currentGame.getWinner().equals("Player ComputerA is the winner")) {
|
||||
actual = "won";
|
||||
} else if (currentGame.getWinner().equals("Player ComputerB is the winner")) {
|
||||
actual = "lost";
|
||||
}
|
||||
Assert.assertEquals("Game results are not equal", expected, actual);
|
||||
return;
|
||||
}
|
||||
if (type.equals(CardTestPlayerBase.ExpectedType.LIFE)) {
|
||||
String player = getStringParam(line, 1);
|
||||
int expected = getIntParam(line, 2);
|
||||
if (player.equals("ComputerA")) {
|
||||
int actual = currentGame.getPlayer(playerA.getId()).getLife();
|
||||
Assert.assertEquals("Life amounts are not equal", expected, actual);
|
||||
} else if (player.equals("ComputerB")) {
|
||||
int actual = currentGame.getPlayer(playerB.getId()).getLife();
|
||||
Assert.assertEquals("Life amounts are not equal", expected, actual);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Wrong player in 'life' line, player=" + player + ", line=" + line);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (type.equals(CardTestPlayerBase.ExpectedType.BATTLEFIELD)) {
|
||||
String playerName = getStringParam(line, 1);
|
||||
String cardName = getStringParam(line, 2);
|
||||
int expectedCount = getIntParam(line, 3);
|
||||
Player player = null;
|
||||
if (playerName.equals("ComputerA")) {
|
||||
player = currentGame.getPlayer(playerA.getId());
|
||||
} else if (playerName.equals("ComputerB")) {
|
||||
player = currentGame.getPlayer(playerB.getId());
|
||||
} else {
|
||||
throw new IllegalArgumentException("Wrong player in 'battlefield' line, player=" + player + ", line=" + line);
|
||||
}
|
||||
int actualCount = 0;
|
||||
for (Permanent permanent : currentGame.getBattlefield().getAllPermanents()) {
|
||||
if (permanent.getControllerId().equals(player.getId())) {
|
||||
if (permanent.getName().equals(cardName)) {
|
||||
actualCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
Assert.assertEquals("(Battlefield) Card counts are not equal (" + cardName + ")", expectedCount, actualCount);
|
||||
return;
|
||||
}
|
||||
if (type.equals(CardTestPlayerBase.ExpectedType.GRAVEYARD)) {
|
||||
String playerName = getStringParam(line, 1);
|
||||
String cardName = getStringParam(line, 2);
|
||||
int expectedCount = getIntParam(line, 3);
|
||||
Player player = null;
|
||||
if (playerName.equals("ComputerA")) {
|
||||
player = currentGame.getPlayer(playerA.getId());
|
||||
} else if (playerName.equals("ComputerB")) {
|
||||
player = currentGame.getPlayer(playerB.getId());
|
||||
} else {
|
||||
throw new IllegalArgumentException("Wrong player in 'graveyard' line, player=" + player + ", line=" + line);
|
||||
}
|
||||
int actualCount = 0;
|
||||
for (Card card : player.getGraveyard().getCards(currentGame)) {
|
||||
if (card.getName().equals(cardName)) {
|
||||
actualCount++;
|
||||
}
|
||||
}
|
||||
Assert.assertEquals("(Graveyard) Card counts are not equal (" + cardName + ")", expectedCount, actualCount);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private int getIntParam(String line, int index) {
|
||||
String[] params = line.split(":");
|
||||
if (index > params.length - 1) {
|
||||
throw new IllegalArgumentException("Not correct line: " + line);
|
||||
}
|
||||
return Integer.parseInt(params[index]);
|
||||
}
|
||||
|
||||
private String getStringParam(String line, int index) {
|
||||
String[] params = line.split(":");
|
||||
if (index > params.length - 1) {
|
||||
throw new IllegalArgumentException("Not correct line: " + line);
|
||||
}
|
||||
return params[index];
|
||||
}
|
||||
|
||||
protected void checkPermanentPT(Player player, String cardName, int power, int toughness, Filter.ComparisonScope scope) {
|
||||
if (currentGame == null) {
|
||||
throw new IllegalStateException("Current game is null");
|
||||
}
|
||||
if (scope.equals(Filter.ComparisonScope.All)) {
|
||||
throw new UnsupportedOperationException("ComparisonScope.All is not implemented.");
|
||||
}
|
||||
int count = 0;
|
||||
int fit = 0;
|
||||
for (Permanent permanent : currentGame.getBattlefield().getAllActivePermanents(player.getId())) {
|
||||
if (permanent.getName().equals(cardName)) {
|
||||
Assert.assertEquals("Power is not the same", power, permanent.getPower().getValue());
|
||||
Assert.assertEquals("Toughness is not the same", toughness, permanent.getToughness().getValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -113,9 +113,9 @@ public abstract class MageTestBase {
|
|||
for (Plugin plugin : config.getPlayerTypes()) {
|
||||
PlayerFactory.getInstance().addPlayerType(plugin.getName(), loadPlugin(plugin));
|
||||
}
|
||||
for (Plugin plugin : config.getDeckTypes()) {
|
||||
DeckValidatorFactory.getInstance().addDeckType(plugin.getName(), loadPlugin(plugin));
|
||||
}
|
||||
// for (Plugin plugin : config.getDeckTypes()) {
|
||||
// DeckValidatorFactory.getInstance().addDeckType(plugin.getName(), loadPlugin(plugin));
|
||||
// }
|
||||
Copier.setLoader(classLoader);
|
||||
}
|
||||
|
||||
|
|
@ -296,6 +296,6 @@ public abstract class MageTestBase {
|
|||
}
|
||||
|
||||
protected Player createPlayer(String name, String playerType) {
|
||||
return PlayerFactory.getInstance().createPlayer(playerType, name, Constants.RangeOfInfluence.ALL, 10);
|
||||
return PlayerFactory.getInstance().createPlayer(playerType, name, Constants.RangeOfInfluence.ALL, 5);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,302 @@
|
|||
package org.mage.test.serverside.base;
|
||||
|
||||
import mage.Constants;
|
||||
import mage.cards.Card;
|
||||
import mage.game.Game;
|
||||
import mage.game.match.MatchType;
|
||||
import mage.game.permanent.PermanentCard;
|
||||
import mage.game.tournament.TournamentType;
|
||||
import mage.players.Player;
|
||||
import mage.server.game.DeckValidatorFactory;
|
||||
import mage.server.game.GameFactory;
|
||||
import mage.server.game.PlayerFactory;
|
||||
import mage.server.tournament.TournamentFactory;
|
||||
import mage.server.util.ConfigSettings;
|
||||
import mage.server.util.PluginClassLoader;
|
||||
import mage.server.util.config.GamePlugin;
|
||||
import mage.server.util.config.Plugin;
|
||||
import mage.sets.Sets;
|
||||
import mage.util.Copier;
|
||||
import org.apache.log4j.Level;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FilenameFilter;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import mage.Constants.PhaseStep;
|
||||
import org.mage.test.player.TestPlayer;
|
||||
|
||||
/**
|
||||
* Base class for all tests.
|
||||
*
|
||||
* @author ayratn
|
||||
*/
|
||||
public abstract class MageTestPlayerBase {
|
||||
protected static Logger logger = Logger.getLogger(MageTestPlayerBase.class);
|
||||
|
||||
public static PluginClassLoader classLoader = new PluginClassLoader();
|
||||
|
||||
private final static String pluginFolder = "plugins";
|
||||
|
||||
protected Pattern pattern = Pattern.compile("([a-zA-Z]*):([\\w]*):([a-zA-Z ,\\-.!'\\d]*):([\\d]*)(:\\{tapped\\})?");
|
||||
|
||||
protected List<Card> handCardsA = new ArrayList<Card>();
|
||||
protected List<Card> handCardsB = new ArrayList<Card>();
|
||||
protected List<PermanentCard> battlefieldCardsA = new ArrayList<PermanentCard>();
|
||||
protected List<PermanentCard> battlefieldCardsB = new ArrayList<PermanentCard>();
|
||||
protected List<Card> graveyardCardsA = new ArrayList<Card>();
|
||||
protected List<Card> graveyardCardsB = new ArrayList<Card>();
|
||||
protected List<Card> libraryCardsA = new ArrayList<Card>();
|
||||
protected List<Card> libraryCardsB = new ArrayList<Card>();
|
||||
|
||||
protected Map<Constants.Zone, String> commandsA = new HashMap<Constants.Zone, String>();
|
||||
protected Map<Constants.Zone, String> commandsB = new HashMap<Constants.Zone, String>();
|
||||
|
||||
protected TestPlayer playerA;
|
||||
protected TestPlayer playerB;
|
||||
|
||||
/**
|
||||
* Game instance initialized in load method.
|
||||
*/
|
||||
protected static Game currentGame = null;
|
||||
|
||||
/**
|
||||
* Player thats starts the game first.
|
||||
* By default, it is ComputerA.
|
||||
*/
|
||||
protected static Player activePlayer = null;
|
||||
|
||||
protected Integer stopOnTurn;
|
||||
|
||||
protected PhaseStep stopAtStep = PhaseStep.UNTAP;
|
||||
|
||||
protected enum ParserState {
|
||||
INIT,
|
||||
OPTIONS,
|
||||
EXPECTED
|
||||
}
|
||||
|
||||
protected ParserState parserState;
|
||||
|
||||
/**
|
||||
* Expected results of the test.
|
||||
* Read from test case in {@link String} based format:
|
||||
* <p/>
|
||||
* Example:
|
||||
* turn:1
|
||||
* result:won:ComputerA
|
||||
* life:ComputerA:20
|
||||
* life:ComputerB:0
|
||||
* battlefield:ComputerB:Tine Shrike:0
|
||||
* graveyard:ComputerB:Tine Shrike:1
|
||||
*/
|
||||
protected List<String> expectedResults = new ArrayList<String>();
|
||||
|
||||
protected static final String TESTS_PATH = "tests" + File.separator;
|
||||
|
||||
@BeforeClass
|
||||
public static void init() {
|
||||
Logger.getRootLogger().setLevel(Level.DEBUG);
|
||||
logger.info("Starting MAGE tests");
|
||||
logger.info("Logging level: " + logger.getLevel());
|
||||
deleteSavedGames();
|
||||
ConfigSettings config = ConfigSettings.getInstance();
|
||||
for (GamePlugin plugin : config.getGameTypes()) {
|
||||
GameFactory.getInstance().addGameType(plugin.getName(), loadGameType(plugin), loadPlugin(plugin));
|
||||
}
|
||||
// for (GamePlugin plugin : config.getTournamentTypes()) {
|
||||
// TournamentFactory.getInstance().addTournamentType(plugin.getName(), loadTournamentType(plugin), loadPlugin(plugin));
|
||||
// }
|
||||
// for (Plugin plugin : config.getPlayerTypes()) {
|
||||
// PlayerFactory.getInstance().addPlayerType(plugin.getName(), loadPlugin(plugin));
|
||||
// }
|
||||
// for (Plugin plugin : config.getDeckTypes()) {
|
||||
// DeckValidatorFactory.getInstance().addDeckType(plugin.getName(), loadPlugin(plugin));
|
||||
// }
|
||||
Copier.setLoader(classLoader);
|
||||
}
|
||||
|
||||
private static Class<?> loadPlugin(Plugin plugin) {
|
||||
try {
|
||||
classLoader.addURL(new File(pluginFolder + "/" + plugin.getJar()).toURI().toURL());
|
||||
logger.info("Loading plugin: " + plugin.getClassName());
|
||||
return Class.forName(plugin.getClassName(), true, classLoader);
|
||||
} catch (ClassNotFoundException ex) {
|
||||
logger.warn("Plugin not Found:" + plugin.getJar() + " - check plugin folder");
|
||||
} catch (Exception ex) {
|
||||
logger.fatal("Error loading plugin " + plugin.getJar(), ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static MatchType loadGameType(GamePlugin plugin) {
|
||||
try {
|
||||
classLoader.addURL(new File(pluginFolder + "/" + plugin.getJar()).toURI().toURL());
|
||||
logger.info("Loading game type: " + plugin.getClassName());
|
||||
return (MatchType) Class.forName(plugin.getTypeName(), true, classLoader).newInstance();
|
||||
} catch (ClassNotFoundException ex) {
|
||||
logger.warn("Game type not found:" + plugin.getJar() + " - check plugin folder");
|
||||
} catch (Exception ex) {
|
||||
logger.fatal("Error loading game type " + plugin.getJar(), ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static TournamentType loadTournamentType(GamePlugin plugin) {
|
||||
try {
|
||||
classLoader.addURL(new File(pluginFolder + "/" + plugin.getJar()).toURI().toURL());
|
||||
logger.info("Loading tournament type: " + plugin.getClassName());
|
||||
return (TournamentType) Class.forName(plugin.getTypeName(), true, classLoader).newInstance();
|
||||
} catch (ClassNotFoundException ex) {
|
||||
logger.warn("Tournament type not found:" + plugin.getJar() + " - check plugin folder");
|
||||
} catch (Exception ex) {
|
||||
logger.fatal("Error loading game type " + plugin.getJar(), ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void deleteSavedGames() {
|
||||
File directory = new File("saved/");
|
||||
if (!directory.exists())
|
||||
directory.mkdirs();
|
||||
File[] files = directory.listFiles(
|
||||
new FilenameFilter() {
|
||||
@Override
|
||||
public boolean accept(File dir, String name) {
|
||||
return name.endsWith(".game");
|
||||
}
|
||||
}
|
||||
);
|
||||
for (File file : files) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
protected void parseScenario(String filename) throws FileNotFoundException {
|
||||
parserState = ParserState.INIT;
|
||||
File f = new File(filename);
|
||||
Scanner scanner = new Scanner(f);
|
||||
try {
|
||||
while (scanner.hasNextLine()) {
|
||||
String line = scanner.nextLine().trim();
|
||||
if (line == null || line.isEmpty() || line.startsWith("#")) continue;
|
||||
if (line.startsWith("$include")) {
|
||||
includeFrom(line);
|
||||
continue;
|
||||
}
|
||||
if (line.startsWith("$expected")) {
|
||||
parserState = ParserState.EXPECTED;
|
||||
continue;
|
||||
}
|
||||
parseLine(line);
|
||||
}
|
||||
} finally {
|
||||
scanner.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void parseLine(String line) {
|
||||
if (parserState.equals(ParserState.EXPECTED)) {
|
||||
expectedResults.add(line); // just remember for future use
|
||||
return;
|
||||
}
|
||||
|
||||
Matcher m = pattern.matcher(line);
|
||||
if (m.matches()) {
|
||||
|
||||
String zone = m.group(1);
|
||||
String nickname = m.group(2);
|
||||
|
||||
if (nickname.equals("ComputerA") || nickname.equals("ComputerB")) {
|
||||
List<Card> cards = null;
|
||||
List<PermanentCard> perms = null;
|
||||
Constants.Zone gameZone;
|
||||
if ("hand".equalsIgnoreCase(zone)) {
|
||||
gameZone = Constants.Zone.HAND;
|
||||
cards = nickname.equals("ComputerA") ? handCardsA : handCardsB;
|
||||
} else if ("battlefield".equalsIgnoreCase(zone)) {
|
||||
gameZone = Constants.Zone.BATTLEFIELD;
|
||||
perms = nickname.equals("ComputerA") ? battlefieldCardsA : battlefieldCardsB;
|
||||
} else if ("graveyard".equalsIgnoreCase(zone)) {
|
||||
gameZone = Constants.Zone.GRAVEYARD;
|
||||
cards = nickname.equals("ComputerA") ? graveyardCardsA : graveyardCardsB;
|
||||
} else if ("library".equalsIgnoreCase(zone)) {
|
||||
gameZone = Constants.Zone.LIBRARY;
|
||||
cards = nickname.equals("ComputerA") ? libraryCardsA : libraryCardsB;
|
||||
} else if ("player".equalsIgnoreCase(zone)) {
|
||||
String command = m.group(3);
|
||||
if ("life".equals(command)) {
|
||||
if (nickname.equals("ComputerA")) {
|
||||
commandsA.put(Constants.Zone.OUTSIDE, "life:" + m.group(4));
|
||||
} else {
|
||||
commandsB.put(Constants.Zone.OUTSIDE, "life:" + m.group(4));
|
||||
}
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
return; // go parse next line
|
||||
}
|
||||
|
||||
String cardName = m.group(3);
|
||||
Integer amount = Integer.parseInt(m.group(4));
|
||||
boolean tapped = m.group(5) != null && m.group(5).equals(":{tapped}");
|
||||
|
||||
if (cardName.equals("clear")) {
|
||||
if (nickname.equals("ComputerA")) {
|
||||
commandsA.put(gameZone, "clear");
|
||||
} else {
|
||||
commandsB.put(gameZone, "clear");
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < amount; i++) {
|
||||
Card card = Sets.findCard(cardName, true);
|
||||
if (card != null) {
|
||||
if (gameZone.equals(Constants.Zone.BATTLEFIELD)) {
|
||||
PermanentCard p = new PermanentCard(card, null);
|
||||
p.setTapped(tapped);
|
||||
perms.add(p);
|
||||
} else {
|
||||
cards.add(card);
|
||||
}
|
||||
} else {
|
||||
logger.fatal("Couldn't find a card: " + cardName);
|
||||
logger.fatal("line: " + line);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.warn("Unknown player: " + nickname);
|
||||
}
|
||||
} else {
|
||||
logger.warn("Init string wasn't parsed: " + line);
|
||||
}
|
||||
}
|
||||
|
||||
private void includeFrom(String line) throws FileNotFoundException {
|
||||
String[] params = line.split(" ");
|
||||
if (params.length == 2) {
|
||||
String paramName = params[1];
|
||||
if (!paramName.contains("..")) {
|
||||
String includePath = TESTS_PATH + paramName;
|
||||
File f = new File(includePath);
|
||||
if (f.exists()) {
|
||||
parseScenario(includePath);
|
||||
} else {
|
||||
logger.warn("Ignored (file doesn't exist): " + line);
|
||||
}
|
||||
} else {
|
||||
logger.warn("Ignored (wrong charactres): " + line);
|
||||
}
|
||||
} else {
|
||||
logger.warn("Ignored (wrong size): " + line);
|
||||
}
|
||||
}
|
||||
|
||||
protected TestPlayer createPlayer(String name) {
|
||||
return new TestPlayer(name, Constants.RangeOfInfluence.ALL);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,405 @@
|
|||
package org.mage.test.serverside.base.impl;
|
||||
|
||||
import mage.Constants;
|
||||
import mage.abilities.Ability;
|
||||
import mage.cards.Card;
|
||||
import mage.filter.Filter;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.permanent.PermanentCard;
|
||||
import mage.players.Player;
|
||||
import mage.sets.Sets;
|
||||
import org.junit.Assert;
|
||||
import org.mage.test.serverside.base.CardTestAPI;
|
||||
import org.mage.test.serverside.base.MageTestPlayerBase;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.Constants.PhaseStep;
|
||||
import org.mage.test.player.TestPlayer;
|
||||
|
||||
/**
|
||||
* API for test initialization and asserting the test results.
|
||||
*
|
||||
* @author ayratn
|
||||
*/
|
||||
public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implements CardTestAPI {
|
||||
|
||||
/**
|
||||
* Default game initialization params for red player (that plays with Mountains)
|
||||
*/
|
||||
public void useRedDefault() {
|
||||
// *** ComputerA ***
|
||||
// battlefield:ComputerA:Mountain:5
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Mountain", 5);
|
||||
// hand:ComputerA:Mountain:4
|
||||
addCard(Constants.Zone.HAND, playerA, "Mountain", 5);
|
||||
// library:ComputerA:clear:0
|
||||
removeAllCardsFromLibrary(playerA);
|
||||
// library:ComputerA:Mountain:10
|
||||
addCard(Constants.Zone.LIBRARY, playerA, "Mountain", 10);
|
||||
|
||||
// *** ComputerB ***
|
||||
// battlefield:ComputerB:Plains:2
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerB, "Plains", 2);
|
||||
// hand:ComputerB:Plains:2
|
||||
addCard(Constants.Zone.HAND, playerB, "Plains", 2);
|
||||
// library:ComputerB:clear:0
|
||||
removeAllCardsFromLibrary(playerB);
|
||||
// library:ComputerB:Plains:10
|
||||
addCard(Constants.Zone.LIBRARY, playerB, "Plains", 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default game initialization params for white player (that plays with Plains)
|
||||
*/
|
||||
public void useWhiteDefault() {
|
||||
// *** ComputerA ***
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Plains", 5);
|
||||
addCard(Constants.Zone.HAND, playerA, "Plains", 5);
|
||||
removeAllCardsFromLibrary(playerA);
|
||||
addCard(Constants.Zone.LIBRARY, playerA, "Plains", 10);
|
||||
|
||||
// *** ComputerB ***
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerB, "Plains", 2);
|
||||
addCard(Constants.Zone.HAND, playerB, "Plains", 2);
|
||||
removeAllCardsFromLibrary(playerB);
|
||||
addCard(Constants.Zone.LIBRARY, playerB, "Plains", 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all cards from player's library from the game.
|
||||
* Usually this should be used once before initialization to form the library in certain order.
|
||||
*
|
||||
* @param player {@link Player} to remove all library cards from.
|
||||
*/
|
||||
public void removeAllCardsFromLibrary(Player player) {
|
||||
if (player.equals(playerA)) {
|
||||
commandsA.put(Constants.Zone.LIBRARY, "clear");
|
||||
} else if (player.equals(playerB)) {
|
||||
commandsB.put(Constants.Zone.LIBRARY, "clear");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a card to specified zone of specified player.
|
||||
*
|
||||
* @param gameZone {@link Constants.Zone} to add cards to.
|
||||
* @param player {@link Player} to add cards for. Use either playerA or playerB.
|
||||
* @param cardName Card name in string format.
|
||||
*/
|
||||
public void addCard(Constants.Zone gameZone, Player player, String cardName) {
|
||||
addCard(gameZone, player, cardName, 1, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add any amount of cards to specified zone of specified player.
|
||||
*
|
||||
* @param gameZone {@link Constants.Zone} to add cards to.
|
||||
* @param player {@link Player} to add cards for. Use either playerA or playerB.
|
||||
* @param cardName Card name in string format.
|
||||
* @param count Amount of cards to be added.
|
||||
*/
|
||||
public void addCard(Constants.Zone gameZone, Player player, String cardName, int count) {
|
||||
addCard(gameZone, player, cardName, count, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add any amount of cards to specified zone of specified player.
|
||||
*
|
||||
* @param gameZone {@link Constants.Zone} to add cards to.
|
||||
* @param player {@link Player} to add cards for. Use either playerA or playerB.
|
||||
* @param cardName Card name in string format.
|
||||
* @param count Amount of cards to be added.
|
||||
* @param tapped In case gameZone is Battlefield, determines whether permanent should be tapped.
|
||||
* In case gameZone is other than Battlefield, {@link IllegalArgumentException} is thrown
|
||||
*/
|
||||
public void addCard(Constants.Zone gameZone, Player player, String cardName, int count, boolean tapped) {
|
||||
|
||||
|
||||
if (gameZone.equals(Constants.Zone.BATTLEFIELD)) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
Card card = Sets.findCard(cardName, true);
|
||||
if (card == null) {
|
||||
throw new IllegalArgumentException("[TEST] Couldn't find a card: " + cardName);
|
||||
}
|
||||
PermanentCard p = new PermanentCard(card, null);
|
||||
p.setTapped(tapped);
|
||||
if (player.equals(playerA)) {
|
||||
battlefieldCardsA.add(p);
|
||||
} else if (player.equals(playerB)) {
|
||||
battlefieldCardsB.add(p);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (tapped) {
|
||||
throw new IllegalArgumentException("Parameter tapped=true can be used only for Zone.BATTLEFIELD.");
|
||||
}
|
||||
List<Card> cards = getCardList(gameZone, player);
|
||||
for (int i = 0; i < count; i++) {
|
||||
Card card = Sets.findCard(cardName, true);
|
||||
cards.add(card);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns card list containter for specified game zone and player.
|
||||
*
|
||||
* @param gameZone
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
private List<Card> getCardList(Constants.Zone gameZone, Player player) {
|
||||
if (player.equals(playerA)) {
|
||||
if (gameZone.equals(Constants.Zone.HAND)) {
|
||||
return handCardsA;
|
||||
} else if (gameZone.equals(Constants.Zone.GRAVEYARD)) {
|
||||
return graveyardCardsA;
|
||||
} else if (gameZone.equals(Constants.Zone.LIBRARY)) {
|
||||
return libraryCardsA;
|
||||
}
|
||||
} else if (player.equals(playerB)) {
|
||||
if (gameZone.equals(Constants.Zone.HAND)) {
|
||||
return handCardsB;
|
||||
} else if (gameZone.equals(Constants.Zone.GRAVEYARD)) {
|
||||
return graveyardCardsB;
|
||||
} else if (gameZone.equals(Constants.Zone.LIBRARY)) {
|
||||
return libraryCardsB;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set player's initial life count.
|
||||
*
|
||||
* @param player {@link Player} to set life count for.
|
||||
* @param life Life count to set.
|
||||
*/
|
||||
public void setLife(Player player, int life) {
|
||||
if (player.equals(playerA)) {
|
||||
commandsA.put(Constants.Zone.OUTSIDE, "life:" + String.valueOf(life));
|
||||
} else if (player.equals(playerB)) {
|
||||
commandsB.put(Constants.Zone.OUTSIDE, "life:" + String.valueOf(life));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Define turn number to stop the game on.
|
||||
*/
|
||||
public void setStopOnTurn(int turn) {
|
||||
stopOnTurn = turn == -1 ? null : Integer.valueOf(turn);
|
||||
stopAtStep = PhaseStep.UNTAP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define turn number and step to stop the game on.
|
||||
*/
|
||||
public void setStopAt(int turn, PhaseStep step) {
|
||||
stopOnTurn = turn == -1 ? null : Integer.valueOf(turn);
|
||||
stopAtStep = step;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert turn number after test execution.
|
||||
*
|
||||
* @param turn Expected turn number to compare with. 1-based.
|
||||
*/
|
||||
public void assertTurn(int turn) throws AssertionError {
|
||||
Assert.assertEquals("Turn numbers are not equal", turn, currentGame.getTurnNum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert game result after test execution.
|
||||
*
|
||||
* @param result Expected {@link GameResult} to compare with.
|
||||
*/
|
||||
public void assertResult(Player player, GameResult result) throws AssertionError {
|
||||
if (player.equals(playerA)) {
|
||||
GameResult actual = CardTestAPI.GameResult.DRAW;
|
||||
if (currentGame.getWinner().equals("Player PlayerA is the winner")) {
|
||||
actual = CardTestAPI.GameResult.WON;
|
||||
} else if (currentGame.getWinner().equals("Player PlayerB is the winner")) {
|
||||
actual = CardTestAPI.GameResult.LOST;
|
||||
}
|
||||
Assert.assertEquals("Game results are not equal", result, actual);
|
||||
} else if (player.equals(playerB)) {
|
||||
GameResult actual = CardTestAPI.GameResult.DRAW;
|
||||
if (currentGame.getWinner().equals("Player PlayerB is the winner")) {
|
||||
actual = CardTestAPI.GameResult.WON;
|
||||
} else if (currentGame.getWinner().equals("Player PlayerA is the winner")) {
|
||||
actual = CardTestAPI.GameResult.LOST;
|
||||
}
|
||||
Assert.assertEquals("Game results are not equal", result, actual);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert player's life count after test execution.
|
||||
*
|
||||
* @param player {@link Player} to get life for comparison.
|
||||
* @param life Expected player's life to compare with.
|
||||
*/
|
||||
public void assertLife(Player player, int life) throws AssertionError {
|
||||
int actual = currentGame.getPlayer(player.getId()).getLife();
|
||||
Assert.assertEquals("Life amounts are not equal", life, actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert creature's power and toughness by card name.
|
||||
* <p/>
|
||||
* Throws {@link AssertionError} in the following cases:
|
||||
* 1. no such player
|
||||
* 2. no such creature under player's control
|
||||
* 3. depending on comparison scope:
|
||||
* 3a. any: no creature under player's control with the specified p\t params
|
||||
* 3b. all: there is at least one creature with the cardName with the different p\t params
|
||||
*
|
||||
* @param player {@link Player} to get creatures for comparison.
|
||||
* @param cardName Card name to compare with.
|
||||
* @param power Expected power to compare with.
|
||||
* @param toughness Expected toughness to compare with.
|
||||
* @param scope {@link mage.filter.Filter.ComparisonScope} Use ANY, if you want "at least one creature with given name should have specified p\t"
|
||||
* Use ALL, if you want "all creature with gived name should have specified p\t"
|
||||
*/
|
||||
public void assertPowerToughness(Player player, String cardName, int power, int toughness, Filter.ComparisonScope scope)
|
||||
throws AssertionError {
|
||||
int count = 0;
|
||||
int fit = 0;
|
||||
for (Permanent permanent : currentGame.getBattlefield().getAllActivePermanents(player.getId())) {
|
||||
if (permanent.getName().equals(cardName)) {
|
||||
count++;
|
||||
if (scope.equals(Filter.ComparisonScope.All)) {
|
||||
Assert.assertEquals("Power is not the same (" + power + " vs. " + permanent.getPower().getValue() + ")",
|
||||
power, permanent.getPower().getValue());
|
||||
Assert.assertEquals("Toughness is not the same (" + toughness + " vs. " + permanent.getToughness().getValue() + ")",
|
||||
toughness, permanent.getToughness().getValue());
|
||||
} else if (scope.equals(Filter.ComparisonScope.Any)) {
|
||||
if (power == permanent.getPower().getValue() && toughness == permanent.getToughness().getValue()) {
|
||||
fit++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Assert.assertTrue("There is no such permanent under player's control, player=" + player.getName() +
|
||||
", cardName=" + cardName, count > 0);
|
||||
|
||||
if (scope.equals(Filter.ComparisonScope.Any)) {
|
||||
Assert.assertTrue("There is no such creature under player's control with specified power&toughness, player=" + player.getName() +
|
||||
", cardName=" + cardName, fit > 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public void assertAbilities(Player player, String cardName, List<Ability> abilities)
|
||||
throws AssertionError {
|
||||
int count = 0;
|
||||
Permanent found = null;
|
||||
for (Permanent permanent : currentGame.getBattlefield().getAllActivePermanents(player.getId())) {
|
||||
if (permanent.getName().equals(cardName)) {
|
||||
found = permanent;
|
||||
}
|
||||
}
|
||||
|
||||
Assert.assertNotNull("There is no such permanent under player's control, player=" + player.getName() +
|
||||
", cardName=" + cardName, found);
|
||||
|
||||
Assert.assertTrue("There is more than one such permanent under player's control, player=" + player.getName() +
|
||||
", cardName=" + cardName, count == 1);
|
||||
|
||||
for (Ability ability : abilities) {
|
||||
Assert.assertTrue("No such ability=" + ability.toString() + ", player=" + player.getName() +
|
||||
", cardName" + cardName, found.getAbilities().contains(ability));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert permanent count under player's control.
|
||||
*
|
||||
* @param player {@link Player} which permanents should be counted.
|
||||
* @param count Expected count.
|
||||
*/
|
||||
public void assertPermanentCount(Player player, int count) throws AssertionError {
|
||||
int actualCount = 0;
|
||||
for (Permanent permanent : currentGame.getBattlefield().getAllPermanents()) {
|
||||
if (permanent.getControllerId().equals(player.getId())) {
|
||||
actualCount++;
|
||||
}
|
||||
}
|
||||
Assert.assertEquals("(Battlefield) Card counts are not equal ", count, actualCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert permanent count under player's control.
|
||||
*
|
||||
* @param player {@link Player} which permanents should be counted.
|
||||
* @param cardName Name of the cards that should be counted.
|
||||
* @param count Expected count.
|
||||
*/
|
||||
public void assertPermanentCount(Player player, String cardName, int count) throws AssertionError {
|
||||
int actualCount = 0;
|
||||
for (Permanent permanent : currentGame.getBattlefield().getAllPermanents()) {
|
||||
if (permanent.getControllerId().equals(player.getId())) {
|
||||
if (permanent.getName().equals(cardName)) {
|
||||
actualCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
Assert.assertEquals("(Battlefield) Card counts are not equal (" + cardName + ")", count, actualCount);
|
||||
}
|
||||
|
||||
public Permanent getPermanent(String cardName, UUID controller) {
|
||||
Permanent permanent0 = null;
|
||||
int count = 0;
|
||||
for (Permanent permanent : currentGame.getBattlefield().getAllPermanents()) {
|
||||
if (permanent.getControllerId().equals(controller)) {
|
||||
if (permanent.getName().equals(cardName)) {
|
||||
permanent0 = permanent;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
Assert.assertNotNull("Couldn't find a card with specified name: " + cardName, permanent0);
|
||||
Assert.assertEquals("More than one permanent was found: " + cardName + "(" + count + ")", 1, count);
|
||||
return permanent0;
|
||||
}
|
||||
|
||||
public void playLand(int turnNum, PhaseStep step, TestPlayer player, String cardName) {
|
||||
player.addAction(turnNum, step, "activate:Cast " + cardName);
|
||||
}
|
||||
|
||||
public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName) {
|
||||
player.addAction(turnNum, step, "activate:Cast " + cardName);
|
||||
}
|
||||
|
||||
public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName, Player target) {
|
||||
player.addAction(turnNum, step, "activate:Cast " + cardName + ";targetPlayer=" + target.getName());
|
||||
}
|
||||
|
||||
public void castSpell(int turnNum, PhaseStep step, TestPlayer player, String cardName, String targetName) {
|
||||
player.addAction(turnNum, step, "activate:Cast " + cardName + ";target=" + targetName);
|
||||
}
|
||||
|
||||
public void activateAbility(int turnNum, PhaseStep step, TestPlayer player, String ability, Player target) {
|
||||
player.addAction(turnNum, step, "activate:" + ability + ";target=" + target.getName());
|
||||
}
|
||||
|
||||
public void activateAbility(int turnNum, PhaseStep step, TestPlayer player, String ability, String targetName) {
|
||||
player.addAction(turnNum, step, "activate:" + ability + ";target=" + targetName);
|
||||
}
|
||||
|
||||
public void useAbility(int turnNum, PhaseStep step, TestPlayer player, String cardName) {
|
||||
}
|
||||
|
||||
public void attack(int turnNum, TestPlayer player, String attacker) {
|
||||
player.addAction(turnNum, PhaseStep.DECLARE_ATTACKERS, "attack:"+attacker);
|
||||
}
|
||||
|
||||
public void block(int turnNum, TestPlayer player, String blocker, String attacker) {
|
||||
player.addAction(turnNum, PhaseStep.DECLARE_BLOCKERS, "block:"+blocker+";"+attacker);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,56 +1,42 @@
|
|||
package org.mage.test.serverside.cards.abilities;
|
||||
|
||||
import mage.Constants;
|
||||
import mage.Constants.PhaseStep;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestAPI;
|
||||
import org.mage.test.serverside.base.CardTestBase;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* @author ayratn
|
||||
*/
|
||||
public class ProtectionFromColorTest extends CardTestBase {
|
||||
public class ProtectionFromColorTest extends CardTestPlayerBase {
|
||||
|
||||
@Test
|
||||
public void testAgainstAbilityInTheStack() {
|
||||
useRedDefault();
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Royal Assassin");
|
||||
|
||||
// tapped White Knight with Protection from Black
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerB, "White Knight", 1, true);
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerB, "Runeclaw Bear", 1, true);
|
||||
// one not tapped White Knight to prevent AI from attacking
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerB, "White Knight", 1, false);
|
||||
|
||||
setStopOnTurn(2);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Destroy target tapped creature. ", "White Knight");
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertTurn(2);
|
||||
assertResult(playerA, CardTestAPI.GameResult.DRAW);
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 20);
|
||||
|
||||
// no one should be destroyed
|
||||
assertPermanentCount(playerB, "White Knight", 2);
|
||||
assertPermanentCount(playerB, "Runeclaw Bear", 0);
|
||||
assertPermanentCount(playerB, "White Knight", 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAgainstAbilityInTheStackNoProtection() {
|
||||
useRedDefault();
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Royal Assassin");
|
||||
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerB, "Runeclaw Bear", 1, true);
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerB, "Runeclaw Bear", 1, false);
|
||||
|
||||
setStopOnTurn(2);
|
||||
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Destroy target tapped creature. ", "Runeclaw Bear");
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertTurn(2);
|
||||
assertResult(playerA, CardTestAPI.GameResult.DRAW);
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 20);
|
||||
|
||||
// One should have beendestroyed by Royal Assassin
|
||||
assertPermanentCount(playerB, "Runeclaw Bear", 1);
|
||||
assertPermanentCount(playerB, "Runeclaw Bear", 0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,27 +3,24 @@ package org.mage.test.serverside.cards.abilities;
|
|||
import mage.Constants;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestBase;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* @author ayratn
|
||||
*/
|
||||
public class ProtectionFromTypeTest extends CardTestBase {
|
||||
public class ProtectionFromTypeTest extends CardTestPlayerBase {
|
||||
|
||||
@Test
|
||||
public void testProtectionFromArtifacts() {
|
||||
useRedDefault();
|
||||
addCard(Constants.Zone.HAND, playerA, "Trigon of Corruption");
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Trigon of Corruption");
|
||||
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerB, "Tel-Jilad Fallen");
|
||||
|
||||
setStopOnTurn(2);
|
||||
activateAbility(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "{2},Remove a Charge counter from {this}, {T}: put a -1/-1 counter on target creature. ", "Tel-Jilad Fallen");
|
||||
setStopAt(1, Constants.PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertTurn(2);
|
||||
assertResult(playerA, GameResult.DRAW);
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 20);
|
||||
|
||||
// no one should be destroyed
|
||||
assertPermanentCount(playerB, "Tel-Jilad Fallen", 1);
|
||||
}
|
||||
|
|
@ -31,19 +28,15 @@ public class ProtectionFromTypeTest extends CardTestBase {
|
|||
@Test
|
||||
public void testNoProtection() {
|
||||
useRedDefault();
|
||||
addCard(Constants.Zone.HAND, playerA, "Trigon of Corruption");
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerA, "Trigon of Corruption");
|
||||
|
||||
addCard(Constants.Zone.BATTLEFIELD, playerB, "Coral Merfolk");
|
||||
|
||||
setStopOnTurn(2);
|
||||
activateAbility(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "{2},Remove a Charge counter from {this}, {T}: put a -1/-1 counter on target creature. ", "Coral Merfolk");
|
||||
setStopAt(1, Constants.PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertTurn(2);
|
||||
assertResult(playerA, GameResult.DRAW);
|
||||
assertLife(playerA, 20);
|
||||
assertLife(playerB, 20);
|
||||
|
||||
// no one should be destroyed
|
||||
// Coral Merfolk should be destroyed
|
||||
assertPermanentCount(playerB, "Coral Merfolk", 0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue