diff --git a/Mage.Client/plugins/AIMinimax.properties b/Mage.Client/plugins/AIMinimax.properties
deleted file mode 100644
index 96b5480294c..00000000000
--- a/Mage.Client/plugins/AIMinimax.properties
+++ /dev/null
@@ -1,7 +0,0 @@
-maxDepth=10
-maxNodes=5000
-evaluatorLifeFactor=2
-evaluatorPermanentFactor=1
-evaluatorCreatureFactor=1
-evaluatorHandFactor=1
-maxThinkSeconds=30
\ No newline at end of file
diff --git a/Mage.Server.Plugins/Mage.Player.AI.DraftBot/pom.xml b/Mage.Server.Plugins/Mage.Player.AI.DraftBot/pom.xml
index 4c02450c7fe..1b6d54688bd 100644
--- a/Mage.Server.Plugins/Mage.Player.AI.DraftBot/pom.xml
+++ b/Mage.Server.Plugins/Mage.Player.AI.DraftBot/pom.xml
@@ -12,7 +12,7 @@
mage-player-ai-draftbotjar
- Mage Player AI.DraftBot
+ Mage Player AI (draft bot)
diff --git a/Mage.Server.Plugins/Mage.Player.AI.DraftBot/src/mage/player/ai/ComputerDraftPlayer.java b/Mage.Server.Plugins/Mage.Player.AI.DraftBot/src/mage/player/ai/ComputerDraftPlayer.java
index 4d7eedfc092..53fda77b4d0 100644
--- a/Mage.Server.Plugins/Mage.Player.AI.DraftBot/src/mage/player/ai/ComputerDraftPlayer.java
+++ b/Mage.Server.Plugins/Mage.Player.AI.DraftBot/src/mage/player/ai/ComputerDraftPlayer.java
@@ -1,18 +1,18 @@
-
-
package mage.player.ai;
import mage.constants.RangeOfInfluence;
import mage.game.Game;
import mage.game.Table;
import mage.game.tournament.TournamentType;
-import mage.players.Player;
/**
+ * AI: server side bot for drafts (draftbot, the latest version)
+ *
+ * Can play drafts only, concede/lose on any real game and tourney
*
* @author nantuko
*/
-public class ComputerDraftPlayer extends ComputerPlayer implements Player {
+public class ComputerDraftPlayer extends ComputerPlayer {
public ComputerDraftPlayer(String name, RangeOfInfluence range) {
super(name, range);
@@ -46,7 +46,7 @@ public class ComputerDraftPlayer extends ComputerPlayer implements Player {
public boolean canJoinTable(Table table) {
if (table.isTournament()) {
TournamentType tournamentType = table.getTournament().getTournamentType();
- if(tournamentType != null && tournamentType.isDraft()) {
+ if (tournamentType != null && tournamentType.isDraft()) {
return true;
}
}
diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/config/AIMinimax.properties b/Mage.Server.Plugins/Mage.Player.AI.MA/config/AIMinimax.properties
deleted file mode 100644
index 219e0264582..00000000000
--- a/Mage.Server.Plugins/Mage.Player.AI.MA/config/AIMinimax.properties
+++ /dev/null
@@ -1,7 +0,0 @@
-maxDepth=10
-maxNodes=5000
-evaluatorLifeFactor=2
-evaluatorPermanentFactor=1
-evaluatorCreatureFactor=1
-evaluatorHandFactor=1
-maxThinkSeconds=10
\ No newline at end of file
diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/pom.xml b/Mage.Server.Plugins/Mage.Player.AI.MA/pom.xml
index 0e3857d37ae..73f91e6dbb8 100644
--- a/Mage.Server.Plugins/Mage.Player.AI.MA/pom.xml
+++ b/Mage.Server.Plugins/Mage.Player.AI.MA/pom.xml
@@ -12,7 +12,7 @@
mage-player-ai-majar
- Mage Player AI.MA
+ Mage Player AI (mad bot)
diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java
index 639eb52b134..58eed8958f1 100644
--- a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java
+++ b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer6.java
@@ -41,12 +41,18 @@ import java.util.concurrent.*;
import java.util.stream.Collectors;
/**
+ * AI: server side bot with game simulations (mad bot, part of implementation)
+ *
* @author nantuko
*/
-public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ {
+public class ComputerPlayer6 extends ComputerPlayer {
private static final Logger logger = Logger.getLogger(ComputerPlayer6.class);
+ // TODO: add and research maxNodes logs, is it good to increase to 50000 for better results?
+ // TODO: increase maxNodes due AI skill level?
+ private static final int MAX_SIMULATED_NODES_PER_CALC = 5000;
+
// same params as Executors.newFixedThreadPool
// no needs erorrs check in afterExecute here cause that pool used for FutureTask with result check already
private static final ExecutorService threadPoolSimulations = new ThreadPoolExecutor(
@@ -97,7 +103,7 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ {
maxDepth = skill;
}
maxThink = skill * 3;
- maxNodes = Config2.maxNodes;
+ maxNodes = MAX_SIMULATED_NODES_PER_CALC;
getSuggestedActions();
this.actionCache = new HashSet<>();
}
diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer7.java b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer7.java
index 6173a8df632..667d64aadb2 100644
--- a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer7.java
+++ b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/ComputerPlayer7.java
@@ -9,6 +9,8 @@ import java.util.Date;
import java.util.LinkedList;
/**
+ * AI: server side bot with game simulations (mad bot, the latest version)
+ *
* @author ayratn
*/
public class ComputerPlayer7 extends ComputerPlayer6 {
diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/Config2.java b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/Config2.java
deleted file mode 100644
index dc528cd0de6..00000000000
--- a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/Config2.java
+++ /dev/null
@@ -1,59 +0,0 @@
-
-
-package mage.player.ai;
-
-import org.apache.log4j.Logger;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.util.Properties;
-
-/**
- *
- * @author BetaSteward_at_googlemail.com
- */
-public final class Config2 {
-
- private static final Logger logger = Logger.getLogger(Config2.class);
-
-// public static final int maxDepth;
- public static final int maxNodes;
- public static final int evaluatorLifeFactor;
- public static final int evaluatorPermanentFactor;
- public static final int evaluatorCreatureFactor;
- public static final int evaluatorHandFactor;
-// public static final int maxThinkSeconds;
-
- static {
- Properties p = new Properties();
- try {
- File file = new File(Config2.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
- File propertiesFile = new File(file.getParent() + File.separator + "AIMinimax.properties");
- if (propertiesFile.exists()) {
- p.load(new FileInputStream(propertiesFile));
- } else {
-// p.setProperty("maxDepth", "10");
- p.setProperty("maxNodes", "50000");
- p.setProperty("evaluatorLifeFactor", "2");
- p.setProperty("evaluatorPermanentFactor", "1");
- p.setProperty("evaluatorCreatureFactor", "1");
- p.setProperty("evaluatorHandFactor", "1");
-// p.setProperty("maxThinkSeconds", "30");
- }
- } catch (IOException ex) {
- logger.error(null, ex);
- } catch (URISyntaxException ex) {
- logger.error(null, ex);
- }
-// maxDepth = Integer.parseInt(p.getProperty("maxDepth"));
- maxNodes = Integer.parseInt(p.getProperty("maxNodes"));
- evaluatorLifeFactor = Integer.parseInt(p.getProperty("evaluatorLifeFactor"));
- evaluatorPermanentFactor = Integer.parseInt(p.getProperty("evaluatorPermanentFactor"));
- evaluatorCreatureFactor = Integer.parseInt(p.getProperty("evaluatorCreatureFactor"));
- evaluatorHandFactor = Integer.parseInt(p.getProperty("evaluatorHandFactor"));
-// maxThinkSeconds = Integer.parseInt(p.getProperty("maxThinkSeconds"));
- }
-
-}
diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/SimulatedPlayer2.java b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/SimulatedPlayer2.java
index e8c137dacf8..2a69f9a69c7 100644
--- a/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/SimulatedPlayer2.java
+++ b/Mage.Server.Plugins/Mage.Player.AI.MA/src/mage/player/ai/SimulatedPlayer2.java
@@ -27,11 +27,11 @@ import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
- * AI: mock player in simulated games (each player replaced by simulated)
+ * AI: helper class to simulate games with computer bot (each player replaced by simulated)
*
* @author BetaSteward_at_googlemail.com
*/
-public class SimulatedPlayer2 extends ComputerPlayer {
+public final class SimulatedPlayer2 extends ComputerPlayer {
private static final Logger logger = Logger.getLogger(SimulatedPlayer2.class);
diff --git a/Mage.Server.Plugins/Mage.Player.AI/pom.xml b/Mage.Server.Plugins/Mage.Player.AI/pom.xml
index f50a620ece1..c3ccebc6803 100644
--- a/Mage.Server.Plugins/Mage.Player.AI/pom.xml
+++ b/Mage.Server.Plugins/Mage.Player.AI/pom.xml
@@ -12,7 +12,7 @@
mage-player-aijar
- Mage Player AI
+ Mage Player AI (basic)
diff --git a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java
index e6573046e7b..741c0d4e7ff 100644
--- a/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java
+++ b/Mage.Server.Plugins/Mage.Player.AI/src/main/java/mage/player/ai/ComputerPlayer.java
@@ -59,11 +59,11 @@ import java.util.*;
import java.util.Map.Entry;
/**
- * suitable for two player games and some multiplayer games
+ * AI: basic server side bot with simple actions support (game, draft, construction/sideboarding)
*
* @author BetaSteward_at_googlemail.com, JayDi85
*/
-public class ComputerPlayer extends PlayerImpl implements Player {
+public class ComputerPlayer extends PlayerImpl {
private static final Logger log = Logger.getLogger(ComputerPlayer.class);
private long lastThinkTime = 0; // msecs for last AI actions calc
diff --git a/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/ComputerPlayerMCTS.java b/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/ComputerPlayerMCTS.java
index e34da5d762a..f9319d6d766 100644
--- a/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/ComputerPlayerMCTS.java
+++ b/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/ComputerPlayerMCTS.java
@@ -25,7 +25,7 @@ import java.util.concurrent.TimeUnit;
/**
* @author BetaSteward_at_googlemail.com
*/
-public class ComputerPlayerMCTS extends ComputerPlayer implements Player {
+public class ComputerPlayerMCTS extends ComputerPlayer {
private static final int THINK_MIN_RATIO = 40;
private static final int THINK_MAX_RATIO = 100;
diff --git a/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/MCTSPlayer.java b/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/MCTSPlayer.java
index 7e3728bf3ea..a79cc57a104 100644
--- a/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/MCTSPlayer.java
+++ b/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/MCTSPlayer.java
@@ -1,4 +1,3 @@
-
package mage.player.ai;
import mage.abilities.Ability;
@@ -15,6 +14,10 @@ import java.util.List;
import java.util.UUID;
/**
+ * AI: server side bot with monte carlo logic (experimental, the latest version)
+ *
+ * Simple implementation for random play, outdate and do not support,
+ * see more details here
*
* @author BetaSteward_at_googlemail.com
*/
@@ -51,22 +54,19 @@ public class MCTSPlayer extends ComputerPlayer {
public List getPlayableOptions(Game game) {
List all = new ArrayList<>();
List playables = getPlayableAbilities(game);
- for (ActivatedAbility ability: playables) {
+ for (ActivatedAbility ability : playables) {
List options = game.getPlayer(playerId).getPlayableOptions(ability, game);
if (options.isEmpty()) {
if (!ability.getManaCosts().getVariableCosts().isEmpty()) {
simulateVariableCosts(ability, all, game);
- }
- else {
+ } else {
all.add(ability);
}
- }
- else {
- for (Ability option: options) {
+ } else {
+ for (Ability option : options) {
if (!ability.getManaCosts().getVariableCosts().isEmpty()) {
simulateVariableCosts(option, all, game);
- }
- else {
+ } else {
all.add(option);
}
}
@@ -137,7 +137,7 @@ public class MCTSPlayer extends ComputerPlayer {
private List> copyEngagement(List> engagement) {
List> newEngagement = new ArrayList<>();
- for (List group: engagement) {
+ for (List group : engagement) {
newEngagement.add(new ArrayList<>(group));
}
return newEngagement;
@@ -154,7 +154,7 @@ public class MCTSPlayer extends ComputerPlayer {
List remaining = remove(blockers, blocker);
for (int i = 0; i < numGroups; i++) {
if (game.getCombat().getGroups().get(i).canBlock(blocker, game)) {
- List>newEngagement = copyEngagement(engagement);
+ List> newEngagement = copyEngagement(engagement);
newEngagement.get(i).add(blocker.getId());
engagements.add(newEngagement);
// logger.debug("simulating -- found redundant block combination");
diff --git a/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/SimulatedPlayerMCTS.java b/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/SimulatedPlayerMCTS.java
index 698c694f96c..09fcfa67339 100644
--- a/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/SimulatedPlayerMCTS.java
+++ b/Mage.Server.Plugins/Mage.Player.AIMCTS/src/mage/player/ai/SimulatedPlayerMCTS.java
@@ -24,11 +24,13 @@ import java.io.Serializable;
import java.util.*;
/**
- * plays randomly
+ * AI: helper class to simulate games with MCTS AI (each player replaced by simulated)
+ *
+ * Plays randomly
*
* @author BetaSteward_at_googlemail.com
*/
-public class SimulatedPlayerMCTS extends MCTSPlayer {
+public final class SimulatedPlayerMCTS extends MCTSPlayer {
private boolean isSimulatedPlayer;
private int actionCount = 0;
@@ -98,28 +100,13 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
ability.addManaCostsToPay(new GenericManaCost(RandomUtil.nextInt(amount)));
}
}
- // check if ability kills player, if not then it's ok to play
-// if (ability.isUsesStack()) {
-// Game testSim = game.copy();
-// activateAbility((ActivatedAbility) ability, testSim);
-// StackObject testAbility = testSim.getStack().pop();
-// testAbility.resolve(testSim);
-// testSim.applyEffects();
-// testSim.checkStateAndTriggered();
-// if (!testSim.getPlayer(playerId).hasLost()) {
-// break;
-// }
-// }
-// else {
break;
-// }
}
return ability;
}
@Override
public boolean triggerAbility(TriggeredAbility source, Game game) {
-// logger.info("trigger");
if (source != null && source.canChooseTarget(game, playerId)) {
Ability ability;
List options = getPlayableOptions(source, game);
@@ -153,7 +140,6 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
@Override
public void selectAttackers(Game game, UUID attackingPlayerId) {
//useful only for two player games - will only attack first opponent
-// logger.info("select attackers");
UUID defenderId = game.getOpponents(playerId).iterator().next();
List attackersList = super.getAvailableAttackers(defenderId, game);
//use binary digits to calculate powerset of attackers
@@ -177,7 +163,6 @@ public class SimulatedPlayerMCTS extends MCTSPlayer {
@Override
public void selectBlockers(Ability source, Game game, UUID defendingPlayerId) {
-// logger.info("select blockers");
int numGroups = game.getCombat().getGroups().size();
if (numGroups == 0) {
return;
diff --git a/Mage.Server.Plugins/Mage.Player.AIMinimax/config/AIMinimax.properties b/Mage.Server.Plugins/Mage.Player.AIMinimax/config/AIMinimax.properties
deleted file mode 100644
index 96b5480294c..00000000000
--- a/Mage.Server.Plugins/Mage.Player.AIMinimax/config/AIMinimax.properties
+++ /dev/null
@@ -1,7 +0,0 @@
-maxDepth=10
-maxNodes=5000
-evaluatorLifeFactor=2
-evaluatorPermanentFactor=1
-evaluatorCreatureFactor=1
-evaluatorHandFactor=1
-maxThinkSeconds=30
\ No newline at end of file
diff --git a/Mage.Server.Plugins/Mage.Player.AIMinimax/pom.xml b/Mage.Server.Plugins/Mage.Player.AIMinimax/pom.xml
deleted file mode 100644
index 305709ae6b1..00000000000
--- a/Mage.Server.Plugins/Mage.Player.AIMinimax/pom.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-
- 4.0.0
-
-
- org.mage
- mage-server-plugins
- 1.4.50
-
-
- mage-player-aiminimax
- jar
- Mage Player AI Minimax
-
-
-
- ${project.groupId}
- mage
- ${project.version}
-
-
- ${project.groupId}
- mage-player-ai
- ${project.version}
-
-
-
-
- src
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
-
- ${java.version}
- ${java.version}
-
-
-
- maven-resources-plugin
-
- UTF-8
-
-
-
-
-
- mage-player-aiminimax
-
-
-
- ${project.basedir}/../..
-
-
-
diff --git a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/Attackers.java b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/Attackers.java
deleted file mode 100644
index 45482be1def..00000000000
--- a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/Attackers.java
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-package mage.player.ai;
-
-import mage.game.permanent.Permanent;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.TreeMap;
-
-/**
- *
- * @author BetaSteward_at_googlemail.com
- */
-public class Attackers extends TreeMap> {
-
- public List getAttackers() {
- List attackers = new ArrayList<>();
- for (List l: this.values()) {
- for (Permanent permanent: l) {
- attackers.add(permanent);
- }
- }
- return attackers;
- }
-
-}
diff --git a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/Config.java b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/Config.java
deleted file mode 100644
index d239b48ff96..00000000000
--- a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/Config.java
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-package mage.player.ai;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.util.Properties;
-import org.apache.log4j.Logger;
-
-/**
- *
- * @author BetaSteward_at_googlemail.com
- */
-public final class Config {
-
- private static final Logger logger = Logger.getLogger(Config.class);
-
-// public static final int maxDepth;
- public static final int maxNodes;
- public static final int evaluatorLifeFactor;
- public static final int evaluatorPermanentFactor;
- public static final int evaluatorCreatureFactor;
- public static final int evaluatorHandFactor;
-// public static final int maxThinkSeconds;
-
- static {
- Properties p = new Properties();
- try {
- File file = new File(Config.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
- p.load(new FileInputStream(new File(file.getParent() + File.separator + "AIMinimax.properties")));
- } catch (IOException ex) {
- logger.fatal("", ex);
- } catch (URISyntaxException ex) {
- logger.fatal("", ex);
- }
-// maxDepth = Integer.parseInt(p.getProperty("maxDepth"));
- maxNodes = Integer.parseInt(p.getProperty("maxNodes"));
- evaluatorLifeFactor = Integer.parseInt(p.getProperty("evaluatorLifeFactor"));
- evaluatorPermanentFactor = Integer.parseInt(p.getProperty("evaluatorPermanentFactor"));
- evaluatorCreatureFactor = Integer.parseInt(p.getProperty("evaluatorCreatureFactor"));
- evaluatorHandFactor = Integer.parseInt(p.getProperty("evaluatorHandFactor"));
-// maxThinkSeconds = Integer.parseInt(p.getProperty("maxThinkSeconds"));
- }
-
-}
diff --git a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/GameStateEvaluator.java b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/GameStateEvaluator.java
deleted file mode 100644
index 236bc2e19e1..00000000000
--- a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/GameStateEvaluator.java
+++ /dev/null
@@ -1,124 +0,0 @@
-
-package mage.player.ai;
-
-import java.util.UUID;
-import mage.abilities.ActivatedAbility;
-import mage.abilities.keyword.DoubleStrikeAbility;
-import mage.abilities.keyword.FirstStrikeAbility;
-import mage.abilities.keyword.TrampleAbility;
-import mage.abilities.mana.ActivatedManaAbilityImpl;
-import mage.constants.CardType;
-import mage.constants.Zone;
-import mage.counters.BoostCounter;
-import mage.counters.Counter;
-import mage.counters.CounterType;
-import mage.game.Game;
-import mage.game.permanent.Permanent;
-import mage.players.Player;
-import org.apache.log4j.Logger;
-
-/**
- *
- * @author BetaSteward_at_googlemail.com
- *
- * this evaluator is only good for two player games
- *
- */
-public final class GameStateEvaluator {
-
- private static final Logger logger = Logger.getLogger(GameStateEvaluator.class);
-
- private static final int LIFE_FACTOR = Config.evaluatorLifeFactor;
- private static final int PERMANENT_FACTOR = Config.evaluatorPermanentFactor;
- private static final int CREATURE_FACTOR = Config.evaluatorCreatureFactor;
- private static final int HAND_FACTOR = Config.evaluatorHandFactor;
-
- public static final int WIN_SCORE = Integer.MAX_VALUE - 1;
- public static final int LOSE_SCORE = Integer.MIN_VALUE + 1;
-
- public static int evaluate(UUID playerId, Game game) {
- return evaluate(playerId, game, false);
- }
-
- public static int evaluate(UUID playerId, Game game, boolean ignoreTapped) {
- Player player = game.getPlayer(playerId);
- Player opponent = game.getPlayer(game.getOpponents(playerId).stream().findFirst().orElse(null));
- if (opponent == null) {
- return WIN_SCORE;
- }
-
- if (game.checkIfGameIsOver()) {
- if (player.hasLost() || opponent.hasWon()) {
- return LOSE_SCORE;
- }
- if (opponent.hasLost() || player.hasWon()) {
- return WIN_SCORE;
- }
- }
- int lifeScore = (player.getLife() - opponent.getLife()) * LIFE_FACTOR;
- int poisonScore = (opponent.getCounters().getCount(CounterType.POISON) - player.getCounters().getCount(CounterType.POISON)) * LIFE_FACTOR * 2;
- int permanentScore = 0;
- for (Permanent permanent : game.getBattlefield().getAllActivePermanents(playerId)) {
- permanentScore += evaluatePermanent(permanent, game, ignoreTapped);
- }
- for (Permanent permanent : game.getBattlefield().getAllActivePermanents(opponent.getId())) {
- permanentScore -= evaluatePermanent(permanent, game, ignoreTapped);
- }
- permanentScore *= PERMANENT_FACTOR;
-
- int handScore = 0;
- handScore = player.getHand().size() - opponent.getHand().size();
- handScore *= HAND_FACTOR;
-
- int score = lifeScore + poisonScore + permanentScore + handScore;
- if (logger.isDebugEnabled()) {
- logger.debug("game state for player " + player.getName() + " evaluated to- lifeScore:" + lifeScore + " permanentScore:" + permanentScore + " handScore:" + handScore + " total:" + score);
- }
- return score;
- }
-
- public static int evaluatePermanent(Permanent permanent, Game game, boolean ignoreTapped) {
- int value = 0;
- if (ignoreTapped) {
- value = 5;
- } else {
- value = permanent.isTapped() ? 4 : 5;
- }
- if (permanent.getCardType(game).contains(CardType.CREATURE)) {
- value += evaluateCreature(permanent, game) * CREATURE_FACTOR;
- }
- value += permanent.getAbilities().getActivatedManaAbilities(Zone.BATTLEFIELD).size();
- for (ActivatedAbility ability : permanent.getAbilities().getActivatedAbilities(Zone.BATTLEFIELD)) {
- if (!(ability instanceof ActivatedManaAbilityImpl) && ability.canActivate(ability.getControllerId(), game).canActivate()) {
- value += ability.getEffects().size();
- }
- }
- for (Counter counter : permanent.getCounters(game).values()) {
- if (!(counter instanceof BoostCounter)) {
- value += counter.getCount();
- }
- }
- value += permanent.getAbilities().getStaticAbilities(Zone.BATTLEFIELD).size();
- value += permanent.getAbilities().getTriggeredAbilities(Zone.BATTLEFIELD).size();
- value += permanent.getManaCost().manaValue();
- //TODO: add a difficulty to calculation to ManaCost - sort permanents by difficulty for casting when evaluating game states
- return value;
- }
-
- public static int evaluateCreature(Permanent creature, Game game) {
- int value = 0;
- value += creature.getPower().getValue();
- value += creature.getToughness().getValue();
-// if (creature.canAttack(game))
-// value += creature.getPower().getValue();
-// if (!creature.isTapped())
-// value += 2;
- value += creature.getAbilities().getEvasionAbilities().size();
- value += creature.getAbilities().getProtectionAbilities().size();
- value += creature.getAbilities().containsKey(FirstStrikeAbility.getInstance().getId()) ? 1 : 0;
- value += creature.getAbilities().containsKey(DoubleStrikeAbility.getInstance().getId()) ? 2 : 0;
- value += creature.getAbilities().containsKey(TrampleAbility.getInstance().getId()) ? 1 : 0;
- return value;
- }
-
-}
diff --git a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/SimulatedAction.java b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/SimulatedAction.java
deleted file mode 100644
index a67d383991d..00000000000
--- a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/SimulatedAction.java
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-package mage.player.ai;
-
-import java.util.List;
-import mage.abilities.Ability;
-import mage.game.Game;
-
-/**
- *
- * @author BetaSteward_at_googlemail.com
- */
-public class SimulatedAction {
-
- private Game game;
- private List abilities;
-
- public SimulatedAction(Game game, List abilities) {
- this.game = game;
- this.abilities = abilities;
- }
-
- public Game getGame() {
- return this.game;
- }
-
- public List getAbilities() {
- return this.abilities;
- }
-
- @Override
- public String toString() {
- return this.abilities.toString();
- }
-
- public boolean usesStack() {
- if (abilities != null && !abilities.isEmpty()) {
- return abilities.get(abilities.size() -1).isUsesStack();
- }
- return true;
- }
-}
diff --git a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/SimulatedPlayer.java b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/SimulatedPlayer.java
deleted file mode 100644
index 3888dad2ecb..00000000000
--- a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/SimulatedPlayer.java
+++ /dev/null
@@ -1,265 +0,0 @@
-
-
-package mage.player.ai;
-
-import mage.abilities.Ability;
-import mage.abilities.ActivatedAbility;
-import mage.abilities.SpellAbility;
-import mage.abilities.TriggeredAbility;
-import mage.abilities.common.PassAbility;
-import mage.abilities.costs.mana.GenericManaCost;
-import mage.game.Game;
-import mage.game.combat.Combat;
-import mage.game.events.GameEvent;
-import mage.game.match.MatchPlayer;
-import mage.game.permanent.Permanent;
-import mage.game.stack.StackAbility;
-import mage.players.Player;
-import mage.target.Target;
-import org.apache.log4j.Logger;
-
-import java.util.*;
-import java.util.concurrent.ConcurrentLinkedQueue;
-
-/**
- *
- * @author BetaSteward_at_googlemail.com
- */
-public class SimulatedPlayer extends ComputerPlayer {
-
- private static final Logger logger = Logger.getLogger(SimulatedPlayer.class);
- private boolean isSimulatedPlayer;
- private transient ConcurrentLinkedQueue allActions;
- protected int maxDepth;
-
- public SimulatedPlayer(Player originalPlayer, boolean isSimulatedPlayer, int maxDepth) {
- super(originalPlayer.getId());
- this.maxDepth = maxDepth;
- this.isSimulatedPlayer = isSimulatedPlayer;
- this.matchPlayer = new MatchPlayer(originalPlayer.getMatchPlayer(), this);
- }
-
- public SimulatedPlayer(final SimulatedPlayer player) {
- super(player);
- this.isSimulatedPlayer = player.isSimulatedPlayer;
- }
-
- @Override
- public SimulatedPlayer copy() {
- return new SimulatedPlayer(this);
- }
-
- public List simulatePriority(Game game) {
- allActions = new ConcurrentLinkedQueue<>();
- Game sim = game.copy();
-
- ActivatedAbility pass = new PassAbility();
- simulateOptions(sim, pass);
-
- List list = new ArrayList<>(allActions);
- //Collections.shuffle(list);
- Collections.reverse(list);
- return list;
- }
-
- protected void simulateOptions(Game game, ActivatedAbility previousActions) {
- allActions.add(previousActions);
- List playables = game.getPlayer(playerId).getPlayable(game, isSimulatedPlayer);
- for (ActivatedAbility ability: playables) {
- List options = game.getPlayer(playerId).getPlayableOptions(ability, game);
- if (options.isEmpty()) {
- if (!ability.getManaCosts().getVariableCosts().isEmpty()) {
- simulateVariableCosts(ability, game);
- }
- else {
- allActions.add(ability);
- }
-// simulateAction(game, previousActions, ability);
- }
- else {
-// ExecutorService simulationExecutor = Executors.newFixedThreadPool(4);
- for (Ability option: options) {
- if (!ability.getManaCosts().getVariableCosts().isEmpty()) {
- simulateVariableCosts(option, game);
- }
- else {
- allActions.add(option);
- }
-// SimulationWorker worker = new SimulationWorker(game, this, previousActions, option);
-// simulationExecutor.submit(worker);
- }
-// simulationExecutor.shutdown();
-// while(!simulationExecutor.isTerminated()) {}
- }
- }
- }
-
-// protected void simulateAction(Game game, SimulatedAction previousActions, Ability action) {
-// List actions = new ArrayList(previousActions.getAbilities());
-// actions.add(action);
-// Game sim = game.copy();
-// if (sim.getPlayer(playerId).activateAbility((ActivatedAbility) action.copy(), sim)) {
-// sim.applyEffects();
-// sim.getPlayers().resetPassed();
-// allActions.add(new SimulatedAction(sim, actions));
-// }
-// }
-
- //add a generic mana cost for each amount possible
- protected void simulateVariableCosts(Ability ability, Game game) {
- int numAvailable = getAvailableManaProducers(game).size() - ability.getManaCosts().manaValue();
- int start = 0;
- if (!(ability instanceof SpellAbility)) {
- //only use x=0 on spell abilities
- if (numAvailable == 0)
- return;
- else
- start = 1;
- }
- for (int i = start; i < numAvailable; i++) {
- Ability newAbility = ability.copy();
- newAbility.addManaCostsToPay(new GenericManaCost(i));
- allActions.add(newAbility);
- }
- }
-
- /*@Override
- public boolean playXMana(VariableManaCost cost, ManaCosts costs, Game game) {
- //simulateVariableCosts method adds a generic mana cost for each option
- for (ManaCost manaCost: costs) {
- if (manaCost instanceof GenericManaCost) {
- cost.setPayment(manaCost.getPayment());
- logger.debug("simulating -- X = " + cost.getPayment().count());
- break;
- }
- }
- cost.setPaid();
- return true;
- }*/
-
- public List addAttackers(Game game) {
- Map engagements = new HashMap<>();
- //useful only for two player games - will only attack first opponent
- UUID defenderId = game.getOpponents(playerId).iterator().next();
- List attackersList = super.getAvailableAttackers(defenderId, game);
- //use binary digits to calculate powerset of attackers
- int powerElements = (int) Math.pow(2, attackersList.size());
- StringBuilder binary = new StringBuilder();
- for (int i = powerElements - 1; i >= 0; i--) {
- Game sim = game.copy();
- binary.setLength(0);
- binary.append(Integer.toBinaryString(i));
- while (binary.length() < attackersList.size()) {
- binary.insert(0, '0');
- }
- for (int j = 0; j < attackersList.size(); j++) {
- if (binary.charAt(j) == '1') {
- setStoredBookmark(sim.bookmarkState()); // makes it possible to UNDO a declared attacker with costs from e.g. Propaganda
- if (!sim.getCombat().declareAttacker(attackersList.get(j).getId(), defenderId, playerId, sim)) {
- sim.undo(playerId);
- }
- }
- }
- if (engagements.put(sim.getCombat().getValue().hashCode(), sim.getCombat()) != null) {
- logger.debug("simulating -- found redundant attack combination");
- }
- else if (logger.isDebugEnabled()) {
- logger.debug("simulating -- attack:" + sim.getCombat().getGroups().size());
- }
- }
- return new ArrayList<>(engagements.values());
- }
-
- public List addBlockers(Game game) {
- Map engagements = new HashMap<>();
- int numGroups = game.getCombat().getGroups().size();
- if (numGroups == 0) return new ArrayList<>();
-
- //add a node with no blockers
- Game sim = game.copy();
- engagements.put(sim.getCombat().getValue().hashCode(), sim.getCombat());
- sim.fireEvent(GameEvent.getEvent(GameEvent.EventType.DECLARED_BLOCKERS, playerId, playerId));
-
- List blockers = getAvailableBlockers(game);
- addBlocker(game, blockers, engagements);
-
- return new ArrayList<>(engagements.values());
- }
-
- protected void addBlocker(Game game, List blockers, Map engagements) {
- if (blockers.isEmpty())
- return;
- int numGroups = game.getCombat().getGroups().size();
- //try to block each attacker with each potential blocker
- Permanent blocker = blockers.get(0);
- if (logger.isDebugEnabled())
- logger.debug("simulating -- block:" + blocker);
- List remaining = remove(blockers, blocker);
- for (int i = 0; i < numGroups; i++) {
- if (game.getCombat().getGroups().get(i).canBlock(blocker, game)) {
- Game sim = game.copy();
- sim.getCombat().getGroups().get(i).addBlocker(blocker.getId(), playerId, sim);
- if (engagements.put(sim.getCombat().getValue().hashCode(), sim.getCombat()) != null)
- logger.debug("simulating -- found redundant block combination");
- addBlocker(sim, remaining, engagements); // and recurse minus the used blocker
- }
- }
- addBlocker(game, remaining, engagements);
- }
-
- @Override
- public boolean triggerAbility(TriggeredAbility source, Game game) {
- Ability ability = source.copy();
- List options = getPlayableOptions(ability, game);
- if (options.isEmpty()) {
- if (logger.isDebugEnabled())
- logger.debug("simulating -- triggered ability:" + ability);
- game.getStack().push(new StackAbility(ability, playerId));
- if (ability.activate(game, false) && ability.isUsesStack()) {
- game.fireEvent(new GameEvent(GameEvent.EventType.TRIGGERED_ABILITY, ability.getId(), ability, ability.getControllerId()));
- }
- game.applyEffects();
- game.getPlayers().resetPassed();
- }
- else {
- SimulationNode parent = (SimulationNode) game.getCustomData();
- if (parent.getDepth() == maxDepth) return true;
- logger.debug(indent(parent.getDepth()) + "simulating -- triggered ability - adding children:" + options.size());
- for (Ability option: options) {
- addAbilityNode(parent, option, game);
- }
- }
- return true;
- }
-
- protected void addAbilityNode(SimulationNode parent, Ability ability, Game game) {
- Game sim = game.copy();
- sim.getStack().push(new StackAbility(ability, playerId));
- ability.activate(sim, false);
- if (ability.activate(sim, false) && ability.isUsesStack()) {
- game.fireEvent(new GameEvent(GameEvent.EventType.TRIGGERED_ABILITY, ability.getId(), ability, ability.getControllerId()));
- }
- sim.applyEffects();
- SimulationNode newNode = new SimulationNode(parent, sim, playerId);
- logger.debug(indent(newNode.getDepth()) + "simulating -- node #:" + SimulationNode.getCount() + " triggered ability option");
- for (Target target: ability.getTargets()) {
- for (UUID targetId: target.getTargets()) {
- newNode.getTargets().add(targetId);
- }
- }
- parent.children.add(newNode);
- }
-
- @Override
- public boolean priority(Game game) {
- //should never get here
- return false;
- }
-
- protected String indent(int num) {
- char[] fill = new char[num];
- Arrays.fill(fill, ' ');
- return new String(fill);
- }
-
-}
diff --git a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/SimulationNode.java b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/SimulationNode.java
deleted file mode 100644
index cac08d4ee16..00000000000
--- a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/SimulationNode.java
+++ /dev/null
@@ -1,111 +0,0 @@
-
-
-package mage.player.ai;
-
-import mage.abilities.Ability;
-import mage.game.Game;
-import mage.game.combat.Combat;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-
-/**
- *
- * @author BetaSteward_at_googlemail.com
- */
-public class SimulationNode implements Serializable {
-
- protected static int nodeCount;
-
- protected Game game;
- protected int gameValue;
- protected List abilities;
- protected int depth;
- protected List children = new ArrayList<>();
- protected SimulationNode parent;
- protected List targets = new ArrayList<>();
- protected List choices = new ArrayList<>();
- protected UUID playerId;
- protected Combat combat;
-
- public SimulationNode(SimulationNode parent, Game game, UUID playerId) {
- this.parent = parent;
- this.game = game;
- if (parent == null)
- this.depth = 1;
- else
- this.depth = parent.getDepth() + 1;
- this.playerId = playerId;
- game.setCustomData(this);
- nodeCount++;
- }
-
- public SimulationNode(SimulationNode parent, Game game, List abilities, UUID playerId) {
- this(parent, game, playerId);
- this.abilities = abilities;
- }
-
- public SimulationNode(SimulationNode parent, Game game, Ability ability, UUID playerId) {
- this(parent, game, playerId);
- this.abilities = new ArrayList<>();
- abilities.add(ability);
- }
-
- public static void resetCount() {
- nodeCount = 0;
- }
-
- public static int getCount() {
- return nodeCount;
- }
-
- public Game getGame() {
- return this.game;
- }
-
- public int getGameValue() {
- return this.gameValue;
- }
-
- public void setGameValue(int value) {
- this.gameValue = value;
- }
-
- public List getAbilities() {
- return this.abilities;
- }
-
- public SimulationNode getParent() {
- return this.parent;
- }
-
- public List getChildren() {
- return this.children;
- }
-
- public int getDepth() {
- return this.depth;
- }
-
- public UUID getPlayerId() {
- return this.playerId;
- }
-
- public Combat getCombat() {
- return this.combat;
- }
-
- public void setCombat(Combat combat) {
- this.combat = combat;
- }
-
- public List getTargets() {
- return this.targets;
- }
-
- public List getChoices() {
- return this.choices;
- }
-}
diff --git a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/SimulationWorker.java b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/SimulationWorker.java
deleted file mode 100644
index 7af884d5032..00000000000
--- a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/SimulationWorker.java
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-package mage.player.ai;
-
-import java.util.concurrent.Callable;
-import mage.abilities.Ability;
-import mage.game.Game;
-import org.apache.log4j.Logger;
-
-/**
- *
- * @author BetaSteward_at_googlemail.com
- */
-public class SimulationWorker implements Callable {
-
- private static final Logger logger = Logger.getLogger(SimulationWorker.class);
-
- private Game game;
- private SimulatedAction previousActions;
- private Ability action;
- private SimulatedPlayer player;
-
- public SimulationWorker(Game game, SimulatedPlayer player, SimulatedAction previousActions, Ability action) {
- this.game = game;
- this.player = player;
- this.previousActions = previousActions;
- this.action = action;
- }
-
- @Override
- public Object call() {
- try {
-// player.simulateAction(game, previousActions, action);
- } catch (Exception ex) {
- logger.error(null, ex);
- }
- return null;
- }
-
-}
-
diff --git a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java
index e6d8bfa2d70..ffe0e1419b8 100644
--- a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java
+++ b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java
@@ -59,6 +59,8 @@ import static mage.constants.PlayerAction.REQUEST_AUTO_ANSWER_RESET_ALL;
import static mage.constants.PlayerAction.TRIGGER_AUTO_ORDER_RESET_ALL;
/**
+ * Human: server side logic to exchange game data between server app and another player's app
+ *
* @author BetaSteward_at_googlemail.com, JayDi85
*/
public class HumanPlayer extends PlayerImpl {
diff --git a/Mage.Server.Plugins/pom.xml b/Mage.Server.Plugins/pom.xml
index f5ff42689c7..778b175b4c2 100644
--- a/Mage.Server.Plugins/pom.xml
+++ b/Mage.Server.Plugins/pom.xml
@@ -36,7 +36,6 @@
Mage.Game.OathbreakerFreeForAllMage.Game.TwoPlayerDuelMage.Player.AI
- Mage.Player.AIMinimaxMage.Player.AI.MAMage.Player.AIMCTSMage.Player.AI.DraftBot
diff --git a/Mage.Server/config/config.xml b/Mage.Server/config/config.xml
index 3e31310ac17..6e85074e835 100644
--- a/Mage.Server/config/config.xml
+++ b/Mage.Server/config/config.xml
@@ -66,7 +66,6 @@
/>
-
diff --git a/Mage.Server/pom.xml b/Mage.Server/pom.xml
index 28e9f587753..eb0d25843b8 100644
--- a/Mage.Server/pom.xml
+++ b/Mage.Server/pom.xml
@@ -89,12 +89,6 @@
${project.version}runtime
-
- ${project.groupId}
- mage-player-aiminimax
- ${project.version}
- runtime
- ${project.groupId}mage-player-ai-ma
diff --git a/Mage.Server/release/plugins/AIMinimax.properties b/Mage.Server/release/plugins/AIMinimax.properties
deleted file mode 100644
index 96b5480294c..00000000000
--- a/Mage.Server/release/plugins/AIMinimax.properties
+++ /dev/null
@@ -1,7 +0,0 @@
-maxDepth=10
-maxNodes=5000
-evaluatorLifeFactor=2
-evaluatorPermanentFactor=1
-evaluatorCreatureFactor=1
-evaluatorHandFactor=1
-maxThinkSeconds=30
\ No newline at end of file
diff --git a/Mage.Server/src/main/assembly/distribution.xml b/Mage.Server/src/main/assembly/distribution.xml
index 62ccfe10340..39a0c0bd9af 100644
--- a/Mage.Server/src/main/assembly/distribution.xml
+++ b/Mage.Server/src/main/assembly/distribution.xml
@@ -23,7 +23,6 @@
org.mage:mage-game-commanderduelorg.mage:mage-game-freeforallorg.mage:mage-game-twoplayerduel
- org.mage:mage-player-aiminimaxorg.mage:mage-player-ai-maorg.mage:mage-player-humanorg.mage:mage-tournament-boosterdraft
@@ -40,7 +39,6 @@
org.mage:mage-game-commanderduelorg.mage:mage-game-freeforallorg.mage:mage-game-twoplayerduel
- org.mage:mage-player-aiminimaxorg.mage:mage-player-ai-maorg.mage:mage-player-humanorg.mage:mage-tournament-boosterdraft
diff --git a/Mage.Tests/src/test/java/org/mage/test/mulligan/MulliganTestBase.java b/Mage.Tests/src/test/java/org/mage/test/mulligan/MulliganTestBase.java
index bed27a2ff81..40fb1c5a621 100644
--- a/Mage.Tests/src/test/java/org/mage/test/mulligan/MulliganTestBase.java
+++ b/Mage.Tests/src/test/java/org/mage/test/mulligan/MulliganTestBase.java
@@ -38,7 +38,7 @@ public class MulliganTestBase {
private final int freeMulligans;
private final List steps = new ArrayList<>();
- private PlayerProxy player1;
+ private MulliganStubPlayer player1;
public MulliganScenarioTest(MulliganType mulliganType, int freeMulligans) {
this.mulliganType = mulliganType;
@@ -73,13 +73,13 @@ public class MulliganTestBase {
options.skipInitShuffling = true;
game.setGameOptions(options);
- this.player1 = new PlayerProxy("p1", ONE);
+ this.player1 = new MulliganStubPlayer("p1", ONE);
player1.setSteps(steps);
Deck deck1 = generateDeck(player1.getId(), 40);
game.loadCards(deck1.getCards(), player1.getId());
game.addPlayer(player1, deck1);
- PlayerProxy player2 = new PlayerProxy("p2", ONE);
+ MulliganStubPlayer player2 = new MulliganStubPlayer("p2", ONE);
Deck deck2 = generateDeck(player2.getId(), 40);
game.loadCards(deck2.getCards(), player2.getId());
game.addPlayer(player2, deck2);
@@ -164,12 +164,12 @@ public class MulliganTestBase {
List discardBottom(int count);
}
- static class PlayerProxy extends StubPlayer {
+ static class MulliganStubPlayer extends StubPlayer {
private List steps = null;
private int current = 0;
- public PlayerProxy(String name, RangeOfInfluence range) {
+ public MulliganStubPlayer(String name, RangeOfInfluence range) {
super(name, range);
}
diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestComputerPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestComputerPlayer.java
index 3cc1c4b9389..d8bb28d0f08 100644
--- a/Mage.Tests/src/test/java/org/mage/test/player/TestComputerPlayer.java
+++ b/Mage.Tests/src/test/java/org/mage/test/player/TestComputerPlayer.java
@@ -11,10 +11,8 @@ import mage.target.Target;
import mage.target.TargetCard;
/**
- * @author JayDi85
- */
-
-/**
+ * AI: helper class for tests
+ *
* Mock class to inject test player support in the inner choice calls, e.g. in PlayerImpl. If you
* want to set up inner choices then override it here.
*
* If you implement set up of random results for tests (die roll, flip coin, etc) and want to support AI tests
* (same random results in simulated games) then override same methods in SimulatedPlayer2 too
+ *
+ * @author JayDi85
*/
-public class TestComputerPlayer extends ComputerPlayer {
+public final class TestComputerPlayer extends ComputerPlayer {
private TestPlayer testPlayerLink;
diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestComputerPlayer7.java b/Mage.Tests/src/test/java/org/mage/test/player/TestComputerPlayer7.java
index 44a4778c7c3..6934c4ecccd 100644
--- a/Mage.Tests/src/test/java/org/mage/test/player/TestComputerPlayer7.java
+++ b/Mage.Tests/src/test/java/org/mage/test/player/TestComputerPlayer7.java
@@ -11,12 +11,14 @@ import mage.target.Target;
import mage.target.TargetCard;
/**
+ * AI: helper class for tests
+ *
* Copied-pasted methods from TestComputerPlayer, see docs in there
*
* @author JayDi85
*/
-public class TestComputerPlayer7 extends ComputerPlayer7 {
+public final class TestComputerPlayer7 extends ComputerPlayer7 {
private TestPlayer testPlayerLink;
diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestComputerPlayerMonteCarlo.java b/Mage.Tests/src/test/java/org/mage/test/player/TestComputerPlayerMonteCarlo.java
index 986d362baa2..8c3d3a83527 100644
--- a/Mage.Tests/src/test/java/org/mage/test/player/TestComputerPlayerMonteCarlo.java
+++ b/Mage.Tests/src/test/java/org/mage/test/player/TestComputerPlayerMonteCarlo.java
@@ -11,12 +11,14 @@ import mage.target.Target;
import mage.target.TargetCard;
/**
+ * AI: helper class for tests
+ *
* Copied-pasted methods from TestComputerPlayer, see docs in there
*
* @author JayDi85
*/
-public class TestComputerPlayerMonteCarlo extends ComputerPlayerMCTS {
+public final class TestComputerPlayerMonteCarlo extends ComputerPlayerMCTS {
private TestPlayer testPlayerLink;
diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java
index 6b5580b7f32..da07ec52407 100644
--- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java
+++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java
@@ -63,6 +63,8 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
+ * Basic implementation of testable player
+ *
* @author BetaSteward_at_googlemail.com
* @author Simown
* @author JayDi85
diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/PlayGameTest.java b/Mage.Tests/src/test/java/org/mage/test/serverside/PlayGameTest.java
deleted file mode 100644
index 656261dd37f..00000000000
--- a/Mage.Tests/src/test/java/org/mage/test/serverside/PlayGameTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package org.mage.test.serverside;
-
-import mage.cards.Card;
-import mage.cards.Sets;
-import mage.cards.decks.Deck;
-import mage.constants.ColoredManaSymbol;
-import mage.constants.MultiplayerAttackOption;
-import mage.constants.RangeOfInfluence;
-import mage.game.Game;
-import mage.game.GameException;
-import mage.game.GameOptions;
-import mage.game.TwoPlayerDuel;
-import mage.game.mulligan.MulliganType;
-import mage.player.ai.ComputerPlayer;
-import mage.players.Player;
-import mage.players.PlayerType;
-import mage.util.RandomUtil;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.mage.test.serverside.base.MageTestBase;
-
-import java.io.FileNotFoundException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Locale;
-
-/**
- * @author ayratn
- */
-public class PlayGameTest extends MageTestBase {
-
- private static final List colorChoices = new ArrayList<>(Arrays.asList("bu", "bg", "br", "bw", "ug", "ur", "uw", "gr", "gw", "rw", "bur", "buw", "bug", "brg", "brw", "bgw", "wur", "wug", "wrg", "rgu"));
- private static final int DECK_SIZE = 40;
-
- @Ignore
- @Test
- public void playOneGame() throws GameException, FileNotFoundException, IllegalArgumentException {
- Game game = new TwoPlayerDuel(MultiplayerAttackOption.LEFT, RangeOfInfluence.ALL, MulliganType.GAME_DEFAULT.getMulligan(0), 60, 20, 7);
-
- Player computerA = createPlayer("ComputerA", PlayerType.COMPUTER_MINIMAX_HYBRID);
-// Player playerA = createPlayer("ComputerA", "Computer - mad");
-// Deck deck = Deck.load(Sets.loadDeck("RB Aggro.dck"));
- Deck deck = generateRandomDeck();
-
- if (deck.getMaindeckCards().size() < DECK_SIZE) {
- throw new IllegalArgumentException("Couldn't load deck, deck size = " + deck.getMaindeckCards().size() + ", but must be " + DECK_SIZE);
- }
- game.addPlayer(computerA, deck);
- game.loadCards(deck.getCards(), computerA.getId());
-
- Player computerB = createPlayer("ComputerB", PlayerType.COMPUTER_MINIMAX_HYBRID);
-// Player playerB = createPlayer("ComputerB", "Computer - mad");
-// Deck deck2 = Deck.load(Sets.loadDeck("RB Aggro.dck"));
- Deck deck2 = generateRandomDeck();
- if (deck2.getMaindeckCards().size() < DECK_SIZE) {
- throw new IllegalArgumentException("Couldn't load deck, deck size = " + deck2.getMaindeckCards().size() + ", but must be " + DECK_SIZE);
- }
- game.addPlayer(computerB, deck2);
- game.loadCards(deck2.getCards(), computerB.getId());
-
-// parseScenario("scenario1.txt");
-// game.cheat(playerA.getId(), commandsA);
-// game.cheat(playerA.getId(), libraryCardsA, handCardsA, battlefieldCardsA, graveyardCardsA);
-// game.cheat(playerB.getId(), commandsB);
-// game.cheat(playerB.getId(), libraryCardsB, handCardsB, battlefieldCardsB, graveyardCardsB);
- //boolean testMode = false;
- boolean testMode = true;
-
- long t1 = System.nanoTime();
- GameOptions options = new GameOptions();
- options.testMode = true;
- game.setGameOptions(options);
- game.start(computerA.getId());
- long t2 = System.nanoTime();
-
- logger.info("Winner: " + game.getWinner());
- logger.info("Time: " + (t2 - t1) / 1000000 + " ms");
- /*if (!game.getWinner().equals("Player ComputerA is the winner")) {
- throw new RuntimeException("Lost :(");
- }*/
- }
-
- private Deck generateRandomDeck() {
- String selectedColors = colorChoices.get(RandomUtil.nextInt(colorChoices.size())).toUpperCase(Locale.ENGLISH);
- List allowedColors = new ArrayList<>();
- logger.info("Building deck with colors: " + selectedColors);
- for (int i = 0; i < selectedColors.length(); i++) {
- char c = selectedColors.charAt(i);
- allowedColors.add(ColoredManaSymbol.lookup(c));
- }
- List cardPool = Sets.generateRandomCardPool(45, allowedColors);
- return ComputerPlayer.buildDeck(DECK_SIZE, cardPool, allowedColors);
- }
-}
diff --git a/Mage.Tests/src/test/java/org/mage/test/serverside/tournament/SwissPairingMinimalWeightMatchingTest.java b/Mage.Tests/src/test/java/org/mage/test/serverside/tournament/SwissPairingMinimalWeightMatchingTest.java
index b144e00eb04..9ca1e968fb1 100644
--- a/Mage.Tests/src/test/java/org/mage/test/serverside/tournament/SwissPairingMinimalWeightMatchingTest.java
+++ b/Mage.Tests/src/test/java/org/mage/test/serverside/tournament/SwissPairingMinimalWeightMatchingTest.java
@@ -1,14 +1,16 @@
package org.mage.test.serverside.tournament;
+import mage.constants.RangeOfInfluence;
import mage.game.tournament.Round;
import mage.game.tournament.TournamentPairing;
import mage.game.tournament.TournamentPlayer;
import mage.game.tournament.pairing.RoundPairings;
import mage.game.tournament.pairing.SwissPairingMinimalWeightMatching;
+import mage.players.Player;
+import mage.players.StubPlayer;
import mage.util.RandomUtil;
import org.junit.Assert;
import org.junit.Test;
-import org.mage.test.stub.PlayerStub;
import org.mage.test.stub.TournamentStub;
import java.util.ArrayList;
@@ -21,15 +23,19 @@ import java.util.Set;
*/
public class SwissPairingMinimalWeightMatchingTest {
+ private Player createTourneyPlayer(int number) {
+ return new StubPlayer("Tourney player " + number, RangeOfInfluence.ALL);
+ }
+
@Test
public void FourPlayersSecondRoundTest() {
// 1 > 3
// 2 > 4
- TournamentPlayer player1 = new TournamentPlayer(new PlayerStub(), null);
- TournamentPlayer player2 = new TournamentPlayer(new PlayerStub(), null);
- TournamentPlayer player3 = new TournamentPlayer(new PlayerStub(), null);
- TournamentPlayer player4 = new TournamentPlayer(new PlayerStub(), null);
+ TournamentPlayer player1 = new TournamentPlayer(createTourneyPlayer(1), null);
+ TournamentPlayer player2 = new TournamentPlayer(createTourneyPlayer(2), null);
+ TournamentPlayer player3 = new TournamentPlayer(createTourneyPlayer(3), null);
+ TournamentPlayer player4 = new TournamentPlayer(createTourneyPlayer(3), null);
List players = new ArrayList<>();
players.add(player4);
players.add(player2);
@@ -68,10 +74,10 @@ public class SwissPairingMinimalWeightMatchingTest {
// 1 > 2
// 3 > 4
- TournamentPlayer player3 = new TournamentPlayer(new PlayerStub(), null);
- TournamentPlayer player2 = new TournamentPlayer(new PlayerStub(), null);
- TournamentPlayer player4 = new TournamentPlayer(new PlayerStub(), null);
- TournamentPlayer player1 = new TournamentPlayer(new PlayerStub(), null);
+ TournamentPlayer player3 = new TournamentPlayer(createTourneyPlayer(3), null);
+ TournamentPlayer player2 = new TournamentPlayer(createTourneyPlayer(2), null);
+ TournamentPlayer player4 = new TournamentPlayer(createTourneyPlayer(4), null);
+ TournamentPlayer player1 = new TournamentPlayer(createTourneyPlayer(1), null);
List players = new ArrayList<>();
players.add(player4);
players.add(player2);
@@ -116,10 +122,10 @@ public class SwissPairingMinimalWeightMatchingTest {
// 2 > 4
// 4 left the tournament
- TournamentPlayer player1 = new TournamentPlayer(new PlayerStub(), null);
- TournamentPlayer player2 = new TournamentPlayer(new PlayerStub(), null);
- TournamentPlayer player3 = new TournamentPlayer(new PlayerStub(), null);
- TournamentPlayer player4 = new TournamentPlayer(new PlayerStub(), null);
+ TournamentPlayer player1 = new TournamentPlayer(createTourneyPlayer(1), null);
+ TournamentPlayer player2 = new TournamentPlayer(createTourneyPlayer(2), null);
+ TournamentPlayer player3 = new TournamentPlayer(createTourneyPlayer(3), null);
+ TournamentPlayer player4 = new TournamentPlayer(createTourneyPlayer(4), null);
List players = new ArrayList<>();
//players.add(player4); -- player 4 is not active
players.add(player2);
@@ -159,11 +165,11 @@ public class SwissPairingMinimalWeightMatchingTest {
// 2 > 3
// 4
- TournamentPlayer player1 = new TournamentPlayer(new PlayerStub(), null);
- TournamentPlayer player2 = new TournamentPlayer(new PlayerStub(), null);
- TournamentPlayer player3 = new TournamentPlayer(new PlayerStub(), null);
- TournamentPlayer player4 = new TournamentPlayer(new PlayerStub(), null);
- TournamentPlayer player5 = new TournamentPlayer(new PlayerStub(), null);
+ TournamentPlayer player1 = new TournamentPlayer(createTourneyPlayer(1), null);
+ TournamentPlayer player2 = new TournamentPlayer(createTourneyPlayer(2), null);
+ TournamentPlayer player3 = new TournamentPlayer(createTourneyPlayer(3), null);
+ TournamentPlayer player4 = new TournamentPlayer(createTourneyPlayer(4), null);
+ TournamentPlayer player5 = new TournamentPlayer(createTourneyPlayer(5), null);
List players = new ArrayList<>();
players.add(player4);
players.add(player2);
@@ -214,11 +220,11 @@ public class SwissPairingMinimalWeightMatchingTest {
// 5 left the tournament
- TournamentPlayer player1 = new TournamentPlayer(new PlayerStub(), null);
- TournamentPlayer player2 = new TournamentPlayer(new PlayerStub(), null);
- TournamentPlayer player3 = new TournamentPlayer(new PlayerStub(), null);
- TournamentPlayer player4 = new TournamentPlayer(new PlayerStub(), null);
- TournamentPlayer player5 = new TournamentPlayer(new PlayerStub(), null);
+ TournamentPlayer player1 = new TournamentPlayer(createTourneyPlayer(1), null);
+ TournamentPlayer player2 = new TournamentPlayer(createTourneyPlayer(2), null);
+ TournamentPlayer player3 = new TournamentPlayer(createTourneyPlayer(3), null);
+ TournamentPlayer player4 = new TournamentPlayer(createTourneyPlayer(4), null);
+ TournamentPlayer player5 = new TournamentPlayer(createTourneyPlayer(5), null);
List players = new ArrayList<>();
//players.add(player5); -- player 5 is not active
players.add(player4);
@@ -268,7 +274,7 @@ public class SwissPairingMinimalWeightMatchingTest {
List players = new ArrayList<>();
for (int i = 0; i < playersCount; i++) {
- players.add(new TournamentPlayer(new PlayerStub(), null));
+ players.add(new TournamentPlayer(createTourneyPlayer(i + 1), null));
}
List playedPairs = new ArrayList<>();
diff --git a/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java b/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java
deleted file mode 100644
index 0b92f4f154c..00000000000
--- a/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java
+++ /dev/null
@@ -1,1466 +0,0 @@
-package org.mage.test.stub;
-
-import mage.ApprovingObject;
-import mage.MageIdentifier;
-import mage.MageObject;
-import mage.Mana;
-import mage.abilities.*;
-import mage.abilities.costs.AlternativeSourceCosts;
-import mage.abilities.costs.Cost;
-import mage.abilities.costs.Costs;
-import mage.abilities.costs.VariableCost;
-import mage.abilities.costs.mana.ManaCost;
-import mage.abilities.costs.mana.ManaCosts;
-import mage.abilities.mana.ManaOptions;
-import mage.cards.Card;
-import mage.cards.Cards;
-import mage.cards.decks.Deck;
-import mage.choices.Choice;
-import mage.constants.*;
-import mage.counters.Counter;
-import mage.counters.Counters;
-import mage.designations.Designation;
-import mage.designations.DesignationType;
-import mage.filter.FilterCard;
-import mage.filter.FilterMana;
-import mage.filter.FilterPermanent;
-import mage.game.Game;
-import mage.game.Graveyard;
-import mage.game.Table;
-import mage.game.combat.CombatGroup;
-import mage.game.draft.Draft;
-import mage.game.events.GameEvent;
-import mage.game.match.Match;
-import mage.game.match.MatchPlayer;
-import mage.game.permanent.Permanent;
-import mage.game.tournament.Tournament;
-import mage.players.Library;
-import mage.players.ManaPool;
-import mage.players.PlayableObjectsList;
-import mage.players.Player;
-import mage.players.net.UserData;
-import mage.target.Target;
-import mage.target.TargetAmount;
-import mage.target.TargetCard;
-import mage.target.common.TargetCardInLibrary;
-import mage.util.MultiAmountMessage;
-
-import java.io.Serializable;
-import java.util.*;
-
-/**
- * @author Quercitron
- */
-public class PlayerStub implements Player {
-
- private final UUID id = UUID.randomUUID();
-
- @Override
- public UUID getId() {
- return id;
- }
-
- @Override
- public boolean isHuman() {
- return false;
- }
-
- @Override
- public String getName() {
- return null;
- }
-
- @Override
- public String getLogName() {
- return null;
- }
-
- @Override
- public RangeOfInfluence getRange() {
- return null;
- }
-
- @Override
- public Library getLibrary() {
- return null;
- }
-
- @Override
- public Cards getSideboard() {
- return null;
- }
-
- @Override
- public Graveyard getGraveyard() {
- return null;
- }
-
- @Override
- public Abilities getAbilities() {
- return null;
- }
-
- @Override
- public void addAbility(Ability ability) {
-
- }
-
- @Override
- public Counters getCounters() {
- return null;
- }
-
- @Override
- public int getLife() {
- return 0;
- }
-
- @Override
- public void initLife(int life) {
-
- }
-
- @Override
- public void setLife(int life, Game game, Ability source) {
-
- }
-
- @Override
- public int loseLife(int amount, Game game, Ability source, boolean atCombat, UUID attackerId) {
- return 0;
- }
-
- @Override
- public int loseLife(int amount, Game game, Ability source, boolean atCombat) {
- return 0;
- }
-
- @Override
- public int gainLife(int amount, Game game, Ability source) {
- return 0;
- }
-
- @Override
- public void exchangeLife(Player player, Ability source, Game game) {
- }
-
- @Override
- public int damage(int damage, UUID attackerId, Ability source, Game game) {
- return 0;
- }
-
- @Override
- public int damage(int damage, Ability source, Game game) {
- return 0;
- }
-
- @Override
- public int damage(int damage, UUID attackerId, Ability source, Game game, boolean combatDamage, boolean preventable) {
- return 0;
- }
-
- @Override
- public int damage(int damage, UUID attackerId, Ability source, Game game, boolean combatDamage, boolean preventable, List appliedEffects) {
- return 0;
- }
-
- @Override
- public boolean isCanLoseLife() {
- return false;
- }
-
- @Override
- public void setCanLoseLife(boolean canLoseLife) {
-
- }
-
- @Override
- public void setCanGainLife(boolean canGainLife) {
-
- }
-
- @Override
- public boolean isCanGainLife() {
- return false;
- }
-
- @Override
- public void setPayLifeCostLevel(PayLifeCostLevel playLifeCostLevel) {
- }
-
- @Override
- public PayLifeCostLevel getPayLifeCostLevel() {
- return PayLifeCostLevel.none;
- }
-
- @Override
- public boolean canPayLifeCost(Ability ability) {
- return false;
- }
-
- @Override
- public void setCanPaySacrificeCostFilter(FilterPermanent filter) {
- }
-
- @Override
- public FilterPermanent getSacrificeCostFilter() {
- return null;
- }
-
- @Override
- public boolean canPaySacrificeCost(Permanent permanent, Ability source, UUID controllerId, Game game) {
- return false;
- }
-
- @Override
- public void setLifeTotalCanChange(boolean lifeTotalCanChange) {
-
- }
-
- @Override
- public boolean isLifeTotalCanChange() {
- return false;
- }
-
- @Override
- public void setLoseByZeroOrLessLife(boolean loseByZeroOrLessLife) {
-
- }
-
- @Override
- public boolean canLoseByZeroOrLessLife() {
- return false;
- }
-
- @Override
- public void setPlayCardsFromGraveyard(boolean playCardsFromGraveyard) {
-
- }
-
- @Override
- public boolean canPlayCardsFromGraveyard() {
- return false;
- }
-
- @Override
- public void setDrawsOnOpponentsTurn(boolean drawsOnOpponentsTurn) {
-
- }
-
- @Override
- public boolean isDrawsOnOpponentsTurn() {
- return false;
- }
-
- @Override
- public List getAlternativeSourceCosts() {
- return null;
- }
-
- @Override
- public Cards getHand() {
- return null;
- }
-
- @Override
- public void incrementLandsPlayed() {
- }
-
- @Override
- public void resetLandsPlayed() {
- }
-
- @Override
- public int getLandsPlayed() {
- return 0;
- }
-
- @Override
- public int getLandsPerTurn() {
- return 0;
- }
-
- @Override
- public void setLandsPerTurn(int landsPerTurn) {
-
- }
-
- @Override
- public int getMaxHandSize() {
- return 0;
- }
-
- @Override
- public void setMaxHandSize(int maxHandSize) {
-
- }
-
- @Override
- public int getMaxAttackedBy() {
- return 0;
- }
-
- @Override
- public void setMaxAttackedBy(int maxAttackedBy) {
-
- }
-
- @Override
- public boolean isPassed() {
- return false;
- }
-
- @Override
- public void pass(Game game) {
-
- }
-
- @Override
- public void resetPassed() {
-
- }
-
- @Override
- public void resetPlayerPassedActions() {
-
- }
-
- @Override
- public boolean getPassedTurn() {
- return false;
- }
-
- @Override
- public boolean getPassedUntilEndOfTurn() {
- return false;
- }
-
- @Override
- public boolean getPassedUntilNextMain() {
- return false;
- }
-
- @Override
- public boolean getPassedUntilStackResolved() {
- return false;
- }
-
- @Override
- public boolean getPassedAllTurns() {
- return false;
- }
-
- @Override
- public boolean getPassedUntilEndStepBeforeMyTurn() {
- return false;
- }
-
- @Override
- public AbilityType getJustActivatedType() {
- return null;
- }
-
- @Override
- public void setJustActivatedType(AbilityType abilityType) {
-
- }
-
- @Override
- public boolean hasLost() {
- return false;
- }
-
- @Override
- public boolean hasWon() {
- return false;
- }
-
- @Override
- public boolean hasQuit() {
- return false;
- }
-
- @Override
- public void quit(Game game) {
-
- }
-
- @Override
- public boolean hasTimerTimeout() {
- return false;
- }
-
- @Override
- public void timerTimeout(Game game) {
-
- }
-
- @Override
- public boolean hasIdleTimeout() {
- return false;
- }
-
- @Override
- public void idleTimeout(Game game) {
-
- }
-
- @Override
- public boolean hasLeft() {
- return false;
- }
-
- @Override
- public boolean isInGame() {
- return false;
- }
-
- @Override
- public boolean canRespond() {
- return false;
- }
-
- @Override
- public ManaPool getManaPool() {
- return null;
- }
-
- @Override
- public Set getInRange() {
- return null;
- }
-
- @Override
- public boolean isTopCardRevealed() {
- return false;
- }
-
- @Override
- public void setTopCardRevealed(boolean topCardRevealed) {
-
- }
-
- @Override
- public UserData getUserData() {
- return null;
- }
-
- @Override
- public void setUserData(UserData userData) {
-
- }
-
- @Override
- public boolean canLose(Game game) {
- return false;
- }
-
- @Override
- public boolean autoLoseGame() {
- return false;
- }
-
- @Override
- public Set getPlayersUnderYourControl() {
- return null;
- }
-
- @Override
- public void controlPlayersTurn(Game game, UUID playerUnderControlId, String info) {
-
- }
-
- @Override
- public void setTurnControlledBy(UUID playerId) {
-
- }
-
- @Override
- public UUID getTurnControlledBy() {
- return null;
- }
-
- @Override
- public void resetOtherTurnsControlled() {
-
- }
-
- @Override
- public boolean isGameUnderControl() {
- return false;
- }
-
- @Override
- public void setGameUnderYourControl(boolean value) {
-
- }
-
- @Override
- public boolean isTestsMode() {
- return false;
- }
-
- @Override
- public void setTestMode(boolean value) {
-
- }
-
- @Override
- public void addAction(String action) {
-
- }
-
- @Override
- public int getActionCount() {
- return 0;
- }
-
- @Override
- public void setAllowBadMoves(boolean allowBadMoves) {
-
- }
-
- @Override
- public void init(Game game) {
-
- }
-
- @Override
- public void useDeck(Deck deck, Game game) {
-
- }
-
- @Override
- public void reset() {
-
- }
-
- @Override
- public void shuffleLibrary(Ability source, Game game) {
-
- }
-
- @Override
- public int drawCards(int num, Ability source, Game game) {
- return 0;
- }
-
- @Override
- public int drawCards(int num, Ability source, Game game, GameEvent event) {
- return 0;
- }
-
- @Override
- public boolean cast(SpellAbility ability, Game game, boolean noMana, ApprovingObject approvingObject) {
- return false;
- }
-
- @Override
- public boolean removeFromHand(Card card, Game game) {
- return false;
- }
-
- @Override
- public boolean removeFromBattlefield(Permanent permanent, Ability source, Game game) {
- return false;
- }
-
- @Override
- public boolean putInGraveyard(Card card, Game game) {
- return false;
- }
-
- @Override
- public boolean removeFromGraveyard(Card card, Game game) {
- return false;
- }
-
- @Override
- public boolean removeFromLibrary(Card card, Game game) {
- return false;
- }
-
- @Override
- public boolean searchLibrary(TargetCardInLibrary target, Ability source, Game game) {
- return false;
- }
-
- @Override
- public boolean searchLibrary(TargetCardInLibrary target, Ability source, Game game, UUID targetPlayerId) {
- return false;
- }
-
- @Override
- public boolean seekCard(FilterCard filter, Ability source, Game game) {
- return false;
- }
-
- @Override
- public void lookAtAllLibraries(Ability source, Game game) {
- }
-
- @Override
- public boolean canPlayLand() {
- return false;
- }
-
- @Override
- public boolean playCard(Card card, Game game, boolean noMana, ApprovingObject approvingObject) {
- return false;
- }
-
- @Override
- public boolean playLand(Card card, Game game, boolean ignoreTiming) {
- return false;
- }
-
- @Override
- public boolean activateAbility(ActivatedAbility ability, Game game) {
- return false;
- }
-
- @Override
- public boolean triggerAbility(TriggeredAbility ability, Game game) {
- return false;
- }
-
- @Override
- public boolean canBeTargetedBy(MageObject source, UUID sourceControllerId, Game game) {
- return false;
- }
-
- @Override
- public boolean hasProtectionFrom(MageObject source, Game game) {
- return false;
- }
-
- @Override
- public boolean flipCoin(Ability source, Game game, boolean winnable) {
- return false;
- }
-
- @Override
- public boolean flipCoinResult(Game game) {
- return false;
- }
-
- @Override
- public List rollDice(Outcome outcome, Ability source, Game game, int numSides, int numDice, int ignoreLowestAmount) {
- return null;
- }
-
- @Override
- public int rollDieResult(int sides, Game game) {
- return 1;
- }
-
- @Override
- public Cards discard(Cards cards, boolean payForCost, Ability source, Game game) {
- return null;
- }
-
- @Override
- public Card discardOne(boolean random, boolean payForCost, Ability source, Game game) {
- return null;
- }
-
- @Override
- public Cards discard(int amount, boolean random, boolean payForCost, Ability source, Game game) {
- return null;
- }
-
- @Override
- public Cards discard(int minAmount, int maxAmount, boolean payForCost, Ability source, Game game) {
- return null;
- }
-
- @Override
- public void discardToMax(Game game) {
-
- }
-
- @Override
- public boolean discard(Card card, boolean payForCost, Ability source, Game game) {
- return false;
- }
-
- @Override
- public void lost(Game game) {
-
- }
-
- @Override
- public void lostForced(Game game) {
-
- }
-
- @Override
- public void won(Game game) {
-
- }
-
- @Override
- public void leave() {
-
- }
-
- @Override
- public void concede(Game game) {
-
- }
-
- @Override
- public void abort() {
-
- }
-
- @Override
- public void signalPlayerConcede() {
-
- }
-
- @Override
- public void signalPlayerCheat() {
-
- }
-
- @Override
- public void abortReset() {
-
- }
-
- @Override
- public void skip() {
-
- }
-
- @Override
- public void sendPlayerAction(PlayerAction passPriorityAction, Game game, Object data) {
-
- }
-
- @Override
- public int getStoredBookmark() {
- return 0;
- }
-
- @Override
- public void setStoredBookmark(int bookmark) {
-
- }
-
- @Override
- public void resetStoredBookmark(Game game) {
-
- }
-
- @Override
- public void revealCards(Ability source, Cards cards, Game game) {
-
- }
-
- @Override
- public void revealCards(String name, Cards cards, Game game) {
-
- }
-
- @Override
- public void revealCards(Ability source, String name, Cards cards, Game game) {
-
- }
-
- @Override
- public void revealCards(String name, Cards cards, Game game, boolean postToLog) {
-
- }
-
- @Override
- public void revealCards(Ability source, String name, Cards cards, Game game, boolean postToLog) {
-
- }
-
- @Override
- public void lookAtCards(String name, Card card, Game game) {
-
- }
-
- @Override
- public void lookAtCards(String name, Cards cards, Game game) {
-
- }
-
- @Override
- public void lookAtCards(Ability source, String name, Cards cards, Game game) {
-
- }
-
- @Override
- public Player copy() {
- return null;
- }
-
- @Override
- public void restore(Player player) {
-
- }
-
- @Override
- public void setResponseString(String responseString) {
-
- }
-
- @Override
- public void setResponseUUID(UUID responseUUID) {
-
- }
-
- @Override
- public void setResponseBoolean(Boolean responseBoolean) {
-
- }
-
- @Override
- public void setResponseInteger(Integer data) {
-
- }
-
- @Override
- public void setResponseManaType(UUID manaTypePlayerId, ManaType responseManaType) {
-
- }
-
- @Override
- public boolean priority(Game game) {
- return false;
- }
-
- @Override
- public boolean choose(Outcome outcome, Target target, Ability source, Game game) {
- return false;
- }
-
- @Override
- public boolean choose(Outcome outcome, Target target, Ability source, Game game, Map options) {
- return false;
- }
-
- @Override
- public boolean choose(Outcome outcome, Cards cards, TargetCard target, Ability source, Game game) {
- return false;
- }
-
- @Override
- public boolean chooseTarget(Outcome outcome, Target target, Ability source, Game game) {
- return false;
- }
-
- @Override
- public boolean chooseTarget(Outcome outcome, Cards cards, TargetCard target, Ability source, Game game) {
- return false;
- }
-
- @Override
- public boolean chooseTargetAmount(Outcome outcome, TargetAmount target, Ability source, Game game) {
- return false;
- }
-
- @Override
- public boolean chooseMulligan(Game game) {
- return false;
- }
-
- @Override
- public boolean chooseUse(Outcome outcome, String message, Ability source, Game game) {
- return false;
- }
-
- @Override
- public boolean chooseUse(Outcome outcome, String message, String secondMessage, String trueText, String falseText, Ability source, Game game) {
- return false;
- }
-
- @Override
- public boolean choose(Outcome outcome, Choice choice, Game game) {
- return false;
- }
-
- @Override
- public boolean choosePile(Outcome outcome, String message, List extends Card> pile1, List extends Card> pile2, Game game) {
- return false;
- }
-
- @Override
- public boolean playMana(Ability ability, ManaCost unpaid, String promptText, Game game) {
- return false;
- }
-
- @Override
- public boolean putCardsOnBottomOfLibrary(Card card, Game game, Ability source, boolean anyOrder) {
- return false;
- }
-
- @Override
- public boolean putCardsOnBottomOfLibrary(Cards cards, Game game, Ability source, boolean anyOrder) {
- return false;
- }
-
- @Override
- public boolean putCardsOnTopOfLibrary(Cards cards, Game game, Ability source, boolean anyOrder) {
- return false;
- }
-
- @Override
- public boolean putCardsOnTopOfLibrary(Card card, Game game, Ability source, boolean anyOrder) {
- return false;
- }
-
- @Override
- public boolean shuffleCardsToLibrary(Cards cards, Game game, Ability source) {
- return false;
- }
-
- @Override
- public boolean shuffleCardsToLibrary(Card card, Game game, Ability source) {
- return false;
- }
-
- @Override
- public boolean putCardOnTopXOfLibrary(Card card, Game game, Ability source, int xFromTheTop, boolean withName) {
- return true;
- }
-
- @Override
- public int announceXMana(int min, int max, int multiplier, String message, Game game, Ability ability) {
- return min;
- }
-
- @Override
- public int announceXCost(int min, int max, String message, Game game, Ability ability, VariableCost variableCost) {
- return min;
- }
-
- @Override
- public int chooseReplacementEffect(Map abilityMap, Game game) {
- return 0;
- }
-
- @Override
- public TriggeredAbility chooseTriggeredAbility(List abilities, Game game) {
- return null;
- }
-
- @Override
- public Mode chooseMode(Modes modes, Ability source, Game game) {
- return null;
- }
-
- @Override
- public void selectAttackers(Game game, UUID attackingPlayerId) {
-
- }
-
- @Override
- public void selectBlockers(Ability source, Game game, UUID defendingPlayerId) {
-
- }
-
- @Override
- public UUID chooseAttackerOrder(List attacker, Game game) {
- return null;
- }
-
- @Override
- public UUID chooseBlockerOrder(List blockers, CombatGroup combatGroup, List blockerOrder, Game game) {
- return null;
- }
-
- @Override
- public void assignDamage(int damage, List targets, String singleTargetName, UUID attackerId, Ability source, Game game) {
-
- }
-
- @Override
- public int getAmount(int min, int max, String message, Game game) {
- return 0;
- }
-
- @Override
- public List getMultiAmountWithIndividualConstraints(Outcome outcome, List messages,
- int min, int max, MultiAmountType type, Game game) {
- return null;
- }
-
- @Override
- public void sideboard(Match match, Deck deck) {
-
- }
-
- @Override
- public void construct(Tournament tournament, Deck deck) {
-
- }
-
- @Override
- public void pickCard(List cards, Deck deck, Draft draft) {
-
- }
-
- @Override
- public void declareAttacker(UUID attackerId, UUID defenderId, Game game, boolean allowUndo) {
-
- }
-
- @Override
- public void declareBlocker(UUID defenderId, UUID blockerId, UUID attackerId, Game game) {
-
- }
-
- @Override
- public void declareBlocker(UUID defenderId, UUID blockerId, UUID attackerId, Game game, boolean allowUndo) {
-
- }
-
- @Override
- public List getAvailableAttackers(Game game) {
- return null;
- }
-
- @Override
- public List getAvailableAttackers(UUID defenderId, Game game) {
- return null;
- }
-
- @Override
- public List getAvailableBlockers(Game game) {
- return null;
- }
-
- @Override
- public void beginTurn(Game game) {
-
- }
-
- @Override
- public void endOfTurn(Game game) {
-
- }
-
- @Override
- public void phasing(Game game) {
-
- }
-
- @Override
- public void untap(Game game) {
-
- }
-
- @Override
- public void updateRange(Game game) {
-
- }
-
- @Override
- public ManaOptions getManaAvailable(Game game) {
- return null;
- }
-
- @Override
- public void addAvailableTriggeredMana(List availableTriggeredMan) {
-
- }
-
- @Override
- public List> getAvailableTriggeredMana() {
- return null;
- }
-
- @Override
- public int announceXMana(int min, int max, String message, Game game, Ability ability) {
- return 0;
- }
-
- @Override
- public List getPlayable(Game game, boolean hidden) {
- return null;
- }
-
- @Override
- public List getPlayableOptions(Ability ability, Game game) {
- return null;
- }
-
- @Override
- public PlayableObjectsList getPlayableObjects(Game game, Zone zone) {
- return null;
- }
-
- @Override
- public LinkedHashMap getPlayableActivatedAbilities(MageObject object, Zone zone, Game game) {
- return null;
- }
-
- @Override
- public boolean addCounters(Counter counter, UUID playerAddingCounters, Ability source, Game game) {
- return true;
- }
-
- @Override
- public void removeCounters(String name, int amount, Ability source, Game game) {
-
- }
-
- @Override
- public List getAttachments() {
- return null;
- }
-
- @Override
- public boolean addAttachment(UUID permanentId, Ability source, Game game) {
- return false;
- }
-
- @Override
- public boolean removeAttachment(Permanent permanent, Ability source, Game game) {
- return false;
- }
-
- @Override
- public void becomesActivePlayer() {
-
- }
-
- @Override
- public int getTurns() {
- return 0;
- }
-
- @Override
- public boolean lookAtFaceDownCard(Card card, Game game, int abilitiesToActivate) {
- return false;
- }
-
- @Override
- public void setPriorityTimeLeft(int timeLeft) {
-
- }
-
- @Override
- public int getPriorityTimeLeft() {
- return 0;
- }
-
- @Override
- public void setBufferTimeLeft(int timeLeft) {
-
- }
-
- @Override
- public int getBufferTimeLeft() {
- return 0;
- }
-
- @Override
- public void setReachedNextTurnAfterLeaving(boolean reachedNextTurnAfterLeaving) {
-
- }
-
- @Override
- public boolean hasReachedNextTurnAfterLeaving() {
- return false;
- }
-
- @Override
- public boolean canJoinTable(Table table) {
- return false;
- }
-
- @Override
- public void addCommanderId(UUID commanderId) {
-
- }
-
- @Override
- public Set getCommandersIds() {
- return null;
- }
-
- @Override
- public boolean moveCards(Card card, Zone toZone, Ability source, Game game) {
- return false;
- }
-
- @Override
- public boolean moveCards(Card card, Zone toZone, Ability source, Game game, boolean tapped, boolean faceDown, boolean byOwner, List appliedEffects) {
- return false;
- }
-
- @Override
- public boolean moveCards(Cards cards, Zone toZone, Ability source, Game game) {
- return false;
- }
-
- @Override
- public boolean moveCards(Set extends Card> cards, Zone toZone, Ability source, Game game) {
- return false;
- }
-
- @Override
- public boolean moveCards(Set extends Card> cards, Zone toZone, Ability source, Game game, boolean tapped, boolean faceDown, boolean byOwner, List appliedEffects) {
- return false;
- }
-
- @Override
- public boolean moveCardsToExile(Card card, Ability source, Game game, boolean withName, UUID exileId, String exileZoneName) {
- return false;
- }
-
- @Override
- public boolean moveCardsToExile(Set cards, Ability source, Game game, boolean withName, UUID exileId, String exileZoneName) {
- return false;
- }
-
- @Override
- public boolean moveCardToHandWithInfo(Card card, Ability source, Game game, boolean withName) {
- return false;
- }
-
- @Override
- public boolean moveCardsToHandWithInfo(Cards cards, Ability source, Game game, boolean withName) {
- return false;
- }
-
- @Override
- public boolean moveCardToExileWithInfo(Card card, UUID exileId, String exileName, Ability source, Game game, Zone fromZone, boolean withName) {
- return false;
- }
-
- @Override
- public boolean moveCardToGraveyardWithInfo(Card card, Ability source, Game game, Zone fromZone) {
- return false;
- }
-
- @Override
- public Set moveCardsToGraveyardWithInfo(Set extends Card> cards, Ability source, Game game, Zone fromZone) {
- return null;
- }
-
- @Override
- public boolean moveCardToLibraryWithInfo(Card card, Ability source, Game game, Zone fromZone, boolean toTop, boolean withName) {
- return false;
- }
-
- @Override
- public boolean moveCardToCommandWithInfo(Card card, Ability source, Game game, Zone fromZone) {
- return false;
- }
-
- @Override
- public Cards millCards(int toMill, Ability source, Game game) {
- return null;
- }
-
- @Override
- public boolean hasOpponent(UUID playerToCheckId, Game game) {
- return false;
- }
-
- @Override
- public void cleanUpOnMatchEnd() {
-
- }
-
- @Override
- public Map> getCastSourceIdWithAlternateMana() {
- return null;
- }
-
- @Override
- public void setCastSourceIdWithAlternateMana(UUID sourceId, ManaCosts manaCosts, Costs costs, MageIdentifier identifier) {
-
- }
-
- @Override
- public Map>> getCastSourceIdCosts() {
- return null;
- }
-
- @Override
- public Map>> getCastSourceIdManaCosts() {
- return null;
- }
-
- @Override
- public void clearCastSourceIdManaCosts() {
-
- }
-
- @Override
- public void addPermissionToShowHandCards(UUID watcherUserId) {
-
- }
-
- @Override
- public boolean hasUserPermissionToSeeHand(UUID userId) {
- return false;
- }
-
- @Override
- public void revokePermissionToSeeHandCards() {
-
- }
-
- @Override
- public boolean isPlayerAllowedToRequestHand(UUID gameId, UUID requesterPlayerId) {
- return false;
- }
-
- @Override
- public void addPlayerToRequestedHandList(UUID gameId, UUID requesterPlayerId) {
- //
- }
-
- @Override
- public Set getUsersAllowedToSeeHandCards() {
- return null;
- }
-
- @Override
- public boolean isInPayManaMode() {
- return false;
- }
-
- @Override
- public void setMatchPlayer(MatchPlayer matchPlayer) {
-
- }
-
- @Override
- public MatchPlayer getMatchPlayer() {
- return null;
- }
-
- @Override
- public boolean scry(int value, Ability source, Game game) {
- return false;
- }
-
- @Override
- public SurveilResult doSurveil(int value, Ability source, Game game) {
- return SurveilResult.noSurveil();
- }
-
- @Override
- public boolean addTargets(Ability ability, Game game) {
- return false;
- }
-
- @Override
- public String getHistory() {
- return "";
- }
-
- @Override
- public boolean hasDrew() {
- return false;
- }
-
- @Override
- public void drew(Game game) {
-
- }
-
- @Override
- public boolean hasDesignation(DesignationType designationName) {
- return false;
- }
-
- @Override
- public void addDesignation(Designation designation) {
-
- }
-
- @Override
- public List getDesignations() {
- return null;
- }
-
- @Override
- public PlanarDieRollResult rollPlanarDie(Outcome outcome, Ability source, Game game, int numberChaosSides, int numberPlanarSides) {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- @Override
- public List getTurnControllers() {
- throw new UnsupportedOperationException("Not supported yet.");
- }
-
- @Override
- public void setGameUnderYourControl(boolean value, boolean fullRestore) {
-
- }
-
- @Override
- public void setPayManaMode(boolean payManaMode) {
-
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
-
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- Player obj = (Player) o;
- if (this.getId() == null || obj.getId() == null) {
- return false;
- }
-
- return this.getId().equals(obj.getId());
- }
-
- @Override
- public int hashCode() {
- int hash = 5;
- hash = 41 * hash + Objects.hashCode(this.id);
- return hash;
- }
-
- @Override
- public void addPhyrexianToColors(FilterMana colors) {
-
- }
-
- @Override
- public FilterMana getPhyrexianColors() {
- return (new FilterMana());
- }
-
- @Override
- public Permanent getRingBearer(Game game) {
- return null;
- }
-
- @Override
- public void chooseRingBearer(Game game) {
- }
-
- @Override
- public UserData getControllingPlayersUserData(Game game) {
- return null;
- }
-
- @Override
- public SpellAbility chooseAbilityForCast(Card card, Game game, boolean noMana) {
- return card.getSpellAbility();
- }
-
- @Override
- public ActivatedAbility chooseLandOrSpellAbility(Card card, Game game, boolean noMana) {
- return card.getSpellAbility();
- }
-}
diff --git a/Mage/src/main/java/mage/game/match/MatchImpl.java b/Mage/src/main/java/mage/game/match/MatchImpl.java
index 6deb8f1d1e1..98ae8b21dd9 100644
--- a/Mage/src/main/java/mage/game/match/MatchImpl.java
+++ b/Mage/src/main/java/mage/game/match/MatchImpl.java
@@ -199,7 +199,7 @@ public abstract class MatchImpl implements Match {
matchPlayer.getPlayer().init(game);
game.loadCards(matchPlayer.getDeck().getCards(), matchPlayer.getPlayer().getId());
game.loadCards(matchPlayer.getDeck().getSideboard(), matchPlayer.getPlayer().getId());
- game.addPlayer(matchPlayer.getPlayer(), matchPlayer.getDeck());
+ game.addPlayer(matchPlayer.getPlayer(), matchPlayer.getDeck()); // TODO: keeps old player?!
// time limits
matchPlayer.getPlayer().setBufferTimeLeft(options.getMatchBufferTime().getBufferSecs());
if (games.isEmpty()) {
diff --git a/Mage/src/main/java/mage/players/PlayerType.java b/Mage/src/main/java/mage/players/PlayerType.java
index 2f8c36e6106..75bd6058227 100644
--- a/Mage/src/main/java/mage/players/PlayerType.java
+++ b/Mage/src/main/java/mage/players/PlayerType.java
@@ -1,16 +1,19 @@
package mage.players;
/**
- * Created by IGOUDT on 2-4-2017.
+ * Server: all possible player types
+ *
+ * Warning, do not change description - it must be same with config.xml file
+ *
+ * @author IGOUDT
*/
public enum PlayerType {
HUMAN("Human"),
COMPUTER_DRAFT_BOT("Computer - draftbot"),
- COMPUTER_MINIMAX_HYBRID("Computer - minimax hybrid"),
COMPUTER_MONTE_CARLO("Computer - monte carlo"),
COMPUTER_MAD("Computer - mad");
- String description;
+ final String description;
PlayerType(String description) {
this.description = description;
@@ -27,6 +30,6 @@ public enum PlayerType {
return type;
}
}
- throw new IllegalArgumentException(String.format("PlayerType (%s) is not configured", description));
+ throw new IllegalArgumentException(String.format("PlayerType (%s) is not configured in server's config.xml", description));
}
}
diff --git a/Mage/src/main/java/mage/players/StubPlayer.java b/Mage/src/main/java/mage/players/StubPlayer.java
index 0cef8efa61b..67af4945a16 100644
--- a/Mage/src/main/java/mage/players/StubPlayer.java
+++ b/Mage/src/main/java/mage/players/StubPlayer.java
@@ -35,7 +35,10 @@ import java.util.UUID;
import static com.google.common.collect.Iterables.getOnlyElement;
-public class StubPlayer extends PlayerImpl implements Player {
+/**
+ * Empty player, do nothing, used for tests only
+ */
+public class StubPlayer extends PlayerImpl {
@Override
public boolean choose(Outcome outcome, Target target, Ability source, Game game) {
@@ -209,7 +212,7 @@ public class StubPlayer extends PlayerImpl implements Player {
@Override
public List getMultiAmountWithIndividualConstraints(Outcome outcome, List messages,
- int min, int max, MultiAmountType type, Game game) {
+ int min, int max, MultiAmountType type, Game game) {
return null;
}
@@ -227,10 +230,10 @@ public class StubPlayer extends PlayerImpl implements Player {
public void pickCard(List cards, Deck deck, Draft draft) {
}
-
+
@Override
public void addPhyrexianToColors(FilterMana colors) {
-
+
}
@Override