remove extraneous whitespace
parent
cd385a4be8
commit
64368e1b9a
|
@ -12,7 +12,7 @@ import magic.ui.GameController;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
public class DeckStrCal {
|
public class DeckStrCal {
|
||||||
|
|
||||||
private static int games = 10;
|
private static int games = 10;
|
||||||
private static int repeat = 1;
|
private static int repeat = 1;
|
||||||
private static int str1 = 6;
|
private static int str1 = 6;
|
||||||
|
@ -95,14 +95,14 @@ public class DeckStrCal {
|
||||||
validArgs = false;
|
validArgs = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deck1.length() == 0) {
|
if (deck1.length() == 0) {
|
||||||
System.err.println("Using player profile to generate deck 1");
|
System.err.println("Using player profile to generate deck 1");
|
||||||
} else if (!(new File(deck1)).exists()) {
|
} else if (!(new File(deck1)).exists()) {
|
||||||
System.err.println("Error: file " + deck1 + " does not exist");
|
System.err.println("Error: file " + deck1 + " does not exist");
|
||||||
validArgs = false;
|
validArgs = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deck2.length() == 0) {
|
if (deck2.length() == 0) {
|
||||||
System.err.println("Using player profile to generate deck 2");
|
System.err.println("Using player profile to generate deck 2");
|
||||||
} else if (!(new File(deck2)).exists()) {
|
} else if (!(new File(deck2)).exists()) {
|
||||||
|
@ -130,7 +130,7 @@ public class DeckStrCal {
|
||||||
testDuel.initialize();
|
testDuel.initialize();
|
||||||
testDuel.setDifficulty(0, str1);
|
testDuel.setDifficulty(0, str1);
|
||||||
testDuel.setDifficulty(1, str2);
|
testDuel.setDifficulty(1, str2);
|
||||||
|
|
||||||
// Set the AI
|
// Set the AI
|
||||||
testDuel.setAIs(new MagicAI[]{ai1.getAI(), ai2.getAI()});
|
testDuel.setAIs(new MagicAI[]{ai1.getAI(), ai2.getAI()});
|
||||||
testDuel.getPlayer(0).setArtificial(true);
|
testDuel.getPlayer(0).setArtificial(true);
|
||||||
|
@ -138,7 +138,7 @@ public class DeckStrCal {
|
||||||
|
|
||||||
// Set the deck.
|
// Set the deck.
|
||||||
if (deck1.length() > 0) {
|
if (deck1.length() > 0) {
|
||||||
DeckUtils.loadDeck(deck1, testDuel.getPlayer(0));
|
DeckUtils.loadDeck(deck1, testDuel.getPlayer(0));
|
||||||
}
|
}
|
||||||
if (deck2.length() > 0) {
|
if (deck2.length() > 0) {
|
||||||
DeckUtils.loadDeck(deck2, testDuel.getPlayer(1));
|
DeckUtils.loadDeck(deck2, testDuel.getPlayer(1));
|
||||||
|
@ -146,11 +146,11 @@ public class DeckStrCal {
|
||||||
|
|
||||||
return testDuel;
|
return testDuel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(final String[] args) {
|
public static void main(final String[] args) {
|
||||||
// setup the handler for any uncaught exception
|
// setup the handler for any uncaught exception
|
||||||
Thread.setDefaultUncaughtExceptionHandler(new magic.model.MagicGameReport());
|
Thread.setDefaultUncaughtExceptionHandler(new magic.model.MagicGameReport());
|
||||||
|
|
||||||
if (!parseArguments(args)) {
|
if (!parseArguments(args)) {
|
||||||
System.err.println("Usage: java -cp <path to Magarena.jar/exe> magic.DeckStrCal --deck1 <.dec file> --deck2 <.dec file> [options]");
|
System.err.println("Usage: java -cp <path to Magarena.jar/exe> magic.DeckStrCal --deck1 <.dec file> --deck2 <.dec file> [options]");
|
||||||
System.err.println("Options:");
|
System.err.println("Options:");
|
||||||
|
@ -160,7 +160,7 @@ public class DeckStrCal {
|
||||||
System.err.println("--games <1-*> (number of games to play, default 10)");
|
System.err.println("--games <1-*> (number of games to play, default 10)");
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load cards and cubes.
|
// Load cards and cubes.
|
||||||
MagicMain.initializeEngine();
|
MagicMain.initializeEngine();
|
||||||
|
|
||||||
|
@ -168,10 +168,10 @@ public class DeckStrCal {
|
||||||
runDuel();
|
runDuel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void runDuel() {
|
private static void runDuel() {
|
||||||
final MagicDuel testDuel = setupDuel();
|
final MagicDuel testDuel = setupDuel();
|
||||||
|
|
||||||
System.out.println(
|
System.out.println(
|
||||||
"#deck1" +
|
"#deck1" +
|
||||||
"\tai1" +
|
"\tai1" +
|
||||||
|
@ -181,15 +181,15 @@ public class DeckStrCal {
|
||||||
"\tstr2" +
|
"\tstr2" +
|
||||||
"\tgames" +
|
"\tgames" +
|
||||||
"\td1win"+
|
"\td1win"+
|
||||||
"\td1lose"
|
"\td1lose"
|
||||||
);
|
);
|
||||||
|
|
||||||
int played = 0;
|
int played = 0;
|
||||||
while (!testDuel.isFinished()) {
|
while (!testDuel.isFinished()) {
|
||||||
final MagicGame game=testDuel.nextGame(false);
|
final MagicGame game=testDuel.nextGame(false);
|
||||||
game.setArtificial(true);
|
game.setArtificial(true);
|
||||||
final GameController controller=new GameController(game);
|
final GameController controller=new GameController(game);
|
||||||
|
|
||||||
//maximum duration of a game is 60 minutes
|
//maximum duration of a game is 60 minutes
|
||||||
controller.setMaxTestGameDuration(3600000);
|
controller.setMaxTestGameDuration(3600000);
|
||||||
|
|
||||||
|
@ -199,13 +199,13 @@ public class DeckStrCal {
|
||||||
deck1 + "\t" +
|
deck1 + "\t" +
|
||||||
ai1 + "\t" +
|
ai1 + "\t" +
|
||||||
str1 + "\t" +
|
str1 + "\t" +
|
||||||
deck2 + "\t" +
|
deck2 + "\t" +
|
||||||
ai2 + "\t" +
|
ai2 + "\t" +
|
||||||
str2 + "\t" +
|
str2 + "\t" +
|
||||||
testDuel.getGamesTotal() + "\t" +
|
testDuel.getGamesTotal() + "\t" +
|
||||||
testDuel.getGamesWon() + "\t" +
|
testDuel.getGamesWon() + "\t" +
|
||||||
(testDuel.getGamesPlayed() - testDuel.getGamesWon())
|
(testDuel.getGamesPlayed() - testDuel.getGamesWon())
|
||||||
);
|
);
|
||||||
played = testDuel.getGamesPlayed();
|
played = testDuel.getGamesPlayed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,12 +213,12 @@ public class DeckStrCal {
|
||||||
deck1 + "\t" +
|
deck1 + "\t" +
|
||||||
ai1 + "\t" +
|
ai1 + "\t" +
|
||||||
str1 + "\t" +
|
str1 + "\t" +
|
||||||
deck2 + "\t" +
|
deck2 + "\t" +
|
||||||
ai2 + "\t" +
|
ai2 + "\t" +
|
||||||
str2 + "\t" +
|
str2 + "\t" +
|
||||||
testDuel.getGamesTotal() + "\t" +
|
testDuel.getGamesTotal() + "\t" +
|
||||||
testDuel.getGamesWon() + "\t" +
|
testDuel.getGamesWon() + "\t" +
|
||||||
(testDuel.getGamesPlayed() - testDuel.getGamesWon())
|
(testDuel.getGamesPlayed() - testDuel.getGamesWon())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,14 +43,14 @@ import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p><code>GraphicsUtilities</code> contains a set of tools to perform
|
* <p><code>GraphicsUtilities</code> contains a set of tools to perform
|
||||||
* common graphics operations easily.
|
* common graphics operations easily.
|
||||||
*
|
*
|
||||||
* @author Romain Guy <romain.guy@mac.com>
|
* @author Romain Guy <romain.guy@mac.com>
|
||||||
* @author rbair
|
* @author rbair
|
||||||
* @author Karl Schaefer
|
* @author Karl Schaefer
|
||||||
*/
|
*/
|
||||||
public class GraphicsUtilities {
|
public class GraphicsUtilities {
|
||||||
|
|
||||||
public static BufferedImage scale(
|
public static BufferedImage scale(
|
||||||
final BufferedImage img,
|
final BufferedImage img,
|
||||||
final int targetWidth,
|
final int targetWidth,
|
||||||
|
@ -59,10 +59,10 @@ public class GraphicsUtilities {
|
||||||
return img;
|
return img;
|
||||||
} else {
|
} else {
|
||||||
return scale(
|
return scale(
|
||||||
img,
|
img,
|
||||||
targetWidth,
|
targetWidth,
|
||||||
targetHeight,
|
targetHeight,
|
||||||
RenderingHints.VALUE_INTERPOLATION_BILINEAR,
|
RenderingHints.VALUE_INTERPOLATION_BILINEAR,
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ public class GraphicsUtilities {
|
||||||
w = targetWidth;
|
w = targetWidth;
|
||||||
h = targetHeight;
|
h = targetHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (higherQuality && w > targetWidth) {
|
if (higherQuality && w > targetWidth) {
|
||||||
w /= 2;
|
w /= 2;
|
||||||
|
|
|
@ -15,27 +15,27 @@ import javax.swing.UIManager.LookAndFeelInfo;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
public class MagicMain {
|
public class MagicMain {
|
||||||
|
|
||||||
private static final String GAME_FOLDER = "Magarena";
|
private static final String GAME_FOLDER = "Magarena";
|
||||||
private static final String MODS_PATH = "mods";
|
private static final String MODS_PATH = "mods";
|
||||||
private static final String SCRIPTS_PATH = "scripts";
|
private static final String SCRIPTS_PATH = "scripts";
|
||||||
private static final String GAME_PATH =
|
private static final String GAME_PATH =
|
||||||
(System.getProperty("magarena.dir") != null ?
|
(System.getProperty("magarena.dir") != null ?
|
||||||
System.getProperty("magarena.dir") :
|
System.getProperty("magarena.dir") :
|
||||||
System.getProperty("user.dir")) +
|
System.getProperty("user.dir")) +
|
||||||
File.separatorChar +
|
File.separatorChar +
|
||||||
GAME_FOLDER;
|
GAME_FOLDER;
|
||||||
|
|
||||||
public static void main(final String[] args) {
|
public static void main(final String[] args) {
|
||||||
// setup the handler for any uncaught exception
|
// setup the handler for any uncaught exception
|
||||||
Thread.setDefaultUncaughtExceptionHandler(new magic.model.MagicGameReport());
|
Thread.setDefaultUncaughtExceptionHandler(new magic.model.MagicGameReport());
|
||||||
|
|
||||||
// setup the game log
|
// setup the game log
|
||||||
MagicGameLog.initialize();
|
MagicGameLog.initialize();
|
||||||
|
|
||||||
// show the data folder being used
|
// show the data folder being used
|
||||||
System.err.println("Data folder : "+GAME_PATH);
|
System.err.println("Data folder : "+GAME_PATH);
|
||||||
|
|
||||||
// try to set the look and feel
|
// try to set the look and feel
|
||||||
try {
|
try {
|
||||||
for (final LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
|
for (final LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
|
||||||
|
@ -44,17 +44,17 @@ public class MagicMain {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// customize nimbus look
|
// customize nimbus look
|
||||||
UIManager.getLookAndFeelDefaults().put("Table.showGrid", true);
|
UIManager.getLookAndFeelDefaults().put("Table.showGrid", true);
|
||||||
// removes hardcoded border
|
// removes hardcoded border
|
||||||
UIManager.getLookAndFeelDefaults().put("ScrollPane[Enabled].borderPainter", null);
|
UIManager.getLookAndFeelDefaults().put("ScrollPane[Enabled].borderPainter", null);
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
System.err.println("Unable to set look and feel. Probably missing the latest version of Java 6.");
|
System.err.println("Unable to set look and feel. Probably missing the latest version of Java 6.");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
final long start_time = System.currentTimeMillis();
|
final long start_time = System.currentTimeMillis();
|
||||||
initialize();
|
initialize();
|
||||||
final double duration = (double)(System.currentTimeMillis() - start_time) / 1000;
|
final double duration = (double)(System.currentTimeMillis() - start_time) / 1000;
|
||||||
|
@ -64,21 +64,21 @@ public class MagicMain {
|
||||||
new MagicFrame();
|
new MagicFrame();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String getGamePath() {
|
public static String getGamePath() {
|
||||||
return GAME_PATH;
|
return GAME_PATH;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getGameFolder() {
|
public static String getGameFolder() {
|
||||||
return GAME_FOLDER;
|
return GAME_FOLDER;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getModsPath() {
|
public static String getModsPath() {
|
||||||
return getGamePath()+File.separatorChar+MODS_PATH;
|
return getGamePath()+File.separatorChar+MODS_PATH;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getScriptsPath() {
|
public static String getScriptsPath() {
|
||||||
return getGamePath()+File.separatorChar+SCRIPTS_PATH;
|
return getGamePath()+File.separatorChar+SCRIPTS_PATH;
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ public class MagicMain {
|
||||||
KeywordDefinitions.getInstance().loadKeywordDefinitions();
|
KeywordDefinitions.getInstance().loadKeywordDefinitions();
|
||||||
DeckGenerators.getInstance().loadDeckGenerators();
|
DeckGenerators.getInstance().loadDeckGenerators();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void initialize() {
|
private static void initialize() {
|
||||||
final File gamePathFile = new File(getGamePath());
|
final File gamePathFile = new File(getGamePath());
|
||||||
if (!gamePathFile.exists() && !gamePathFile.mkdir()) {
|
if (!gamePathFile.exists() && !gamePathFile.mkdir()) {
|
||||||
|
@ -101,7 +101,7 @@ public class MagicMain {
|
||||||
if (!modsPathFile.exists() && !modsPathFile.mkdir()) {
|
if (!modsPathFile.exists() && !modsPathFile.mkdir()) {
|
||||||
System.err.println("Unable to create directory " + getModsPath());
|
System.err.println("Unable to create directory " + getModsPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
DeckUtils.createDeckFolder();
|
DeckUtils.createDeckFolder();
|
||||||
History.createHistoryFolder();
|
History.createHistoryFolder();
|
||||||
initializeEngine();
|
initializeEngine();
|
||||||
|
|
|
@ -22,7 +22,7 @@ public class MagicTools {
|
||||||
System.out.println(name);
|
System.out.println(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void checkCards() {
|
private static void checkCards() {
|
||||||
final String[] filenames = new File(MagicMain.getGamePath(),"cards").list();
|
final String[] filenames = new File(MagicMain.getGamePath(),"cards").list();
|
||||||
final Set<MagicCardDefinition> remaining = new HashSet<MagicCardDefinition>(CardDefinitions.getCards());
|
final Set<MagicCardDefinition> remaining = new HashSet<MagicCardDefinition>(CardDefinitions.getCards());
|
||||||
|
@ -37,7 +37,7 @@ public class MagicTools {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(final String[] args) {
|
public static void main(final String[] args) {
|
||||||
MagicMain.initializeEngine();
|
MagicMain.initializeEngine();
|
||||||
checkCards();
|
checkCards();
|
||||||
|
|
|
@ -5,15 +5,15 @@ import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <h3>MersenneTwister and MersenneTwisterFast</h3>
|
* <h3>MersenneTwister and MersenneTwisterFast</h3>
|
||||||
* <p><b>Version 17</b>, based on version MT199937(99/10/29)
|
* <p><b>Version 17</b>, based on version MT199937(99/10/29)
|
||||||
* of the Mersenne Twister algorithm found at
|
* of the Mersenne Twister algorithm found at
|
||||||
* <a href="http://www.math.keio.ac.jp/matumoto/emt.html">
|
* <a href="http://www.math.keio.ac.jp/matumoto/emt.html">
|
||||||
* The Mersenne Twister Home Page</a>, with the initialization
|
* The Mersenne Twister Home Page</a>, with the initialization
|
||||||
* improved using the new 2002/1/26 initialization algorithm
|
* improved using the new 2002/1/26 initialization algorithm
|
||||||
* By Sean Luke, October 2004.
|
* By Sean Luke, October 2004.
|
||||||
*
|
*
|
||||||
* <p><b>MersenneTwister</b> is a drop-in subclass replacement
|
* <p><b>MersenneTwister</b> is a drop-in subclass replacement
|
||||||
* for java.util.Random. It is properly synchronized and
|
* for java.util.Random. It is properly synchronized and
|
||||||
* can be used in a multithreaded environment. On modern VMs such
|
* can be used in a multithreaded environment. On modern VMs such
|
||||||
|
@ -57,9 +57,9 @@ import java.io.Serializable;
|
||||||
* as it presently makes no difference in the speed, correctness, or results of the
|
* as it presently makes no difference in the speed, correctness, or results of the
|
||||||
* algorithm.
|
* algorithm.
|
||||||
*
|
*
|
||||||
* <p><b>Changes Since V13:</b> clone() method CloneNotSupportedException removed.
|
* <p><b>Changes Since V13:</b> clone() method CloneNotSupportedException removed.
|
||||||
*
|
*
|
||||||
* <p><b>Changes Since V12:</b> clone() method added.
|
* <p><b>Changes Since V12:</b> clone() method added.
|
||||||
*
|
*
|
||||||
* <p><b>Changes Since V11:</b> stateEquals(...) method added. MersenneTwisterFast
|
* <p><b>Changes Since V11:</b> stateEquals(...) method added. MersenneTwisterFast
|
||||||
* is equal to other MersenneTwisterFasts with identical state; likewise
|
* is equal to other MersenneTwisterFasts with identical state; likewise
|
||||||
|
@ -91,7 +91,7 @@ import java.io.Serializable;
|
||||||
* in speed to the point where it is faster than MersenneTwister but slower
|
* in speed to the point where it is faster than MersenneTwister but slower
|
||||||
* than MersenneTwisterFast (which should be the case, as it's a less complex
|
* than MersenneTwisterFast (which should be the case, as it's a less complex
|
||||||
* algorithm but is synchronized).
|
* algorithm but is synchronized).
|
||||||
*
|
*
|
||||||
* <p><b>Changes Since V5:</b> New empty constructor made to work the same
|
* <p><b>Changes Since V5:</b> New empty constructor made to work the same
|
||||||
* as java.util.Random -- namely, it seeds based on the current time in
|
* as java.util.Random -- namely, it seeds based on the current time in
|
||||||
* milliseconds.
|
* milliseconds.
|
||||||
|
@ -100,17 +100,17 @@ import java.io.Serializable;
|
||||||
* (see <a href="http://www.math.keio.ac.jp/matumoto/MT2002/emt19937ar.html"</a>
|
* (see <a href="http://www.math.keio.ac.jp/matumoto/MT2002/emt19937ar.html"</a>
|
||||||
* http://www.math.keio.ac.jp/matumoto/MT2002/emt19937ar.html</a>)
|
* http://www.math.keio.ac.jp/matumoto/MT2002/emt19937ar.html</a>)
|
||||||
*
|
*
|
||||||
* <p>The MersenneTwister code is based on standard MT19937 C/C++
|
* <p>The MersenneTwister code is based on standard MT19937 C/C++
|
||||||
* code by Takuji Nishimura,
|
* code by Takuji Nishimura,
|
||||||
* with suggestions from Topher Cooper and Marc Rieffel, July 1997.
|
* with suggestions from Topher Cooper and Marc Rieffel, July 1997.
|
||||||
* The code was originally translated into Java by Michael Lecuyer,
|
* The code was originally translated into Java by Michael Lecuyer,
|
||||||
* January 1999, and the original code is Copyright (c) 1999 by Michael Lecuyer.
|
* January 1999, and the original code is Copyright (c) 1999 by Michael Lecuyer.
|
||||||
*
|
*
|
||||||
* <h3>Java notes</h3>
|
* <h3>Java notes</h3>
|
||||||
*
|
*
|
||||||
* <p>This implementation implements the bug fixes made
|
* <p>This implementation implements the bug fixes made
|
||||||
* in Java 1.2's version of Random, which means it can be used with
|
* in Java 1.2's version of Random, which means it can be used with
|
||||||
* earlier versions of Java. See
|
* earlier versions of Java. See
|
||||||
* <a href="http://www.javasoft.com/products/jdk/1.2/docs/api/java/util/Random.html">
|
* <a href="http://www.javasoft.com/products/jdk/1.2/docs/api/java/util/Random.html">
|
||||||
* the JDK 1.2 java.util.Random documentation</a> for further documentation
|
* the JDK 1.2 java.util.Random documentation</a> for further documentation
|
||||||
* on the random-number generation contracts made. Additionally, there's
|
* on the random-number generation contracts made. Additionally, there's
|
||||||
|
@ -122,7 +122,7 @@ import java.io.Serializable;
|
||||||
* uses 48 bits. The Mersenne Twister instead uses 32 bits (int size).
|
* uses 48 bits. The Mersenne Twister instead uses 32 bits (int size).
|
||||||
* So it's best if your seed does not exceed the int range.
|
* So it's best if your seed does not exceed the int range.
|
||||||
*
|
*
|
||||||
* <p>MersenneTwister can be used reliably
|
* <p>MersenneTwister can be used reliably
|
||||||
* on JDK version 1.1.5 or above. Earlier Java versions have serious bugs in
|
* on JDK version 1.1.5 or above. Earlier Java versions have serious bugs in
|
||||||
* java.util.Random; only MersenneTwisterFast (and not MersenneTwister nor
|
* java.util.Random; only MersenneTwisterFast (and not MersenneTwister nor
|
||||||
* java.util.Random) should be used with them.
|
* java.util.Random) should be used with them.
|
||||||
|
@ -133,28 +133,28 @@ import java.io.Serializable;
|
||||||
* Portions copyright (c) 1993 by Michael Lecuyer. <br>
|
* Portions copyright (c) 1993 by Michael Lecuyer. <br>
|
||||||
* All rights reserved. <br>
|
* All rights reserved. <br>
|
||||||
*
|
*
|
||||||
* <p>Redistribution and use in source and binary forms, with or without
|
* <p>Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li> Redistributions of source code must retain the above copyright notice,
|
* <li> Redistributions of source code must retain the above copyright notice,
|
||||||
* this list of conditions and the following disclaimer.
|
* this list of conditions and the following disclaimer.
|
||||||
* <li> Redistributions in binary form must reproduce the above copyright notice,
|
* <li> Redistributions in binary form must reproduce the above copyright notice,
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
* and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
* <li> Neither the name of the copyright owners, their employers, nor the
|
* <li> Neither the name of the copyright owners, their employers, nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
* </ul>
|
* </ul>
|
||||||
* <p>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
* <p>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNERS OR CONTRIBUTORS BE
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNERS OR CONTRIBUTORS BE
|
||||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
* 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
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
@version 17
|
@version 17
|
||||||
|
@ -170,7 +170,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
{
|
{
|
||||||
// Serialization
|
// Serialization
|
||||||
private static final long serialVersionUID = -8219700664442619525L; // locked as of Version 15
|
private static final long serialVersionUID = -8219700664442619525L; // locked as of Version 15
|
||||||
|
|
||||||
// Period parameters
|
// Period parameters
|
||||||
private static final int N = 624;
|
private static final int N = 624;
|
||||||
private static final int M = 397;
|
private static final int M = 397;
|
||||||
|
@ -182,17 +182,17 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
// Tempering parameters
|
// Tempering parameters
|
||||||
private static final int TEMPERING_MASK_B = 0x9d2c5680;
|
private static final int TEMPERING_MASK_B = 0x9d2c5680;
|
||||||
private static final int TEMPERING_MASK_C = 0xefc60000;
|
private static final int TEMPERING_MASK_C = 0xefc60000;
|
||||||
|
|
||||||
private int[] mt; // the array for the state vector
|
private int[] mt; // the array for the state vector
|
||||||
private int mti; // mti==N+1 means mt[N] is not initialized
|
private int mti; // mti==N+1 means mt[N] is not initialized
|
||||||
private int[] mag01;
|
private int[] mag01;
|
||||||
|
|
||||||
// a good initial seed (of int size, though stored in a long)
|
// a good initial seed (of int size, though stored in a long)
|
||||||
//private static final long GOOD_SEED = 4357;
|
//private static final long GOOD_SEED = 4357;
|
||||||
|
|
||||||
private double __nextNextGaussian;
|
private double __nextNextGaussian;
|
||||||
private boolean __haveNextNextGaussian;
|
private boolean __haveNextNextGaussian;
|
||||||
|
|
||||||
/* We're overriding all internal data, to my knowledge, so this should be okay */
|
/* We're overriding all internal data, to my knowledge, so this should be okay */
|
||||||
public Object clone()
|
public Object clone()
|
||||||
{
|
{
|
||||||
|
@ -205,7 +205,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
}
|
}
|
||||||
catch (CloneNotSupportedException e) { throw new InternalError(); } // should never happen
|
catch (CloneNotSupportedException e) { throw new InternalError(); } // should never happen
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean stateEquals(final Object o)
|
public boolean stateEquals(final Object o)
|
||||||
{
|
{
|
||||||
if (o==this) return true;
|
if (o==this) return true;
|
||||||
|
@ -225,24 +225,24 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
{
|
{
|
||||||
int len = mt.length;
|
int len = mt.length;
|
||||||
for(int x=0;x<len;x++) mt[x] = stream.readInt();
|
for(int x=0;x<len;x++) mt[x] = stream.readInt();
|
||||||
|
|
||||||
len = mag01.length;
|
len = mag01.length;
|
||||||
for(int x=0;x<len;x++) mag01[x] = stream.readInt();
|
for(int x=0;x<len;x++) mag01[x] = stream.readInt();
|
||||||
|
|
||||||
mti = stream.readInt();
|
mti = stream.readInt();
|
||||||
__nextNextGaussian = stream.readDouble();
|
__nextNextGaussian = stream.readDouble();
|
||||||
__haveNextNextGaussian = stream.readBoolean();
|
__haveNextNextGaussian = stream.readBoolean();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Writes the entire state of the MersenneTwister RNG to the stream */
|
/** Writes the entire state of the MersenneTwister RNG to the stream */
|
||||||
public void writeState(final DataOutputStream stream) throws IOException
|
public void writeState(final DataOutputStream stream) throws IOException
|
||||||
{
|
{
|
||||||
int len = mt.length;
|
int len = mt.length;
|
||||||
for(int x=0;x<len;x++) stream.writeInt(mt[x]);
|
for(int x=0;x<len;x++) stream.writeInt(mt[x]);
|
||||||
|
|
||||||
len = mag01.length;
|
len = mag01.length;
|
||||||
for(int x=0;x<len;x++) stream.writeInt(mag01[x]);
|
for(int x=0;x<len;x++) stream.writeInt(mag01[x]);
|
||||||
|
|
||||||
stream.writeInt(mti);
|
stream.writeInt(mti);
|
||||||
stream.writeDouble(__nextNextGaussian);
|
stream.writeDouble(__nextNextGaussian);
|
||||||
stream.writeBoolean(__haveNextNextGaussian);
|
stream.writeBoolean(__haveNextNextGaussian);
|
||||||
|
@ -255,7 +255,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
{
|
{
|
||||||
this(System.currentTimeMillis());
|
this(System.currentTimeMillis());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor using a given seed. Though you pass this seed in
|
* Constructor using a given seed. Though you pass this seed in
|
||||||
* as a long, it's best to make sure it's actually an integer.
|
* as a long, it's best to make sure it's actually an integer.
|
||||||
|
@ -265,7 +265,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
{
|
{
|
||||||
setSeed(seed);
|
setSeed(seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor using an array of integers as seed.
|
* Constructor using an array of integers as seed.
|
||||||
|
@ -282,7 +282,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
/**
|
/**
|
||||||
* Initalize the pseudo random number generator. Don't
|
* Initalize the pseudo random number generator. Don't
|
||||||
* pass in a long that's bigger than an int (Mersenne Twister
|
* pass in a long that's bigger than an int (Mersenne Twister
|
||||||
* only uses the first 32 bits for its seed).
|
* only uses the first 32 bits for its seed).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
synchronized public void setSeed(final long seed)
|
synchronized public void setSeed(final long seed)
|
||||||
|
@ -292,16 +292,16 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
__haveNextNextGaussian = false;
|
__haveNextNextGaussian = false;
|
||||||
|
|
||||||
mt = new int[N];
|
mt = new int[N];
|
||||||
|
|
||||||
mag01 = new int[2];
|
mag01 = new int[2];
|
||||||
mag01[0] = 0x0;
|
mag01[0] = 0x0;
|
||||||
mag01[1] = MATRIX_A;
|
mag01[1] = MATRIX_A;
|
||||||
|
|
||||||
mt[0]= (int)(seed & 0xffffffff);
|
mt[0]= (int)(seed & 0xffffffff);
|
||||||
for (mti=1; mti<N; mti++)
|
for (mti=1; mti<N; mti++)
|
||||||
{
|
{
|
||||||
mt[mti] =
|
mt[mti] =
|
||||||
(1812433253 * (mt[mti-1] ^ (mt[mti-1] >>> 30)) + mti);
|
(1812433253 * (mt[mti-1] ^ (mt[mti-1] >>> 30)) + mti);
|
||||||
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
|
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
|
||||||
/* In the previous versions, MSBs of the seed affect */
|
/* In the previous versions, MSBs of the seed affect */
|
||||||
/* only MSBs of the array mt[]. */
|
/* only MSBs of the array mt[]. */
|
||||||
|
@ -327,7 +327,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
setSeed(19650218);
|
setSeed(19650218);
|
||||||
i=1; j=0;
|
i=1; j=0;
|
||||||
k = (array.length < N ? N : array.length);
|
k = (array.length < N ? N : array.length);
|
||||||
for (; k!=0; k--)
|
for (; k!=0; k--)
|
||||||
{
|
{
|
||||||
mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >>> 30)) * 1664525)) + array[j] + j; /* non linear */
|
mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >>> 30)) * 1664525)) + array[j] + j; /* non linear */
|
||||||
mt[i] &= 0xffffffff; /* for WORDSIZE > 32 machines */
|
mt[i] &= 0xffffffff; /* for WORDSIZE > 32 machines */
|
||||||
|
@ -336,30 +336,30 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
if (i>=N) { mt[0] = mt[N-1]; i=1; }
|
if (i>=N) { mt[0] = mt[N-1]; i=1; }
|
||||||
if (j>=array.length) j=0;
|
if (j>=array.length) j=0;
|
||||||
}
|
}
|
||||||
for (k=N-1; k!=0; k--)
|
for (k=N-1; k!=0; k--)
|
||||||
{
|
{
|
||||||
mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >>> 30)) * 1566083941)) - i; /* non linear */
|
mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >>> 30)) * 1566083941)) - i; /* non linear */
|
||||||
mt[i] &= 0xffffffff; /* for WORDSIZE > 32 machines */
|
mt[i] &= 0xffffffff; /* for WORDSIZE > 32 machines */
|
||||||
i++;
|
i++;
|
||||||
if (i>=N)
|
if (i>=N)
|
||||||
{
|
{
|
||||||
mt[0] = mt[N-1]; i=1;
|
mt[0] = mt[N-1]; i=1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mt[0] = 0x80000000; /* MSB is 1; assuring non-zero initial array */
|
mt[0] = 0x80000000; /* MSB is 1; assuring non-zero initial array */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public final int nextInt()
|
public final int nextInt()
|
||||||
{
|
{
|
||||||
int y;
|
int y;
|
||||||
|
|
||||||
if (mti >= N) // generate N words at one time
|
if (mti >= N) // generate N words at one time
|
||||||
{
|
{
|
||||||
int kk;
|
int kk;
|
||||||
final int[] mt = this.mt; // locals are slightly faster
|
final int[] mt = this.mt; // locals are slightly faster
|
||||||
final int[] mag01 = this.mag01; // locals are slightly faster
|
final int[] mag01 = this.mag01; // locals are slightly faster
|
||||||
|
|
||||||
for (kk = 0; kk < N - M; kk++)
|
for (kk = 0; kk < N - M; kk++)
|
||||||
{
|
{
|
||||||
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
||||||
|
@ -375,7 +375,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
|
|
||||||
mti = 0;
|
mti = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
y = mt[mti++];
|
y = mt[mti++];
|
||||||
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
||||||
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
||||||
|
@ -390,13 +390,13 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
public final short nextShort()
|
public final short nextShort()
|
||||||
{
|
{
|
||||||
int y;
|
int y;
|
||||||
|
|
||||||
if (mti >= N) // generate N words at one time
|
if (mti >= N) // generate N words at one time
|
||||||
{
|
{
|
||||||
int kk;
|
int kk;
|
||||||
final int[] mt = this.mt; // locals are slightly faster
|
final int[] mt = this.mt; // locals are slightly faster
|
||||||
final int[] mag01 = this.mag01; // locals are slightly faster
|
final int[] mag01 = this.mag01; // locals are slightly faster
|
||||||
|
|
||||||
for (kk = 0; kk < N - M; kk++)
|
for (kk = 0; kk < N - M; kk++)
|
||||||
{
|
{
|
||||||
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
||||||
|
@ -412,7 +412,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
|
|
||||||
mti = 0;
|
mti = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
y = mt[mti++];
|
y = mt[mti++];
|
||||||
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
||||||
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
||||||
|
@ -427,13 +427,13 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
public final char nextChar()
|
public final char nextChar()
|
||||||
{
|
{
|
||||||
int y;
|
int y;
|
||||||
|
|
||||||
if (mti >= N) // generate N words at one time
|
if (mti >= N) // generate N words at one time
|
||||||
{
|
{
|
||||||
int kk;
|
int kk;
|
||||||
final int[] mt = this.mt; // locals are slightly faster
|
final int[] mt = this.mt; // locals are slightly faster
|
||||||
final int[] mag01 = this.mag01; // locals are slightly faster
|
final int[] mag01 = this.mag01; // locals are slightly faster
|
||||||
|
|
||||||
for (kk = 0; kk < N - M; kk++)
|
for (kk = 0; kk < N - M; kk++)
|
||||||
{
|
{
|
||||||
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
||||||
|
@ -449,7 +449,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
|
|
||||||
mti = 0;
|
mti = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
y = mt[mti++];
|
y = mt[mti++];
|
||||||
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
||||||
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
||||||
|
@ -463,13 +463,13 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
public final boolean nextBoolean()
|
public final boolean nextBoolean()
|
||||||
{
|
{
|
||||||
int y;
|
int y;
|
||||||
|
|
||||||
if (mti >= N) // generate N words at one time
|
if (mti >= N) // generate N words at one time
|
||||||
{
|
{
|
||||||
int kk;
|
int kk;
|
||||||
final int[] mt = this.mt; // locals are slightly faster
|
final int[] mt = this.mt; // locals are slightly faster
|
||||||
final int[] mag01 = this.mag01; // locals are slightly faster
|
final int[] mag01 = this.mag01; // locals are slightly faster
|
||||||
|
|
||||||
for (kk = 0; kk < N - M; kk++)
|
for (kk = 0; kk < N - M; kk++)
|
||||||
{
|
{
|
||||||
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
||||||
|
@ -485,7 +485,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
|
|
||||||
mti = 0;
|
mti = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
y = mt[mti++];
|
y = mt[mti++];
|
||||||
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
||||||
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
||||||
|
@ -506,7 +506,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
public final boolean nextBoolean(final float probability)
|
public final boolean nextBoolean(final float probability)
|
||||||
{
|
{
|
||||||
int y;
|
int y;
|
||||||
|
|
||||||
if (probability < 0.0f || probability > 1.0f)
|
if (probability < 0.0f || probability > 1.0f)
|
||||||
throw new IllegalArgumentException ("probability must be between 0.0 and 1.0 inclusive.");
|
throw new IllegalArgumentException ("probability must be between 0.0 and 1.0 inclusive.");
|
||||||
if (probability==0.0f) return false; // fix half-open issues
|
if (probability==0.0f) return false; // fix half-open issues
|
||||||
|
@ -514,9 +514,9 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
if (mti >= N) // generate N words at one time
|
if (mti >= N) // generate N words at one time
|
||||||
{
|
{
|
||||||
int kk;
|
int kk;
|
||||||
final int[] mt = this.mt; // locals are slightly faster
|
final int[] mt = this.mt; // locals are slightly faster
|
||||||
final int[] mag01 = this.mag01; // locals are slightly faster
|
final int[] mag01 = this.mag01; // locals are slightly faster
|
||||||
|
|
||||||
for (kk = 0; kk < N - M; kk++)
|
for (kk = 0; kk < N - M; kk++)
|
||||||
{
|
{
|
||||||
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
||||||
|
@ -532,7 +532,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
|
|
||||||
mti = 0;
|
mti = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
y = mt[mti++];
|
y = mt[mti++];
|
||||||
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
||||||
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
||||||
|
@ -559,9 +559,9 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
if (mti >= N) // generate N words at one time
|
if (mti >= N) // generate N words at one time
|
||||||
{
|
{
|
||||||
int kk;
|
int kk;
|
||||||
final int[] mt = this.mt; // locals are slightly faster
|
final int[] mt = this.mt; // locals are slightly faster
|
||||||
final int[] mag01 = this.mag01; // locals are slightly faster
|
final int[] mag01 = this.mag01; // locals are slightly faster
|
||||||
|
|
||||||
for (kk = 0; kk < N - M; kk++)
|
for (kk = 0; kk < N - M; kk++)
|
||||||
{
|
{
|
||||||
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
||||||
|
@ -577,7 +577,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
|
|
||||||
mti = 0;
|
mti = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
y = mt[mti++];
|
y = mt[mti++];
|
||||||
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
||||||
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
||||||
|
@ -587,9 +587,9 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
if (mti >= N) // generate N words at one time
|
if (mti >= N) // generate N words at one time
|
||||||
{
|
{
|
||||||
int kk;
|
int kk;
|
||||||
final int[] mt = this.mt; // locals are slightly faster
|
final int[] mt = this.mt; // locals are slightly faster
|
||||||
final int[] mag01 = this.mag01; // locals are slightly faster
|
final int[] mag01 = this.mag01; // locals are slightly faster
|
||||||
|
|
||||||
for (kk = 0; kk < N - M; kk++)
|
for (kk = 0; kk < N - M; kk++)
|
||||||
{
|
{
|
||||||
z = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
z = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
||||||
|
@ -602,16 +602,16 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
}
|
}
|
||||||
z = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
z = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
||||||
mt[N-1] = mt[M-1] ^ (z >>> 1) ^ mag01[z & 0x1];
|
mt[N-1] = mt[M-1] ^ (z >>> 1) ^ mag01[z & 0x1];
|
||||||
|
|
||||||
mti = 0;
|
mti = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
z = mt[mti++];
|
z = mt[mti++];
|
||||||
z ^= z >>> 11; // TEMPERING_SHIFT_U(z)
|
z ^= z >>> 11; // TEMPERING_SHIFT_U(z)
|
||||||
z ^= (z << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(z)
|
z ^= (z << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(z)
|
||||||
z ^= (z << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(z)
|
z ^= (z << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(z)
|
||||||
z ^= (z >>> 18); // TEMPERING_SHIFT_L(z)
|
z ^= (z >>> 18); // TEMPERING_SHIFT_L(z)
|
||||||
|
|
||||||
/* derived from nextDouble documentation in jdk 1.2 docs, see top */
|
/* derived from nextDouble documentation in jdk 1.2 docs, see top */
|
||||||
return ((((long)(y >>> 6)) << 27) + (z >>> 5)) / (double)(1L << 53) < probability;
|
return ((((long)(y >>> 6)) << 27) + (z >>> 5)) / (double)(1L << 53) < probability;
|
||||||
}
|
}
|
||||||
|
@ -620,13 +620,13 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
public final byte nextByte()
|
public final byte nextByte()
|
||||||
{
|
{
|
||||||
int y;
|
int y;
|
||||||
|
|
||||||
if (mti >= N) // generate N words at one time
|
if (mti >= N) // generate N words at one time
|
||||||
{
|
{
|
||||||
int kk;
|
int kk;
|
||||||
final int[] mt = this.mt; // locals are slightly faster
|
final int[] mt = this.mt; // locals are slightly faster
|
||||||
final int[] mag01 = this.mag01; // locals are slightly faster
|
final int[] mag01 = this.mag01; // locals are slightly faster
|
||||||
|
|
||||||
for (kk = 0; kk < N - M; kk++)
|
for (kk = 0; kk < N - M; kk++)
|
||||||
{
|
{
|
||||||
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
||||||
|
@ -642,7 +642,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
|
|
||||||
mti = 0;
|
mti = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
y = mt[mti++];
|
y = mt[mti++];
|
||||||
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
||||||
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
||||||
|
@ -656,15 +656,15 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
public final void nextBytes(final byte[] bytes)
|
public final void nextBytes(final byte[] bytes)
|
||||||
{
|
{
|
||||||
int y;
|
int y;
|
||||||
|
|
||||||
for (int x=0;x<bytes.length;x++)
|
for (int x=0;x<bytes.length;x++)
|
||||||
{
|
{
|
||||||
if (mti >= N) // generate N words at one time
|
if (mti >= N) // generate N words at one time
|
||||||
{
|
{
|
||||||
int kk;
|
int kk;
|
||||||
final int[] mt = this.mt; // locals are slightly faster
|
final int[] mt = this.mt; // locals are slightly faster
|
||||||
final int[] mag01 = this.mag01; // locals are slightly faster
|
final int[] mag01 = this.mag01; // locals are slightly faster
|
||||||
|
|
||||||
for (kk = 0; kk < N - M; kk++)
|
for (kk = 0; kk < N - M; kk++)
|
||||||
{
|
{
|
||||||
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
||||||
|
@ -677,10 +677,10 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
}
|
}
|
||||||
y = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
y = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
||||||
mt[N-1] = mt[M-1] ^ (y >>> 1) ^ mag01[y & 0x1];
|
mt[N-1] = mt[M-1] ^ (y >>> 1) ^ mag01[y & 0x1];
|
||||||
|
|
||||||
mti = 0;
|
mti = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
y = mt[mti++];
|
y = mt[mti++];
|
||||||
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
||||||
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
||||||
|
@ -700,9 +700,9 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
if (mti >= N) // generate N words at one time
|
if (mti >= N) // generate N words at one time
|
||||||
{
|
{
|
||||||
int kk;
|
int kk;
|
||||||
final int[] mt = this.mt; // locals are slightly faster
|
final int[] mt = this.mt; // locals are slightly faster
|
||||||
final int[] mag01 = this.mag01; // locals are slightly faster
|
final int[] mag01 = this.mag01; // locals are slightly faster
|
||||||
|
|
||||||
for (kk = 0; kk < N - M; kk++)
|
for (kk = 0; kk < N - M; kk++)
|
||||||
{
|
{
|
||||||
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
||||||
|
@ -718,7 +718,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
|
|
||||||
mti = 0;
|
mti = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
y = mt[mti++];
|
y = mt[mti++];
|
||||||
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
||||||
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
||||||
|
@ -728,9 +728,9 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
if (mti >= N) // generate N words at one time
|
if (mti >= N) // generate N words at one time
|
||||||
{
|
{
|
||||||
int kk;
|
int kk;
|
||||||
final int[] mt = this.mt; // locals are slightly faster
|
final int[] mt = this.mt; // locals are slightly faster
|
||||||
final int[] mag01 = this.mag01; // locals are slightly faster
|
final int[] mag01 = this.mag01; // locals are slightly faster
|
||||||
|
|
||||||
for (kk = 0; kk < N - M; kk++)
|
for (kk = 0; kk < N - M; kk++)
|
||||||
{
|
{
|
||||||
z = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
z = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
||||||
|
@ -743,16 +743,16 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
}
|
}
|
||||||
z = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
z = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
||||||
mt[N-1] = mt[M-1] ^ (z >>> 1) ^ mag01[z & 0x1];
|
mt[N-1] = mt[M-1] ^ (z >>> 1) ^ mag01[z & 0x1];
|
||||||
|
|
||||||
mti = 0;
|
mti = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
z = mt[mti++];
|
z = mt[mti++];
|
||||||
z ^= z >>> 11; // TEMPERING_SHIFT_U(z)
|
z ^= z >>> 11; // TEMPERING_SHIFT_U(z)
|
||||||
z ^= (z << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(z)
|
z ^= (z << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(z)
|
||||||
z ^= (z << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(z)
|
z ^= (z << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(z)
|
||||||
z ^= (z >>> 18); // TEMPERING_SHIFT_L(z)
|
z ^= (z >>> 18); // TEMPERING_SHIFT_L(z)
|
||||||
|
|
||||||
return (((long)y) << 32) + (long)z;
|
return (((long)y) << 32) + (long)z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -764,19 +764,19 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
{
|
{
|
||||||
if (n<=0)
|
if (n<=0)
|
||||||
throw new IllegalArgumentException("n must be positive, got: " + n);
|
throw new IllegalArgumentException("n must be positive, got: " + n);
|
||||||
|
|
||||||
long bits, val;
|
long bits, val;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
int y;
|
int y;
|
||||||
int z;
|
int z;
|
||||||
|
|
||||||
if (mti >= N) // generate N words at one time
|
if (mti >= N) // generate N words at one time
|
||||||
{
|
{
|
||||||
int kk;
|
int kk;
|
||||||
final int[] mt = this.mt; // locals are slightly faster
|
final int[] mt = this.mt; // locals are slightly faster
|
||||||
final int[] mag01 = this.mag01; // locals are slightly faster
|
final int[] mag01 = this.mag01; // locals are slightly faster
|
||||||
|
|
||||||
for (kk = 0; kk < N - M; kk++)
|
for (kk = 0; kk < N - M; kk++)
|
||||||
{
|
{
|
||||||
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
||||||
|
@ -789,22 +789,22 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
}
|
}
|
||||||
y = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
y = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
||||||
mt[N-1] = mt[M-1] ^ (y >>> 1) ^ mag01[y & 0x1];
|
mt[N-1] = mt[M-1] ^ (y >>> 1) ^ mag01[y & 0x1];
|
||||||
|
|
||||||
mti = 0;
|
mti = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
y = mt[mti++];
|
y = mt[mti++];
|
||||||
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
||||||
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
||||||
y ^= (y << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(y)
|
y ^= (y << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(y)
|
||||||
y ^= (y >>> 18); // TEMPERING_SHIFT_L(y)
|
y ^= (y >>> 18); // TEMPERING_SHIFT_L(y)
|
||||||
|
|
||||||
if (mti >= N) // generate N words at one time
|
if (mti >= N) // generate N words at one time
|
||||||
{
|
{
|
||||||
int kk;
|
int kk;
|
||||||
final int[] mt = this.mt; // locals are slightly faster
|
final int[] mt = this.mt; // locals are slightly faster
|
||||||
final int[] mag01 = this.mag01; // locals are slightly faster
|
final int[] mag01 = this.mag01; // locals are slightly faster
|
||||||
|
|
||||||
for (kk = 0; kk < N - M; kk++)
|
for (kk = 0; kk < N - M; kk++)
|
||||||
{
|
{
|
||||||
z = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
z = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
||||||
|
@ -817,16 +817,16 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
}
|
}
|
||||||
z = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
z = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
||||||
mt[N-1] = mt[M-1] ^ (z >>> 1) ^ mag01[z & 0x1];
|
mt[N-1] = mt[M-1] ^ (z >>> 1) ^ mag01[z & 0x1];
|
||||||
|
|
||||||
mti = 0;
|
mti = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
z = mt[mti++];
|
z = mt[mti++];
|
||||||
z ^= z >>> 11; // TEMPERING_SHIFT_U(z)
|
z ^= z >>> 11; // TEMPERING_SHIFT_U(z)
|
||||||
z ^= (z << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(z)
|
z ^= (z << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(z)
|
||||||
z ^= (z << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(z)
|
z ^= (z << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(z)
|
||||||
z ^= (z >>> 18); // TEMPERING_SHIFT_L(z)
|
z ^= (z >>> 18); // TEMPERING_SHIFT_L(z)
|
||||||
|
|
||||||
bits = (((((long)y) << 32) + (long)z) >>> 1);
|
bits = (((((long)y) << 32) + (long)z) >>> 1);
|
||||||
val = bits % n;
|
val = bits % n;
|
||||||
} while (bits - val + (n-1) < 0);
|
} while (bits - val + (n-1) < 0);
|
||||||
|
@ -843,9 +843,9 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
if (mti >= N) // generate N words at one time
|
if (mti >= N) // generate N words at one time
|
||||||
{
|
{
|
||||||
int kk;
|
int kk;
|
||||||
final int[] mt = this.mt; // locals are slightly faster
|
final int[] mt = this.mt; // locals are slightly faster
|
||||||
final int[] mag01 = this.mag01; // locals are slightly faster
|
final int[] mag01 = this.mag01; // locals are slightly faster
|
||||||
|
|
||||||
for (kk = 0; kk < N - M; kk++)
|
for (kk = 0; kk < N - M; kk++)
|
||||||
{
|
{
|
||||||
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
||||||
|
@ -861,7 +861,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
|
|
||||||
mti = 0;
|
mti = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
y = mt[mti++];
|
y = mt[mti++];
|
||||||
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
||||||
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
||||||
|
@ -871,9 +871,9 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
if (mti >= N) // generate N words at one time
|
if (mti >= N) // generate N words at one time
|
||||||
{
|
{
|
||||||
int kk;
|
int kk;
|
||||||
final int[] mt = this.mt; // locals are slightly faster
|
final int[] mt = this.mt; // locals are slightly faster
|
||||||
final int[] mag01 = this.mag01; // locals are slightly faster
|
final int[] mag01 = this.mag01; // locals are slightly faster
|
||||||
|
|
||||||
for (kk = 0; kk < N - M; kk++)
|
for (kk = 0; kk < N - M; kk++)
|
||||||
{
|
{
|
||||||
z = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
z = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
||||||
|
@ -886,16 +886,16 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
}
|
}
|
||||||
z = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
z = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
||||||
mt[N-1] = mt[M-1] ^ (z >>> 1) ^ mag01[z & 0x1];
|
mt[N-1] = mt[M-1] ^ (z >>> 1) ^ mag01[z & 0x1];
|
||||||
|
|
||||||
mti = 0;
|
mti = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
z = mt[mti++];
|
z = mt[mti++];
|
||||||
z ^= z >>> 11; // TEMPERING_SHIFT_U(z)
|
z ^= z >>> 11; // TEMPERING_SHIFT_U(z)
|
||||||
z ^= (z << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(z)
|
z ^= (z << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(z)
|
||||||
z ^= (z << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(z)
|
z ^= (z << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(z)
|
||||||
z ^= (z >>> 18); // TEMPERING_SHIFT_L(z)
|
z ^= (z >>> 18); // TEMPERING_SHIFT_L(z)
|
||||||
|
|
||||||
/* derived from nextDouble documentation in jdk 1.2 docs, see top */
|
/* derived from nextDouble documentation in jdk 1.2 docs, see top */
|
||||||
return ((((long)(y >>> 6)) << 27) + (z >>> 5)) / (double)(1L << 53);
|
return ((((long)(y >>> 6)) << 27) + (z >>> 5)) / (double)(1L << 53);
|
||||||
}
|
}
|
||||||
|
@ -911,7 +911,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
<tr><td>nextDouble(false, true)<td>(0.0, 1.0]
|
<tr><td>nextDouble(false, true)<td>(0.0, 1.0]
|
||||||
<tr><td>nextDouble(true, true)<td>[0.0, 1.0]
|
<tr><td>nextDouble(true, true)<td>[0.0, 1.0]
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<p>This version preserves all possible random values in the double range.
|
<p>This version preserves all possible random values in the double range.
|
||||||
*/
|
*/
|
||||||
public double nextDouble(final boolean includeZero, final boolean includeOne)
|
public double nextDouble(final boolean includeZero, final boolean includeOne)
|
||||||
|
@ -921,7 +921,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
{
|
{
|
||||||
d = nextDouble(); // grab a value, initially from half-open [0.0, 1.0)
|
d = nextDouble(); // grab a value, initially from half-open [0.0, 1.0)
|
||||||
if (includeOne && nextBoolean()) d += 1.0; // if includeOne, with 1/2 probability, push to [1.0, 2.0)
|
if (includeOne && nextBoolean()) d += 1.0; // if includeOne, with 1/2 probability, push to [1.0, 2.0)
|
||||||
}
|
}
|
||||||
while ( (d > 1.0) || // everything above 1.0 is always invalid
|
while ( (d > 1.0) || // everything above 1.0 is always invalid
|
||||||
(!includeZero && d == 0.0)); // if we're not including zero, 0.0 is invalid
|
(!includeZero && d == 0.0)); // if we're not including zero, 0.0 is invalid
|
||||||
return d;
|
return d;
|
||||||
|
@ -935,23 +935,23 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
{
|
{
|
||||||
__haveNextNextGaussian = false;
|
__haveNextNextGaussian = false;
|
||||||
return __nextNextGaussian;
|
return __nextNextGaussian;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
double v1, v2, s;
|
double v1, v2, s;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
int y;
|
int y;
|
||||||
int z;
|
int z;
|
||||||
int a;
|
int a;
|
||||||
int b;
|
int b;
|
||||||
|
|
||||||
if (mti >= N) // generate N words at one time
|
if (mti >= N) // generate N words at one time
|
||||||
{
|
{
|
||||||
int kk;
|
int kk;
|
||||||
final int[] mt = this.mt; // locals are slightly faster
|
final int[] mt = this.mt; // locals are slightly faster
|
||||||
final int[] mag01 = this.mag01; // locals are slightly faster
|
final int[] mag01 = this.mag01; // locals are slightly faster
|
||||||
|
|
||||||
for (kk = 0; kk < N - M; kk++)
|
for (kk = 0; kk < N - M; kk++)
|
||||||
{
|
{
|
||||||
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
||||||
|
@ -964,22 +964,22 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
}
|
}
|
||||||
y = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
y = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
||||||
mt[N-1] = mt[M-1] ^ (y >>> 1) ^ mag01[y & 0x1];
|
mt[N-1] = mt[M-1] ^ (y >>> 1) ^ mag01[y & 0x1];
|
||||||
|
|
||||||
mti = 0;
|
mti = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
y = mt[mti++];
|
y = mt[mti++];
|
||||||
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
||||||
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
||||||
y ^= (y << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(y)
|
y ^= (y << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(y)
|
||||||
y ^= (y >>> 18); // TEMPERING_SHIFT_L(y)
|
y ^= (y >>> 18); // TEMPERING_SHIFT_L(y)
|
||||||
|
|
||||||
if (mti >= N) // generate N words at one time
|
if (mti >= N) // generate N words at one time
|
||||||
{
|
{
|
||||||
int kk;
|
int kk;
|
||||||
final int[] mt = this.mt; // locals are slightly faster
|
final int[] mt = this.mt; // locals are slightly faster
|
||||||
final int[] mag01 = this.mag01; // locals are slightly faster
|
final int[] mag01 = this.mag01; // locals are slightly faster
|
||||||
|
|
||||||
for (kk = 0; kk < N - M; kk++)
|
for (kk = 0; kk < N - M; kk++)
|
||||||
{
|
{
|
||||||
z = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
z = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
||||||
|
@ -992,22 +992,22 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
}
|
}
|
||||||
z = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
z = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
||||||
mt[N-1] = mt[M-1] ^ (z >>> 1) ^ mag01[z & 0x1];
|
mt[N-1] = mt[M-1] ^ (z >>> 1) ^ mag01[z & 0x1];
|
||||||
|
|
||||||
mti = 0;
|
mti = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
z = mt[mti++];
|
z = mt[mti++];
|
||||||
z ^= z >>> 11; // TEMPERING_SHIFT_U(z)
|
z ^= z >>> 11; // TEMPERING_SHIFT_U(z)
|
||||||
z ^= (z << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(z)
|
z ^= (z << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(z)
|
||||||
z ^= (z << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(z)
|
z ^= (z << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(z)
|
||||||
z ^= (z >>> 18); // TEMPERING_SHIFT_L(z)
|
z ^= (z >>> 18); // TEMPERING_SHIFT_L(z)
|
||||||
|
|
||||||
if (mti >= N) // generate N words at one time
|
if (mti >= N) // generate N words at one time
|
||||||
{
|
{
|
||||||
int kk;
|
int kk;
|
||||||
final int[] mt = this.mt; // locals are slightly faster
|
final int[] mt = this.mt; // locals are slightly faster
|
||||||
final int[] mag01 = this.mag01; // locals are slightly faster
|
final int[] mag01 = this.mag01; // locals are slightly faster
|
||||||
|
|
||||||
for (kk = 0; kk < N - M; kk++)
|
for (kk = 0; kk < N - M; kk++)
|
||||||
{
|
{
|
||||||
a = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
a = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
||||||
|
@ -1020,22 +1020,22 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
}
|
}
|
||||||
a = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
a = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
||||||
mt[N-1] = mt[M-1] ^ (a >>> 1) ^ mag01[a & 0x1];
|
mt[N-1] = mt[M-1] ^ (a >>> 1) ^ mag01[a & 0x1];
|
||||||
|
|
||||||
mti = 0;
|
mti = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
a = mt[mti++];
|
a = mt[mti++];
|
||||||
a ^= a >>> 11; // TEMPERING_SHIFT_U(a)
|
a ^= a >>> 11; // TEMPERING_SHIFT_U(a)
|
||||||
a ^= (a << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(a)
|
a ^= (a << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(a)
|
||||||
a ^= (a << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(a)
|
a ^= (a << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(a)
|
||||||
a ^= (a >>> 18); // TEMPERING_SHIFT_L(a)
|
a ^= (a >>> 18); // TEMPERING_SHIFT_L(a)
|
||||||
|
|
||||||
if (mti >= N) // generate N words at one time
|
if (mti >= N) // generate N words at one time
|
||||||
{
|
{
|
||||||
int kk;
|
int kk;
|
||||||
final int[] mt = this.mt; // locals are slightly faster
|
final int[] mt = this.mt; // locals are slightly faster
|
||||||
final int[] mag01 = this.mag01; // locals are slightly faster
|
final int[] mag01 = this.mag01; // locals are slightly faster
|
||||||
|
|
||||||
for (kk = 0; kk < N - M; kk++)
|
for (kk = 0; kk < N - M; kk++)
|
||||||
{
|
{
|
||||||
b = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
b = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
||||||
|
@ -1048,16 +1048,16 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
}
|
}
|
||||||
b = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
b = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
||||||
mt[N-1] = mt[M-1] ^ (b >>> 1) ^ mag01[b & 0x1];
|
mt[N-1] = mt[M-1] ^ (b >>> 1) ^ mag01[b & 0x1];
|
||||||
|
|
||||||
mti = 0;
|
mti = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
b = mt[mti++];
|
b = mt[mti++];
|
||||||
b ^= b >>> 11; // TEMPERING_SHIFT_U(b)
|
b ^= b >>> 11; // TEMPERING_SHIFT_U(b)
|
||||||
b ^= (b << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(b)
|
b ^= (b << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(b)
|
||||||
b ^= (b << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(b)
|
b ^= (b << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(b)
|
||||||
b ^= (b >>> 18); // TEMPERING_SHIFT_L(b)
|
b ^= (b >>> 18); // TEMPERING_SHIFT_L(b)
|
||||||
|
|
||||||
/* derived from nextDouble documentation in jdk 1.2 docs, see top */
|
/* derived from nextDouble documentation in jdk 1.2 docs, see top */
|
||||||
v1 = 2 *
|
v1 = 2 *
|
||||||
(((((long)(y >>> 6)) << 27) + (z >>> 5)) / (double)(1L << 53))
|
(((((long)(y >>> 6)) << 27) + (z >>> 5)) / (double)(1L << 53))
|
||||||
|
@ -1072,23 +1072,23 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
return v1 * multiplier;
|
return v1 * multiplier;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Returns a random float in the half-open range from [0.0f,1.0f). Thus 0.0f is a valid
|
/** Returns a random float in the half-open range from [0.0f,1.0f). Thus 0.0f is a valid
|
||||||
result but 1.0f is not. */
|
result but 1.0f is not. */
|
||||||
public final float nextFloat()
|
public final float nextFloat()
|
||||||
{
|
{
|
||||||
int y;
|
int y;
|
||||||
|
|
||||||
if (mti >= N) // generate N words at one time
|
if (mti >= N) // generate N words at one time
|
||||||
{
|
{
|
||||||
int kk;
|
int kk;
|
||||||
final int[] mt = this.mt; // locals are slightly faster
|
final int[] mt = this.mt; // locals are slightly faster
|
||||||
final int[] mag01 = this.mag01; // locals are slightly faster
|
final int[] mag01 = this.mag01; // locals are slightly faster
|
||||||
|
|
||||||
for (kk = 0; kk < N - M; kk++)
|
for (kk = 0; kk < N - M; kk++)
|
||||||
{
|
{
|
||||||
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
||||||
|
@ -1104,7 +1104,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
|
|
||||||
mti = 0;
|
mti = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
y = mt[mti++];
|
y = mt[mti++];
|
||||||
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
||||||
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
||||||
|
@ -1124,7 +1124,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
<tr><td>nextFloat(false, true)<td>(0.0f, 1.0f]
|
<tr><td>nextFloat(false, true)<td>(0.0f, 1.0f]
|
||||||
<tr><td>nextFloat(true, true)<td>[0.0f, 1.0f]
|
<tr><td>nextFloat(true, true)<td>[0.0f, 1.0f]
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<p>This version preserves all possible random values in the float range.
|
<p>This version preserves all possible random values in the float range.
|
||||||
*/
|
*/
|
||||||
public double nextFloat(final boolean includeZero, final boolean includeOne)
|
public double nextFloat(final boolean includeZero, final boolean includeOne)
|
||||||
|
@ -1134,7 +1134,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
{
|
{
|
||||||
d = nextFloat(); // grab a value, initially from half-open [0.0f, 1.0f)
|
d = nextFloat(); // grab a value, initially from half-open [0.0f, 1.0f)
|
||||||
if (includeOne && nextBoolean()) d += 1.0f; // if includeOne, with 1/2 probability, push to [1.0f, 2.0f)
|
if (includeOne && nextBoolean()) d += 1.0f; // if includeOne, with 1/2 probability, push to [1.0f, 2.0f)
|
||||||
}
|
}
|
||||||
while ( (d > 1.0f) || // everything above 1.0f is always invalid
|
while ( (d > 1.0f) || // everything above 1.0f is always invalid
|
||||||
(!includeZero && d == 0.0f)); // if we're not including zero, 0.0f is invalid
|
(!includeZero && d == 0.0f)); // if we're not including zero, 0.0f is invalid
|
||||||
return d;
|
return d;
|
||||||
|
@ -1148,17 +1148,17 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
{
|
{
|
||||||
if (n<=0)
|
if (n<=0)
|
||||||
throw new IllegalArgumentException("n must be positive, got: " + n);
|
throw new IllegalArgumentException("n must be positive, got: " + n);
|
||||||
|
|
||||||
if ((n & -n) == n) // i.e., n is a power of 2
|
if ((n & -n) == n) // i.e., n is a power of 2
|
||||||
{
|
{
|
||||||
int y;
|
int y;
|
||||||
|
|
||||||
if (mti >= N) // generate N words at one time
|
if (mti >= N) // generate N words at one time
|
||||||
{
|
{
|
||||||
int kk;
|
int kk;
|
||||||
final int[] mt = this.mt; // locals are slightly faster
|
final int[] mt = this.mt; // locals are slightly faster
|
||||||
final int[] mag01 = this.mag01; // locals are slightly faster
|
final int[] mag01 = this.mag01; // locals are slightly faster
|
||||||
|
|
||||||
for (kk = 0; kk < N - M; kk++)
|
for (kk = 0; kk < N - M; kk++)
|
||||||
{
|
{
|
||||||
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
||||||
|
@ -1171,30 +1171,30 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
}
|
}
|
||||||
y = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
y = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
||||||
mt[N-1] = mt[M-1] ^ (y >>> 1) ^ mag01[y & 0x1];
|
mt[N-1] = mt[M-1] ^ (y >>> 1) ^ mag01[y & 0x1];
|
||||||
|
|
||||||
mti = 0;
|
mti = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
y = mt[mti++];
|
y = mt[mti++];
|
||||||
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
||||||
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
||||||
y ^= (y << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(y)
|
y ^= (y << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(y)
|
||||||
y ^= (y >>> 18); // TEMPERING_SHIFT_L(y)
|
y ^= (y >>> 18); // TEMPERING_SHIFT_L(y)
|
||||||
|
|
||||||
return (int)((n * (long) (y >>> 1) ) >> 31);
|
return (int)((n * (long) (y >>> 1) ) >> 31);
|
||||||
}
|
}
|
||||||
|
|
||||||
int bits, val;
|
int bits, val;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
int y;
|
int y;
|
||||||
|
|
||||||
if (mti >= N) // generate N words at one time
|
if (mti >= N) // generate N words at one time
|
||||||
{
|
{
|
||||||
int kk;
|
int kk;
|
||||||
final int[] mt = this.mt; // locals are slightly faster
|
final int[] mt = this.mt; // locals are slightly faster
|
||||||
final int[] mag01 = this.mag01; // locals are slightly faster
|
final int[] mag01 = this.mag01; // locals are slightly faster
|
||||||
|
|
||||||
for (kk = 0; kk < N - M; kk++)
|
for (kk = 0; kk < N - M; kk++)
|
||||||
{
|
{
|
||||||
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
|
||||||
|
@ -1207,16 +1207,16 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
|
||||||
}
|
}
|
||||||
y = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
y = (mt[N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
|
||||||
mt[N-1] = mt[M-1] ^ (y >>> 1) ^ mag01[y & 0x1];
|
mt[N-1] = mt[M-1] ^ (y >>> 1) ^ mag01[y & 0x1];
|
||||||
|
|
||||||
mti = 0;
|
mti = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
y = mt[mti++];
|
y = mt[mti++];
|
||||||
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
|
||||||
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
|
||||||
y ^= (y << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(y)
|
y ^= (y << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(y)
|
||||||
y ^= (y >>> 18); // TEMPERING_SHIFT_L(y)
|
y ^= (y >>> 18); // TEMPERING_SHIFT_L(y)
|
||||||
|
|
||||||
bits = (y >>> 1);
|
bits = (y >>> 1);
|
||||||
val = bits % n;
|
val = bits % n;
|
||||||
} while(bits - val + (n-1) < 0);
|
} while(bits - val + (n-1) < 0);
|
||||||
|
|
|
@ -27,11 +27,11 @@ package magic;
|
||||||
* MurmurHash3 implementation in Java, based on Austin Appleby's <a href=
|
* MurmurHash3 implementation in Java, based on Austin Appleby's <a href=
|
||||||
* "https://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp"
|
* "https://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp"
|
||||||
* >original in C</a>
|
* >original in C</a>
|
||||||
*
|
*
|
||||||
* Only implementing x64 version, because this should always be faster on 64 bit
|
* Only implementing x64 version, because this should always be faster on 64 bit
|
||||||
* native processors, even 64 bit being ran with a 32 bit OS; this should also
|
* native processors, even 64 bit being ran with a 32 bit OS; this should also
|
||||||
* be as fast or faster than the x86 version on some modern 32 bit processors.
|
* be as fast or faster than the x86 version on some modern 32 bit processors.
|
||||||
*
|
*
|
||||||
* @author Patrick McFarland
|
* @author Patrick McFarland
|
||||||
* @see <a href="http://sites.google.com/site/murmurhash/">MurmurHash website</a>
|
* @see <a href="http://sites.google.com/site/murmurhash/">MurmurHash website</a>
|
||||||
* @see <a href="http://en.wikipedia.org/wiki/MurmurHash">MurmurHash entry on Wikipedia</a>
|
* @see <a href="http://en.wikipedia.org/wiki/MurmurHash">MurmurHash entry on Wikipedia</a>
|
||||||
|
@ -96,7 +96,7 @@ public class MurmurHash3 {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hash a value using the x64 128 bit variant of MurmurHash3
|
* Hash a value using the x64 128 bit variant of MurmurHash3
|
||||||
*
|
*
|
||||||
* @param key value to hash
|
* @param key value to hash
|
||||||
* @param seed random value
|
* @param seed random value
|
||||||
* @return 128 bit hashed key, in an array containing two longs
|
* @return 128 bit hashed key, in an array containing two longs
|
||||||
|
@ -159,7 +159,7 @@ public class MurmurHash3 {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hash a value using the x64 64 bit variant of MurmurHash3
|
* Hash a value using the x64 64 bit variant of MurmurHash3
|
||||||
*
|
*
|
||||||
* @param key value to hash
|
* @param key value to hash
|
||||||
* @param seed random value
|
* @param seed random value
|
||||||
* @return 64 bit hashed key
|
* @return 64 bit hashed key
|
||||||
|
@ -170,7 +170,7 @@ public class MurmurHash3 {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hash a value using the x64 32 bit variant of MurmurHash3
|
* Hash a value using the x64 32 bit variant of MurmurHash3
|
||||||
*
|
*
|
||||||
* @param key value to hash
|
* @param key value to hash
|
||||||
* @param seed random value
|
* @param seed random value
|
||||||
* @return 32 bit hashed key
|
* @return 32 bit hashed key
|
||||||
|
@ -181,7 +181,7 @@ public class MurmurHash3 {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hash a value using the x64 128 bit variant of MurmurHash3
|
* Hash a value using the x64 128 bit variant of MurmurHash3
|
||||||
*
|
*
|
||||||
* @param key value to hash
|
* @param key value to hash
|
||||||
* @param seed random value
|
* @param seed random value
|
||||||
* @return 128 bit hashed key, in an array containing two longs
|
* @return 128 bit hashed key, in an array containing two longs
|
||||||
|
@ -225,7 +225,7 @@ public class MurmurHash3 {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hash a value using the x64 64 bit variant of MurmurHash3
|
* Hash a value using the x64 64 bit variant of MurmurHash3
|
||||||
*
|
*
|
||||||
* @param key value to hash
|
* @param key value to hash
|
||||||
* @param seed random value
|
* @param seed random value
|
||||||
* @return 64 bit hashed key
|
* @return 64 bit hashed key
|
||||||
|
@ -236,7 +236,7 @@ public class MurmurHash3 {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hash a value using the x64 32 bit variant of MurmurHash3
|
* Hash a value using the x64 32 bit variant of MurmurHash3
|
||||||
*
|
*
|
||||||
* @param key value to hash
|
* @param key value to hash
|
||||||
* @param seed random value
|
* @param seed random value
|
||||||
* @return 32 bit hashed key
|
* @return 32 bit hashed key
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package magic.ai;
|
package magic.ai;
|
||||||
|
|
||||||
public class ArtificialChoiceResults {
|
public class ArtificialChoiceResults {
|
||||||
|
|
||||||
final Object[] choiceResults;
|
final Object[] choiceResults;
|
||||||
ArtificialScore aiScore=ArtificialScore.INVALID_SCORE;
|
ArtificialScore aiScore=ArtificialScore.INVALID_SCORE;
|
||||||
int worker=-1;
|
int worker=-1;
|
||||||
|
@ -10,7 +10,7 @@ public class ArtificialChoiceResults {
|
||||||
ArtificialChoiceResults(final Object[] choiceResults) {
|
ArtificialChoiceResults(final Object[] choiceResults) {
|
||||||
this.choiceResults=choiceResults;
|
this.choiceResults=choiceResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
final StringBuilder buffer=new StringBuilder();
|
final StringBuilder buffer=new StringBuilder();
|
||||||
buffer.append("[").append(worker).append('/').append(gameCount).append('/').append(aiScore).append("]");
|
buffer.append("[").append(worker).append('/').append(gameCount).append('/').append(aiScore).append("]");
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
package magic.ai;
|
package magic.ai;
|
||||||
|
|
||||||
public class ArtificialMultiPruneScore implements ArtificialPruneScore {
|
public class ArtificialMultiPruneScore implements ArtificialPruneScore {
|
||||||
|
|
||||||
private final int maxBest;
|
private final int maxBest;
|
||||||
private final int minWorst;
|
private final int minWorst;
|
||||||
|
|
||||||
private ArtificialMultiPruneScore(final int maxBest,final int minWorst) {
|
private ArtificialMultiPruneScore(final int maxBest,final int minWorst) {
|
||||||
this.maxBest=maxBest;
|
this.maxBest=maxBest;
|
||||||
this.minWorst=minWorst;
|
this.minWorst=minWorst;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArtificialMultiPruneScore() {
|
ArtificialMultiPruneScore() {
|
||||||
this(Integer.MIN_VALUE,Integer.MAX_VALUE);
|
this(Integer.MIN_VALUE,Integer.MAX_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getScore() {
|
public int getScore() {
|
||||||
return maxBest; // Does matter for game id.
|
return maxBest; // Does matter for game id.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean pruneScore(final int score,final boolean best) {
|
public boolean pruneScore(final int score,final boolean best) {
|
||||||
return best?score>minWorst:score<maxBest;
|
return best?score>minWorst:score<maxBest;
|
||||||
|
@ -32,7 +32,7 @@ public class ArtificialMultiPruneScore implements ArtificialPruneScore {
|
||||||
return score<minWorst?new ArtificialMultiPruneScore(maxBest,score):this;
|
return score<minWorst?new ArtificialMultiPruneScore(maxBest,score):this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return maxBest+" / "+minWorst;
|
return maxBest+" / "+minWorst;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package magic.ai;
|
package magic.ai;
|
||||||
|
|
||||||
public interface ArtificialPruneScore {
|
public interface ArtificialPruneScore {
|
||||||
|
|
||||||
int getScore();
|
int getScore();
|
||||||
|
|
||||||
boolean pruneScore(final int score,final boolean best);
|
boolean pruneScore(final int score,final boolean best);
|
||||||
|
|
||||||
ArtificialPruneScore getPruneScore(final int score,final boolean best);
|
ArtificialPruneScore getPruneScore(final int score,final boolean best);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
package magic.ai;
|
package magic.ai;
|
||||||
|
|
||||||
class ArtificialPruneScoreRef {
|
class ArtificialPruneScoreRef {
|
||||||
|
|
||||||
private ArtificialPruneScore pruneScore;
|
private ArtificialPruneScore pruneScore;
|
||||||
|
@ -7,11 +7,11 @@ class ArtificialPruneScoreRef {
|
||||||
public ArtificialPruneScoreRef(final ArtificialPruneScore pScore) {
|
public ArtificialPruneScoreRef(final ArtificialPruneScore pScore) {
|
||||||
pruneScore = pScore;
|
pruneScore = pScore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(final int score) {
|
public void update(final int score) {
|
||||||
pruneScore = pruneScore.getPruneScore(score,true);
|
pruneScore = pruneScore.getPruneScore(score,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArtificialPruneScore get() {
|
public ArtificialPruneScore get() {
|
||||||
return pruneScore;
|
return pruneScore;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,10 @@ public class ArtificialScore {
|
||||||
static final ArtificialScore INVALID_SCORE=new ArtificialScore(0,0);
|
static final ArtificialScore INVALID_SCORE=new ArtificialScore(0,0);
|
||||||
static final int MAX = 99900000;
|
static final int MAX = 99900000;
|
||||||
static final int MIN = -MAX;
|
static final int MIN = -MAX;
|
||||||
|
|
||||||
private final int score;
|
private final int score;
|
||||||
private final int depth;
|
private final int depth;
|
||||||
|
|
||||||
ArtificialScore(final int aScore,final int aDepth) {
|
ArtificialScore(final int aScore,final int aDepth) {
|
||||||
int boundedScore = Math.min(MAX,aScore);
|
int boundedScore = Math.min(MAX,aScore);
|
||||||
score = Math.max(MIN,boundedScore);
|
score = Math.max(MIN,boundedScore);
|
||||||
|
@ -25,7 +25,7 @@ public class ArtificialScore {
|
||||||
int getScore() {
|
int getScore() {
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isBetter(final ArtificialScore other,final boolean max) {
|
boolean isBetter(final ArtificialScore other,final boolean max) {
|
||||||
if (other==INVALID_SCORE) {
|
if (other==INVALID_SCORE) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -44,11 +44,11 @@ public class ArtificialScore {
|
||||||
return other.score < score;
|
return other.score < score;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if (this==INVALID_SCORE) {
|
if (this==INVALID_SCORE) {
|
||||||
return "none";
|
return "none";
|
||||||
}
|
}
|
||||||
final StringBuilder buffer=new StringBuilder();
|
final StringBuilder buffer=new StringBuilder();
|
||||||
buffer.append(score).append(" at ").append(depth);
|
buffer.append(score).append(" at ").append(depth);
|
||||||
|
|
|
@ -5,7 +5,7 @@ import magic.data.LRUCache;
|
||||||
public class ArtificialScoreBoard {
|
public class ArtificialScoreBoard {
|
||||||
|
|
||||||
private final LRUCache<Long,ArtificialScore> gameScoresMap;
|
private final LRUCache<Long,ArtificialScore> gameScoresMap;
|
||||||
|
|
||||||
ArtificialScoreBoard() {
|
ArtificialScoreBoard() {
|
||||||
gameScoresMap=new LRUCache<Long,ArtificialScore>(100000);
|
gameScoresMap=new LRUCache<Long,ArtificialScore>(100000);
|
||||||
}
|
}
|
||||||
|
@ -13,11 +13,11 @@ public class ArtificialScoreBoard {
|
||||||
synchronized void setGameScore(final long gameId,final ArtificialScore aiScore) {
|
synchronized void setGameScore(final long gameId,final ArtificialScore aiScore) {
|
||||||
gameScoresMap.put(gameId,aiScore);
|
gameScoresMap.put(gameId,aiScore);
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized ArtificialScore getGameScore(final long gameId) {
|
synchronized ArtificialScore getGameScore(final long gameId) {
|
||||||
return gameScoresMap.get(gameId);
|
return gameScoresMap.get(gameId);
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized void clear() {
|
synchronized void clear() {
|
||||||
gameScoresMap.clear();
|
gameScoresMap.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,15 +19,15 @@ public class ArtificialScoringSystem {
|
||||||
public static final int ITEM_ON_STACK_SCORE=-1;
|
public static final int ITEM_ON_STACK_SCORE=-1;
|
||||||
public static final int UNEQUIP_SCORE=-100;
|
public static final int UNEQUIP_SCORE=-100;
|
||||||
public static final int UNNECESSARY_EQUIP_SCORE=-1000;
|
public static final int UNNECESSARY_EQUIP_SCORE=-1000;
|
||||||
|
|
||||||
private static final int[] LIFE_SCORES={
|
private static final int[] LIFE_SCORES={
|
||||||
0,1000,2000,3000,4000,
|
0,1000,2000,3000,4000,
|
||||||
4500,5000,5500,6000,6500,
|
4500,5000,5500,6000,6500,
|
||||||
7000,7400,7800,8200,8600,
|
7000,7400,7800,8200,8600,
|
||||||
9000,9200,9400,9600,9800,
|
9000,9200,9400,9600,9800,
|
||||||
10000
|
10000
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final int[] POISON_SCORES={
|
private static final int[] POISON_SCORES={
|
||||||
5000,4700,4400,4100,3800,
|
5000,4700,4400,4100,3800,
|
||||||
3400,3000,2500,2000,1000,
|
3400,3000,2500,2000,1000,
|
||||||
|
@ -37,31 +37,31 @@ public class ArtificialScoringSystem {
|
||||||
private static final int MAX_LIFE=LIFE_SCORES.length-1;
|
private static final int MAX_LIFE=LIFE_SCORES.length-1;
|
||||||
|
|
||||||
private static final int MAX_POISON=10;
|
private static final int MAX_POISON=10;
|
||||||
|
|
||||||
private static final int LIFE_ABOVE_MULTIPLIER=100;
|
private static final int LIFE_ABOVE_MULTIPLIER=100;
|
||||||
|
|
||||||
private static final int UNKNOWN_CARD_SCORE=300;
|
private static final int UNKNOWN_CARD_SCORE=300;
|
||||||
|
|
||||||
private static final int PERMANENT_SCORE=300;
|
private static final int PERMANENT_SCORE=300;
|
||||||
|
|
||||||
public static int getTurnScore(final MagicGame game) {
|
public static int getTurnScore(final MagicGame game) {
|
||||||
return Math.max(0,10-(game.getTurn()-1)>>1);
|
return Math.max(0,10-(game.getTurn()-1)>>1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getLoseGameScore(final MagicGame game) {
|
public static int getLoseGameScore(final MagicGame game) {
|
||||||
// Lose score is lowered in function of the turn and phase when it occurs. Encourages AI to win as fast as possible.
|
// Lose score is lowered in function of the turn and phase when it occurs. Encourages AI to win as fast as possible.
|
||||||
return LOSE_GAME_SCORE+game.getTurn()*2500+game.getPhase().getType().ordinal()*200;
|
return LOSE_GAME_SCORE+game.getTurn()*2500+game.getPhase().getType().ordinal()*200;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getCardDefinitionScore(final MagicCardDefinition cardDefinition) {
|
public static int getCardDefinitionScore(final MagicCardDefinition cardDefinition) {
|
||||||
return getCardDefinitionScore(cardDefinition, 1);
|
return getCardDefinitionScore(cardDefinition, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// score for a card that gets put into play without paying the mana cost
|
// score for a card that gets put into play without paying the mana cost
|
||||||
public static int getFreeCardDefinitionScore(final MagicCardDefinition cardDefinition) {
|
public static int getFreeCardDefinitionScore(final MagicCardDefinition cardDefinition) {
|
||||||
return getCardDefinitionScore(cardDefinition, 0);
|
return getCardDefinitionScore(cardDefinition, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getCardDefinitionScore(final MagicCardDefinition cardDefinition, final int costFactor) {
|
private static int getCardDefinitionScore(final MagicCardDefinition cardDefinition, final int costFactor) {
|
||||||
if (cardDefinition.isLand()) {
|
if (cardDefinition.isLand()) {
|
||||||
int score=(int)(cardDefinition.getValue()*50);
|
int score=(int)(cardDefinition.getValue()*50);
|
||||||
|
@ -77,11 +77,11 @@ public class ArtificialScoringSystem {
|
||||||
return score+cardDefinition.getRemoval()*50+cardDefinition.getRarity()*30;
|
return score+cardDefinition.getRemoval()*50+cardDefinition.getRarity()*30;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getCardScore(final MagicCard card) {
|
public static int getCardScore(final MagicCard card) {
|
||||||
return card.isKnown()?card.getCardDefinition().getScore():UNKNOWN_CARD_SCORE;
|
return card.isKnown()?card.getCardDefinition().getScore():UNKNOWN_CARD_SCORE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getFreeCardScore(final MagicCard card) {
|
public static int getFreeCardScore(final MagicCard card) {
|
||||||
return card.isKnown()?card.getCardDefinition().getFreeScore():UNKNOWN_CARD_SCORE;
|
return card.isKnown()?card.getCardDefinition().getFreeScore():UNKNOWN_CARD_SCORE;
|
||||||
}
|
}
|
||||||
|
@ -90,16 +90,16 @@ public class ArtificialScoringSystem {
|
||||||
int score = permanent.getCardScore();
|
int score = permanent.getCardScore();
|
||||||
if (permanent.isCreature()) {
|
if (permanent.isCreature()) {
|
||||||
score+=permanent.getActivations().size()*50;
|
score+=permanent.getActivations().size()*50;
|
||||||
score+=permanent.getManaActivations().size()*80;
|
score+=permanent.getManaActivations().size()*80;
|
||||||
} else {
|
} else {
|
||||||
score+=PERMANENT_SCORE;
|
score+=PERMANENT_SCORE;
|
||||||
if (permanent.isEquipment()) {
|
if (permanent.isEquipment()) {
|
||||||
score+=100;
|
score+=100;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getVariablePermanentScore(final MagicPermanent permanent) {
|
public static int getVariablePermanentScore(final MagicPermanent permanent) {
|
||||||
int score=permanent.getCounters(MagicCounterType.Charge)*30;
|
int score=permanent.getCounters(MagicCounterType.Charge)*30;
|
||||||
if (!permanent.canTap()) {
|
if (!permanent.canTap()) {
|
||||||
|
@ -111,14 +111,14 @@ public class ArtificialScoringSystem {
|
||||||
final Set<MagicAbility> abilityFlags=permanent.getAbilityFlags();
|
final Set<MagicAbility> abilityFlags=permanent.getAbilityFlags();
|
||||||
score+=pt.power()*300+pt.getPositiveToughness()*200+MagicAbility.getScore(abilityFlags)*(pt.getPositivePower()+1)/2;
|
score+=pt.power()*300+pt.getPositiveToughness()*200+MagicAbility.getScore(abilityFlags)*(pt.getPositivePower()+1)/2;
|
||||||
score+=permanent.getEquipmentPermanents().size()*50+permanent.getAuraPermanents().size()*100;
|
score+=permanent.getEquipmentPermanents().size()*50+permanent.getAuraPermanents().size()*100;
|
||||||
}
|
}
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getTappedScore(final MagicPermanent permanent) {
|
public static int getTappedScore(final MagicPermanent permanent) {
|
||||||
return permanent.isCreature()?-10:-5;
|
return permanent.isCreature()?-10:-5;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getLifeScore(final int life) {
|
public static int getLifeScore(final int life) {
|
||||||
if (life>MAX_LIFE) {
|
if (life>MAX_LIFE) {
|
||||||
return LIFE_SCORES[MAX_LIFE]+(life-MAX_LIFE)*LIFE_ABOVE_MULTIPLIER;
|
return LIFE_SCORES[MAX_LIFE]+(life-MAX_LIFE)*LIFE_ABOVE_MULTIPLIER;
|
||||||
|
@ -128,42 +128,42 @@ public class ArtificialScoringSystem {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getPoisonScore(final int poison) {
|
public static int getPoisonScore(final int poison) {
|
||||||
if (poison>MAX_POISON) {
|
if (poison>MAX_POISON) {
|
||||||
return POISON_SCORES[MAX_POISON];
|
return POISON_SCORES[MAX_POISON];
|
||||||
}
|
}
|
||||||
return POISON_SCORES[poison];
|
return POISON_SCORES[poison];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getManaScore(final int amount) {
|
public static int getManaScore(final int amount) {
|
||||||
return -amount;
|
return -amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getAttackerScore(final MagicCombatCreature attacker) {
|
public static int getAttackerScore(final MagicCombatCreature attacker) {
|
||||||
int score=attacker.power*5+attacker.lethalDamage*2-attacker.candidateBlockers.length;
|
int score=attacker.power*5+attacker.lethalDamage*2-attacker.candidateBlockers.length;
|
||||||
for (final MagicCombatCreature blocker : attacker.candidateBlockers) {
|
for (final MagicCombatCreature blocker : attacker.candidateBlockers) {
|
||||||
score-=blocker.power;
|
score-=blocker.power;
|
||||||
}
|
}
|
||||||
// Dedicated attacker.
|
// Dedicated attacker.
|
||||||
if (attacker.hasAbility(MagicAbility.AttacksEachTurnIfAble) ||
|
if (attacker.hasAbility(MagicAbility.AttacksEachTurnIfAble) ||
|
||||||
attacker.hasAbility(MagicAbility.CannotBlock)) {
|
attacker.hasAbility(MagicAbility.CannotBlock)) {
|
||||||
score+=10;
|
score+=10;
|
||||||
}
|
}
|
||||||
// Abilities for attacking.
|
// Abilities for attacking.
|
||||||
if (attacker.hasAbility(MagicAbility.Trample) ||
|
if (attacker.hasAbility(MagicAbility.Trample) ||
|
||||||
attacker.hasAbility(MagicAbility.Vigilance)) {
|
attacker.hasAbility(MagicAbility.Vigilance)) {
|
||||||
score+=8;
|
score+=8;
|
||||||
}
|
}
|
||||||
// Dangerous to block.
|
// Dangerous to block.
|
||||||
if (!attacker.normalDamage ||
|
if (!attacker.normalDamage ||
|
||||||
attacker.hasAbility(MagicAbility.FirstStrike) ||
|
attacker.hasAbility(MagicAbility.FirstStrike) ||
|
||||||
attacker.hasAbility(MagicAbility.Indestructible)) {
|
attacker.hasAbility(MagicAbility.Indestructible)) {
|
||||||
score+=7;
|
score+=7;
|
||||||
}
|
}
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getMillScore(final int amount) {
|
public static int getMillScore(final int amount) {
|
||||||
return -amount;
|
return -amount;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ Classical MCTS (UCT)
|
||||||
- score = XX% (25000 matches against MMAB-1)
|
- score = XX% (25000 matches against MMAB-1)
|
||||||
|
|
||||||
Enchancements to basic UCT
|
Enchancements to basic UCT
|
||||||
- use ratio selection (v + 10)/(n + 10)
|
- use ratio selection (v + 10)/(n + 10)
|
||||||
- UCB1 with C = 1.0
|
- UCB1 with C = 1.0
|
||||||
- UCB1 with C = 2.0
|
- UCB1 with C = 2.0
|
||||||
- UCB1 with C = 3.0
|
- UCB1 with C = 3.0
|
||||||
|
@ -46,7 +46,7 @@ Consistency Modifications for Automatically Tuned Monte-Carlo Tree Search
|
||||||
using v_t threshold ensures consistency for case of reward in {0,1} using any score function
|
using v_t threshold ensures consistency for case of reward in {0,1} using any score function
|
||||||
v(s) < v_t (0.3), randomy pick a child, else pick child that maximize score
|
v(s) < v_t (0.3), randomy pick a child, else pick child that maximize score
|
||||||
|
|
||||||
Monte-Carlo Tree Search in Lines of Action
|
Monte-Carlo Tree Search in Lines of Action
|
||||||
1-ply lookahread to detect direct win for player to move
|
1-ply lookahread to detect direct win for player to move
|
||||||
secure child formula for decision v + A/sqrt(n)
|
secure child formula for decision v + A/sqrt(n)
|
||||||
evaluation cut-off: use score function to stop simulation early
|
evaluation cut-off: use score function to stop simulation early
|
||||||
|
@ -55,7 +55,7 @@ Monte-Carlo Tree Search in Lines of Action
|
||||||
mixed: start with corrective, rest of the moves use greedy
|
mixed: start with corrective, rest of the moves use greedy
|
||||||
*/
|
*/
|
||||||
public class MCTSAI implements MagicAI {
|
public class MCTSAI implements MagicAI {
|
||||||
|
|
||||||
private static int MIN_SCORE = Integer.MAX_VALUE;
|
private static int MIN_SCORE = Integer.MAX_VALUE;
|
||||||
static int MIN_SIM = Integer.MAX_VALUE;
|
static int MIN_SIM = Integer.MAX_VALUE;
|
||||||
private static final int MAX_ACTIONS = 10000;
|
private static final int MAX_ACTIONS = 10000;
|
||||||
|
@ -72,12 +72,12 @@ public class MCTSAI implements MagicAI {
|
||||||
MIN_SCORE = Integer.parseInt(System.getProperty("min_score"));
|
MIN_SCORE = Integer.parseInt(System.getProperty("min_score"));
|
||||||
System.err.println("MIN_SCORE = " + MIN_SCORE);
|
System.err.println("MIN_SCORE = " + MIN_SCORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (System.getProperty("ucb1_c") != null) {
|
if (System.getProperty("ucb1_c") != null) {
|
||||||
UCB1_C = Double.parseDouble(System.getProperty("ucb1_c"));
|
UCB1_C = Double.parseDouble(System.getProperty("ucb1_c"));
|
||||||
System.err.println("UCB1_C = " + UCB1_C);
|
System.err.println("UCB1_C = " + UCB1_C);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (System.getProperty("ratio_k") != null) {
|
if (System.getProperty("ratio_k") != null) {
|
||||||
RATIO_K = Double.parseDouble(System.getProperty("ratio_k"));
|
RATIO_K = Double.parseDouble(System.getProperty("ratio_k"));
|
||||||
System.err.println("RATIO_K = " + RATIO_K);
|
System.err.println("RATIO_K = " + RATIO_K);
|
||||||
|
@ -105,7 +105,7 @@ public class MCTSAI implements MagicAI {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object[] findNextEventChoiceResults(
|
public Object[] findNextEventChoiceResults(
|
||||||
final MagicGame startGame,
|
final MagicGame startGame,
|
||||||
final MagicPlayer scorePlayer) {
|
final MagicPlayer scorePlayer) {
|
||||||
|
|
||||||
// Determine possible choices
|
// Determine possible choices
|
||||||
|
@ -115,21 +115,21 @@ public class MCTSAI implements MagicAI {
|
||||||
choiceGame = null;
|
choiceGame = null;
|
||||||
|
|
||||||
final int size = RCHOICES.size();
|
final int size = RCHOICES.size();
|
||||||
|
|
||||||
// No choice
|
// No choice
|
||||||
assert size > 0 : "ERROR! No choice found at start of MCTS";
|
assert size > 0 : "ERROR! No choice found at start of MCTS";
|
||||||
|
|
||||||
// Single choice
|
// Single choice
|
||||||
if (size == 1) {
|
if (size == 1) {
|
||||||
return startGame.map(RCHOICES.get(0));
|
return startGame.map(RCHOICES.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
//normal: max time is 1000 * level
|
//normal: max time is 1000 * level
|
||||||
int MAX_TIME = 1000 * startGame.getArtificialLevel(scorePlayer.getIndex());
|
int MAX_TIME = 1000 * startGame.getArtificialLevel(scorePlayer.getIndex());
|
||||||
int MAX_SIM = Integer.MAX_VALUE;
|
int MAX_SIM = Integer.MAX_VALUE;
|
||||||
|
|
||||||
final long START_TIME = System.currentTimeMillis();
|
final long START_TIME = System.currentTimeMillis();
|
||||||
|
|
||||||
//root represents the start state
|
//root represents the start state
|
||||||
final MCTSGameTree root = MCTSGameTree.getNode(CACHE, startGame, RCHOICES);
|
final MCTSGameTree root = MCTSGameTree.getNode(CACHE, startGame, RCHOICES);
|
||||||
|
|
||||||
|
@ -139,29 +139,29 @@ public class MCTSAI implements MagicAI {
|
||||||
int sims;
|
int sims;
|
||||||
for (sims = 0;
|
for (sims = 0;
|
||||||
System.currentTimeMillis() - START_TIME < MAX_TIME &&
|
System.currentTimeMillis() - START_TIME < MAX_TIME &&
|
||||||
sims < MAX_SIM &&
|
sims < MAX_SIM &&
|
||||||
!root.isAIWin();
|
!root.isAIWin();
|
||||||
sims++) {
|
sims++) {
|
||||||
|
|
||||||
//clone the MagicGame object for simulation
|
//clone the MagicGame object for simulation
|
||||||
final MagicGame rootGame = new MagicGame(startGame, scorePlayer);
|
final MagicGame rootGame = new MagicGame(startGame, scorePlayer);
|
||||||
if (!CHEAT) {
|
if (!CHEAT) {
|
||||||
rootGame.hideHiddenCards();
|
rootGame.hideHiddenCards();
|
||||||
}
|
}
|
||||||
|
|
||||||
//pass in a clone of the state,
|
//pass in a clone of the state,
|
||||||
//genNewTreeNode grows the tree by one node
|
//genNewTreeNode grows the tree by one node
|
||||||
//and returns the path from the root to the new node
|
//and returns the path from the root to the new node
|
||||||
final LinkedList<MCTSGameTree> path = growTree(root, rootGame);
|
final LinkedList<MCTSGameTree> path = growTree(root, rootGame);
|
||||||
|
|
||||||
assert path.size() >= 2 : "ERROR! length of MCTS path is " + path.size();
|
assert path.size() >= 2 : "ERROR! length of MCTS path is " + path.size();
|
||||||
|
|
||||||
// play a simulated game to get score
|
// play a simulated game to get score
|
||||||
// update all nodes along the path from root to new node
|
// update all nodes along the path from root to new node
|
||||||
final double score = randomPlay(path.getLast(), rootGame);
|
final double score = randomPlay(path.getLast(), rootGame);
|
||||||
|
|
||||||
// update score and game theoretic value along the chosen path
|
// update score and game theoretic value along the chosen path
|
||||||
MCTSGameTree child = null;
|
MCTSGameTree child = null;
|
||||||
MCTSGameTree parent = null;
|
MCTSGameTree parent = null;
|
||||||
while (!path.isEmpty()) {
|
while (!path.isEmpty()) {
|
||||||
child = parent;
|
child = parent;
|
||||||
|
@ -179,8 +179,8 @@ public class MCTSAI implements MagicAI {
|
||||||
parent.incLose(steps);
|
parent.incLose(steps);
|
||||||
} else if (parent.isOpp() && child.isAIWin()) {
|
} else if (parent.isOpp() && child.isAIWin()) {
|
||||||
parent.incLose(steps);
|
parent.incLose(steps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,7 +193,7 @@ public class MCTSAI implements MagicAI {
|
||||||
for (final MCTSGameTree node : root) {
|
for (final MCTSGameTree node : root) {
|
||||||
final double D = node.getDecision();
|
final double D = node.getDecision();
|
||||||
final int C = node.getChoice();
|
final int C = node.getChoice();
|
||||||
if (D > maxD) {
|
if (D > maxD) {
|
||||||
maxD = D;
|
maxD = D;
|
||||||
bestC = C;
|
bestC = C;
|
||||||
}
|
}
|
||||||
|
@ -203,22 +203,22 @@ public class MCTSAI implements MagicAI {
|
||||||
|
|
||||||
return startGame.map(RCHOICES.get(bestC));
|
return startGame.map(RCHOICES.get(bestC));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String outputChoice(
|
private String outputChoice(
|
||||||
final MagicPlayer scorePlayer,
|
final MagicPlayer scorePlayer,
|
||||||
final MCTSGameTree root,
|
final MCTSGameTree root,
|
||||||
final long START_TIME,
|
final long START_TIME,
|
||||||
final int bestC,
|
final int bestC,
|
||||||
final int sims) {
|
final int sims) {
|
||||||
|
|
||||||
final StringBuilder out = new StringBuilder();
|
final StringBuilder out = new StringBuilder();
|
||||||
final long duration = System.currentTimeMillis() - START_TIME;
|
final long duration = System.currentTimeMillis() - START_TIME;
|
||||||
|
|
||||||
out.append("MCTS" +
|
out.append("MCTS" +
|
||||||
" cheat=" + CHEAT +
|
" cheat=" + CHEAT +
|
||||||
" index=" + scorePlayer.getIndex() +
|
" index=" + scorePlayer.getIndex() +
|
||||||
" life=" + scorePlayer.getLife() +
|
" life=" + scorePlayer.getLife() +
|
||||||
" time=" + duration +
|
" time=" + duration +
|
||||||
" sims=" + sims);
|
" sims=" + sims);
|
||||||
out.append('\n');
|
out.append('\n');
|
||||||
|
|
||||||
|
@ -262,16 +262,16 @@ public class MCTSAI implements MagicAI {
|
||||||
choices = getNextChoices(game, false)) {
|
choices = getNextChoices(game, false)) {
|
||||||
|
|
||||||
assert choices.size() > 0 : "ERROR! No choice at start of genNewTreeNode";
|
assert choices.size() > 0 : "ERROR! No choice at start of genNewTreeNode";
|
||||||
|
|
||||||
assert !curr.hasDetails() || MCTSGameTree.checkNode(curr, choices) :
|
assert !curr.hasDetails() || MCTSGameTree.checkNode(curr, choices) :
|
||||||
"ERROR! Inconsistent node found" + "\n" +
|
"ERROR! Inconsistent node found" + "\n" +
|
||||||
game + " " +
|
game + " " +
|
||||||
printPath(path) + " " +
|
printPath(path) + " " +
|
||||||
MCTSGameTree.printNode(curr, choices);
|
MCTSGameTree.printNode(curr, choices);
|
||||||
|
|
||||||
final MagicEvent event = game.getNextEvent();
|
final MagicEvent event = game.getNextEvent();
|
||||||
|
|
||||||
//first time considering the choices available at this node,
|
//first time considering the choices available at this node,
|
||||||
//fill in additional details for curr
|
//fill in additional details for curr
|
||||||
if (!curr.hasDetails()) {
|
if (!curr.hasDetails()) {
|
||||||
curr.setIsAI(game.getScorePlayer() == event.getPlayer());
|
curr.setIsAI(game.getScorePlayer() == event.getPlayer());
|
||||||
|
@ -292,17 +292,17 @@ public class MCTSAI implements MagicAI {
|
||||||
final int idx = curr.size();
|
final int idx = curr.size();
|
||||||
final Object[] choice = choices.get(idx);
|
final Object[] choice = choices.get(idx);
|
||||||
game.executeNextEvent(choice);
|
game.executeNextEvent(choice);
|
||||||
final MCTSGameTree child = new MCTSGameTree(curr, idx, game.getScore());
|
final MCTSGameTree child = new MCTSGameTree(curr, idx, game.getScore());
|
||||||
assert (child.desc = MCTSGameTree.obj2String(choice[0])).equals(child.desc);
|
assert (child.desc = MCTSGameTree.obj2String(choice[0])).equals(child.desc);
|
||||||
curr.addChild(child);
|
curr.addChild(child);
|
||||||
path.add(child);
|
path.add(child);
|
||||||
return path;
|
return path;
|
||||||
|
|
||||||
//all the children are in the tree, find the "best" child to explore
|
//all the children are in the tree, find the "best" child to explore
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
assert curr.size() == choices.size() : "ERROR! Different number of choices in node and game" +
|
assert curr.size() == choices.size() : "ERROR! Different number of choices in node and game" +
|
||||||
printPath(path) + MCTSGameTree.printNode(curr, choices);
|
printPath(path) + MCTSGameTree.printNode(curr, choices);
|
||||||
|
|
||||||
MCTSGameTree next = null;
|
MCTSGameTree next = null;
|
||||||
double bestS = Double.NEGATIVE_INFINITY ;
|
double bestS = Double.NEGATIVE_INFINITY ;
|
||||||
|
@ -317,13 +317,13 @@ public class MCTSAI implements MagicAI {
|
||||||
|
|
||||||
//move down the tree
|
//move down the tree
|
||||||
curr = next;
|
curr = next;
|
||||||
|
|
||||||
//update the game state and path
|
//update the game state and path
|
||||||
game.executeNextEvent(choices.get(curr.getChoice()));
|
game.executeNextEvent(choices.get(curr.getChoice()));
|
||||||
path.add(curr);
|
path.add(curr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,7 +339,7 @@ public class MCTSAI implements MagicAI {
|
||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CHEAT) {
|
if (!CHEAT) {
|
||||||
game.showRandomizedHiddenCards();
|
game.showRandomizedHiddenCards();
|
||||||
}
|
}
|
||||||
|
@ -355,16 +355,16 @@ public class MCTSAI implements MagicAI {
|
||||||
return 1.0 - actions/(2.0 * MAX_ACTIONS);
|
return 1.0 - actions/(2.0 * MAX_ACTIONS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Object[]> getNextChoices(final MagicGame game, final boolean sim) {
|
private List<Object[]> getNextChoices(final MagicGame game, final boolean sim) {
|
||||||
|
|
||||||
final int startActions = game.getNumActions();
|
final int startActions = game.getNumActions();
|
||||||
|
|
||||||
//use fast choices during simulation
|
//use fast choices during simulation
|
||||||
game.setFastChoices(sim);
|
game.setFastChoices(sim);
|
||||||
|
|
||||||
// simulate game until it is finished or simulated MAX_ACTIONS actions
|
// simulate game until it is finished or simulated MAX_ACTIONS actions
|
||||||
while (!game.isFinished() &&
|
while (!game.isFinished() &&
|
||||||
(game.getNumActions() - startActions) < MAX_ACTIONS) {
|
(game.getNumActions() - startActions) < MAX_ACTIONS) {
|
||||||
|
|
||||||
//do not accumulate score down the tree when not in simulation
|
//do not accumulate score down the tree when not in simulation
|
||||||
|
@ -384,7 +384,7 @@ public class MCTSAI implements MagicAI {
|
||||||
game.executeNextEvent();
|
game.executeNextEvent();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//event has choice
|
//event has choice
|
||||||
|
|
||||||
if (sim) {
|
if (sim) {
|
||||||
|
@ -413,10 +413,10 @@ public class MCTSAI implements MagicAI {
|
||||||
choices = event.getArtificialChoiceResults(game);
|
choices = event.getArtificialChoiceResults(game);
|
||||||
}
|
}
|
||||||
assert choices != null;
|
assert choices != null;
|
||||||
|
|
||||||
final int size = choices.size();
|
final int size = choices.size();
|
||||||
assert size > 0 : "ERROR! No choice found during MCTS getACR";
|
assert size > 0 : "ERROR! No choice found during MCTS getACR";
|
||||||
|
|
||||||
if (size == 1) {
|
if (size == 1) {
|
||||||
//single choice
|
//single choice
|
||||||
game.executeNextEvent(choices.get(0));
|
game.executeNextEvent(choices.get(0));
|
||||||
|
@ -426,11 +426,11 @@ public class MCTSAI implements MagicAI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//game is finished or number of actions > MAX_ACTIONS
|
//game is finished or number of actions > MAX_ACTIONS
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String CR2String(final Object[] choiceResults) {
|
private static String CR2String(final Object[] choiceResults) {
|
||||||
final StringBuilder buffer=new StringBuilder();
|
final StringBuilder buffer=new StringBuilder();
|
||||||
if (choiceResults!=null) {
|
if (choiceResults!=null) {
|
||||||
|
@ -461,7 +461,7 @@ public class MCTSAI implements MagicAI {
|
||||||
|
|
||||||
//each tree node stores the choice from the parent that leads to this node
|
//each tree node stores the choice from the parent that leads to this node
|
||||||
class MCTSGameTree implements Iterable<MCTSGameTree> {
|
class MCTSGameTree implements Iterable<MCTSGameTree> {
|
||||||
|
|
||||||
private final MCTSGameTree parent;
|
private final MCTSGameTree parent;
|
||||||
private final LinkedList<MCTSGameTree> children = new LinkedList<MCTSGameTree>();
|
private final LinkedList<MCTSGameTree> children = new LinkedList<MCTSGameTree>();
|
||||||
private final int choice;
|
private final int choice;
|
||||||
|
@ -476,21 +476,21 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
|
||||||
private double S;
|
private double S;
|
||||||
String desc;
|
String desc;
|
||||||
private String[] choicesStr;
|
private String[] choicesStr;
|
||||||
|
|
||||||
//min sim for using robust max
|
//min sim for using robust max
|
||||||
private int maxChildSim = MCTSAI.MIN_SIM;
|
private int maxChildSim = MCTSAI.MIN_SIM;
|
||||||
|
|
||||||
MCTSGameTree(final MCTSGameTree parent, final int choice, final int evalScore) {
|
MCTSGameTree(final MCTSGameTree parent, final int choice, final int evalScore) {
|
||||||
this.evalScore = evalScore;
|
this.evalScore = evalScore;
|
||||||
this.choice = choice;
|
this.choice = choice;
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean log(final String message) {
|
private static boolean log(final String message) {
|
||||||
System.err.println(message);
|
System.err.println(message);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int obj2StringHash(final Object obj) {
|
private static int obj2StringHash(final Object obj) {
|
||||||
return obj2String(obj).hashCode();
|
return obj2String(obj).hashCode();
|
||||||
}
|
}
|
||||||
|
@ -504,10 +504,10 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
|
||||||
return obj.toString();
|
return obj.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addNode(
|
static void addNode(
|
||||||
final LRUCache<Long, MCTSGameTree> cache,
|
final LRUCache<Long, MCTSGameTree> cache,
|
||||||
final MagicGame game,
|
final MagicGame game,
|
||||||
final MCTSGameTree node) {
|
final MCTSGameTree node) {
|
||||||
if (node.isCached()) {
|
if (node.isCached()) {
|
||||||
return;
|
return;
|
||||||
|
@ -519,13 +519,13 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
|
||||||
}
|
}
|
||||||
|
|
||||||
static MCTSGameTree getNode(
|
static MCTSGameTree getNode(
|
||||||
final LRUCache<Long, MCTSGameTree> cache,
|
final LRUCache<Long, MCTSGameTree> cache,
|
||||||
final MagicGame game,
|
final MagicGame game,
|
||||||
final List<Object[]> choices) {
|
final List<Object[]> choices) {
|
||||||
final long gid = game.getStateId();
|
final long gid = game.getStateId();
|
||||||
final MCTSGameTree candidate = cache.get(gid);
|
final MCTSGameTree candidate = cache.get(gid);
|
||||||
|
|
||||||
if (candidate != null) {
|
if (candidate != null) {
|
||||||
assert log("CACHE HIT");
|
assert log("CACHE HIT");
|
||||||
assert log("HIT : " + game.getIdString());
|
assert log("HIT : " + game.getIdString());
|
||||||
assert printNode(candidate, choices);
|
assert printNode(candidate, choices);
|
||||||
|
@ -538,7 +538,7 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean checkNode(final MCTSGameTree curr, final List<Object[]> choices) {
|
static boolean checkNode(final MCTSGameTree curr, final List<Object[]> choices) {
|
||||||
if (curr.getMaxChildren() != choices.size()) {
|
if (curr.getMaxChildren() != choices.size()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -557,8 +557,8 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static boolean printNode(final MCTSGameTree curr, final List<Object[]> choices) {
|
static boolean printNode(final MCTSGameTree curr, final List<Object[]> choices) {
|
||||||
if (curr.choicesStr != null) {
|
if (curr.choicesStr != null) {
|
||||||
for (final String str : curr.choicesStr) {
|
for (final String str : curr.choicesStr) {
|
||||||
|
@ -600,7 +600,7 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
|
||||||
void setMaxChildren(final int mc) {
|
void setMaxChildren(final int mc) {
|
||||||
maxChildren = mc;
|
maxChildren = mc;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getMaxChildren() {
|
private int getMaxChildren() {
|
||||||
return maxChildren;
|
return maxChildren;
|
||||||
}
|
}
|
||||||
|
@ -612,7 +612,7 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
|
||||||
boolean isOpp() {
|
boolean isOpp() {
|
||||||
return !isAI;
|
return !isAI;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setIsAI(final boolean ai) {
|
void setIsAI(final boolean ai) {
|
||||||
this.isAI = ai;
|
this.isAI = ai;
|
||||||
}
|
}
|
||||||
|
@ -620,13 +620,13 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
|
||||||
boolean isSolved() {
|
boolean isSolved() {
|
||||||
return evalScore == Integer.MAX_VALUE || evalScore == Integer.MIN_VALUE;
|
return evalScore == Integer.MAX_VALUE || evalScore == Integer.MIN_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateScore(final MCTSGameTree child, final double delta) {
|
void updateScore(final MCTSGameTree child, final double delta) {
|
||||||
final double oldMean = (numSim > 0) ? sum/numSim : 0;
|
final double oldMean = (numSim > 0) ? sum/numSim : 0;
|
||||||
sum += delta;
|
sum += delta;
|
||||||
numSim += 1;
|
numSim += 1;
|
||||||
final double newMean = sum/numSim;
|
final double newMean = sum/numSim;
|
||||||
S += (delta - oldMean) * (delta - newMean);
|
S += (delta - oldMean) * (delta - newMean);
|
||||||
|
|
||||||
//if child has sufficient simulations, backup using robust max instead of average
|
//if child has sufficient simulations, backup using robust max instead of average
|
||||||
if (child != null && child.getNumSim() > maxChildSim) {
|
if (child != null && child.getNumSim() > maxChildSim) {
|
||||||
|
@ -635,11 +635,11 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
|
||||||
numSim = child.numSim;
|
numSim = child.numSim;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double getUCT() {
|
double getUCT() {
|
||||||
return getV() + MCTSAI.UCB1_C * Math.sqrt(Math.log(parent.getNumSim()) / getNumSim());
|
return getV() + MCTSAI.UCB1_C * Math.sqrt(Math.log(parent.getNumSim()) / getNumSim());
|
||||||
}
|
}
|
||||||
|
|
||||||
private double getRatio() {
|
private double getRatio() {
|
||||||
return (getSum() + MCTSAI.RATIO_K)/(getNumSim() + 2*MCTSAI.RATIO_K);
|
return (getSum() + MCTSAI.RATIO_K)/(getNumSim() + 2*MCTSAI.RATIO_K);
|
||||||
}
|
}
|
||||||
|
@ -647,7 +647,7 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
|
||||||
private double getNormal() {
|
private double getNormal() {
|
||||||
return Math.max(1.0, getV() + 2 * Math.sqrt(getVar()));
|
return Math.max(1.0, getV() + 2 * Math.sqrt(getVar()));
|
||||||
}
|
}
|
||||||
|
|
||||||
//decrease score of lose node, boost score of win nodes
|
//decrease score of lose node, boost score of win nodes
|
||||||
double modify(final double sc) {
|
double modify(final double sc) {
|
||||||
if ((!parent.isAI() && isAIWin()) || (parent.isAI() && isAILose())) {
|
if ((!parent.isAI() && isAIWin()) || (parent.isAI() && isAILose())) {
|
||||||
|
@ -655,8 +655,8 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
|
||||||
} else if ((parent.isAI() && isAIWin()) || (!parent.isAI() && isAILose())) {
|
} else if ((parent.isAI() && isAIWin()) || (!parent.isAI() && isAILose())) {
|
||||||
return sc + 2.0;
|
return sc + 2.0;
|
||||||
} else {
|
} else {
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private double getVar() {
|
private double getVar() {
|
||||||
|
@ -671,7 +671,7 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
|
||||||
boolean isAIWin() {
|
boolean isAIWin() {
|
||||||
return evalScore == Integer.MAX_VALUE;
|
return evalScore == Integer.MAX_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isAILose() {
|
boolean isAILose() {
|
||||||
return evalScore == Integer.MIN_VALUE;
|
return evalScore == Integer.MIN_VALUE;
|
||||||
}
|
}
|
||||||
|
@ -691,7 +691,7 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
|
||||||
int getChoice() {
|
int getChoice() {
|
||||||
return choice;
|
return choice;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getSteps() {
|
int getSteps() {
|
||||||
return steps;
|
return steps;
|
||||||
}
|
}
|
||||||
|
@ -709,9 +709,9 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
|
||||||
private int getEvalScore() {
|
private int getEvalScore() {
|
||||||
return evalScore;
|
return evalScore;
|
||||||
}
|
}
|
||||||
|
|
||||||
double getDecision() {
|
double getDecision() {
|
||||||
//boost decision score of win nodes by BOOST
|
//boost decision score of win nodes by BOOST
|
||||||
final int BOOST = 1000000;
|
final int BOOST = 1000000;
|
||||||
if (isAIWin()) {
|
if (isAIWin()) {
|
||||||
return BOOST + getNumSim();
|
return BOOST + getNumSim();
|
||||||
|
@ -721,16 +721,16 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
|
||||||
return getNumSim();
|
return getNumSim();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int getNumSim() {
|
int getNumSim() {
|
||||||
return numSim;
|
return numSim;
|
||||||
}
|
}
|
||||||
|
|
||||||
private double getSum() {
|
private double getSum() {
|
||||||
// AI is max player, other is min player
|
// AI is max player, other is min player
|
||||||
return parent.isAI() ? sum : -sum;
|
return parent.isAI() ? sum : -sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getAvg() {
|
public double getAvg() {
|
||||||
return sum / numSim;
|
return sum / numSim;
|
||||||
}
|
}
|
||||||
|
@ -738,7 +738,7 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
|
||||||
double getV() {
|
double getV() {
|
||||||
return getSum() / numSim;
|
return getSum() / numSim;
|
||||||
}
|
}
|
||||||
|
|
||||||
private double getSecureScore() {
|
private double getSecureScore() {
|
||||||
return getV() + 1.0/Math.sqrt(numSim);
|
return getV() + 1.0/Math.sqrt(numSim);
|
||||||
}
|
}
|
||||||
|
@ -747,11 +747,11 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
|
||||||
assert children.size() < maxChildren : "ERROR! Number of children nodes exceed maxChildren";
|
assert children.size() < maxChildren : "ERROR! Number of children nodes exceed maxChildren";
|
||||||
children.add(child);
|
children.add(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
MCTSGameTree first() {
|
MCTSGameTree first() {
|
||||||
return children.get(0);
|
return children.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Iterator<MCTSGameTree> iterator() {
|
public Iterator<MCTSGameTree> iterator() {
|
||||||
return children.iterator();
|
return children.iterator();
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ Classical MCTS (UCT)
|
||||||
- score = XX% (25000 matches against MMAB-1)
|
- score = XX% (25000 matches against MMAB-1)
|
||||||
|
|
||||||
Enchancements to basic UCT
|
Enchancements to basic UCT
|
||||||
- use ratio selection (v + 10)/(n + 10)
|
- use ratio selection (v + 10)/(n + 10)
|
||||||
- UCB1 with C = 1.0
|
- UCB1 with C = 1.0
|
||||||
- UCB1 with C = 2.0
|
- UCB1 with C = 2.0
|
||||||
- UCB1 with C = 3.0
|
- UCB1 with C = 3.0
|
||||||
|
@ -46,7 +46,7 @@ Consistency Modifications for Automatically Tuned Monte-Carlo Tree Search
|
||||||
using v_t threshold ensures consistency for case of reward in {0,1} using any score function
|
using v_t threshold ensures consistency for case of reward in {0,1} using any score function
|
||||||
v(s) < v_t (0.3), randomy pick a child, else pick child that maximize score
|
v(s) < v_t (0.3), randomy pick a child, else pick child that maximize score
|
||||||
|
|
||||||
Monte-Carlo Tree Search in Lines of Action
|
Monte-Carlo Tree Search in Lines of Action
|
||||||
1-ply lookahread to detect direct win for player to move
|
1-ply lookahread to detect direct win for player to move
|
||||||
secure child formula for decision v + A/sqrt(n)
|
secure child formula for decision v + A/sqrt(n)
|
||||||
evaluation cut-off: use score function to stop simulation early
|
evaluation cut-off: use score function to stop simulation early
|
||||||
|
@ -55,7 +55,7 @@ Monte-Carlo Tree Search in Lines of Action
|
||||||
mixed: start with corrective, rest of the moves use greedy
|
mixed: start with corrective, rest of the moves use greedy
|
||||||
*/
|
*/
|
||||||
public class MCTSAI2 implements MagicAI {
|
public class MCTSAI2 implements MagicAI {
|
||||||
|
|
||||||
private static int MIN_SCORE = Integer.MAX_VALUE;
|
private static int MIN_SCORE = Integer.MAX_VALUE;
|
||||||
static int MIN_SIM = Integer.MAX_VALUE;
|
static int MIN_SIM = Integer.MAX_VALUE;
|
||||||
private static final int MAX_ACTIONS = 10000;
|
private static final int MAX_ACTIONS = 10000;
|
||||||
|
@ -72,12 +72,12 @@ public class MCTSAI2 implements MagicAI {
|
||||||
MIN_SCORE = Integer.parseInt(System.getProperty("min_score"));
|
MIN_SCORE = Integer.parseInt(System.getProperty("min_score"));
|
||||||
System.err.println("MIN_SCORE = " + MIN_SCORE);
|
System.err.println("MIN_SCORE = " + MIN_SCORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (System.getProperty("ucb1_c") != null) {
|
if (System.getProperty("ucb1_c") != null) {
|
||||||
UCB1_C = Double.parseDouble(System.getProperty("ucb1_c"));
|
UCB1_C = Double.parseDouble(System.getProperty("ucb1_c"));
|
||||||
System.err.println("UCB1_C = " + UCB1_C);
|
System.err.println("UCB1_C = " + UCB1_C);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (System.getProperty("ratio_k") != null) {
|
if (System.getProperty("ratio_k") != null) {
|
||||||
RATIO_K = Double.parseDouble(System.getProperty("ratio_k"));
|
RATIO_K = Double.parseDouble(System.getProperty("ratio_k"));
|
||||||
System.err.println("RATIO_K = " + RATIO_K);
|
System.err.println("RATIO_K = " + RATIO_K);
|
||||||
|
@ -105,7 +105,7 @@ public class MCTSAI2 implements MagicAI {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object[] findNextEventChoiceResults(
|
public Object[] findNextEventChoiceResults(
|
||||||
final MagicGame startGame,
|
final MagicGame startGame,
|
||||||
final MagicPlayer scorePlayer) {
|
final MagicPlayer scorePlayer) {
|
||||||
|
|
||||||
// Determine possible choices
|
// Determine possible choices
|
||||||
|
@ -115,21 +115,21 @@ public class MCTSAI2 implements MagicAI {
|
||||||
choiceGame = null;
|
choiceGame = null;
|
||||||
|
|
||||||
final int size = RCHOICES.size();
|
final int size = RCHOICES.size();
|
||||||
|
|
||||||
// No choice
|
// No choice
|
||||||
assert size > 0 : "ERROR! No choice found at start of MCTS";
|
assert size > 0 : "ERROR! No choice found at start of MCTS";
|
||||||
|
|
||||||
// Single choice
|
// Single choice
|
||||||
if (size == 1) {
|
if (size == 1) {
|
||||||
return startGame.map(RCHOICES.get(0));
|
return startGame.map(RCHOICES.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
//normal: max time is 1000 * level
|
//normal: max time is 1000 * level
|
||||||
int MAX_TIME = 1000 * startGame.getArtificialLevel(scorePlayer.getIndex());
|
int MAX_TIME = 1000 * startGame.getArtificialLevel(scorePlayer.getIndex());
|
||||||
int MAX_SIM = Integer.MAX_VALUE;
|
int MAX_SIM = Integer.MAX_VALUE;
|
||||||
|
|
||||||
final long START_TIME = System.currentTimeMillis();
|
final long START_TIME = System.currentTimeMillis();
|
||||||
|
|
||||||
//root represents the start state
|
//root represents the start state
|
||||||
final MCTSGameTree root = MCTSGameTree.getNode(CACHE, startGame, RCHOICES);
|
final MCTSGameTree root = MCTSGameTree.getNode(CACHE, startGame, RCHOICES);
|
||||||
|
|
||||||
|
@ -139,29 +139,29 @@ public class MCTSAI2 implements MagicAI {
|
||||||
int sims;
|
int sims;
|
||||||
for (sims = 0;
|
for (sims = 0;
|
||||||
System.currentTimeMillis() - START_TIME < MAX_TIME &&
|
System.currentTimeMillis() - START_TIME < MAX_TIME &&
|
||||||
sims < MAX_SIM &&
|
sims < MAX_SIM &&
|
||||||
!root.isAIWin();
|
!root.isAIWin();
|
||||||
sims++) {
|
sims++) {
|
||||||
|
|
||||||
//clone the MagicGame object for simulation
|
//clone the MagicGame object for simulation
|
||||||
final MagicGame rootGame = new MagicGame(startGame, scorePlayer);
|
final MagicGame rootGame = new MagicGame(startGame, scorePlayer);
|
||||||
if (!CHEAT) {
|
if (!CHEAT) {
|
||||||
rootGame.hideHiddenCards();
|
rootGame.hideHiddenCards();
|
||||||
}
|
}
|
||||||
|
|
||||||
//pass in a clone of the state,
|
//pass in a clone of the state,
|
||||||
//genNewTreeNode grows the tree by one node
|
//genNewTreeNode grows the tree by one node
|
||||||
//and returns the path from the root to the new node
|
//and returns the path from the root to the new node
|
||||||
final LinkedList<MCTSGameTree> path = growTree(root, rootGame);
|
final LinkedList<MCTSGameTree> path = growTree(root, rootGame);
|
||||||
|
|
||||||
assert path.size() >= 2 : "ERROR! length of MCTS path is " + path.size();
|
assert path.size() >= 2 : "ERROR! length of MCTS path is " + path.size();
|
||||||
|
|
||||||
// play a simulated game to get score
|
// play a simulated game to get score
|
||||||
// update all nodes along the path from root to new node
|
// update all nodes along the path from root to new node
|
||||||
final double score = randomPlay(path.getLast(), rootGame);
|
final double score = randomPlay(path.getLast(), rootGame);
|
||||||
|
|
||||||
// update score and game theoretic value along the chosen path
|
// update score and game theoretic value along the chosen path
|
||||||
MCTSGameTree child = null;
|
MCTSGameTree child = null;
|
||||||
MCTSGameTree parent = null;
|
MCTSGameTree parent = null;
|
||||||
while (!path.isEmpty()) {
|
while (!path.isEmpty()) {
|
||||||
child = parent;
|
child = parent;
|
||||||
|
@ -179,8 +179,8 @@ public class MCTSAI2 implements MagicAI {
|
||||||
parent.incLose(steps);
|
parent.incLose(steps);
|
||||||
} else if (parent.isOpp() && child.isAIWin()) {
|
} else if (parent.isOpp() && child.isAIWin()) {
|
||||||
parent.incLose(steps);
|
parent.incLose(steps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,7 +193,7 @@ public class MCTSAI2 implements MagicAI {
|
||||||
for (final MCTSGameTree node : root) {
|
for (final MCTSGameTree node : root) {
|
||||||
final double D = node.getDecision();
|
final double D = node.getDecision();
|
||||||
final int C = node.getChoice();
|
final int C = node.getChoice();
|
||||||
if (D > maxD) {
|
if (D > maxD) {
|
||||||
maxD = D;
|
maxD = D;
|
||||||
bestC = C;
|
bestC = C;
|
||||||
}
|
}
|
||||||
|
@ -203,22 +203,22 @@ public class MCTSAI2 implements MagicAI {
|
||||||
|
|
||||||
return startGame.map(RCHOICES.get(bestC));
|
return startGame.map(RCHOICES.get(bestC));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String outputChoice(
|
private String outputChoice(
|
||||||
final MagicPlayer scorePlayer,
|
final MagicPlayer scorePlayer,
|
||||||
final MCTSGameTree root,
|
final MCTSGameTree root,
|
||||||
final long START_TIME,
|
final long START_TIME,
|
||||||
final int bestC,
|
final int bestC,
|
||||||
final int sims) {
|
final int sims) {
|
||||||
|
|
||||||
final StringBuilder out = new StringBuilder();
|
final StringBuilder out = new StringBuilder();
|
||||||
final long duration = System.currentTimeMillis() - START_TIME;
|
final long duration = System.currentTimeMillis() - START_TIME;
|
||||||
|
|
||||||
out.append("MCTS2" +
|
out.append("MCTS2" +
|
||||||
" cheat=" + CHEAT +
|
" cheat=" + CHEAT +
|
||||||
" index=" + scorePlayer.getIndex() +
|
" index=" + scorePlayer.getIndex() +
|
||||||
" life=" + scorePlayer.getLife() +
|
" life=" + scorePlayer.getLife() +
|
||||||
" time=" + duration +
|
" time=" + duration +
|
||||||
" sims=" + sims);
|
" sims=" + sims);
|
||||||
out.append('\n');
|
out.append('\n');
|
||||||
|
|
||||||
|
@ -262,16 +262,16 @@ public class MCTSAI2 implements MagicAI {
|
||||||
choices = getNextChoices(game, false)) {
|
choices = getNextChoices(game, false)) {
|
||||||
|
|
||||||
assert choices.size() > 0 : "ERROR! No choice at start of genNewTreeNode";
|
assert choices.size() > 0 : "ERROR! No choice at start of genNewTreeNode";
|
||||||
|
|
||||||
assert !curr.hasDetails() || MCTSGameTree.checkNode(curr, choices) :
|
assert !curr.hasDetails() || MCTSGameTree.checkNode(curr, choices) :
|
||||||
"ERROR! Inconsistent node found" + "\n" +
|
"ERROR! Inconsistent node found" + "\n" +
|
||||||
game + " " +
|
game + " " +
|
||||||
printPath(path) + " " +
|
printPath(path) + " " +
|
||||||
MCTSGameTree.printNode(curr, choices);
|
MCTSGameTree.printNode(curr, choices);
|
||||||
|
|
||||||
final MagicEvent event = game.getNextEvent();
|
final MagicEvent event = game.getNextEvent();
|
||||||
|
|
||||||
//first time considering the choices available at this node,
|
//first time considering the choices available at this node,
|
||||||
//fill in additional details for curr
|
//fill in additional details for curr
|
||||||
if (!curr.hasDetails()) {
|
if (!curr.hasDetails()) {
|
||||||
curr.setIsAI(game.getScorePlayer() == event.getPlayer());
|
curr.setIsAI(game.getScorePlayer() == event.getPlayer());
|
||||||
|
@ -292,23 +292,23 @@ public class MCTSAI2 implements MagicAI {
|
||||||
final int idx = curr.size();
|
final int idx = curr.size();
|
||||||
final Object[] choice = choices.get(idx);
|
final Object[] choice = choices.get(idx);
|
||||||
game.executeNextEvent(choice);
|
game.executeNextEvent(choice);
|
||||||
final MCTSGameTree child = new MCTSGameTree(curr, idx, game.getScore());
|
final MCTSGameTree child = new MCTSGameTree(curr, idx, game.getScore());
|
||||||
assert (child.desc = MCTSGameTree.obj2String(choice[0])).equals(child.desc);
|
assert (child.desc = MCTSGameTree.obj2String(choice[0])).equals(child.desc);
|
||||||
curr.addChild(child);
|
curr.addChild(child);
|
||||||
path.add(child);
|
path.add(child);
|
||||||
return path;
|
return path;
|
||||||
|
|
||||||
//all the children are in the tree, find the "best" child to explore
|
//all the children are in the tree, find the "best" child to explore
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
assert curr.size() == choices.size() : "ERROR! Different number of choices in node and game" +
|
assert curr.size() == choices.size() : "ERROR! Different number of choices in node and game" +
|
||||||
printPath(path) + MCTSGameTree.printNode(curr, choices);
|
printPath(path) + MCTSGameTree.printNode(curr, choices);
|
||||||
|
|
||||||
MCTSGameTree next = null;
|
MCTSGameTree next = null;
|
||||||
double bestS = Double.NEGATIVE_INFINITY ;
|
double bestS = Double.NEGATIVE_INFINITY ;
|
||||||
for (final MCTSGameTree child : curr) {
|
for (final MCTSGameTree child : curr) {
|
||||||
final double raw =
|
final double raw =
|
||||||
child.getAvg() * (curr.isAI() ? 1 : -1) +
|
child.getAvg() * (curr.isAI() ? 1 : -1) +
|
||||||
MCTSAI.UCB1_C * Math.sqrt(Math.log(curr.getNumSim()) / child.getNumSim());
|
MCTSAI.UCB1_C * Math.sqrt(Math.log(curr.getNumSim()) / child.getNumSim());
|
||||||
final double S = child.modify(raw);
|
final double S = child.modify(raw);
|
||||||
if (S > bestS) {
|
if (S > bestS) {
|
||||||
|
@ -319,13 +319,13 @@ public class MCTSAI2 implements MagicAI {
|
||||||
|
|
||||||
//move down the tree
|
//move down the tree
|
||||||
curr = next;
|
curr = next;
|
||||||
|
|
||||||
//update the game state and path
|
//update the game state and path
|
||||||
game.executeNextEvent(choices.get(curr.getChoice()));
|
game.executeNextEvent(choices.get(curr.getChoice()));
|
||||||
path.add(curr);
|
path.add(curr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,7 +341,7 @@ public class MCTSAI2 implements MagicAI {
|
||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CHEAT) {
|
if (!CHEAT) {
|
||||||
game.showRandomizedHiddenCards();
|
game.showRandomizedHiddenCards();
|
||||||
}
|
}
|
||||||
|
@ -357,16 +357,16 @@ public class MCTSAI2 implements MagicAI {
|
||||||
return 1.0 - actions/(2.0 * MAX_ACTIONS);
|
return 1.0 - actions/(2.0 * MAX_ACTIONS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Object[]> getNextChoices(final MagicGame game, final boolean sim) {
|
private List<Object[]> getNextChoices(final MagicGame game, final boolean sim) {
|
||||||
|
|
||||||
final int startActions = game.getNumActions();
|
final int startActions = game.getNumActions();
|
||||||
|
|
||||||
//use fast choices during simulation
|
//use fast choices during simulation
|
||||||
game.setFastChoices(sim);
|
game.setFastChoices(sim);
|
||||||
|
|
||||||
// simulate game until it is finished or simulated MAX_ACTIONS actions
|
// simulate game until it is finished or simulated MAX_ACTIONS actions
|
||||||
while (!game.isFinished() &&
|
while (!game.isFinished() &&
|
||||||
(game.getNumActions() - startActions) < MAX_ACTIONS) {
|
(game.getNumActions() - startActions) < MAX_ACTIONS) {
|
||||||
|
|
||||||
//do not accumulate score down the tree when not in simulation
|
//do not accumulate score down the tree when not in simulation
|
||||||
|
@ -386,7 +386,7 @@ public class MCTSAI2 implements MagicAI {
|
||||||
game.executeNextEvent();
|
game.executeNextEvent();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//event has choice
|
//event has choice
|
||||||
|
|
||||||
if (sim) {
|
if (sim) {
|
||||||
|
@ -415,10 +415,10 @@ public class MCTSAI2 implements MagicAI {
|
||||||
choices = event.getArtificialChoiceResults(game);
|
choices = event.getArtificialChoiceResults(game);
|
||||||
}
|
}
|
||||||
assert choices != null;
|
assert choices != null;
|
||||||
|
|
||||||
final int size = choices.size();
|
final int size = choices.size();
|
||||||
assert size > 0 : "ERROR! No choice found during MCTS getACR";
|
assert size > 0 : "ERROR! No choice found during MCTS getACR";
|
||||||
|
|
||||||
if (size == 1) {
|
if (size == 1) {
|
||||||
//single choice
|
//single choice
|
||||||
game.executeNextEvent(choices.get(0));
|
game.executeNextEvent(choices.get(0));
|
||||||
|
@ -428,11 +428,11 @@ public class MCTSAI2 implements MagicAI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//game is finished or number of actions > MAX_ACTIONS
|
//game is finished or number of actions > MAX_ACTIONS
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String CR2String(final Object[] choiceResults) {
|
private static String CR2String(final Object[] choiceResults) {
|
||||||
final StringBuilder buffer=new StringBuilder();
|
final StringBuilder buffer=new StringBuilder();
|
||||||
if (choiceResults!=null) {
|
if (choiceResults!=null) {
|
||||||
|
|
|
@ -14,10 +14,10 @@ import magic.model.event.MagicEvent;
|
||||||
import magic.model.phase.MagicPhase;
|
import magic.model.phase.MagicPhase;
|
||||||
|
|
||||||
public class MMAB implements MagicAI {
|
public class MMAB implements MagicAI {
|
||||||
|
|
||||||
private static final long SEC_TO_NANO=1000000000L;
|
private static final long SEC_TO_NANO=1000000000L;
|
||||||
private static final int THREADS = Runtime.getRuntime().availableProcessors();
|
private static final int THREADS = Runtime.getRuntime().availableProcessors();
|
||||||
|
|
||||||
private final boolean LOGGING = Boolean.getBoolean("debug");
|
private final boolean LOGGING = Boolean.getBoolean("debug");
|
||||||
private final boolean CHEAT;
|
private final boolean CHEAT;
|
||||||
private final boolean DECKSTR;
|
private final boolean DECKSTR;
|
||||||
|
@ -34,32 +34,32 @@ public class MMAB implements MagicAI {
|
||||||
CHEAT = cheat;
|
CHEAT = cheat;
|
||||||
DECKSTR = deckStr;
|
DECKSTR = deckStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void log(final String message) {
|
private void log(final String message) {
|
||||||
MagicGameLog.log(message);
|
MagicGameLog.log(message);
|
||||||
if (LOGGING) {
|
if (LOGGING) {
|
||||||
System.err.println(message);
|
System.err.println(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object[] findNextEventChoiceResults(final MagicGame sourceGame, final MagicPlayer scorePlayer) {
|
public Object[] findNextEventChoiceResults(final MagicGame sourceGame, final MagicPlayer scorePlayer) {
|
||||||
final long startTime = System.currentTimeMillis();
|
final long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
// copying the game is necessary because for some choices game scores might be calculated,
|
// copying the game is necessary because for some choices game scores might be calculated,
|
||||||
// find all possible choice results.
|
// find all possible choice results.
|
||||||
MagicGame choiceGame = new MagicGame(sourceGame,scorePlayer);
|
MagicGame choiceGame = new MagicGame(sourceGame,scorePlayer);
|
||||||
final MagicEvent event = choiceGame.getNextEvent();
|
final MagicEvent event = choiceGame.getNextEvent();
|
||||||
final List<Object[]> choices = event.getArtificialChoiceResults(choiceGame);
|
final List<Object[]> choices = event.getArtificialChoiceResults(choiceGame);
|
||||||
final int size = choices.size();
|
final int size = choices.size();
|
||||||
choiceGame = null;
|
choiceGame = null;
|
||||||
|
|
||||||
assert size != 0 : "ERROR: no choices available for MMAB";
|
assert size != 0 : "ERROR: no choices available for MMAB";
|
||||||
|
|
||||||
// single choice result.
|
// single choice result.
|
||||||
if (size == 1) {
|
if (size == 1) {
|
||||||
return sourceGame.map(choices.get(0));
|
return sourceGame.map(choices.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// submit jobs
|
// submit jobs
|
||||||
final ArtificialPruneScoreRef scoreRef = new ArtificialPruneScoreRef(new ArtificialMultiPruneScore());
|
final ArtificialPruneScoreRef scoreRef = new ArtificialPruneScoreRef(new ArtificialMultiPruneScore());
|
||||||
final ArtificialScoreBoard scoreBoard = new ArtificialScoreBoard();
|
final ArtificialScoreBoard scoreBoard = new ArtificialScoreBoard();
|
||||||
|
@ -103,14 +103,14 @@ public class MMAB implements MagicAI {
|
||||||
// force termination of workers
|
// force termination of workers
|
||||||
executor.shutdownNow();
|
executor.shutdownNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
// select the best scoring choice result.
|
// select the best scoring choice result.
|
||||||
ArtificialScore bestScore = ArtificialScore.INVALID_SCORE;
|
ArtificialScore bestScore = ArtificialScore.INVALID_SCORE;
|
||||||
ArtificialChoiceResults bestAchoice = achoices.get(0);
|
ArtificialChoiceResults bestAchoice = achoices.get(0);
|
||||||
for (final ArtificialChoiceResults achoice : achoices) {
|
for (final ArtificialChoiceResults achoice : achoices) {
|
||||||
if (bestScore.isBetter(achoice.aiScore,true)) {
|
if (bestScore.isBetter(achoice.aiScore,true)) {
|
||||||
bestScore = achoice.aiScore;
|
bestScore = achoice.aiScore;
|
||||||
bestAchoice = achoice;
|
bestAchoice = achoice;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ public class MMAB implements MagicAI {
|
||||||
" cheat=" + CHEAT +
|
" cheat=" + CHEAT +
|
||||||
" index=" + scorePlayer.getIndex() +
|
" index=" + scorePlayer.getIndex() +
|
||||||
" life=" + scorePlayer.getLife() +
|
" life=" + scorePlayer.getLife() +
|
||||||
" phase=" + sourceGame.getPhase().getType() +
|
" phase=" + sourceGame.getPhase().getType() +
|
||||||
" slice=" + (slice/1000000) +
|
" slice=" + (slice/1000000) +
|
||||||
" time=" + timeTaken
|
" time=" + timeTaken
|
||||||
);
|
);
|
||||||
|
@ -139,21 +139,21 @@ class MMABWorker {
|
||||||
private final ArtificialScoreBoard scoreBoard;
|
private final ArtificialScoreBoard scoreBoard;
|
||||||
|
|
||||||
private int gameCount;
|
private int gameCount;
|
||||||
|
|
||||||
MMABWorker(final int id,final MagicGame game,final ArtificialScoreBoard scoreBoard, final boolean CHEAT) {
|
MMABWorker(final int id,final MagicGame game,final ArtificialScoreBoard scoreBoard, final boolean CHEAT) {
|
||||||
this.id=id;
|
this.id=id;
|
||||||
this.game=game;
|
this.game=game;
|
||||||
this.scoreBoard=scoreBoard;
|
this.scoreBoard=scoreBoard;
|
||||||
this.CHEAT=CHEAT;
|
this.CHEAT=CHEAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArtificialScore runGame(final Object[] nextChoiceResults, final ArtificialPruneScore pruneScore, final int depth, final long maxTime) {
|
private ArtificialScore runGame(final Object[] nextChoiceResults, final ArtificialPruneScore pruneScore, final int depth, final long maxTime) {
|
||||||
game.startActions();
|
game.startActions();
|
||||||
|
|
||||||
if (nextChoiceResults!=null) {
|
if (nextChoiceResults!=null) {
|
||||||
game.executeNextEvent(nextChoiceResults);
|
game.executeNextEvent(nextChoiceResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (System.nanoTime() > maxTime || Thread.currentThread().isInterrupted()) {
|
if (System.nanoTime() > maxTime || Thread.currentThread().isInterrupted()) {
|
||||||
final ArtificialScore aiScore=new ArtificialScore(game.getScore(),depth);
|
final ArtificialScore aiScore=new ArtificialScore(game.getScore(),depth);
|
||||||
game.undoActions();
|
game.undoActions();
|
||||||
|
@ -165,7 +165,7 @@ class MMABWorker {
|
||||||
while (!game.isFinished()) {
|
while (!game.isFinished()) {
|
||||||
if (!game.hasNextEvent()) {
|
if (!game.hasNextEvent()) {
|
||||||
game.executePhase();
|
game.executePhase();
|
||||||
|
|
||||||
// Caching of best score for game situations.
|
// Caching of best score for game situations.
|
||||||
if (game.cacheState()) {
|
if (game.cacheState()) {
|
||||||
final long gameId=game.getGameId(pruneScore.getScore());
|
final long gameId=game.getGameId(pruneScore.getScore());
|
||||||
|
@ -181,7 +181,7 @@ class MMABWorker {
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
final MagicEvent event=game.getNextEvent();
|
final MagicEvent event=game.getNextEvent();
|
||||||
|
|
||||||
if (!event.hasChoice()) {
|
if (!event.hasChoice()) {
|
||||||
|
@ -203,14 +203,14 @@ class MMABWorker {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
final int nrOfChoices=choiceResultsList.size();
|
final int nrOfChoices=choiceResultsList.size();
|
||||||
|
|
||||||
assert nrOfChoices > 0 : "nrOfChoices is 0";
|
assert nrOfChoices > 0 : "nrOfChoices is 0";
|
||||||
|
|
||||||
if (nrOfChoices==1) {
|
if (nrOfChoices==1) {
|
||||||
game.executeNextEvent(choiceResultsList.get(0));
|
game.executeNextEvent(choiceResultsList.get(0));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean best=game.getScorePlayer()==event.getPlayer();
|
final boolean best=game.getScorePlayer()==event.getPlayer();
|
||||||
ArtificialScore bestScore=ArtificialScore.INVALID_SCORE;
|
ArtificialScore bestScore=ArtificialScore.INVALID_SCORE;
|
||||||
ArtificialPruneScore newPruneScore=pruneScore;
|
ArtificialPruneScore newPruneScore=pruneScore;
|
||||||
|
@ -241,7 +241,7 @@ class MMABWorker {
|
||||||
|
|
||||||
void evaluateGame(final ArtificialChoiceResults aiChoiceResults, final ArtificialPruneScore pruneScore, long maxTime) {
|
void evaluateGame(final ArtificialChoiceResults aiChoiceResults, final ArtificialPruneScore pruneScore, long maxTime) {
|
||||||
gameCount = 0;
|
gameCount = 0;
|
||||||
|
|
||||||
aiChoiceResults.worker = id;
|
aiChoiceResults.worker = id;
|
||||||
aiChoiceResults.aiScore = runGame(game.map(aiChoiceResults.choiceResults),pruneScore,0,maxTime);
|
aiChoiceResults.aiScore = runGame(game.map(aiChoiceResults.choiceResults),pruneScore,0,maxTime);
|
||||||
aiChoiceResults.gameCount = gameCount;
|
aiChoiceResults.gameCount = gameCount;
|
||||||
|
|
|
@ -14,10 +14,10 @@ import magic.model.event.MagicEvent;
|
||||||
import magic.model.phase.MagicPhase;
|
import magic.model.phase.MagicPhase;
|
||||||
|
|
||||||
public class MMAB2 implements MagicAI {
|
public class MMAB2 implements MagicAI {
|
||||||
|
|
||||||
private static final long SEC_TO_NANO=1000000000L;
|
private static final long SEC_TO_NANO=1000000000L;
|
||||||
private static final int THREADS = Runtime.getRuntime().availableProcessors();
|
private static final int THREADS = Runtime.getRuntime().availableProcessors();
|
||||||
|
|
||||||
private final boolean LOGGING;
|
private final boolean LOGGING;
|
||||||
private final boolean CHEAT;
|
private final boolean CHEAT;
|
||||||
private ArtificialPruneScore pruneScore = new ArtificialMultiPruneScore();
|
private ArtificialPruneScore pruneScore = new ArtificialMultiPruneScore();
|
||||||
|
@ -26,37 +26,37 @@ public class MMAB2 implements MagicAI {
|
||||||
//default: no logging, no cheats
|
//default: no logging, no cheats
|
||||||
this(false, false);
|
this(false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
MMAB2(final boolean log, final boolean cheat) {
|
MMAB2(final boolean log, final boolean cheat) {
|
||||||
LOGGING = log || Boolean.getBoolean("debug");
|
LOGGING = log || Boolean.getBoolean("debug");
|
||||||
CHEAT = cheat;
|
CHEAT = cheat;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void log(final String message) {
|
private void log(final String message) {
|
||||||
MagicGameLog.log(message);
|
MagicGameLog.log(message);
|
||||||
if (LOGGING) {
|
if (LOGGING) {
|
||||||
System.err.println(message);
|
System.err.println(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object[] findNextEventChoiceResults(final MagicGame sourceGame, final MagicPlayer scorePlayer) {
|
public Object[] findNextEventChoiceResults(final MagicGame sourceGame, final MagicPlayer scorePlayer) {
|
||||||
final long startTime = System.currentTimeMillis();
|
final long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
// copying the game is necessary because for some choices game scores might be calculated,
|
// copying the game is necessary because for some choices game scores might be calculated,
|
||||||
// find all possible choice results.
|
// find all possible choice results.
|
||||||
MagicGame choiceGame = new MagicGame(sourceGame,scorePlayer);
|
MagicGame choiceGame = new MagicGame(sourceGame,scorePlayer);
|
||||||
final MagicEvent event = choiceGame.getNextEvent();
|
final MagicEvent event = choiceGame.getNextEvent();
|
||||||
final List<Object[]> choices = event.getArtificialChoiceResults(choiceGame);
|
final List<Object[]> choices = event.getArtificialChoiceResults(choiceGame);
|
||||||
final int size = choices.size();
|
final int size = choices.size();
|
||||||
choiceGame = null;
|
choiceGame = null;
|
||||||
|
|
||||||
assert size != 0 : "ERROR: no choices available for MMAB2";
|
assert size != 0 : "ERROR: no choices available for MMAB2";
|
||||||
|
|
||||||
// single choice result.
|
// single choice result.
|
||||||
if (size == 1) {
|
if (size == 1) {
|
||||||
return sourceGame.map(choices.get(0));
|
return sourceGame.map(choices.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// submit jobs
|
// submit jobs
|
||||||
final ArtificialScoreBoard scoreBoard = new ArtificialScoreBoard();
|
final ArtificialScoreBoard scoreBoard = new ArtificialScoreBoard();
|
||||||
final ExecutorService executor = Executors.newFixedThreadPool(THREADS);
|
final ExecutorService executor = Executors.newFixedThreadPool(THREADS);
|
||||||
|
@ -96,14 +96,14 @@ public class MMAB2 implements MagicAI {
|
||||||
// force termination of workers
|
// force termination of workers
|
||||||
executor.shutdownNow();
|
executor.shutdownNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
// select the best scoring choice result.
|
// select the best scoring choice result.
|
||||||
ArtificialScore bestScore = ArtificialScore.INVALID_SCORE;
|
ArtificialScore bestScore = ArtificialScore.INVALID_SCORE;
|
||||||
ArtificialChoiceResults bestAchoice = achoices.get(0);
|
ArtificialChoiceResults bestAchoice = achoices.get(0);
|
||||||
for (final ArtificialChoiceResults achoice : achoices) {
|
for (final ArtificialChoiceResults achoice : achoices) {
|
||||||
if (bestScore.isBetter(achoice.aiScore,true)) {
|
if (bestScore.isBetter(achoice.aiScore,true)) {
|
||||||
bestScore = achoice.aiScore;
|
bestScore = achoice.aiScore;
|
||||||
bestAchoice = achoice;
|
bestAchoice = achoice;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ public class MMAB2 implements MagicAI {
|
||||||
" cheat=" + CHEAT +
|
" cheat=" + CHEAT +
|
||||||
" index=" + scorePlayer.getIndex() +
|
" index=" + scorePlayer.getIndex() +
|
||||||
" life=" + scorePlayer.getLife() +
|
" life=" + scorePlayer.getLife() +
|
||||||
" phase=" + sourceGame.getPhase().getType() +
|
" phase=" + sourceGame.getPhase().getType() +
|
||||||
" slice=" + (slice/1000000) +
|
" slice=" + (slice/1000000) +
|
||||||
" time=" + timeTaken
|
" time=" + timeTaken
|
||||||
);
|
);
|
||||||
|
@ -127,7 +127,7 @@ public class MMAB2 implements MagicAI {
|
||||||
private void updatePruneScore(final int score) {
|
private void updatePruneScore(final int score) {
|
||||||
pruneScore = pruneScore.getPruneScore(score,true);
|
pruneScore = pruneScore.getPruneScore(score,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArtificialPruneScore getPruneScore() {
|
private ArtificialPruneScore getPruneScore() {
|
||||||
return pruneScore;
|
return pruneScore;
|
||||||
}
|
}
|
||||||
|
@ -140,21 +140,21 @@ class MMABWorker {
|
||||||
private final ArtificialScoreBoard scoreBoard;
|
private final ArtificialScoreBoard scoreBoard;
|
||||||
|
|
||||||
private int gameCount;
|
private int gameCount;
|
||||||
|
|
||||||
MMABWorker(final int id,final MagicGame game,final ArtificialScoreBoard scoreBoard, final boolean CHEAT) {
|
MMABWorker(final int id,final MagicGame game,final ArtificialScoreBoard scoreBoard, final boolean CHEAT) {
|
||||||
this.id=id;
|
this.id=id;
|
||||||
this.game=game;
|
this.game=game;
|
||||||
this.scoreBoard=scoreBoard;
|
this.scoreBoard=scoreBoard;
|
||||||
this.CHEAT=CHEAT;
|
this.CHEAT=CHEAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArtificialScore runGame(final Object[] nextChoiceResults, final ArtificialPruneScore pruneScore, final int depth, final long maxTime) {
|
private ArtificialScore runGame(final Object[] nextChoiceResults, final ArtificialPruneScore pruneScore, final int depth, final long maxTime) {
|
||||||
game.startActions();
|
game.startActions();
|
||||||
|
|
||||||
if (nextChoiceResults!=null) {
|
if (nextChoiceResults!=null) {
|
||||||
game.executeNextEvent(nextChoiceResults);
|
game.executeNextEvent(nextChoiceResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (System.nanoTime() > maxTime || Thread.currentThread().isInterrupted()) {
|
if (System.nanoTime() > maxTime || Thread.currentThread().isInterrupted()) {
|
||||||
final ArtificialScore aiScore=new ArtificialScore(game.getScore(),depth);
|
final ArtificialScore aiScore=new ArtificialScore(game.getScore(),depth);
|
||||||
game.undoActions();
|
game.undoActions();
|
||||||
|
@ -166,7 +166,7 @@ class MMABWorker {
|
||||||
while (!game.isFinished()) {
|
while (!game.isFinished()) {
|
||||||
if (!game.hasNextEvent()) {
|
if (!game.hasNextEvent()) {
|
||||||
game.executePhase();
|
game.executePhase();
|
||||||
|
|
||||||
// Caching of best score for game situations.
|
// Caching of best score for game situations.
|
||||||
if (game.cacheState()) {
|
if (game.cacheState()) {
|
||||||
final long gameId=game.getGameId(pruneScore.getScore());
|
final long gameId=game.getGameId(pruneScore.getScore());
|
||||||
|
@ -182,7 +182,7 @@ class MMABWorker {
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
final MagicEvent event=game.getNextEvent();
|
final MagicEvent event=game.getNextEvent();
|
||||||
|
|
||||||
if (!event.hasChoice()) {
|
if (!event.hasChoice()) {
|
||||||
|
@ -204,14 +204,14 @@ class MMABWorker {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
final int nrOfChoices=choiceResultsList.size();
|
final int nrOfChoices=choiceResultsList.size();
|
||||||
|
|
||||||
assert nrOfChoices > 0 : "nrOfChoices is 0";
|
assert nrOfChoices > 0 : "nrOfChoices is 0";
|
||||||
|
|
||||||
if (nrOfChoices==1) {
|
if (nrOfChoices==1) {
|
||||||
game.executeNextEvent(choiceResultsList.get(0));
|
game.executeNextEvent(choiceResultsList.get(0));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean best=game.getScorePlayer()==event.getPlayer();
|
final boolean best=game.getScorePlayer()==event.getPlayer();
|
||||||
ArtificialScore bestScore=ArtificialScore.INVALID_SCORE;
|
ArtificialScore bestScore=ArtificialScore.INVALID_SCORE;
|
||||||
ArtificialPruneScore newPruneScore=pruneScore;
|
ArtificialPruneScore newPruneScore=pruneScore;
|
||||||
|
@ -242,7 +242,7 @@ class MMABWorker {
|
||||||
|
|
||||||
void evaluateGame(final ArtificialChoiceResults aiChoiceResults, final ArtificialPruneScore pruneScore, long maxTime) {
|
void evaluateGame(final ArtificialChoiceResults aiChoiceResults, final ArtificialPruneScore pruneScore, long maxTime) {
|
||||||
gameCount = 0;
|
gameCount = 0;
|
||||||
|
|
||||||
aiChoiceResults.worker = id;
|
aiChoiceResults.worker = id;
|
||||||
aiChoiceResults.aiScore = runGame(game.map(aiChoiceResults.choiceResults),pruneScore,0,maxTime);
|
aiChoiceResults.aiScore = runGame(game.map(aiChoiceResults.choiceResults),pruneScore,0,maxTime);
|
||||||
aiChoiceResults.gameCount = gameCount;
|
aiChoiceResults.gameCount = gameCount;
|
||||||
|
|
|
@ -5,5 +5,5 @@ import magic.model.MagicPlayer;
|
||||||
|
|
||||||
public interface MagicAI {
|
public interface MagicAI {
|
||||||
int MAX_LEVEL = 8;
|
int MAX_LEVEL = 8;
|
||||||
Object[] findNextEventChoiceResults(final MagicGame game, final MagicPlayer player);
|
Object[] findNextEventChoiceResults(final MagicGame game, final MagicPlayer player);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
package magic.ai;
|
package magic.ai;
|
||||||
|
|
||||||
public enum MagicAIImpl {
|
public enum MagicAIImpl {
|
||||||
MMAB("minimax", new MMAB(false)),
|
MMAB("minimax", new MMAB(false)),
|
||||||
MMABC("minimax (cheat)", new MMAB(true)),
|
MMABC("minimax (cheat)", new MMAB(true)),
|
||||||
MCTS("monte carlo tree search", new MCTSAI(false)),
|
MCTS("monte carlo tree search", new MCTSAI(false)),
|
||||||
MCTSC("monte carlo tree search (cheat)", new MCTSAI(true)),
|
MCTSC("monte carlo tree search (cheat)", new MCTSAI(true)),
|
||||||
VEGAS("vegas", new VegasAI(false)),
|
VEGAS("vegas", new VegasAI(false)),
|
||||||
VEGASC("vegas (cheat)", new VegasAI(true)),
|
VEGASC("vegas (cheat)", new VegasAI(true)),
|
||||||
RND("random", new RandomAI()),
|
RND("random", new RandomAI()),
|
||||||
MMABFast("minimax (deck strength)", magic.ai.MMAB.DeckStrAI()),
|
MMABFast("minimax (deck strength)", magic.ai.MMAB.DeckStrAI()),
|
||||||
|
|
||||||
MCTS2("monte carlo tree search", new MCTSAI2(false)),
|
MCTS2("monte carlo tree search", new MCTSAI2(false)),
|
||||||
MCTSC2("monte carlo tree search (cheat)", new MCTSAI2(true)),
|
MCTSC2("monte carlo tree search (cheat)", new MCTSAI2(true)),
|
||||||
;
|
;
|
||||||
|
|
||||||
private static final MagicAIImpl[] SUPPORTED_AIS = {MMAB, MMABC, MCTS, MCTSC, VEGAS, VEGASC};
|
private static final MagicAIImpl[] SUPPORTED_AIS = {MMAB, MMABC, MCTS, MCTSC, VEGAS, VEGASC};
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final MagicAI ai;
|
private final MagicAI ai;
|
||||||
|
|
||||||
|
@ -23,15 +23,15 @@ public enum MagicAIImpl {
|
||||||
this.name=name;
|
this.name=name;
|
||||||
this.ai=ai;
|
this.ai=ai;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getName() {
|
private String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicAI getAI() {
|
public MagicAI getAI() {
|
||||||
return ai;
|
return ai;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MagicAIImpl getAI(final String name) {
|
public static MagicAIImpl getAI(final String name) {
|
||||||
for (final MagicAIImpl ai : values()) {
|
for (final MagicAIImpl ai : values()) {
|
||||||
if (ai.getName().equals(name)) {
|
if (ai.getName().equals(name)) {
|
||||||
|
@ -40,7 +40,7 @@ public enum MagicAIImpl {
|
||||||
}
|
}
|
||||||
return MMAB;
|
return MMAB;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String[] getNames() {
|
public static String[] getNames() {
|
||||||
final String[] names=new String[SUPPORTED_AIS.length];
|
final String[] names=new String[SUPPORTED_AIS.length];
|
||||||
int index=0;
|
int index=0;
|
||||||
|
|
|
@ -11,9 +11,9 @@ import java.util.List;
|
||||||
|
|
||||||
//AI that plays randomly
|
//AI that plays randomly
|
||||||
public class RandomAI implements MagicAI {
|
public class RandomAI implements MagicAI {
|
||||||
|
|
||||||
private final boolean LOGGING;
|
private final boolean LOGGING;
|
||||||
|
|
||||||
public RandomAI() {
|
public RandomAI() {
|
||||||
this(false);
|
this(false);
|
||||||
}
|
}
|
||||||
|
@ -21,24 +21,24 @@ public class RandomAI implements MagicAI {
|
||||||
private RandomAI(final boolean log) {
|
private RandomAI(final boolean log) {
|
||||||
LOGGING = log || Boolean.getBoolean("debug");
|
LOGGING = log || Boolean.getBoolean("debug");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void log(final String message) {
|
private void log(final String message) {
|
||||||
MagicGameLog.log(message);
|
MagicGameLog.log(message);
|
||||||
if (LOGGING) {
|
if (LOGGING) {
|
||||||
System.err.println(message);
|
System.err.println(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object[] findNextEventChoiceResults(final MagicGame game, final MagicPlayer scorePlayer) {
|
public Object[] findNextEventChoiceResults(final MagicGame game, final MagicPlayer scorePlayer) {
|
||||||
//get a list of choices
|
//get a list of choices
|
||||||
MagicGame choiceGame = new MagicGame(game, scorePlayer);
|
MagicGame choiceGame = new MagicGame(game, scorePlayer);
|
||||||
final MagicEvent event=choiceGame.getNextEvent();
|
final MagicEvent event=choiceGame.getNextEvent();
|
||||||
final List<Object[]> choices=event.getArtificialChoiceResults(choiceGame);
|
final List<Object[]> choices=event.getArtificialChoiceResults(choiceGame);
|
||||||
choiceGame = null;
|
choiceGame = null;
|
||||||
|
|
||||||
final int size = choices.size();
|
final int size = choices.size();
|
||||||
final String info = "RandomAI " + scorePlayer.getIndex() + " (" + scorePlayer.getLife() + ")";
|
final String info = "RandomAI " + scorePlayer.getIndex() + " (" + scorePlayer.getLife() + ")";
|
||||||
|
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
throw new RuntimeException("No choice results");
|
throw new RuntimeException("No choice results");
|
||||||
}
|
}
|
||||||
|
@ -48,17 +48,17 @@ public class RandomAI implements MagicAI {
|
||||||
for (final Object[] choice : choices) {
|
for (final Object[] choice : choices) {
|
||||||
achoices.add(new ArtificialChoiceResults(choice));
|
achoices.add(new ArtificialChoiceResults(choice));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select a random artificial choice result
|
// Select a random artificial choice result
|
||||||
final int idx = MagicRandom.nextInt(size);
|
final int idx = MagicRandom.nextInt(size);
|
||||||
final ArtificialChoiceResults selected=achoices.get(idx);
|
final ArtificialChoiceResults selected=achoices.get(idx);
|
||||||
if (size >= 2) {
|
if (size >= 2) {
|
||||||
log(info);
|
log(info);
|
||||||
for (final ArtificialChoiceResults achoice : achoices) {
|
for (final ArtificialChoiceResults achoice : achoices) {
|
||||||
log((achoice==selected?"* ":" ")+achoice);
|
log((achoice==selected?"* ":" ")+achoice);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//log(info + " " + selected);
|
//log(info + " " + selected);
|
||||||
}
|
}
|
||||||
return game.map(selected.choiceResults);
|
return game.map(selected.choiceResults);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,21 +17,21 @@ public class VegasAI implements MagicAI {
|
||||||
|
|
||||||
private static final long SEC_TO_NANO=1000000000L;
|
private static final long SEC_TO_NANO=1000000000L;
|
||||||
private static final int THREADS=Runtime.getRuntime().availableProcessors();
|
private static final int THREADS=Runtime.getRuntime().availableProcessors();
|
||||||
|
|
||||||
private final boolean LOGGING = Boolean.getBoolean("debug");
|
private final boolean LOGGING = Boolean.getBoolean("debug");
|
||||||
private final boolean CHEAT;
|
private final boolean CHEAT;
|
||||||
|
|
||||||
VegasAI(final boolean cheat) {
|
VegasAI(final boolean cheat) {
|
||||||
CHEAT = cheat;
|
CHEAT = cheat;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void log(final String message) {
|
private void log(final String message) {
|
||||||
MagicGameLog.log(message);
|
MagicGameLog.log(message);
|
||||||
if (LOGGING) {
|
if (LOGGING) {
|
||||||
System.err.println(message);
|
System.err.println(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object[] findNextEventChoiceResults(final MagicGame sourceGame,final MagicPlayer scorePlayer) {
|
public Object[] findNextEventChoiceResults(final MagicGame sourceGame,final MagicPlayer scorePlayer) {
|
||||||
final long startTime = System.currentTimeMillis();
|
final long startTime = System.currentTimeMillis();
|
||||||
|
@ -42,18 +42,18 @@ public class VegasAI implements MagicAI {
|
||||||
}
|
}
|
||||||
final MagicEvent event=choiceGame.getNextEvent();
|
final MagicEvent event=choiceGame.getNextEvent();
|
||||||
final List<Object[]> choiceResultsList=event.getArtificialChoiceResults(choiceGame);
|
final List<Object[]> choiceResultsList=event.getArtificialChoiceResults(choiceGame);
|
||||||
|
|
||||||
// No choices
|
// No choices
|
||||||
final int size=choiceResultsList.size();
|
final int size=choiceResultsList.size();
|
||||||
if (size==0) {
|
if (size==0) {
|
||||||
throw new RuntimeException("No choice results");
|
throw new RuntimeException("No choice results");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Single choice
|
// Single choice
|
||||||
if (size==1) {
|
if (size==1) {
|
||||||
return sourceGame.map(choiceResultsList.get(0));
|
return sourceGame.map(choiceResultsList.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Multiple choices
|
// Multiple choices
|
||||||
final ExecutorService executor = Executors.newFixedThreadPool(THREADS);
|
final ExecutorService executor = Executors.newFixedThreadPool(THREADS);
|
||||||
final List<VegasScore> scores=new ArrayList<VegasScore>();
|
final List<VegasScore> scores=new ArrayList<VegasScore>();
|
||||||
|
@ -80,7 +80,7 @@ public class VegasAI implements MagicAI {
|
||||||
// force termination of workers
|
// force termination of workers
|
||||||
executor.shutdownNow();
|
executor.shutdownNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return best choice
|
// Return best choice
|
||||||
VegasScore bestScore=scores.get(0);
|
VegasScore bestScore=scores.get(0);
|
||||||
for (final VegasScore score : scores) {
|
for (final VegasScore score : scores) {
|
||||||
|
@ -88,14 +88,14 @@ public class VegasAI implements MagicAI {
|
||||||
bestScore = score;
|
bestScore = score;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logging.
|
// Logging.
|
||||||
final long timeTaken = System.currentTimeMillis() - startTime;
|
final long timeTaken = System.currentTimeMillis() - startTime;
|
||||||
log("VEGAS" +
|
log("VEGAS" +
|
||||||
" cheat=" + CHEAT +
|
" cheat=" + CHEAT +
|
||||||
" index=" + scorePlayer.getIndex() +
|
" index=" + scorePlayer.getIndex() +
|
||||||
" life=" + scorePlayer.getLife() +
|
" life=" + scorePlayer.getLife() +
|
||||||
" phase=" + sourceGame.getPhase().getType() +
|
" phase=" + sourceGame.getPhase().getType() +
|
||||||
" slice=" + (slice/1000000) +
|
" slice=" + (slice/1000000) +
|
||||||
" time=" + timeTaken
|
" time=" + timeTaken
|
||||||
);
|
);
|
||||||
|
|
|
@ -5,11 +5,11 @@ public class VegasScore {
|
||||||
private final Object[] choiceResults;
|
private final Object[] choiceResults;
|
||||||
private long totalScore;
|
private long totalScore;
|
||||||
private int count;
|
private int count;
|
||||||
|
|
||||||
VegasScore(final Object[] choiceResults) {
|
VegasScore(final Object[] choiceResults) {
|
||||||
this.choiceResults=choiceResults;
|
this.choiceResults=choiceResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
void incrementScore(final int score) {
|
void incrementScore(final int score) {
|
||||||
totalScore+=score;
|
totalScore+=score;
|
||||||
count++;
|
count++;
|
||||||
|
@ -18,7 +18,7 @@ public class VegasScore {
|
||||||
Object[] getChoiceResults() {
|
Object[] getChoiceResults() {
|
||||||
return choiceResults;
|
return choiceResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
final StringBuilder buffer=new StringBuilder();
|
final StringBuilder buffer=new StringBuilder();
|
||||||
buffer.append("[").append(getScore()).append('/').append(count).append("]");
|
buffer.append("[").append(getScore()).append('/').append(count).append("]");
|
||||||
|
@ -37,7 +37,7 @@ public class VegasScore {
|
||||||
}
|
}
|
||||||
return buffer.toString();
|
return buffer.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
int getScore() {
|
int getScore() {
|
||||||
return count>0?(int)(totalScore/count):ArtificialScoringSystem.LOSE_GAME_SCORE;
|
return count>0?(int)(totalScore/count):ArtificialScoringSystem.LOSE_GAME_SCORE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,14 +10,14 @@ import java.util.Random;
|
||||||
public class VegasWorker implements Runnable {
|
public class VegasWorker implements Runnable {
|
||||||
|
|
||||||
private static final int MAIN_PHASES=6;
|
private static final int MAIN_PHASES=6;
|
||||||
|
|
||||||
private final MagicGame sourceGame;
|
private final MagicGame sourceGame;
|
||||||
private final VegasScore score;
|
private final VegasScore score;
|
||||||
private final Object[] choiceResults;
|
private final Object[] choiceResults;
|
||||||
private final Random random;
|
private final Random random;
|
||||||
private final long slice;
|
private final long slice;
|
||||||
private final boolean CHEAT;
|
private final boolean CHEAT;
|
||||||
|
|
||||||
VegasWorker(final boolean cheat, final MagicGame sourceGame, final VegasScore score,final Random random,final long slice) {
|
VegasWorker(final boolean cheat, final MagicGame sourceGame, final VegasScore score,final Random random,final long slice) {
|
||||||
this.CHEAT = cheat;
|
this.CHEAT = cheat;
|
||||||
this.sourceGame=sourceGame;
|
this.sourceGame=sourceGame;
|
||||||
|
@ -36,21 +36,21 @@ public class VegasWorker implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
final MagicEvent event=game.getNextEvent();
|
final MagicEvent event=game.getNextEvent();
|
||||||
|
|
||||||
if (!event.hasChoice()) {
|
if (!event.hasChoice()) {
|
||||||
game.executeNextEvent();
|
game.executeNextEvent();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<Object[]> choiceResultsList=event.getArtificialChoiceResults(game);
|
final List<Object[]> choiceResultsList=event.getArtificialChoiceResults(game);
|
||||||
final int nrOfChoices=choiceResultsList.size();
|
final int nrOfChoices=choiceResultsList.size();
|
||||||
|
|
||||||
assert nrOfChoices != 0 : "ERROR: no choices available for VegasWorker";
|
assert nrOfChoices != 0 : "ERROR: no choices available for VegasWorker";
|
||||||
|
|
||||||
game.executeNextEvent(choiceResultsList.get(random.nextInt(nrOfChoices)));
|
game.executeNextEvent(choiceResultsList.get(random.nextInt(nrOfChoices)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
final long endTime = System.nanoTime() + slice;
|
final long endTime = System.nanoTime() + slice;
|
||||||
|
@ -64,5 +64,5 @@ public class VegasWorker implements Runnable {
|
||||||
runGame(game);
|
runGame(game);
|
||||||
score.incrementScore(game.getScore());
|
score.incrementScore(game.getScore());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,12 +11,12 @@ import java.util.Vector;
|
||||||
public class AvatarImages {
|
public class AvatarImages {
|
||||||
|
|
||||||
private static final AvatarImages INSTANCE = new AvatarImages();
|
private static final AvatarImages INSTANCE = new AvatarImages();
|
||||||
|
|
||||||
private final File avatarPath;
|
private final File avatarPath;
|
||||||
private final Vector<String> names;
|
private final Vector<String> names;
|
||||||
private String current = "";
|
private String current = "";
|
||||||
private PlayerAvatar[] avatars;
|
private PlayerAvatar[] avatars;
|
||||||
|
|
||||||
private AvatarImages() {
|
private AvatarImages() {
|
||||||
avatarPath=new File(MagicMain.getGamePath(),"avatars");
|
avatarPath=new File(MagicMain.getGamePath(),"avatars");
|
||||||
final File[] files=avatarPath.listFiles();
|
final File[] files=avatarPath.listFiles();
|
||||||
|
@ -29,15 +29,15 @@ public class AvatarImages {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector<String> getNames() {
|
public Vector<String> getNames() {
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PlayerAvatar loadAvatar(final File file) {
|
private static PlayerAvatar loadAvatar(final File file) {
|
||||||
return new PlayerAvatar(FileIO.toImg(file, IconImages.MISSING));
|
return new PlayerAvatar(FileIO.toImg(file, IconImages.MISSING));
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void loadAvatars() {
|
private synchronized void loadAvatars() {
|
||||||
final String avatar=GeneralConfig.getInstance().getAvatar();
|
final String avatar=GeneralConfig.getInstance().getAvatar();
|
||||||
if (!avatar.equals(current)) {
|
if (!avatar.equals(current)) {
|
||||||
|
@ -48,7 +48,7 @@ public class AvatarImages {
|
||||||
avatars=new PlayerAvatar[files.length];
|
avatars=new PlayerAvatar[files.length];
|
||||||
for (int index=0;index<files.length;index++) {
|
for (int index=0;index<files.length;index++) {
|
||||||
avatars[index]=loadAvatar(files[index]);
|
avatars[index]=loadAvatar(files[index]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
avatars=new PlayerAvatar[2];
|
avatars=new PlayerAvatar[2];
|
||||||
avatars[0]=loadAvatar(new File(""));
|
avatars[0]=loadAvatar(new File(""));
|
||||||
|
@ -56,7 +56,7 @@ public class AvatarImages {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized ImageIcon getAvatarIcon(int index,final int size) {
|
public synchronized ImageIcon getAvatarIcon(int index,final int size) {
|
||||||
loadAvatars();
|
loadAvatars();
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
|
@ -66,7 +66,7 @@ public class AvatarImages {
|
||||||
}
|
}
|
||||||
return avatars[index].getIcon(size);
|
return avatars[index].getIcon(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized int getNumberOfAvatars() {
|
public synchronized int getNumberOfAvatars() {
|
||||||
loadAvatars();
|
loadAvatars();
|
||||||
return avatars.length;
|
return avatars.length;
|
||||||
|
|
|
@ -35,7 +35,7 @@ public class CardDefinitions {
|
||||||
public static final String TOKEN_IMAGE_FOLDER = "tokens";
|
public static final String TOKEN_IMAGE_FOLDER = "tokens";
|
||||||
public static final String CARD_IMAGE_EXT = CardImagesProvider.IMAGE_EXTENSION;
|
public static final String CARD_IMAGE_EXT = CardImagesProvider.IMAGE_EXTENSION;
|
||||||
public static final String CARD_TEXT_EXT = ".txt";
|
public static final String CARD_TEXT_EXT = ".txt";
|
||||||
|
|
||||||
private static final List<MagicCardDefinition> cards = new ArrayList<MagicCardDefinition>();
|
private static final List<MagicCardDefinition> cards = new ArrayList<MagicCardDefinition>();
|
||||||
private static final List<MagicCardDefinition> landCards = new ArrayList<MagicCardDefinition>();
|
private static final List<MagicCardDefinition> landCards = new ArrayList<MagicCardDefinition>();
|
||||||
private static final List<MagicCardDefinition> spellCards = new ArrayList<MagicCardDefinition>();
|
private static final List<MagicCardDefinition> spellCards = new ArrayList<MagicCardDefinition>();
|
||||||
|
@ -51,7 +51,7 @@ public class CardDefinitions {
|
||||||
new ImportCustomizer().addStarImports(
|
new ImportCustomizer().addStarImports(
|
||||||
"java.util",
|
"java.util",
|
||||||
"magic.data",
|
"magic.data",
|
||||||
"magic.model",
|
"magic.model",
|
||||||
"magic.model.action",
|
"magic.model.action",
|
||||||
"magic.model.choice",
|
"magic.model.choice",
|
||||||
"magic.model.condition",
|
"magic.model.condition",
|
||||||
|
@ -73,7 +73,7 @@ public class CardDefinitions {
|
||||||
throw new RuntimeException("Unsupported card property: " + property);
|
throw new RuntimeException("Unsupported card property: " + property);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void filterCards() {
|
private static void filterCards() {
|
||||||
for (final MagicCardDefinition card : cards) {
|
for (final MagicCardDefinition card : cards) {
|
||||||
if (!card.isLand() && !card.isToken()) {
|
if (!card.isLand() && !card.isToken()) {
|
||||||
|
@ -100,7 +100,7 @@ public class CardDefinitions {
|
||||||
CubeDefinitions.getCubeDefinition("all").add(cardDefinition.getName());
|
CubeDefinitions.getCubeDefinition("all").add(cardDefinition.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MagicCardDefinition prop2carddef(final Properties content) {
|
private static MagicCardDefinition prop2carddef(final Properties content) {
|
||||||
final MagicCardDefinition cardDefinition=new MagicCardDefinition();
|
final MagicCardDefinition cardDefinition=new MagicCardDefinition();
|
||||||
|
|
||||||
|
@ -124,11 +124,11 @@ public class CardDefinitions {
|
||||||
throw new RuntimeException(ex);
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getCanonicalName(String fullName) {
|
private static String getCanonicalName(String fullName) {
|
||||||
return fullName.replaceAll("[^A-Za-z0-9]", "_");
|
return fullName.replaceAll("[^A-Za-z0-9]", "_");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void loadCardDefinition(final File file) {
|
private static void loadCardDefinition(final File file) {
|
||||||
try {
|
try {
|
||||||
final MagicCardDefinition cdef = prop2carddef(FileIO.toProp(file));
|
final MagicCardDefinition cdef = prop2carddef(FileIO.toProp(file));
|
||||||
|
@ -141,7 +141,7 @@ public class CardDefinitions {
|
||||||
throw new RuntimeException("Error loading " + file, cause);
|
throw new RuntimeException("Error loading " + file, cause);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void loadCardDefinitions() {
|
public static void loadCardDefinitions() {
|
||||||
//load all files in card directory
|
//load all files in card directory
|
||||||
final File[] files = cardDir.listFiles(new FilenameFilter() {
|
final File[] files = cardDir.listFiles(new FilenameFilter() {
|
||||||
|
@ -152,24 +152,24 @@ public class CardDefinitions {
|
||||||
for (final File file : files) {
|
for (final File file : files) {
|
||||||
loadCardDefinition(file);
|
loadCardDefinition(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
filterCards();
|
filterCards();
|
||||||
printStatistics();
|
printStatistics();
|
||||||
|
|
||||||
addDefinition(MagicCardDefinition.UNKNOWN);
|
addDefinition(MagicCardDefinition.UNKNOWN);
|
||||||
|
|
||||||
System.err.println(getNumberOfCards()+ " card definitions");
|
System.err.println(getNumberOfCards()+ " card definitions");
|
||||||
MagicCardDefinition.printStatistics();
|
MagicCardDefinition.printStatistics();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getNumberOfCards() {
|
public static int getNumberOfCards() {
|
||||||
return cards.size();
|
return cards.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MagicCardDefinition getCard(final int cindex) {
|
public static MagicCardDefinition getCard(final int cindex) {
|
||||||
return cards.get(cindex);
|
return cards.get(cindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MagicCardDefinition getCard(final String name) {
|
public static MagicCardDefinition getCard(final String name) {
|
||||||
final MagicCardDefinition cardDefinition=cardsMap.get(name);
|
final MagicCardDefinition cardDefinition=cardsMap.get(name);
|
||||||
if (cardDefinition == null) {
|
if (cardDefinition == null) {
|
||||||
|
@ -177,7 +177,7 @@ public class CardDefinitions {
|
||||||
}
|
}
|
||||||
return cardDefinition;
|
return cardDefinition;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void loadCardTexts() {
|
public static void loadCardTexts() {
|
||||||
executor.execute(new Runnable() {
|
executor.execute(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -190,21 +190,21 @@ public class CardDefinitions {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void loadCardText(final MagicCardDefinition card) {
|
private static void loadCardText(final MagicCardDefinition card) {
|
||||||
// try to load text from file
|
// try to load text from file
|
||||||
final StringBuilder buffer = new StringBuilder();
|
final StringBuilder buffer = new StringBuilder();
|
||||||
buffer.append(MagicMain.getGamePath());
|
buffer.append(MagicMain.getGamePath());
|
||||||
buffer.append(File.separator);
|
buffer.append(File.separator);
|
||||||
buffer.append(CARD_TEXT_FOLDER);
|
buffer.append(CARD_TEXT_FOLDER);
|
||||||
buffer.append(File.separator);
|
buffer.append(File.separator);
|
||||||
buffer.append(card.getCardTextName());
|
buffer.append(card.getCardTextName());
|
||||||
buffer.append(CARD_TEXT_EXT);
|
buffer.append(CARD_TEXT_EXT);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final String text = FileIO.toStr(new File(buffer.toString()));
|
final String text = FileIO.toStr(new File(buffer.toString()));
|
||||||
if (text != null) {
|
if (text != null) {
|
||||||
card.setText(text);
|
card.setText(text);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// text not downloaded or missing
|
// text not downloaded or missing
|
||||||
|
@ -229,15 +229,15 @@ public class CardDefinitions {
|
||||||
public static List<MagicCardDefinition> getCards() {
|
public static List<MagicCardDefinition> getCards() {
|
||||||
return cards;
|
return cards;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<MagicCardDefinition> getLandCards() {
|
public static List<MagicCardDefinition> getLandCards() {
|
||||||
return landCards;
|
return landCards;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<MagicCardDefinition> getSpellCards() {
|
public static List<MagicCardDefinition> getSpellCards() {
|
||||||
return spellCards;
|
return spellCards;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void printStatistics() {
|
private static void printStatistics() {
|
||||||
final CardStatistics statistics=new CardStatistics(cards);
|
final CardStatistics statistics=new CardStatistics(cards);
|
||||||
statistics.printStatictics(System.err);
|
statistics.printStatictics(System.err);
|
||||||
|
|
|
@ -5,7 +5,7 @@ import magic.model.MagicCardDefinition;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for getting image of a card
|
* Interface for getting image of a card
|
||||||
*/
|
*/
|
||||||
public interface CardImagesProvider {
|
public interface CardImagesProvider {
|
||||||
|
@ -15,7 +15,7 @@ public interface CardImagesProvider {
|
||||||
//native resolution of images from magiccards.info
|
//native resolution of images from magiccards.info
|
||||||
int CARD_WIDTH=312;
|
int CARD_WIDTH=312;
|
||||||
int CARD_HEIGHT=445;
|
int CARD_HEIGHT=445;
|
||||||
|
|
||||||
Dimension CARD_DIMENSION = new Dimension(CARD_WIDTH, CARD_HEIGHT);
|
Dimension CARD_DIMENSION = new Dimension(CARD_WIDTH, CARD_HEIGHT);
|
||||||
|
|
||||||
BufferedImage getImage(
|
BufferedImage getImage(
|
||||||
|
|
|
@ -191,7 +191,7 @@ public enum CardProperty {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
;
|
;
|
||||||
|
|
||||||
public void setProperty(final MagicCardDefinition card, final String value) {
|
public void setProperty(final MagicCardDefinition card, final String value) {
|
||||||
//do nothing
|
//do nothing
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ public class CardStatistics {
|
||||||
IconImages.COST_NINE
|
IconImages.COST_NINE
|
||||||
));
|
));
|
||||||
public static final int MANA_CURVE_SIZE=MANA_CURVE_TEXT.size();
|
public static final int MANA_CURVE_SIZE=MANA_CURVE_TEXT.size();
|
||||||
|
|
||||||
private static final List<String> TYPE_NAMES = Collections.unmodifiableList(Arrays.asList(
|
private static final List<String> TYPE_NAMES = Collections.unmodifiableList(Arrays.asList(
|
||||||
"Land","Spell","Creature","Equipment","Aura","Enchantment","Artifact"));
|
"Land","Spell","Creature","Equipment","Aura","Enchantment","Artifact"));
|
||||||
public static final List<ImageIcon> TYPE_ICONS = Collections.unmodifiableList(Arrays.asList(
|
public static final List<ImageIcon> TYPE_ICONS = Collections.unmodifiableList(Arrays.asList(
|
||||||
|
@ -37,22 +37,22 @@ public class CardStatistics {
|
||||||
IconImages.SPELL,
|
IconImages.SPELL,
|
||||||
IconImages.CREATURE,
|
IconImages.CREATURE,
|
||||||
IconImages.EQUIPMENT,
|
IconImages.EQUIPMENT,
|
||||||
IconImages.AURA,
|
IconImages.AURA,
|
||||||
IconImages.ENCHANTMENT,
|
IconImages.ENCHANTMENT,
|
||||||
IconImages.ARTIFACT
|
IconImages.ARTIFACT
|
||||||
));
|
));
|
||||||
public static final int NR_OF_TYPES=TYPE_NAMES.size();
|
public static final int NR_OF_TYPES=TYPE_NAMES.size();
|
||||||
|
|
||||||
private final Collection<MagicCardDefinition> cards;
|
private final Collection<MagicCardDefinition> cards;
|
||||||
|
|
||||||
private int totalCards;
|
private int totalCards;
|
||||||
public final int[] totalTypes=new int[NR_OF_TYPES];
|
public final int[] totalTypes=new int[NR_OF_TYPES];
|
||||||
|
|
||||||
private final int[] totalRarity=new int[MagicRarity.length];
|
private final int[] totalRarity=new int[MagicRarity.length];
|
||||||
|
|
||||||
private double averageCost;
|
private double averageCost;
|
||||||
private double averageValue;
|
private double averageValue;
|
||||||
|
|
||||||
public final int[] colorCount=new int[MagicColor.NR_COLORS];
|
public final int[] colorCount=new int[MagicColor.NR_COLORS];
|
||||||
public final int[] colorMono=new int[MagicColor.NR_COLORS];
|
public final int[] colorMono=new int[MagicColor.NR_COLORS];
|
||||||
public final int[] colorLands=new int[MagicColor.NR_COLORS];
|
public final int[] colorLands=new int[MagicColor.NR_COLORS];
|
||||||
|
@ -60,12 +60,12 @@ public class CardStatistics {
|
||||||
public int monoColor;
|
public int monoColor;
|
||||||
public int multiColor;
|
public int multiColor;
|
||||||
public int colorless;
|
public int colorless;
|
||||||
|
|
||||||
public CardStatistics(final Collection<MagicCardDefinition> cards) {
|
public CardStatistics(final Collection<MagicCardDefinition> cards) {
|
||||||
this.cards=cards;
|
this.cards=cards;
|
||||||
createStatistics();
|
createStatistics();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createStatistics() {
|
private void createStatistics() {
|
||||||
for (final MagicCardDefinition card : cards) {
|
for (final MagicCardDefinition card : cards) {
|
||||||
//ignore tokens
|
//ignore tokens
|
||||||
|
@ -74,16 +74,16 @@ public class CardStatistics {
|
||||||
}
|
}
|
||||||
|
|
||||||
totalCards++;
|
totalCards++;
|
||||||
|
|
||||||
totalRarity[card.getRarity()]++;
|
totalRarity[card.getRarity()]++;
|
||||||
|
|
||||||
if (card.isLand()) {
|
if (card.isLand()) {
|
||||||
totalTypes[0]++;
|
totalTypes[0]++;
|
||||||
for (final MagicColor color : MagicColor.values()) {
|
for (final MagicColor color : MagicColor.values()) {
|
||||||
if (card.getManaSource(color) > 0) {
|
if (card.getManaSource(color) > 0) {
|
||||||
colorLands[color.ordinal()]++;
|
colorLands[color.ordinal()]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (card.hasX()) {
|
if (card.hasX()) {
|
||||||
manaCurve[0]++;
|
manaCurve[0]++;
|
||||||
|
@ -91,10 +91,10 @@ public class CardStatistics {
|
||||||
final int convertedCost=card.getConvertedCost();
|
final int convertedCost=card.getConvertedCost();
|
||||||
manaCurve[convertedCost+1>=MANA_CURVE_SIZE?MANA_CURVE_SIZE-1:convertedCost+1]++;
|
manaCurve[convertedCost+1>=MANA_CURVE_SIZE?MANA_CURVE_SIZE-1:convertedCost+1]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
averageCost+=card.getConvertedCost();
|
averageCost+=card.getConvertedCost();
|
||||||
averageValue+=card.getValue();
|
averageValue+=card.getValue();
|
||||||
|
|
||||||
if (card.isCreature()) {
|
if (card.isCreature()) {
|
||||||
totalTypes[2]++;
|
totalTypes[2]++;
|
||||||
} else if (card.isEquipment()) {
|
} else if (card.isEquipment()) {
|
||||||
|
@ -108,11 +108,11 @@ public class CardStatistics {
|
||||||
} else {
|
} else {
|
||||||
totalTypes[1]++;
|
totalTypes[1]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int count=0;
|
int count=0;
|
||||||
int index=-1;
|
int index=-1;
|
||||||
for (final MagicColor color : MagicColor.values()) {
|
for (final MagicColor color : MagicColor.values()) {
|
||||||
|
|
||||||
if (color.hasColor(card.getColorFlags())) {
|
if (color.hasColor(card.getColorFlags())) {
|
||||||
index=color.ordinal();
|
index=color.ordinal();
|
||||||
colorCount[index]++;
|
colorCount[index]++;
|
||||||
|
@ -129,14 +129,14 @@ public class CardStatistics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final int total=totalCards-totalTypes[0];
|
final int total=totalCards-totalTypes[0];
|
||||||
if (total>0) {
|
if (total>0) {
|
||||||
averageValue /= total;
|
averageValue /= total;
|
||||||
averageCost /= total;
|
averageCost /= total;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void printStatictics(final PrintStream stream) {
|
void printStatictics(final PrintStream stream) {
|
||||||
|
|
||||||
stream.print("Cards : "+totalCards);
|
stream.print("Cards : "+totalCards);
|
||||||
|
@ -144,9 +144,9 @@ public class CardStatistics {
|
||||||
stream.print(" "+TYPE_NAMES.get(index)+" : "+totalTypes[index]);
|
stream.print(" "+TYPE_NAMES.get(index)+" : "+totalTypes[index]);
|
||||||
}
|
}
|
||||||
stream.println();
|
stream.println();
|
||||||
|
|
||||||
for (int index=0;index<MagicRarity.length;index++) {
|
for (int index=0;index<MagicRarity.length;index++) {
|
||||||
|
|
||||||
stream.print(MagicRarity.values()[index].getName() + " : " + totalRarity[index] + " ");
|
stream.print(MagicRarity.values()[index].getName() + " : " + totalRarity[index] + " ");
|
||||||
}
|
}
|
||||||
stream.println();
|
stream.println();
|
||||||
|
@ -154,16 +154,16 @@ public class CardStatistics {
|
||||||
stream.println("Monocolor : "+monoColor+" Multicolor : "+multiColor+" Colorless : "+colorless);
|
stream.println("Monocolor : "+monoColor+" Multicolor : "+multiColor+" Colorless : "+colorless);
|
||||||
|
|
||||||
for (final MagicColor color : MagicColor.values()) {
|
for (final MagicColor color : MagicColor.values()) {
|
||||||
|
|
||||||
final int index=color.ordinal();
|
final int index=color.ordinal();
|
||||||
stream.print("Color "+color.getName()+" : "+colorCount[index]);
|
stream.print("Color "+color.getName()+" : "+colorCount[index]);
|
||||||
stream.print(" Mono : "+colorMono[index]);
|
stream.print(" Mono : "+colorMono[index]);
|
||||||
stream.print(" Lands : "+colorLands[index]);
|
stream.print(" Lands : "+colorLands[index]);
|
||||||
stream.println();
|
stream.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int index=0;index<MANA_CURVE_SIZE;index++) {
|
for (int index=0;index<MANA_CURVE_SIZE;index++) {
|
||||||
|
|
||||||
stream.print(MANA_CURVE_TEXT.get(index)+" = "+manaCurve[index]+" ");
|
stream.print(MANA_CURVE_TEXT.get(index)+" = "+manaCurve[index]+" ");
|
||||||
}
|
}
|
||||||
stream.println();
|
stream.println();
|
||||||
|
|
|
@ -11,28 +11,28 @@ import java.util.List;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
|
||||||
public class CubeDefinitions {
|
public class CubeDefinitions {
|
||||||
|
|
||||||
private static final String[] INCLUDED_CUBES={"all"};
|
private static final String[] INCLUDED_CUBES={"all"};
|
||||||
private static final String CUBE_FILE_EXTENSION="_cube.txt";
|
private static final String CUBE_FILE_EXTENSION="_cube.txt";
|
||||||
|
|
||||||
static final String DEFAULT_NAME=INCLUDED_CUBES[0];
|
static final String DEFAULT_NAME=INCLUDED_CUBES[0];
|
||||||
|
|
||||||
private static final FileFilter CUBE_FILE_FILTER=new FileFilter() {
|
private static final FileFilter CUBE_FILE_FILTER=new FileFilter() {
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(final File file) {
|
public boolean accept(final File file) {
|
||||||
return file.isFile()&&file.getName().endsWith(CUBE_FILE_EXTENSION);
|
return file.isFile()&&file.getName().endsWith(CUBE_FILE_EXTENSION);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final List<MagicCubeDefinition> cubeDefinitions;
|
private static final List<MagicCubeDefinition> cubeDefinitions;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
cubeDefinitions=new ArrayList<MagicCubeDefinition>();
|
cubeDefinitions=new ArrayList<MagicCubeDefinition>();
|
||||||
for (final String cubeName : INCLUDED_CUBES) {
|
for (final String cubeName : INCLUDED_CUBES) {
|
||||||
cubeDefinitions.add(new MagicCubeDefinition(cubeName));
|
cubeDefinitions.add(new MagicCubeDefinition(cubeName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String[] getCubeNames() {
|
public static String[] getCubeNames() {
|
||||||
final String[] names=new String[cubeDefinitions.size()];
|
final String[] names=new String[cubeDefinitions.size()];
|
||||||
for (int index=0;index<names.length;index++) {
|
for (int index=0;index<names.length;index++) {
|
||||||
|
@ -40,7 +40,7 @@ public class CubeDefinitions {
|
||||||
}
|
}
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MagicCubeDefinition getCubeDefinition(final String name) {
|
public static MagicCubeDefinition getCubeDefinition(final String name) {
|
||||||
for (final MagicCubeDefinition cubeDefinition : cubeDefinitions) {
|
for (final MagicCubeDefinition cubeDefinition : cubeDefinitions) {
|
||||||
if (cubeDefinition.getName().equals(name)) {
|
if (cubeDefinition.getName().equals(name)) {
|
||||||
|
@ -49,7 +49,7 @@ public class CubeDefinitions {
|
||||||
}
|
}
|
||||||
return cubeDefinitions.get(0);
|
return cubeDefinitions.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void loadCubeDefinition(final String name,final File file) {
|
private static void loadCubeDefinition(final String name,final File file) {
|
||||||
String content = "";
|
String content = "";
|
||||||
try { //load cube
|
try { //load cube
|
||||||
|
@ -70,7 +70,7 @@ public class CubeDefinitions {
|
||||||
}
|
}
|
||||||
cubeDefinitions.add(cubeDefinition);
|
cubeDefinitions.add(cubeDefinition);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void loadCubeDefinitions() {
|
public static void loadCubeDefinitions() {
|
||||||
final File[] cubeFiles=new File(MagicMain.getModsPath()).listFiles(CUBE_FILE_FILTER);
|
final File[] cubeFiles=new File(MagicMain.getModsPath()).listFiles(CUBE_FILE_FILTER);
|
||||||
if (cubeFiles!=null) {
|
if (cubeFiles!=null) {
|
||||||
|
@ -80,7 +80,7 @@ public class CubeDefinitions {
|
||||||
loadCubeDefinition(name.substring(0,index),file);
|
loadCubeDefinition(name.substring(0,index),file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
System.err.println(cubeDefinitions.size()+" cube definitions");
|
System.err.println(cubeDefinitions.size()+" cube definitions");
|
||||||
for (final MagicCubeDefinition cubeDefinition : cubeDefinitions) {
|
for (final MagicCubeDefinition cubeDefinition : cubeDefinitions) {
|
||||||
System.err.println("Cube "+cubeDefinition.getName());
|
System.err.println("Cube "+cubeDefinition.getName());
|
||||||
|
|
|
@ -15,47 +15,47 @@ import java.util.TreeMap;
|
||||||
public class DeckGenerators {
|
public class DeckGenerators {
|
||||||
|
|
||||||
private static final DeckGenerators INSTANCE = new DeckGenerators();
|
private static final DeckGenerators INSTANCE = new DeckGenerators();
|
||||||
|
|
||||||
private static final String FILENAME = "deckgenerators.txt";
|
private static final String FILENAME = "deckgenerators.txt";
|
||||||
|
|
||||||
private final Map<String, Class> generatorsMap;
|
private final Map<String, Class> generatorsMap;
|
||||||
|
|
||||||
private DeckGenerators() {
|
private DeckGenerators() {
|
||||||
generatorsMap = new TreeMap<String, Class>();
|
generatorsMap = new TreeMap<String, Class>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getGeneratorNames() {
|
public Set<String> getGeneratorNames() {
|
||||||
return generatorsMap.keySet();
|
return generatorsMap.keySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addDeckGenerator(final String name, final Class c) {
|
private void addDeckGenerator(final String name, final Class c) {
|
||||||
generatorsMap.put(name, c);
|
generatorsMap.put(name, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addDeckGenerator(final String name) {
|
private void addDeckGenerator(final String name) {
|
||||||
// find class
|
// find class
|
||||||
final String cname = name.replaceAll("[^A-Za-z0-9]", "_");
|
final String cname = name.replaceAll("[^A-Za-z0-9]", "_");
|
||||||
try { // reflection
|
try { // reflection
|
||||||
final Class c = Class.forName("magic.generator." + cname + "_DeckGenerator");
|
final Class c = Class.forName("magic.generator." + cname + "_DeckGenerator");
|
||||||
|
|
||||||
addDeckGenerator(name, c);
|
addDeckGenerator(name, c);
|
||||||
|
|
||||||
System.err.println("added deck generator " + name);
|
System.err.println("added deck generator " + name);
|
||||||
} catch (final ClassNotFoundException ex) {
|
} catch (final ClassNotFoundException ex) {
|
||||||
// no class found
|
// no class found
|
||||||
} catch (final ClassCastException ex) {
|
} catch (final ClassCastException ex) {
|
||||||
throw new RuntimeException(ex);
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DefaultDeckGenerator getDeckGenerator(final String name) {
|
public DefaultDeckGenerator getDeckGenerator(final String name) {
|
||||||
return getDeckGenerator(generatorsMap.get(name));
|
return getDeckGenerator(generatorsMap.get(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
private DefaultDeckGenerator getDeckGenerator(final Class c) {
|
private DefaultDeckGenerator getDeckGenerator(final Class c) {
|
||||||
DefaultDeckGenerator gen = null;
|
DefaultDeckGenerator gen = null;
|
||||||
|
|
||||||
if(c != null) {
|
if(c != null) {
|
||||||
try {
|
try {
|
||||||
gen = (DefaultDeckGenerator) c.newInstance();
|
gen = (DefaultDeckGenerator) c.newInstance();
|
||||||
|
@ -67,10 +67,10 @@ public class DeckGenerators {
|
||||||
throw new RuntimeException(ex);
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return gen;
|
return gen;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadDeckGenerators(final String filename) {
|
private void loadDeckGenerators(final String filename) {
|
||||||
final InputStream stream = this.getClass().getResourceAsStream(filename);
|
final InputStream stream = this.getClass().getResourceAsStream(filename);
|
||||||
String content = null;
|
String content = null;
|
||||||
|
@ -92,17 +92,17 @@ public class DeckGenerators {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadDeckGenerators() {
|
public void loadDeckGenerators() {
|
||||||
loadDeckGenerators(FILENAME);
|
loadDeckGenerators(FILENAME);
|
||||||
|
|
||||||
System.err.println(getNrGenerators()+ " deck generators loaded");
|
System.err.println(getNrGenerators()+ " deck generators loaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNrGenerators() {
|
public int getNrGenerators() {
|
||||||
return generatorsMap.size();
|
return generatorsMap.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DeckGenerators getInstance() {
|
public static DeckGenerators getInstance() {
|
||||||
return INSTANCE;
|
return INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ import java.util.TreeMap;
|
||||||
public class DeckUtils {
|
public class DeckUtils {
|
||||||
|
|
||||||
public static final String DECK_EXTENSION=".dec";
|
public static final String DECK_EXTENSION=".dec";
|
||||||
|
|
||||||
public static final FileFilter DECK_FILEFILTER=new FileFilter() {
|
public static final FileFilter DECK_FILEFILTER=new FileFilter() {
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(final File file) {
|
public boolean accept(final File file) {
|
||||||
|
@ -35,20 +35,20 @@ public class DeckUtils {
|
||||||
return "Magarena deck";
|
return "Magarena deck";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final String[] CARD_TYPES={"creatures","spells","lands"};
|
private static final String[] CARD_TYPES={"creatures","spells","lands"};
|
||||||
|
|
||||||
public static String getDeckFolder() {
|
public static String getDeckFolder() {
|
||||||
return MagicMain.getGamePath()+File.separator+"decks";
|
return MagicMain.getGamePath()+File.separator+"decks";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void createDeckFolder() {
|
public static void createDeckFolder() {
|
||||||
final File deckFolderFile=new File(getDeckFolder());
|
final File deckFolderFile=new File(getDeckFolder());
|
||||||
if (!deckFolderFile.exists() && !deckFolderFile.mkdir()) {
|
if (!deckFolderFile.exists() && !deckFolderFile.mkdir()) {
|
||||||
System.err.println("WARNING. Unable to create " + getDeckFolder());
|
System.err.println("WARNING. Unable to create " + getDeckFolder());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean saveDeck(final String filename,final MagicPlayerDefinition player) {
|
public static boolean saveDeck(final String filename,final MagicPlayerDefinition player) {
|
||||||
final List<SortedMap<String,Integer>> cardMaps=new ArrayList<SortedMap<String,Integer>>();
|
final List<SortedMap<String,Integer>> cardMaps=new ArrayList<SortedMap<String,Integer>>();
|
||||||
boolean isSuccessful = true;
|
boolean isSuccessful = true;
|
||||||
|
@ -56,7 +56,7 @@ public class DeckUtils {
|
||||||
for (int count=3;count>0;count--) {
|
for (int count=3;count>0;count--) {
|
||||||
cardMaps.add(new TreeMap<String, Integer>());
|
cardMaps.add(new TreeMap<String, Integer>());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final MagicCardDefinition cardDefinition : player.getDeck()) {
|
for (final MagicCardDefinition cardDefinition : player.getDeck()) {
|
||||||
final String name=cardDefinition.getName();
|
final String name=cardDefinition.getName();
|
||||||
final int index;
|
final int index;
|
||||||
|
@ -71,9 +71,9 @@ public class DeckUtils {
|
||||||
final Integer count=cardMap.get(name);
|
final Integer count=cardMap.get(name);
|
||||||
cardMap.put(name,count==null?Integer.valueOf(1):Integer.valueOf(count+1));
|
cardMap.put(name,count==null?Integer.valueOf(1):Integer.valueOf(count+1));
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferedWriter writer = null;
|
BufferedWriter writer = null;
|
||||||
try { //save deck
|
try { //save deck
|
||||||
writer = new BufferedWriter(new FileWriter(filename));
|
writer = new BufferedWriter(new FileWriter(filename));
|
||||||
for (int index=0;index<=2;index++) {
|
for (int index=0;index<=2;index++) {
|
||||||
final SortedMap<String,Integer> cardMap=cardMaps.get(index);
|
final SortedMap<String,Integer> cardMap=cardMaps.get(index);
|
||||||
|
@ -99,10 +99,10 @@ public class DeckUtils {
|
||||||
} finally {
|
} finally {
|
||||||
magic.data.FileIO.close(writer);
|
magic.data.FileIO.close(writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return isSuccessful;
|
return isSuccessful;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void loadDeck(final String filename,final MagicPlayerDefinition player) {
|
public static void loadDeck(final String filename,final MagicPlayerDefinition player) {
|
||||||
String content = "";
|
String content = "";
|
||||||
try { //load deck
|
try { //load deck
|
||||||
|
@ -118,7 +118,7 @@ public class DeckUtils {
|
||||||
final int[] colorCount = new int[MagicColor.NR_COLORS];
|
final int[] colorCount = new int[MagicColor.NR_COLORS];
|
||||||
final MagicDeck deck = player.getDeck();
|
final MagicDeck deck = player.getDeck();
|
||||||
final MagicDeck unsupported = new MagicDeck();
|
final MagicDeck unsupported = new MagicDeck();
|
||||||
|
|
||||||
deck.setName(new File(filename).getName());
|
deck.setName(new File(filename).getName());
|
||||||
deck.clear(); // remove previous cards
|
deck.clear(); // remove previous cards
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ public class DeckUtils {
|
||||||
profile.setPreConstructed();
|
profile.setPreConstructed();
|
||||||
player.setProfile(profile);
|
player.setProfile(profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void showUnsupportedCards(final MagicDeck unsupported) {
|
public static void showUnsupportedCards(final MagicDeck unsupported) {
|
||||||
if (unsupported.isEmpty()) {
|
if (unsupported.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
|
@ -182,7 +182,7 @@ public class DeckUtils {
|
||||||
// show error message for unsupported cards
|
// show error message for unsupported cards
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
sb.append("The loaded deck contained unsupported card(s): ");
|
sb.append("The loaded deck contained unsupported card(s): ");
|
||||||
|
|
||||||
// generate list of unsupported cards
|
// generate list of unsupported cards
|
||||||
for (int i = 0; i < unsupported.size(); i++) {
|
for (int i = 0; i < unsupported.size(); i++) {
|
||||||
if(i > 0) {
|
if(i > 0) {
|
||||||
|
@ -190,27 +190,27 @@ public class DeckUtils {
|
||||||
}
|
}
|
||||||
sb.append(unsupported.get(i).getName());
|
sb.append(unsupported.get(i).getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
// options panel doesn't have automatic text wrapping
|
// options panel doesn't have automatic text wrapping
|
||||||
// because the method that provides max char limit isn't
|
// because the method that provides max char limit isn't
|
||||||
// coded, so override that method
|
// coded, so override that method
|
||||||
final JOptionPane cleanupPane = new JOptionPane(sb.toString(), JOptionPane.ERROR_MESSAGE) {
|
final JOptionPane cleanupPane = new JOptionPane(sb.toString(), JOptionPane.ERROR_MESSAGE) {
|
||||||
private static final long serialVersionUID = 232L;
|
private static final long serialVersionUID = 232L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxCharactersPerLineCount() {
|
public int getMaxCharactersPerLineCount() {
|
||||||
return 70;
|
return 70;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
cleanupPane.createDialog(null, "Unsupported Cards").setVisible(true);
|
cleanupPane.createDialog(null, "Unsupported Cards").setVisible(true);
|
||||||
|
|
||||||
unsupported.clear();
|
unsupported.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void retrieveDeckFiles(final File folder,final List<File> deckFiles) {
|
private static void retrieveDeckFiles(final File folder,final List<File> deckFiles) {
|
||||||
final File[] files=folder.listFiles();
|
final File[] files=folder.listFiles();
|
||||||
for (final File file : files) {
|
for (final File file : files) {
|
||||||
|
|
||||||
if (file.isDirectory()) {
|
if (file.isDirectory()) {
|
||||||
retrieveDeckFiles(file,deckFiles);
|
retrieveDeckFiles(file,deckFiles);
|
||||||
} else if (file.getName().endsWith(DECK_EXTENSION)) {
|
} else if (file.getName().endsWith(DECK_EXTENSION)) {
|
||||||
|
@ -218,11 +218,11 @@ public class DeckUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void loadRandomDeck(final MagicPlayerDefinition player) {
|
public static void loadRandomDeck(final MagicPlayerDefinition player) {
|
||||||
final File deckFile=new File(getDeckFolder());
|
final File deckFile=new File(getDeckFolder());
|
||||||
final List<File> deckFiles=new ArrayList<File>();
|
final List<File> deckFiles=new ArrayList<File>();
|
||||||
retrieveDeckFiles(deckFile,deckFiles);
|
retrieveDeckFiles(deckFile,deckFiles);
|
||||||
final int size=deckFiles.size();
|
final int size=deckFiles.size();
|
||||||
if (size==0) {
|
if (size==0) {
|
||||||
// Creates a simple default deck.
|
// Creates a simple default deck.
|
||||||
|
|
|
@ -9,19 +9,19 @@ import java.net.URL;
|
||||||
public class DownloadCardTextFile extends WebDownloader {
|
public class DownloadCardTextFile extends WebDownloader {
|
||||||
private static final String startPattern = "ctext\">";
|
private static final String startPattern = "ctext\">";
|
||||||
private static final String endPattern = "</p>";
|
private static final String endPattern = "</p>";
|
||||||
|
|
||||||
private final File file;
|
private final File file;
|
||||||
private final URL url;
|
private final URL url;
|
||||||
|
|
||||||
DownloadCardTextFile(final File file, final URL url) {
|
DownloadCardTextFile(final File file, final URL url) {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.url = url;
|
this.url = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFilename() {
|
public String getFilename() {
|
||||||
return file.getName();
|
return file.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getFile() {
|
public File getFile() {
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
@ -29,10 +29,10 @@ public class DownloadCardTextFile extends WebDownloader {
|
||||||
public boolean exists() {
|
public boolean exists() {
|
||||||
return file.exists();
|
return file.exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void download(final Proxy proxy) {
|
public void download(final Proxy proxy) {
|
||||||
final String html = WebDownloader.getHTML(proxy, url);
|
final String html = WebDownloader.getHTML(proxy, url);
|
||||||
|
|
||||||
// find text in html
|
// find text in html
|
||||||
int iStart = html.indexOf(startPattern);
|
int iStart = html.indexOf(startPattern);
|
||||||
String foundText = null;
|
String foundText = null;
|
||||||
|
@ -40,12 +40,12 @@ public class DownloadCardTextFile extends WebDownloader {
|
||||||
iStart += startPattern.length();
|
iStart += startPattern.length();
|
||||||
final int iEnd = html.indexOf(endPattern, iStart);
|
final int iEnd = html.indexOf(endPattern, iStart);
|
||||||
foundText = html.substring(iStart, iEnd) + " ";
|
foundText = html.substring(iStart, iEnd) + " ";
|
||||||
|
|
||||||
foundText = foundText.replace((char) 195, 'A').replace((char) 8224, 'E');; // replace Æ character with AE
|
foundText = foundText.replace((char) 195, 'A').replace((char) 8224, 'E');; // replace Æ character with AE
|
||||||
foundText = foundText.replaceAll("\\<br\\>", " "); // replace newlines
|
foundText = foundText.replaceAll("\\<br\\>", " "); // replace newlines
|
||||||
foundText = foundText.replaceAll("\\<[^\\>]*\\>", ""); // remove other html tags
|
foundText = foundText.replaceAll("\\<[^\\>]*\\>", ""); // remove other html tags
|
||||||
}
|
}
|
||||||
|
|
||||||
// write text out to file
|
// write text out to file
|
||||||
// even if there's no text we want to create the file to ensure that we don't redownload it
|
// even if there's no text we want to create the file to ensure that we don't redownload it
|
||||||
if(foundText != null) {
|
if(foundText != null) {
|
||||||
|
@ -66,6 +66,6 @@ public class DownloadCardTextFile extends WebDownloader {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
System.err.println("ERROR! Unable to download card text for " + file);
|
System.err.println("ERROR! Unable to download card text for " + file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,17 +11,17 @@ public class DownloadImageFile extends WebDownloader {
|
||||||
private final File file;
|
private final File file;
|
||||||
private final URL url;
|
private final URL url;
|
||||||
private final MagicCardDefinition cdef;
|
private final MagicCardDefinition cdef;
|
||||||
|
|
||||||
DownloadImageFile(final File file, final URL url) {
|
DownloadImageFile(final File file, final URL url) {
|
||||||
this(file, url, MagicCardDefinition.UNKNOWN);
|
this(file, url, MagicCardDefinition.UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
DownloadImageFile(final File file, final URL url, final MagicCardDefinition cdef) {
|
DownloadImageFile(final File file, final URL url, final MagicCardDefinition cdef) {
|
||||||
this.file=file;
|
this.file=file;
|
||||||
this.url=url;
|
this.url=url;
|
||||||
this.cdef=cdef;
|
this.cdef=cdef;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFilename() {
|
public String getFilename() {
|
||||||
return file.getName();
|
return file.getName();
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ public class DownloadImageFile extends WebDownloader {
|
||||||
public File getFile() {
|
public File getFile() {
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void download(final Proxy proxy) {
|
public void download(final Proxy proxy) {
|
||||||
WebDownloader.downloadToFile(proxy, url, file);
|
WebDownloader.downloadToFile(proxy, url, file);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Download the necessary images and files from the WWW
|
* Download the necessary images and files from the WWW
|
||||||
*/
|
*/
|
||||||
public class DownloadMissingFiles extends ArrayList<WebDownloader> {
|
public class DownloadMissingFiles extends ArrayList<WebDownloader> {
|
||||||
|
@ -21,11 +21,11 @@ public class DownloadMissingFiles extends ArrayList<WebDownloader> {
|
||||||
|
|
||||||
public DownloadMissingFiles(final String filename) {
|
public DownloadMissingFiles(final String filename) {
|
||||||
loadDownloadImageFiles(filename);
|
loadDownloadImageFiles(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadDownloadImageFiles(final String filename) {
|
private void loadDownloadImageFiles(final String filename) {
|
||||||
final InputStream stream;
|
final InputStream stream;
|
||||||
|
|
||||||
// download additional images
|
// download additional images
|
||||||
if (filename.startsWith("file://")) {
|
if (filename.startsWith("file://")) {
|
||||||
try { //create file input stream
|
try { //create file input stream
|
||||||
|
@ -73,27 +73,27 @@ public class DownloadMissingFiles extends ArrayList<WebDownloader> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// download card images and texts
|
// download card images and texts
|
||||||
final File cardsPathFile=new File(gamePathFile, CardDefinitions.CARD_IMAGE_FOLDER);
|
final File cardsPathFile=new File(gamePathFile, CardDefinitions.CARD_IMAGE_FOLDER);
|
||||||
final File tokensPathFile = new File(gamePathFile, CardDefinitions.TOKEN_IMAGE_FOLDER);
|
final File tokensPathFile = new File(gamePathFile, CardDefinitions.TOKEN_IMAGE_FOLDER);
|
||||||
final File textPathFile = new File(gamePathFile, CardDefinitions.CARD_TEXT_FOLDER);
|
final File textPathFile = new File(gamePathFile, CardDefinitions.CARD_TEXT_FOLDER);
|
||||||
|
|
||||||
if (!tokensPathFile.exists() && !tokensPathFile.mkdir()) {
|
if (!tokensPathFile.exists() && !tokensPathFile.mkdir()) {
|
||||||
System.err.println("WARNING. Unable to create " + tokensPathFile);
|
System.err.println("WARNING. Unable to create " + tokensPathFile);
|
||||||
}
|
}
|
||||||
if (!textPathFile.exists() && !textPathFile.mkdir()) {
|
if (!textPathFile.exists() && !textPathFile.mkdir()) {
|
||||||
System.err.println("WARNING. Unable to create " + textPathFile);
|
System.err.println("WARNING. Unable to create " + textPathFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final MagicCardDefinition cardDefinition : CardDefinitions.getCards()) {
|
for (final MagicCardDefinition cardDefinition : CardDefinitions.getCards()) {
|
||||||
// card image
|
// card image
|
||||||
final String imageURL = cardDefinition.getImageURL();
|
final String imageURL = cardDefinition.getImageURL();
|
||||||
if (imageURL != null) {
|
if (imageURL != null) {
|
||||||
final File imageFile = cardDefinition.isToken()?
|
final File imageFile = cardDefinition.isToken()?
|
||||||
new File(tokensPathFile,
|
new File(tokensPathFile,
|
||||||
cardDefinition.getImageName() + CardDefinitions.CARD_IMAGE_EXT) :
|
cardDefinition.getImageName() + CardDefinitions.CARD_IMAGE_EXT) :
|
||||||
new File(cardsPathFile,
|
new File(cardsPathFile,
|
||||||
cardDefinition.getImageName() + CardDefinitions.CARD_IMAGE_EXT);
|
cardDefinition.getImageName() + CardDefinitions.CARD_IMAGE_EXT);
|
||||||
|
|
||||||
try { //create URL
|
try { //create URL
|
||||||
|
@ -105,15 +105,15 @@ public class DownloadMissingFiles extends ArrayList<WebDownloader> {
|
||||||
System.err.println("ERROR! URL malformed " + imageURL);
|
System.err.println("ERROR! URL malformed " + imageURL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// card text
|
// card text
|
||||||
final String textUrl = cardDefinition.getCardInfoURL();
|
final String textUrl = cardDefinition.getCardInfoURL();
|
||||||
if (textUrl != null && textUrl.length() > 0) {
|
if (textUrl != null && textUrl.length() > 0) {
|
||||||
final File textFile = new File(textPathFile,
|
final File textFile = new File(textPathFile,
|
||||||
cardDefinition.getCardTextName() + CardDefinitions.CARD_TEXT_EXT);
|
cardDefinition.getCardTextName() + CardDefinitions.CARD_TEXT_EXT);
|
||||||
|
|
||||||
// download if the file does not exists OR it is zero length OR it is outdated
|
// download if the file does not exists OR it is zero length OR it is outdated
|
||||||
if (!textFile.exists() ||
|
if (!textFile.exists() ||
|
||||||
textFile.length() == 0L ||
|
textFile.length() == 0L ||
|
||||||
cardDefinition.isIgnored(textFile.length())) {
|
cardDefinition.isIgnored(textFile.length())) {
|
||||||
try { // create URL
|
try { // create URL
|
||||||
|
|
|
@ -18,7 +18,7 @@ public class DuelConfig {
|
||||||
private static final String ANY_THREE="***";
|
private static final String ANY_THREE="***";
|
||||||
private static final String ANY_TWO="**";
|
private static final String ANY_TWO="**";
|
||||||
private static final String ANY_ONE="*";
|
private static final String ANY_ONE="*";
|
||||||
|
|
||||||
private static final String CONFIG_FILENAME="duel.cfg";
|
private static final String CONFIG_FILENAME="duel.cfg";
|
||||||
private static final String AVATAR="avatar";
|
private static final String AVATAR="avatar";
|
||||||
private static final String NAME="name";
|
private static final String NAME="name";
|
||||||
|
@ -39,11 +39,11 @@ public class DuelConfig {
|
||||||
private String opponentColors=ANY_THREE;
|
private String opponentColors=ANY_THREE;
|
||||||
private String cube=CubeDefinitions.DEFAULT_NAME;
|
private String cube=CubeDefinitions.DEFAULT_NAME;
|
||||||
private String ai="minimax";
|
private String ai="minimax";
|
||||||
|
|
||||||
public DuelConfig() {
|
public DuelConfig() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DuelConfig(final DuelConfig duelConfig) {
|
public DuelConfig(final DuelConfig duelConfig) {
|
||||||
avatar=duelConfig.avatar;
|
avatar=duelConfig.avatar;
|
||||||
startLife=duelConfig.startLife;
|
startLife=duelConfig.startLife;
|
||||||
|
@ -53,7 +53,7 @@ public class DuelConfig {
|
||||||
opponentColors=duelConfig.opponentColors;
|
opponentColors=duelConfig.opponentColors;
|
||||||
ai=duelConfig.ai;
|
ai=duelConfig.ai;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getAvatar() {
|
public int getAvatar() {
|
||||||
return avatar;
|
return avatar;
|
||||||
}
|
}
|
||||||
|
@ -61,11 +61,11 @@ public class DuelConfig {
|
||||||
public void setAvatar(final int avatar) {
|
public void setAvatar(final int avatar) {
|
||||||
this.avatar = avatar;
|
this.avatar = avatar;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setName(final String name) {
|
public void setName(final String name) {
|
||||||
this.name=name;
|
this.name=name;
|
||||||
}
|
}
|
||||||
|
@ -85,15 +85,15 @@ public class DuelConfig {
|
||||||
public void setHandSize(final int handSize) {
|
public void setHandSize(final int handSize) {
|
||||||
this.handSize = handSize;
|
this.handSize = handSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNrOfGames(final int aGames) {
|
public void setNrOfGames(final int aGames) {
|
||||||
this.games = aGames;
|
this.games = aGames;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNrOfGames() {
|
public int getNrOfGames() {
|
||||||
return games;
|
return games;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MagicPlayerProfile getProfile(final String colorText) {
|
private static MagicPlayerProfile getProfile(final String colorText) {
|
||||||
if (ANY_DECK.equals(colorText)) {
|
if (ANY_DECK.equals(colorText)) {
|
||||||
return new MagicPlayerProfile("");
|
return new MagicPlayerProfile("");
|
||||||
|
@ -109,48 +109,48 @@ public class DuelConfig {
|
||||||
}
|
}
|
||||||
return new MagicPlayerProfile(colorText);
|
return new MagicPlayerProfile(colorText);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPlayerColors() {
|
public String getPlayerColors() {
|
||||||
return playerColors;
|
return playerColors;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPlayerColors(final String colors) {
|
public void setPlayerColors(final String colors) {
|
||||||
playerColors=colors;
|
playerColors=colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicPlayerProfile getPlayerProfile() {
|
public MagicPlayerProfile getPlayerProfile() {
|
||||||
return getProfile(playerColors);
|
return getProfile(playerColors);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOpponentColors() {
|
public String getOpponentColors() {
|
||||||
return opponentColors;
|
return opponentColors;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOpponentColors(final String colors) {
|
public void setOpponentColors(final String colors) {
|
||||||
opponentColors=colors;
|
opponentColors=colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicPlayerProfile getOpponentProfile() {
|
public MagicPlayerProfile getOpponentProfile() {
|
||||||
return getProfile(opponentColors);
|
return getProfile(opponentColors);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCube() {
|
public String getCube() {
|
||||||
return cube;
|
return cube;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCube(final String cube) {
|
public void setCube(final String cube) {
|
||||||
this.cube=cube;
|
this.cube=cube;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicAI[] getPlayerAIs() {
|
public MagicAI[] getPlayerAIs() {
|
||||||
final MagicAI playerAI = MagicAIImpl.getAI(ai).getAI();
|
final MagicAI playerAI = MagicAIImpl.getAI(ai).getAI();
|
||||||
return new MagicAI[]{playerAI, playerAI};
|
return new MagicAI[]{playerAI, playerAI};
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAI() {
|
public String getAI() {
|
||||||
return ai;
|
return ai;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAI(final String ai) {
|
public void setAI(final String ai) {
|
||||||
this.ai=ai;
|
this.ai=ai;
|
||||||
}
|
}
|
||||||
|
@ -166,11 +166,11 @@ public class DuelConfig {
|
||||||
cube=properties.getProperty(CUBE,cube);
|
cube=properties.getProperty(CUBE,cube);
|
||||||
ai=properties.getProperty(AI,ai);
|
ai=properties.getProperty(AI,ai);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void load() {
|
public void load() {
|
||||||
load(FileIO.toProp(getConfigFile()));
|
load(FileIO.toProp(getConfigFile()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save(final Properties properties) {
|
public void save(final Properties properties) {
|
||||||
properties.setProperty(AVATAR,Integer.toString(avatar));
|
properties.setProperty(AVATAR,Integer.toString(avatar));
|
||||||
properties.setProperty(NAME,name);
|
properties.setProperty(NAME,name);
|
||||||
|
@ -182,22 +182,22 @@ public class DuelConfig {
|
||||||
properties.setProperty(CUBE,cube);
|
properties.setProperty(CUBE,cube);
|
||||||
properties.setProperty(AI,ai);
|
properties.setProperty(AI,ai);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save() {
|
public void save() {
|
||||||
final Properties properties=new Properties();
|
final Properties properties=new Properties();
|
||||||
save(properties);
|
save(properties);
|
||||||
try { //save config
|
try { //save config
|
||||||
FileIO.toFile(getConfigFile(), properties, "Duel configuration");
|
FileIO.toFile(getConfigFile(), properties, "Duel configuration");
|
||||||
System.err.println("Saved duel config");
|
System.err.println("Saved duel config");
|
||||||
} catch (final IOException ex) {
|
} catch (final IOException ex) {
|
||||||
System.err.println("ERROR! Unable to save duel config");
|
System.err.println("ERROR! Unable to save duel config");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static File getConfigFile() {
|
private static File getConfigFile() {
|
||||||
return new File(MagicMain.getGamePath(),CONFIG_FILENAME);
|
return new File(MagicMain.getGamePath(),CONFIG_FILENAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DuelConfig getInstance() {
|
public static DuelConfig getInstance() {
|
||||||
return INSTANCE;
|
return INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ public class FileIO {
|
||||||
close(stream);
|
close(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String toStr(final BufferedReader input) throws IOException {
|
private static String toStr(final BufferedReader input) throws IOException {
|
||||||
final StringBuilder contents = new StringBuilder();
|
final StringBuilder contents = new StringBuilder();
|
||||||
try {
|
try {
|
||||||
|
@ -55,7 +55,7 @@ public class FileIO {
|
||||||
public static String toStr(final File aFile) throws IOException {
|
public static String toStr(final File aFile) throws IOException {
|
||||||
return toStr(new FileInputStream(aFile));
|
return toStr(new FileInputStream(aFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
static String toStr(final InputStream ins) throws IOException {
|
static String toStr(final InputStream ins) throws IOException {
|
||||||
return toStr(new BufferedReader(new InputStreamReader(ins)));
|
return toStr(new BufferedReader(new InputStreamReader(ins)));
|
||||||
}
|
}
|
||||||
|
@ -66,10 +66,10 @@ public class FileIO {
|
||||||
properties = toProp(new FileInputStream(aFile));
|
properties = toProp(new FileInputStream(aFile));
|
||||||
} catch (final IOException ex) {
|
} catch (final IOException ex) {
|
||||||
System.err.println("ERROR! Unable to load from " + aFile + ", " + ex.getMessage());
|
System.err.println("ERROR! Unable to load from " + aFile + ", " + ex.getMessage());
|
||||||
}
|
}
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Properties toProp(final InputStream ins) {
|
public static Properties toProp(final InputStream ins) {
|
||||||
final Properties properties = new Properties();
|
final Properties properties = new Properties();
|
||||||
try {
|
try {
|
||||||
|
@ -84,7 +84,7 @@ public class FileIO {
|
||||||
|
|
||||||
public static BufferedImage toImg(final File input, final BufferedImage def) {
|
public static BufferedImage toImg(final File input, final BufferedImage def) {
|
||||||
BufferedImage img = def;
|
BufferedImage img = def;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
img = ImageIO.read(input);
|
img = ImageIO.read(input);
|
||||||
} catch (final IOException ex) {
|
} catch (final IOException ex) {
|
||||||
|
@ -92,16 +92,16 @@ public class FileIO {
|
||||||
} catch (final IllegalArgumentException ex) {
|
} catch (final IllegalArgumentException ex) {
|
||||||
System.err.println("ERROR! Unable to read from null");
|
System.err.println("ERROR! Unable to read from null");
|
||||||
}
|
}
|
||||||
|
|
||||||
// no registered ImageReader able to read the file, likely file is corrupted
|
// no registered ImageReader able to read the file, likely file is corrupted
|
||||||
if (img == null) {
|
if (img == null) {
|
||||||
img = def;
|
img = def;
|
||||||
input.delete();
|
input.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BufferedImage toImg(final URL input, final BufferedImage def) {
|
static BufferedImage toImg(final URL input, final BufferedImage def) {
|
||||||
BufferedImage img = def;
|
BufferedImage img = def;
|
||||||
try {
|
try {
|
||||||
|
@ -113,7 +113,7 @@ public class FileIO {
|
||||||
}
|
}
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BufferedImage toImg(final InputStream input, final BufferedImage def) {
|
public static BufferedImage toImg(final InputStream input, final BufferedImage def) {
|
||||||
BufferedImage img = def;
|
BufferedImage img = def;
|
||||||
try {
|
try {
|
||||||
|
@ -127,7 +127,7 @@ public class FileIO {
|
||||||
}
|
}
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void toFile(final File aFile, final String aContents, final boolean append) throws IOException {
|
public static void toFile(final File aFile, final String aContents, final boolean append) throws IOException {
|
||||||
Writer output = null;
|
Writer output = null;
|
||||||
try {
|
try {
|
||||||
|
@ -137,10 +137,10 @@ public class FileIO {
|
||||||
close(output);
|
close(output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void toFile(
|
public static void toFile(
|
||||||
final File aFile,
|
final File aFile,
|
||||||
final Properties properties,
|
final Properties properties,
|
||||||
final String name) throws IOException {
|
final String name) throws IOException {
|
||||||
FileOutputStream fos = null;
|
FileOutputStream fos = null;
|
||||||
try {
|
try {
|
||||||
|
@ -199,4 +199,4 @@ public class FileIO {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import java.util.Properties;
|
||||||
public class GeneralConfig {
|
public class GeneralConfig {
|
||||||
|
|
||||||
private static final GeneralConfig INSTANCE=new GeneralConfig();
|
private static final GeneralConfig INSTANCE=new GeneralConfig();
|
||||||
|
|
||||||
private static final String CONFIG_FILENAME="general.cfg";
|
private static final String CONFIG_FILENAME="general.cfg";
|
||||||
private static final String LEFT="left";
|
private static final String LEFT="left";
|
||||||
private static final String TOP="top";
|
private static final String TOP="top";
|
||||||
|
@ -79,9 +79,9 @@ public class GeneralConfig {
|
||||||
private boolean sound=DEFAULT_SOUND;
|
private boolean sound=DEFAULT_SOUND;
|
||||||
private boolean confirmExit = DEFAULT_CONFIRM_EXIT;
|
private boolean confirmExit = DEFAULT_CONFIRM_EXIT;
|
||||||
private boolean touchscreen = DEFAULT_TOUCHSCREEN;
|
private boolean touchscreen = DEFAULT_TOUCHSCREEN;
|
||||||
|
|
||||||
private GeneralConfig() {}
|
private GeneralConfig() {}
|
||||||
|
|
||||||
public int getLeft() {
|
public int getLeft() {
|
||||||
return left;
|
return left;
|
||||||
}
|
}
|
||||||
|
@ -121,51 +121,51 @@ public class GeneralConfig {
|
||||||
public void setMaximized(final boolean maximized) {
|
public void setMaximized(final boolean maximized) {
|
||||||
this.maximized=maximized;
|
this.maximized=maximized;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTheme() {
|
public String getTheme() {
|
||||||
return theme;
|
return theme;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTheme(final String theme) {
|
public void setTheme(final String theme) {
|
||||||
this.theme=theme;
|
this.theme=theme;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAvatar() {
|
public String getAvatar() {
|
||||||
return avatar;
|
return avatar;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAvatar(final String avatar) {
|
public void setAvatar(final String avatar) {
|
||||||
this.avatar=avatar;
|
this.avatar=avatar;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isHighlightNone() {
|
public boolean isHighlightNone() {
|
||||||
return "none".equals(highlight);
|
return "none".equals(highlight);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isHighlightOverlay() {
|
public boolean isHighlightOverlay() {
|
||||||
return "overlay".equals(highlight);
|
return "overlay".equals(highlight);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isHighlightTheme() {
|
public boolean isHighlightTheme() {
|
||||||
return "theme".equals(highlight);
|
return "theme".equals(highlight);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getHighlight() {
|
public String getHighlight() {
|
||||||
return highlight;
|
return highlight;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHighlight(final String highlight) {
|
public void setHighlight(final String highlight) {
|
||||||
this.highlight = highlight;
|
this.highlight = highlight;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getTextView() {
|
public boolean getTextView() {
|
||||||
return textView;
|
return textView;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTextView(final boolean textView) {
|
public void setTextView(final boolean textView) {
|
||||||
this.textView=textView;
|
this.textView=textView;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getSkipSingle() {
|
public boolean getSkipSingle() {
|
||||||
return skipSingle;
|
return skipSingle;
|
||||||
}
|
}
|
||||||
|
@ -173,19 +173,19 @@ public class GeneralConfig {
|
||||||
public void setSkipSingle(final boolean skipSingle) {
|
public void setSkipSingle(final boolean skipSingle) {
|
||||||
this.skipSingle=skipSingle;
|
this.skipSingle=skipSingle;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getAlwaysPass() {
|
public boolean getAlwaysPass() {
|
||||||
return alwaysPass;
|
return alwaysPass;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAlwaysPass(final boolean alwaysPass) {
|
public void setAlwaysPass(final boolean alwaysPass) {
|
||||||
this.alwaysPass=alwaysPass;
|
this.alwaysPass=alwaysPass;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getSmartTarget() {
|
public boolean getSmartTarget() {
|
||||||
return smartTarget;
|
return smartTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSmartTarget(final boolean smartTarget) {
|
public void setSmartTarget(final boolean smartTarget) {
|
||||||
this.smartTarget=smartTarget;
|
this.smartTarget=smartTarget;
|
||||||
}
|
}
|
||||||
|
@ -193,83 +193,83 @@ public class GeneralConfig {
|
||||||
public int getDifficulty() {
|
public int getDifficulty() {
|
||||||
return difficulty;
|
return difficulty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDifficulty(final int difficulty) {
|
public void setDifficulty(final int difficulty) {
|
||||||
this.difficulty=difficulty;
|
this.difficulty=difficulty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getExtraLife() {
|
public int getExtraLife() {
|
||||||
return extraLife;
|
return extraLife;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setExtraLife(final int extraLife) {
|
public void setExtraLife(final int extraLife) {
|
||||||
this.extraLife=extraLife;
|
this.extraLife=extraLife;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getPopupDelay() {
|
public int getPopupDelay() {
|
||||||
return popupDelay;
|
return popupDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPopupDelay(final int popupDelay) {
|
public void setPopupDelay(final int popupDelay) {
|
||||||
this.popupDelay=popupDelay;
|
this.popupDelay=popupDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMessageDelay() {
|
public int getMessageDelay() {
|
||||||
return messageDelay;
|
return messageDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMessageDelay(final int messageDelay) {
|
public void setMessageDelay(final int messageDelay) {
|
||||||
this.messageDelay = messageDelay;
|
this.messageDelay = messageDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getStrengthDifficulty() {
|
public int getStrengthDifficulty() {
|
||||||
return strengthDifficulty;
|
return strengthDifficulty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStrengthDifficulty(final int strengthDifficulty) {
|
public void setStrengthDifficulty(final int strengthDifficulty) {
|
||||||
this.strengthDifficulty=strengthDifficulty;
|
this.strengthDifficulty=strengthDifficulty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getStrengthGames() {
|
public int getStrengthGames() {
|
||||||
return strengthGames;
|
return strengthGames;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStrengthGames(final int strengthGames) {
|
public void setStrengthGames(final int strengthGames) {
|
||||||
this.strengthGames=strengthGames;
|
this.strengthGames=strengthGames;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isHighQuality() {
|
public boolean isHighQuality() {
|
||||||
return highQuality;
|
return highQuality;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHighQuality(final boolean highQuality) {
|
public void setHighQuality(final boolean highQuality) {
|
||||||
this.highQuality=highQuality;
|
this.highQuality=highQuality;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSound() {
|
public boolean isSound() {
|
||||||
return sound;
|
return sound;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSound(final boolean sound) {
|
public void setSound(final boolean sound) {
|
||||||
this.sound=sound;
|
this.sound=sound;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isConfirmExit() {
|
public boolean isConfirmExit() {
|
||||||
return confirmExit;
|
return confirmExit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setConfirmExit(final boolean confirmExit) {
|
public void setConfirmExit(final boolean confirmExit) {
|
||||||
this.confirmExit = confirmExit;
|
this.confirmExit = confirmExit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTouchscreen() {
|
public boolean isTouchscreen() {
|
||||||
return touchscreen;
|
return touchscreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTouchscreen(final boolean touchscreen) {
|
public void setTouchscreen(final boolean touchscreen) {
|
||||||
this.touchscreen = touchscreen;
|
this.touchscreen = touchscreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void load(final Properties properties) {
|
private void load(final Properties properties) {
|
||||||
left=Integer.parseInt(properties.getProperty(LEFT,""+DEFAULT_LEFT));
|
left=Integer.parseInt(properties.getProperty(LEFT,""+DEFAULT_LEFT));
|
||||||
top=Integer.parseInt(properties.getProperty(TOP,""+DEFAULT_TOP));
|
top=Integer.parseInt(properties.getProperty(TOP,""+DEFAULT_TOP));
|
||||||
|
@ -294,11 +294,11 @@ public class GeneralConfig {
|
||||||
confirmExit = Boolean.parseBoolean(properties.getProperty(CONFIRM_EXIT,""+DEFAULT_CONFIRM_EXIT));
|
confirmExit = Boolean.parseBoolean(properties.getProperty(CONFIRM_EXIT,""+DEFAULT_CONFIRM_EXIT));
|
||||||
touchscreen = Boolean.parseBoolean(properties.getProperty(TOUCHSCREEN,""+DEFAULT_TOUCHSCREEN));
|
touchscreen = Boolean.parseBoolean(properties.getProperty(TOUCHSCREEN,""+DEFAULT_TOUCHSCREEN));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void load() {
|
public void load() {
|
||||||
load(FileIO.toProp(getConfigFile()));
|
load(FileIO.toProp(getConfigFile()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void save(final Properties properties) {
|
private void save(final Properties properties) {
|
||||||
properties.setProperty(LEFT,String.valueOf(left));
|
properties.setProperty(LEFT,String.valueOf(left));
|
||||||
properties.setProperty(TOP,String.valueOf(top));
|
properties.setProperty(TOP,String.valueOf(top));
|
||||||
|
@ -323,7 +323,7 @@ public class GeneralConfig {
|
||||||
properties.setProperty(CONFIRM_EXIT,String.valueOf(confirmExit));
|
properties.setProperty(CONFIRM_EXIT,String.valueOf(confirmExit));
|
||||||
properties.setProperty(TOUCHSCREEN,String.valueOf(touchscreen));
|
properties.setProperty(TOUCHSCREEN,String.valueOf(touchscreen));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save() {
|
public void save() {
|
||||||
final Properties properties=new Properties();
|
final Properties properties=new Properties();
|
||||||
save(properties);
|
save(properties);
|
||||||
|
|
|
@ -12,17 +12,17 @@ import java.util.Map;
|
||||||
* the cards directory
|
* the cards directory
|
||||||
*/
|
*/
|
||||||
public class HighQualityCardImagesProvider implements CardImagesProvider {
|
public class HighQualityCardImagesProvider implements CardImagesProvider {
|
||||||
|
|
||||||
private static final CardImagesProvider INSTANCE=new HighQualityCardImagesProvider();
|
private static final CardImagesProvider INSTANCE=new HighQualityCardImagesProvider();
|
||||||
|
|
||||||
private static final int MAX_IMAGES=100;
|
private static final int MAX_IMAGES=100;
|
||||||
private final Map<String,BufferedImage> scaledImages =
|
private final Map<String,BufferedImage> scaledImages =
|
||||||
new magic.data.LRUCache<String,BufferedImage>(MAX_IMAGES);
|
new magic.data.LRUCache<String,BufferedImage>(MAX_IMAGES);
|
||||||
private final Map<String,BufferedImage> origImages =
|
private final Map<String,BufferedImage> origImages =
|
||||||
new magic.data.LRUCache<String,BufferedImage>(MAX_IMAGES);
|
new magic.data.LRUCache<String,BufferedImage>(MAX_IMAGES);
|
||||||
|
|
||||||
private HighQualityCardImagesProvider() {}
|
private HighQualityCardImagesProvider() {}
|
||||||
|
|
||||||
private static final String getFilename(
|
private static final String getFilename(
|
||||||
final MagicCardDefinition cardDefinition,
|
final MagicCardDefinition cardDefinition,
|
||||||
final int index) {
|
final int index) {
|
||||||
|
@ -35,11 +35,11 @@ public class HighQualityCardImagesProvider implements CardImagesProvider {
|
||||||
buffer.append(IMAGE_EXTENSION);
|
buffer.append(IMAGE_EXTENSION);
|
||||||
return buffer.toString();
|
return buffer.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BufferedImage loadCardImage(final String filename) {
|
private static BufferedImage loadCardImage(final String filename) {
|
||||||
return FileIO.toImg(new File(filename), IconImages.MISSING_CARD);
|
return FileIO.toImg(new File(filename), IconImages.MISSING_CARD);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BufferedImage getImage(
|
public BufferedImage getImage(
|
||||||
final MagicCardDefinition cardDefinition,
|
final MagicCardDefinition cardDefinition,
|
||||||
|
@ -56,10 +56,10 @@ public class HighQualityCardImagesProvider implements CardImagesProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!scaledImages.containsKey(filename)) {
|
if (!scaledImages.containsKey(filename)) {
|
||||||
scaledImages.put(filename,
|
scaledImages.put(filename,
|
||||||
magic.GraphicsUtilities.scale(
|
magic.GraphicsUtilities.scale(
|
||||||
origImages.get(filename),
|
origImages.get(filename),
|
||||||
CARD_WIDTH,
|
CARD_WIDTH,
|
||||||
CARD_HEIGHT
|
CARD_HEIGHT
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -67,12 +67,12 @@ public class HighQualityCardImagesProvider implements CardImagesProvider {
|
||||||
|
|
||||||
return orig ? origImages.get(filename) : scaledImages.get(filename);
|
return orig ? origImages.get(filename) : scaledImages.get(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CardImagesProvider getInstance() {
|
public static CardImagesProvider getInstance() {
|
||||||
return INSTANCE;
|
return INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearCache() {
|
public void clearCache() {
|
||||||
origImages.clear();
|
origImages.clear();
|
||||||
scaledImages.clear();
|
scaledImages.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,10 @@ import java.io.IOException;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
public class History {
|
public class History {
|
||||||
|
|
||||||
public static final String HISTORY_FOLDER = "history";
|
public static final String HISTORY_FOLDER = "history";
|
||||||
private static final String HISTORY_EXTENSION = ".hist";
|
private static final String HISTORY_EXTENSION = ".hist";
|
||||||
|
|
||||||
private static final String GAMES_PLAYED = "gamesPlayed";
|
private static final String GAMES_PLAYED = "gamesPlayed";
|
||||||
private static final String GAMES_WON = "gamesWon";
|
private static final String GAMES_WON = "gamesWon";
|
||||||
private static final String DUELS_PLAYED = "duelsPlayed";
|
private static final String DUELS_PLAYED = "duelsPlayed";
|
||||||
|
@ -28,7 +28,7 @@ public class History {
|
||||||
private static final String COLOR_GREEN = "colorGreen";
|
private static final String COLOR_GREEN = "colorGreen";
|
||||||
private static final String COLOR_RED = "colorRed";
|
private static final String COLOR_RED = "colorRed";
|
||||||
private static final String COLOR_WHITE = "colorWhite";
|
private static final String COLOR_WHITE = "colorWhite";
|
||||||
|
|
||||||
private static int gamesPlayed;
|
private static int gamesPlayed;
|
||||||
private static int gamesWon;
|
private static int gamesWon;
|
||||||
private static int turnsPlayed;
|
private static int turnsPlayed;
|
||||||
|
@ -41,25 +41,25 @@ public class History {
|
||||||
private static int colorGreen;
|
private static int colorGreen;
|
||||||
private static int colorRed;
|
private static int colorRed;
|
||||||
private static int colorWhite;
|
private static int colorWhite;
|
||||||
|
|
||||||
private static String name = "";
|
private static String name = "";
|
||||||
private final MagicDuel duel;
|
private final MagicDuel duel;
|
||||||
|
|
||||||
public History(final MagicDuel duel) {
|
public History(final MagicDuel duel) {
|
||||||
this.duel = duel;
|
this.duel = duel;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getHistoryFolder() {
|
private static String getHistoryFolder() {
|
||||||
return MagicMain.getGamePath() + File.separator + HISTORY_FOLDER;
|
return MagicMain.getGamePath() + File.separator + HISTORY_FOLDER;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void createHistoryFolder() {
|
public static void createHistoryFolder() {
|
||||||
final File HistoryFolderFile = new File(getHistoryFolder());
|
final File HistoryFolderFile = new File(getHistoryFolder());
|
||||||
if (!HistoryFolderFile.exists() && !HistoryFolderFile.mkdir()) {
|
if (!HistoryFolderFile.exists() && !HistoryFolderFile.mkdir()) {
|
||||||
System.err.println("WARNING. Unable to create " + getHistoryFolder());
|
System.err.println("WARNING. Unable to create " + getHistoryFolder());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(final boolean won,final MagicGame game,final DuelConfig configuration) {
|
public void update(final boolean won,final MagicGame game,final DuelConfig configuration) {
|
||||||
gamesPlayed++;
|
gamesPlayed++;
|
||||||
if (won) {
|
if (won) {
|
||||||
|
@ -107,7 +107,7 @@ public class History {
|
||||||
}
|
}
|
||||||
saveHistory(name + HISTORY_EXTENSION);
|
saveHistory(name + HISTORY_EXTENSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void load(final Properties properties) {
|
private void load(final Properties properties) {
|
||||||
gamesPlayed = Integer.parseInt(properties.getProperty(GAMES_PLAYED,"0"));
|
gamesPlayed = Integer.parseInt(properties.getProperty(GAMES_PLAYED,"0"));
|
||||||
gamesWon = Integer.parseInt(properties.getProperty(GAMES_WON,"0"));
|
gamesWon = Integer.parseInt(properties.getProperty(GAMES_WON,"0"));
|
||||||
|
@ -122,13 +122,13 @@ public class History {
|
||||||
colorRed = Integer.parseInt(properties.getProperty(COLOR_RED,"0"));
|
colorRed = Integer.parseInt(properties.getProperty(COLOR_RED,"0"));
|
||||||
colorWhite = Integer.parseInt(properties.getProperty(COLOR_WHITE,"0"));
|
colorWhite = Integer.parseInt(properties.getProperty(COLOR_WHITE,"0"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadHistory(final String name) {
|
public void loadHistory(final String name) {
|
||||||
setName(name);
|
setName(name);
|
||||||
load(FileIO.toProp(new File(getHistoryFolder() +
|
load(FileIO.toProp(new File(getHistoryFolder() +
|
||||||
File.separator + name + HISTORY_EXTENSION)));
|
File.separator + name + HISTORY_EXTENSION)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void save(final Properties properties) {
|
private void save(final Properties properties) {
|
||||||
properties.setProperty(GAMES_PLAYED,String.valueOf(gamesPlayed));
|
properties.setProperty(GAMES_PLAYED,String.valueOf(gamesPlayed));
|
||||||
properties.setProperty(GAMES_WON,String.valueOf(gamesWon));
|
properties.setProperty(GAMES_WON,String.valueOf(gamesWon));
|
||||||
|
@ -143,7 +143,7 @@ public class History {
|
||||||
properties.setProperty(COLOR_RED,String.valueOf(colorRed));
|
properties.setProperty(COLOR_RED,String.valueOf(colorRed));
|
||||||
properties.setProperty(COLOR_WHITE,String.valueOf(colorWhite));
|
properties.setProperty(COLOR_WHITE,String.valueOf(colorWhite));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveHistory(final String filename) {
|
private void saveHistory(final String filename) {
|
||||||
final Properties properties = new Properties();
|
final Properties properties = new Properties();
|
||||||
save(properties);
|
save(properties);
|
||||||
|
@ -160,11 +160,11 @@ public class History {
|
||||||
private static void setName(final String aName) {
|
private static void setName(final String aName) {
|
||||||
History.name = aName;
|
History.name = aName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getName() {
|
public static String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getGamesPlayed() {
|
public static int getGamesPlayed() {
|
||||||
return gamesPlayed;
|
return gamesPlayed;
|
||||||
}
|
}
|
||||||
|
@ -176,19 +176,19 @@ public class History {
|
||||||
public static int getTurnsPlayed() {
|
public static int getTurnsPlayed() {
|
||||||
return turnsPlayed;
|
return turnsPlayed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getDuelsPlayed() {
|
public static int getDuelsPlayed() {
|
||||||
return duelsPlayed;
|
return duelsPlayed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getDuelsWon() {
|
public static int getDuelsWon() {
|
||||||
return duelsWon;
|
return duelsWon;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getLifeLeftPlayer() {
|
public static int getLifeLeftPlayer() {
|
||||||
return lifeLeftPlayer;
|
return lifeLeftPlayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getLifeLeftAI() {
|
public static int getLifeLeftAI() {
|
||||||
return lifeLeftAI;
|
return lifeLeftAI;
|
||||||
}
|
}
|
||||||
|
@ -196,19 +196,19 @@ public class History {
|
||||||
public static int getColorBlack() {
|
public static int getColorBlack() {
|
||||||
return colorBlack;
|
return colorBlack;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getColorBlue() {
|
public static int getColorBlue() {
|
||||||
return colorBlue;
|
return colorBlue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getColorGreen() {
|
public static int getColorGreen() {
|
||||||
return colorGreen;
|
return colorGreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getColorRed() {
|
public static int getColorRed() {
|
||||||
return colorRed;
|
return colorRed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getColorWhite() {
|
public static int getColorWhite() {
|
||||||
return colorWhite;
|
return colorWhite;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,14 +11,14 @@ public class IconImages {
|
||||||
public static final BufferedImage MISSING2=loadImage("icons/missing2.png");
|
public static final BufferedImage MISSING2=loadImage("icons/missing2.png");
|
||||||
public static final BufferedImage MISSING_CARD=loadImage("icons/missing_card.png");
|
public static final BufferedImage MISSING_CARD=loadImage("icons/missing_card.png");
|
||||||
public static final ImageIcon MISSING_ICON=loadIcon("missing2.png");
|
public static final ImageIcon MISSING_ICON=loadIcon("missing2.png");
|
||||||
|
|
||||||
private static final BufferedImage MANA = loadImage("icons/Mana.png");
|
private static final BufferedImage MANA = loadImage("icons/Mana.png");
|
||||||
public static final BufferedImage LOGO=loadImage("textures/logo.jpg");
|
public static final BufferedImage LOGO=loadImage("textures/logo.jpg");
|
||||||
public static final BufferedImage WIZARD=loadImage("icons/wizard.png");
|
public static final BufferedImage WIZARD=loadImage("icons/wizard.png");
|
||||||
public static final BufferedImage WOOD=loadImage("textures/wood.jpg");
|
public static final BufferedImage WOOD=loadImage("textures/wood.jpg");
|
||||||
public static final BufferedImage MARBLE=loadImage("textures/marble.jpg");
|
public static final BufferedImage MARBLE=loadImage("textures/marble.jpg");
|
||||||
public static final BufferedImage GRANITE=loadImage("textures/granite.jpg");
|
public static final BufferedImage GRANITE=loadImage("textures/granite.jpg");
|
||||||
public static final BufferedImage GRANITE2=loadImage("textures/granite2.jpg");
|
public static final BufferedImage GRANITE2=loadImage("textures/granite2.jpg");
|
||||||
public static final BufferedImage OPAL=loadImage("textures/opal.jpg");
|
public static final BufferedImage OPAL=loadImage("textures/opal.jpg");
|
||||||
public static final BufferedImage OPAL2=loadImage("textures/opal2.jpg");
|
public static final BufferedImage OPAL2=loadImage("textures/opal2.jpg");
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ public class IconImages {
|
||||||
public static final ImageIcon DAMAGE=loadIcon("damage.gif");
|
public static final ImageIcon DAMAGE=loadIcon("damage.gif");
|
||||||
public static final ImageIcon COMBAT=loadIcon("combat.gif");
|
public static final ImageIcon COMBAT=loadIcon("combat.gif");
|
||||||
public static final ImageIcon ATTACK=loadIcon("attack.gif");
|
public static final ImageIcon ATTACK=loadIcon("attack.gif");
|
||||||
public static final ImageIcon BLOCK=loadIcon("block.gif");
|
public static final ImageIcon BLOCK=loadIcon("block.gif");
|
||||||
public static final ImageIcon BLOCKED=loadIcon("blocked.gif");
|
public static final ImageIcon BLOCKED=loadIcon("blocked.gif");
|
||||||
public static final ImageIcon MESSAGE=loadIcon("message.png");
|
public static final ImageIcon MESSAGE=loadIcon("message.png");
|
||||||
public static final ImageIcon PROGRESS=loadIcon("progress.png");
|
public static final ImageIcon PROGRESS=loadIcon("progress.png");
|
||||||
|
@ -97,7 +97,7 @@ public class IconImages {
|
||||||
public static final ImageIcon DELAY=loadIcon("delay.png");
|
public static final ImageIcon DELAY=loadIcon("delay.png");
|
||||||
public static final ImageIcon PICTURE=loadIcon("picture.png");
|
public static final ImageIcon PICTURE=loadIcon("picture.png");
|
||||||
public static final ImageIcon AVATAR=loadIcon("avatar.gif");
|
public static final ImageIcon AVATAR=loadIcon("avatar.gif");
|
||||||
|
|
||||||
public static final ImageIcon FLYING=loadIcon("flying.png");
|
public static final ImageIcon FLYING=loadIcon("flying.png");
|
||||||
public static final ImageIcon TRAMPLE=loadIcon("trample.png");
|
public static final ImageIcon TRAMPLE=loadIcon("trample.png");
|
||||||
public static final ImageIcon STRIKE=loadIcon("strike.png");
|
public static final ImageIcon STRIKE=loadIcon("strike.png");
|
||||||
|
@ -110,12 +110,12 @@ public class IconImages {
|
||||||
public static final ImageIcon BLUE=loadSymbolIcon(25, true);
|
public static final ImageIcon BLUE=loadSymbolIcon(25, true);
|
||||||
public static final ImageIcon BLACK=loadSymbolIcon(26, true);
|
public static final ImageIcon BLACK=loadSymbolIcon(26, true);
|
||||||
public static final ImageIcon RED=loadSymbolIcon(27, true);
|
public static final ImageIcon RED=loadSymbolIcon(27, true);
|
||||||
public static final ImageIcon GREEN=loadSymbolIcon(28, true);
|
public static final ImageIcon GREEN=loadSymbolIcon(28, true);
|
||||||
public static final ImageIcon COST_WHITE=loadSymbolIcon(24, false);
|
public static final ImageIcon COST_WHITE=loadSymbolIcon(24, false);
|
||||||
public static final ImageIcon COST_BLUE=loadSymbolIcon(25, false);
|
public static final ImageIcon COST_BLUE=loadSymbolIcon(25, false);
|
||||||
public static final ImageIcon COST_BLACK=loadSymbolIcon(26, false);
|
public static final ImageIcon COST_BLACK=loadSymbolIcon(26, false);
|
||||||
public static final ImageIcon COST_RED=loadSymbolIcon(27, false);
|
public static final ImageIcon COST_RED=loadSymbolIcon(27, false);
|
||||||
public static final ImageIcon COST_GREEN=loadSymbolIcon(28, false);
|
public static final ImageIcon COST_GREEN=loadSymbolIcon(28, false);
|
||||||
public static final ImageIcon COST_WHITE_BLUE=loadSymbolIcon(30, false);
|
public static final ImageIcon COST_WHITE_BLUE=loadSymbolIcon(30, false);
|
||||||
public static final ImageIcon COST_WHITE_BLACK=loadSymbolIcon(31, false);
|
public static final ImageIcon COST_WHITE_BLACK=loadSymbolIcon(31, false);
|
||||||
public static final ImageIcon COST_BLUE_BLACK=loadSymbolIcon(32, false);
|
public static final ImageIcon COST_BLUE_BLACK=loadSymbolIcon(32, false);
|
||||||
|
@ -145,11 +145,11 @@ public class IconImages {
|
||||||
public static final ImageIcon COST_SIXTEEN=loadSymbolIcon(16, false);
|
public static final ImageIcon COST_SIXTEEN=loadSymbolIcon(16, false);
|
||||||
// public static final ImageIcon COST_NINE_OR_MORE=loadIcon("nineplus.gif");
|
// public static final ImageIcon COST_NINE_OR_MORE=loadIcon("nineplus.gif");
|
||||||
public static final ImageIcon COST_X=loadSymbolIcon(21, false);
|
public static final ImageIcon COST_X=loadSymbolIcon(21, false);
|
||||||
|
|
||||||
private static BufferedImage loadImage(final String name) {
|
private static BufferedImage loadImage(final String name) {
|
||||||
return FileIO.toImg(IconImages.class.getResource(name), MISSING2);
|
return FileIO.toImg(IconImages.class.getResource(name), MISSING2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ImageIcon loadIcon(final String name) {
|
private static ImageIcon loadIcon(final String name) {
|
||||||
final BufferedImage image=loadImage("icons/"+name);
|
final BufferedImage image=loadImage("icons/"+name);
|
||||||
return new ImageIcon(image);
|
return new ImageIcon(image);
|
||||||
|
@ -171,7 +171,7 @@ public class IconImages {
|
||||||
return new ImageIcon(magic.GraphicsUtilities.scale(subimage,icoW,icoH));
|
return new ImageIcon(magic.GraphicsUtilities.scale(subimage,icoW,icoH));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ImageIcon loadAnimatedIcon(final String name) {
|
private static ImageIcon loadAnimatedIcon(final String name) {
|
||||||
final byte[] data = new byte[1<<16];
|
final byte[] data = new byte[1<<16];
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
|
|
@ -10,13 +10,13 @@ public class KeywordDefinitions {
|
||||||
private static final KeywordDefinitions INSTANCE=new KeywordDefinitions();
|
private static final KeywordDefinitions INSTANCE=new KeywordDefinitions();
|
||||||
|
|
||||||
private static final String KEYWORDS_FILENAME="keywords.txt";
|
private static final String KEYWORDS_FILENAME="keywords.txt";
|
||||||
|
|
||||||
private final List<KeywordDefinition> keywordDefinitions;
|
private final List<KeywordDefinition> keywordDefinitions;
|
||||||
|
|
||||||
private KeywordDefinitions() {
|
private KeywordDefinitions() {
|
||||||
keywordDefinitions=new ArrayList<KeywordDefinition>();
|
keywordDefinitions=new ArrayList<KeywordDefinition>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadKeywordDefinitions() {
|
public void loadKeywordDefinitions() {
|
||||||
keywordDefinitions.clear();
|
keywordDefinitions.clear();
|
||||||
String content = null;
|
String content = null;
|
||||||
|
@ -44,15 +44,15 @@ public class KeywordDefinitions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<KeywordDefinition> getKeywordDefinitions() {
|
public List<KeywordDefinition> getKeywordDefinitions() {
|
||||||
return keywordDefinitions;
|
return keywordDefinitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static KeywordDefinitions getInstance() {
|
public static KeywordDefinitions getInstance() {
|
||||||
return INSTANCE;
|
return INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class KeywordDefinition {
|
public static class KeywordDefinition {
|
||||||
public String name;
|
public String name;
|
||||||
public String description="";
|
public String description="";
|
||||||
|
|
|
@ -4,16 +4,16 @@ File: OSXAdapter.java
|
||||||
|
|
||||||
Abstract: Hooks existing preferences/about/quit functionality from an
|
Abstract: Hooks existing preferences/about/quit functionality from an
|
||||||
existing Java app into handlers for the Mac OS X application menu.
|
existing Java app into handlers for the Mac OS X application menu.
|
||||||
Uses a Proxy object to dynamically implement the
|
Uses a Proxy object to dynamically implement the
|
||||||
com.apple.eawt.ApplicationListener interface and register it with the
|
com.apple.eawt.ApplicationListener interface and register it with the
|
||||||
com.apple.eawt.Application object. This allows the complete project
|
com.apple.eawt.Application object. This allows the complete project
|
||||||
to be both built and run on any platform without any stubs or
|
to be both built and run on any platform without any stubs or
|
||||||
placeholders. Useful for developers looking to implement Mac OS X
|
placeholders. Useful for developers looking to implement Mac OS X
|
||||||
features while supporting multiple platforms with minimal impact.
|
features while supporting multiple platforms with minimal impact.
|
||||||
|
|
||||||
Version: 2.0
|
Version: 2.0
|
||||||
|
|
||||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by
|
Disclaimer: IMPORTANT: This Apple software is supplied to you by
|
||||||
Apple Inc. ("Apple") in consideration of your agreement to the
|
Apple Inc. ("Apple") in consideration of your agreement to the
|
||||||
following terms, and your use, installation, modification or
|
following terms, and your use, installation, modification or
|
||||||
redistribution of this Apple software constitutes acceptance of these
|
redistribution of this Apple software constitutes acceptance of these
|
||||||
|
@ -27,8 +27,8 @@ license, under Apple's copyrights in this original Apple software (the
|
||||||
Software, with or without modifications, in source and/or binary forms;
|
Software, with or without modifications, in source and/or binary forms;
|
||||||
provided that if you redistribute the Apple Software in its entirety and
|
provided that if you redistribute the Apple Software in its entirety and
|
||||||
without modifications, you must retain this notice and the following
|
without modifications, you must retain this notice and the following
|
||||||
text and disclaimers in all such redistributions of the Apple Software.
|
text and disclaimers in all such redistributions of the Apple Software.
|
||||||
Neither the name, trademarks, service marks or logos of Apple Inc.
|
Neither the name, trademarks, service marks or logos of Apple Inc.
|
||||||
may be used to endorse or promote products derived from the Apple
|
may be used to endorse or promote products derived from the Apple
|
||||||
Software without specific prior written permission from Apple. Except
|
Software without specific prior written permission from Apple. Except
|
||||||
as expressly stated in this notice, no other rights or licenses, express
|
as expressly stated in this notice, no other rights or licenses, express
|
||||||
|
@ -68,7 +68,7 @@ public class OSXAdapter implements InvocationHandler {
|
||||||
protected Object targetObject;
|
protected Object targetObject;
|
||||||
protected Method targetMethod;
|
protected Method targetMethod;
|
||||||
protected String proxySignature;
|
protected String proxySignature;
|
||||||
|
|
||||||
static Object macOSXApplication;
|
static Object macOSXApplication;
|
||||||
|
|
||||||
// Pass this method an Object and Method equipped to perform application shutdown logic
|
// Pass this method an Object and Method equipped to perform application shutdown logic
|
||||||
|
@ -76,7 +76,7 @@ public class OSXAdapter implements InvocationHandler {
|
||||||
public static void setQuitHandler(final Object target, final Method quitHandler) {
|
public static void setQuitHandler(final Object target, final Method quitHandler) {
|
||||||
setHandler(new OSXAdapter("handleQuit", target, quitHandler));
|
setHandler(new OSXAdapter("handleQuit", target, quitHandler));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass this method an Object and Method equipped to display application info
|
// Pass this method an Object and Method equipped to display application info
|
||||||
// They will be called when the About menu item is selected from the application menu
|
// They will be called when the About menu item is selected from the application menu
|
||||||
public static void setAboutHandler(final Object target, final Method aboutHandler) {
|
public static void setAboutHandler(final Object target, final Method aboutHandler) {
|
||||||
|
@ -94,7 +94,7 @@ public class OSXAdapter implements InvocationHandler {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass this method an Object and a Method equipped to display application options
|
// Pass this method an Object and a Method equipped to display application options
|
||||||
// They will be called when the Preferences menu item is selected from the application menu
|
// They will be called when the Preferences menu item is selected from the application menu
|
||||||
public static void setPreferencesHandler(final Object target, final Method prefsHandler) {
|
public static void setPreferencesHandler(final Object target, final Method prefsHandler) {
|
||||||
|
@ -112,9 +112,9 @@ public class OSXAdapter implements InvocationHandler {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass this method an Object and a Method equipped to handle document events from the Finder
|
// Pass this method an Object and a Method equipped to handle document events from the Finder
|
||||||
// Documents are registered with the Finder via the CFBundleDocumentTypes dictionary in the
|
// Documents are registered with the Finder via the CFBundleDocumentTypes dictionary in the
|
||||||
// application bundle's Info.plist
|
// application bundle's Info.plist
|
||||||
public static void setFileHandler(final Object target, final Method fileHandler) {
|
public static void setFileHandler(final Object target, final Method fileHandler) {
|
||||||
setHandler(new OSXAdapter("handleOpenFile", target, fileHandler) {
|
setHandler(new OSXAdapter("handleOpenFile", target, fileHandler) {
|
||||||
|
@ -127,14 +127,14 @@ public class OSXAdapter implements InvocationHandler {
|
||||||
final String filename = (String) getFilenameMethod.invoke(appleEvent, (Object[])null);
|
final String filename = (String) getFilenameMethod.invoke(appleEvent, (Object[])null);
|
||||||
this.targetMethod.invoke(this.targetObject, filename);
|
this.targetMethod.invoke(this.targetObject, filename);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// setHandler creates a Proxy object from the passed OSXAdapter and adds it as an ApplicationListener
|
// setHandler creates a Proxy object from the passed OSXAdapter and adds it as an ApplicationListener
|
||||||
public static void setHandler(final OSXAdapter adapter) {
|
public static void setHandler(final OSXAdapter adapter) {
|
||||||
try {
|
try {
|
||||||
|
@ -162,8 +162,8 @@ public class OSXAdapter implements InvocationHandler {
|
||||||
this.targetObject = target;
|
this.targetObject = target;
|
||||||
this.targetMethod = handler;
|
this.targetMethod = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Override this method to perform any operations on the event
|
// Override this method to perform any operations on the event
|
||||||
// that comes with the various callbacks
|
// that comes with the various callbacks
|
||||||
// See setFileHandler above for an example
|
// See setFileHandler above for an example
|
||||||
public boolean callTarget(final Object appleEvent) throws InvocationTargetException, IllegalAccessException {
|
public boolean callTarget(final Object appleEvent) throws InvocationTargetException, IllegalAccessException {
|
||||||
|
@ -173,7 +173,7 @@ public class OSXAdapter implements InvocationHandler {
|
||||||
}
|
}
|
||||||
return Boolean.valueOf(result.toString()).booleanValue();
|
return Boolean.valueOf(result.toString()).booleanValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
// InvocationHandler implementation
|
// InvocationHandler implementation
|
||||||
// This is the entry point for our proxy object; it is called every time an ApplicationListener method is invoked
|
// This is the entry point for our proxy object; it is called every time an ApplicationListener method is invoked
|
||||||
public Object invoke (final Object proxy, final Method method, final Object[] args) throws Throwable {
|
public Object invoke (final Object proxy, final Method method, final Object[] args) throws Throwable {
|
||||||
|
@ -184,13 +184,13 @@ public class OSXAdapter implements InvocationHandler {
|
||||||
// All of the ApplicationListener methods are void; return null regardless of what happens
|
// All of the ApplicationListener methods are void; return null regardless of what happens
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare the method that was called to the intended method when the OSXAdapter instance was created
|
// Compare the method that was called to the intended method when the OSXAdapter instance was created
|
||||||
// (e.g. handleAbout, handleQuit, handleOpenFile, etc.)
|
// (e.g. handleAbout, handleQuit, handleOpenFile, etc.)
|
||||||
protected boolean isCorrectMethod(final Method method, final Object[] args) {
|
protected boolean isCorrectMethod(final Method method, final Object[] args) {
|
||||||
return (targetMethod != null && proxySignature.equals(method.getName()) && args.length == 1);
|
return (targetMethod != null && proxySignature.equals(method.getName()) && args.length == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// It is important to mark the ApplicationEvent as handled and cancel the default behavior
|
// It is important to mark the ApplicationEvent as handled and cancel the default behavior
|
||||||
// This method checks for a boolean result from the proxy method and sets the event accordingly
|
// This method checks for a boolean result from the proxy method and sets the event accordingly
|
||||||
protected void setApplicationEventHandled(final Object event, final boolean handled) {
|
protected void setApplicationEventHandled(final Object event, final boolean handled) {
|
||||||
|
|
|
@ -20,12 +20,12 @@ public class SoundEffects implements LineListener {
|
||||||
public static final String TURN_SOUND="turn.au";
|
public static final String TURN_SOUND="turn.au";
|
||||||
public static final String RESOLVE_SOUND="resolve.au";
|
public static final String RESOLVE_SOUND="resolve.au";
|
||||||
public static final String COMBAT_SOUND="combat.au";
|
public static final String COMBAT_SOUND="combat.au";
|
||||||
|
|
||||||
private static final File SOUNDS_PATH=new File(MagicMain.getGamePath(),"sounds");
|
private static final File SOUNDS_PATH=new File(MagicMain.getGamePath(),"sounds");
|
||||||
private static final SoundEffects INSTANCE=new SoundEffects();
|
private static final SoundEffects INSTANCE=new SoundEffects();
|
||||||
|
|
||||||
private SoundEffects() {}
|
private SoundEffects() {}
|
||||||
|
|
||||||
public static void playClip(final String name) {
|
public static void playClip(final String name) {
|
||||||
if (GeneralConfig.getInstance().isSound()) {
|
if (GeneralConfig.getInstance().isSound()) {
|
||||||
Clip clip = null;
|
Clip clip = null;
|
||||||
|
@ -60,4 +60,4 @@ public class SoundEffects implements LineListener {
|
||||||
event.getLine().close();
|
event.getLine().close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,9 @@ import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class TextImages {
|
public class TextImages {
|
||||||
|
|
||||||
private static final Map<String,ImageIcon> TEXT_ICONS=new HashMap<String,ImageIcon>();
|
private static final Map<String,ImageIcon> TEXT_ICONS=new HashMap<String,ImageIcon>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
TEXT_ICONS.put("{0}",IconImages.COST_ZERO);
|
TEXT_ICONS.put("{0}",IconImages.COST_ZERO);
|
||||||
TEXT_ICONS.put("{1}",IconImages.COST_ONE);
|
TEXT_ICONS.put("{1}",IconImages.COST_ONE);
|
||||||
|
@ -27,7 +27,7 @@ public class TextImages {
|
||||||
TEXT_ICONS.put("{15}",IconImages.COST_FIFTEEN);
|
TEXT_ICONS.put("{15}",IconImages.COST_FIFTEEN);
|
||||||
TEXT_ICONS.put("{16}",IconImages.COST_SIXTEEN);
|
TEXT_ICONS.put("{16}",IconImages.COST_SIXTEEN);
|
||||||
TEXT_ICONS.put("{X}",IconImages.COST_X);
|
TEXT_ICONS.put("{X}",IconImages.COST_X);
|
||||||
|
|
||||||
TEXT_ICONS.put("{B}",IconImages.COST_BLACK);
|
TEXT_ICONS.put("{B}",IconImages.COST_BLACK);
|
||||||
TEXT_ICONS.put("{U}",IconImages.COST_BLUE);
|
TEXT_ICONS.put("{U}",IconImages.COST_BLUE);
|
||||||
TEXT_ICONS.put("{G}",IconImages.COST_GREEN);
|
TEXT_ICONS.put("{G}",IconImages.COST_GREEN);
|
||||||
|
@ -63,7 +63,7 @@ public class TextImages {
|
||||||
TEXT_ICONS.put("{br}",IconImages.BRIBECOUNTER);
|
TEXT_ICONS.put("{br}",IconImages.BRIBECOUNTER);
|
||||||
TEXT_ICONS.put("{L}",IconImages.LOSE);
|
TEXT_ICONS.put("{L}",IconImages.LOSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ImageIcon getIcon(final String text) {
|
public static ImageIcon getIcon(final String text) {
|
||||||
if (!TEXT_ICONS.containsKey(text)) {
|
if (!TEXT_ICONS.containsKey(text)) {
|
||||||
throw new RuntimeException("No corresponding icon for " + text);
|
throw new RuntimeException("No corresponding icon for " + text);
|
||||||
|
|
|
@ -13,7 +13,7 @@ public class TokenCardDefinitions {
|
||||||
public static Collection<MagicCardDefinition> getAll() {
|
public static Collection<MagicCardDefinition> getAll() {
|
||||||
return tokensMap.values();
|
return tokensMap.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MagicCardDefinition get(final String name) {
|
public static MagicCardDefinition get(final String name) {
|
||||||
if (tokensMap.containsKey(name)) {
|
if (tokensMap.containsKey(name)) {
|
||||||
return tokensMap.get(name);
|
return tokensMap.get(name);
|
||||||
|
@ -21,7 +21,7 @@ public class TokenCardDefinitions {
|
||||||
throw new RuntimeException("token " + name + " not found");
|
throw new RuntimeException("token " + name + " not found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void add(final MagicCardDefinition token) {
|
public static void add(final MagicCardDefinition token) {
|
||||||
tokensMap.put(token.getFullName(), token);
|
tokensMap.put(token.getFullName(), token);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
public class URLUtils {
|
public class URLUtils {
|
||||||
|
|
||||||
public static void openURL(final String url) {
|
public static void openURL(final String url) {
|
||||||
try {
|
try {
|
||||||
Desktop desktop = null;
|
Desktop desktop = null;
|
||||||
|
|
|
@ -11,15 +11,15 @@ import java.io.OutputStream;
|
||||||
import java.net.Proxy;
|
import java.net.Proxy;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
public abstract class WebDownloader {
|
public abstract class WebDownloader {
|
||||||
public abstract void download(final Proxy proxy);
|
public abstract void download(final Proxy proxy);
|
||||||
|
|
||||||
public abstract String getFilename();
|
public abstract String getFilename();
|
||||||
|
|
||||||
public abstract File getFile();
|
public abstract File getFile();
|
||||||
|
|
||||||
public abstract boolean exists();
|
public abstract boolean exists();
|
||||||
|
|
||||||
public static void downloadToFile(final Proxy proxy, final URL url, final File file) {
|
public static void downloadToFile(final Proxy proxy, final URL url, final File file) {
|
||||||
OutputStream outputStream = null;
|
OutputStream outputStream = null;
|
||||||
InputStream inputStream = null;
|
InputStream inputStream = null;
|
||||||
|
@ -47,17 +47,17 @@ public abstract class WebDownloader {
|
||||||
magic.data.FileIO.close(outputStream);
|
magic.data.FileIO.close(outputStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getHTML(final Proxy proxy, final URL url) {
|
public static String getHTML(final Proxy proxy, final URL url) {
|
||||||
InputStream inputStream = null;
|
InputStream inputStream = null;
|
||||||
BufferedReader dataStream = null;
|
BufferedReader dataStream = null;
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
String line;
|
String line;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
inputStream = url.openConnection(proxy).getInputStream();
|
inputStream = url.openConnection(proxy).getInputStream();
|
||||||
dataStream = new BufferedReader(new InputStreamReader(inputStream));
|
dataStream = new BufferedReader(new InputStreamReader(inputStream));
|
||||||
|
|
||||||
while( (line = dataStream.readLine()) != null) {
|
while( (line = dataStream.readLine()) != null) {
|
||||||
sb.append(line);
|
sb.append(line);
|
||||||
sb.append("\n");
|
sb.append("\n");
|
||||||
|
@ -70,7 +70,7 @@ public abstract class WebDownloader {
|
||||||
magic.data.FileIO.close(inputStream);
|
magic.data.FileIO.close(inputStream);
|
||||||
magic.data.FileIO.close(dataStream);
|
magic.data.FileIO.close(dataStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,23 +14,23 @@ import java.util.Random;
|
||||||
public class Ability_Mono_DeckGenerator extends DefaultDeckGenerator {
|
public class Ability_Mono_DeckGenerator extends DefaultDeckGenerator {
|
||||||
|
|
||||||
private static final int MIN_NUM_CARDS_WITH_SUBTYPE = 30;
|
private static final int MIN_NUM_CARDS_WITH_SUBTYPE = 30;
|
||||||
|
|
||||||
private static final Random randGen = new Random();
|
private static final Random randGen = new Random();
|
||||||
// all possible tribes - calculated once
|
// all possible tribes - calculated once
|
||||||
private static final ArrayList<MagicAbility> possibleAbilities = new ArrayList<MagicAbility>();
|
private static final ArrayList<MagicAbility> possibleAbilities = new ArrayList<MagicAbility>();
|
||||||
private static final ArrayList<ArrayList<String>> possibleColors = new ArrayList<ArrayList<String>>();
|
private static final ArrayList<ArrayList<String>> possibleColors = new ArrayList<ArrayList<String>>();
|
||||||
|
|
||||||
// random tribe from all possible for each instance
|
// random tribe from all possible for each instance
|
||||||
private final MagicAbility ability;
|
private final MagicAbility ability;
|
||||||
private final String colorText;
|
private final String colorText;
|
||||||
|
|
||||||
public Ability_Mono_DeckGenerator() {
|
public Ability_Mono_DeckGenerator() {
|
||||||
super(null);
|
super(null);
|
||||||
|
|
||||||
if(!hasChoice()) {
|
if(!hasChoice()) {
|
||||||
getPossibleTribes();
|
getPossibleTribes();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(hasChoice()) {
|
if(hasChoice()) {
|
||||||
final int i = randGen.nextInt(possibleAbilities.size());
|
final int i = randGen.nextInt(possibleAbilities.size());
|
||||||
ability = possibleAbilities.get(i);
|
ability = possibleAbilities.get(i);
|
||||||
|
@ -39,14 +39,14 @@ public class Ability_Mono_DeckGenerator extends DefaultDeckGenerator {
|
||||||
ability = null;
|
ability = null;
|
||||||
colorText = "";
|
colorText = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
|
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasChoice() {
|
private boolean hasChoice() {
|
||||||
return possibleAbilities.size() > 0 && possibleColors.size() == possibleAbilities.size();
|
return possibleAbilities.size() > 0 && possibleColors.size() == possibleAbilities.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getPossibleTribes() {
|
private void getPossibleTribes() {
|
||||||
for(final MagicAbility ab : MagicAbility.CORE) {
|
for(final MagicAbility ab : MagicAbility.CORE) {
|
||||||
final HashMap<MagicColor, Integer> countColors = new HashMap<MagicColor, Integer>();
|
final HashMap<MagicColor, Integer> countColors = new HashMap<MagicColor, Integer>();
|
||||||
|
@ -55,7 +55,7 @@ public class Ability_Mono_DeckGenerator extends DefaultDeckGenerator {
|
||||||
countColors.put(MagicColor.Green, 0);
|
countColors.put(MagicColor.Green, 0);
|
||||||
countColors.put(MagicColor.Red, 0);
|
countColors.put(MagicColor.Red, 0);
|
||||||
countColors.put(MagicColor.Blue, 0);
|
countColors.put(MagicColor.Blue, 0);
|
||||||
|
|
||||||
// count colors
|
// count colors
|
||||||
for(final MagicCardDefinition card : CardDefinitions.getCards()) {
|
for(final MagicCardDefinition card : CardDefinitions.getCards()) {
|
||||||
if (card.hasAbility(ab)) {
|
if (card.hasAbility(ab)) {
|
||||||
|
@ -67,37 +67,37 @@ public class Ability_Mono_DeckGenerator extends DefaultDeckGenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final ArrayList<String> choiceColors = getPossibleColors(countColors);
|
final ArrayList<String> choiceColors = getPossibleColors(countColors);
|
||||||
|
|
||||||
if(choiceColors.size() > 0) {
|
if(choiceColors.size() > 0) {
|
||||||
possibleAbilities.add(ab);
|
possibleAbilities.add(ab);
|
||||||
possibleColors.add(choiceColors);
|
possibleColors.add(choiceColors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArrayList<String> getPossibleColors(final HashMap<MagicColor, Integer> countColors) {
|
private ArrayList<String> getPossibleColors(final HashMap<MagicColor, Integer> countColors) {
|
||||||
// monocolor
|
// monocolor
|
||||||
final ArrayList<String> a = new ArrayList<String>();
|
final ArrayList<String> a = new ArrayList<String>();
|
||||||
|
|
||||||
for(final MagicColor c : countColors.keySet()) {
|
for(final MagicColor c : countColors.keySet()) {
|
||||||
if(countColors.get(c).intValue() > MIN_NUM_CARDS_WITH_SUBTYPE) {
|
if(countColors.get(c).intValue() > MIN_NUM_CARDS_WITH_SUBTYPE) {
|
||||||
a.add("" + c.getSymbol());
|
a.add("" + c.getSymbol());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getColorText() {
|
public String getColorText() {
|
||||||
return colorText;
|
return colorText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMinRarity() {
|
public int getMinRarity() {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
|
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
|
||||||
if(hasChoice()) {
|
if(hasChoice()) {
|
||||||
return !card.isCreature() || card.hasAbility(ability);
|
return !card.isCreature() || card.hasAbility(ability);
|
||||||
|
@ -105,11 +105,11 @@ public class Ability_Mono_DeckGenerator extends DefaultDeckGenerator {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setColors(final MagicPlayerProfile profile) {
|
public void setColors(final MagicPlayerProfile profile) {
|
||||||
profile.setColors(getColorText());
|
profile.setColors(getColorText());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean ignoreMaxCost() {
|
public boolean ignoreMaxCost() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,16 +12,16 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class DefaultDeckGenerator {
|
public class DefaultDeckGenerator {
|
||||||
|
|
||||||
private final List<MagicCardDefinition> spellCards = new ArrayList<MagicCardDefinition>();
|
private final List<MagicCardDefinition> spellCards = new ArrayList<MagicCardDefinition>();
|
||||||
private final List<MagicCardDefinition> landCards = new ArrayList<MagicCardDefinition>();
|
private final List<MagicCardDefinition> landCards = new ArrayList<MagicCardDefinition>();
|
||||||
|
|
||||||
private MagicCubeDefinition cubeDefinition;
|
private MagicCubeDefinition cubeDefinition;
|
||||||
|
|
||||||
public DefaultDeckGenerator(final MagicCubeDefinition cubeDefinition) {
|
public DefaultDeckGenerator(final MagicCubeDefinition cubeDefinition) {
|
||||||
this.cubeDefinition = cubeDefinition;
|
this.cubeDefinition = cubeDefinition;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCubeDefinition(final MagicCubeDefinition cube) {
|
public void setCubeDefinition(final MagicCubeDefinition cube) {
|
||||||
cubeDefinition = cube;
|
cubeDefinition = cube;
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ public class DefaultDeckGenerator {
|
||||||
if(cubeDefinition == null) {
|
if(cubeDefinition == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spellCards.clear();
|
spellCards.clear();
|
||||||
for (int rarity = getMinRarity(); rarity <= getMaxRarity(); rarity++) {
|
for (int rarity = getMinRarity(); rarity <= getMaxRarity(); rarity++) {
|
||||||
for (final MagicCardDefinition card : CardDefinitions.getSpellCards()) {
|
for (final MagicCardDefinition card : CardDefinitions.getSpellCards()) {
|
||||||
|
@ -42,15 +42,15 @@ public class DefaultDeckGenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMinRarity() {
|
public int getMinRarity() {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMaxRarity() {
|
public int getMaxRarity() {
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
|
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ public class DefaultDeckGenerator {
|
||||||
if(cubeDefinition == null) {
|
if(cubeDefinition == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
landCards.clear();
|
landCards.clear();
|
||||||
for (final MagicCardDefinition card : CardDefinitions.getLandCards()) {
|
for (final MagicCardDefinition card : CardDefinitions.getLandCards()) {
|
||||||
if (cubeDefinition.containsCard(card)) {
|
if (cubeDefinition.containsCard(card)) {
|
||||||
|
@ -69,38 +69,38 @@ public class DefaultDeckGenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean acceptPossibleLandCard(final MagicCardDefinition card) {
|
public boolean acceptPossibleLandCard(final MagicCardDefinition card) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateDeck(final int size, final MagicPlayerProfile profile, final MagicDeck deck) {
|
public void generateDeck(final int size, final MagicPlayerProfile profile, final MagicDeck deck) {
|
||||||
setColors(profile);
|
setColors(profile);
|
||||||
|
|
||||||
final MagicCondensedDeck condensedDeck = new MagicCondensedDeck();
|
final MagicCondensedDeck condensedDeck = new MagicCondensedDeck();
|
||||||
|
|
||||||
genSpells();
|
genSpells();
|
||||||
genLands();
|
genLands();
|
||||||
|
|
||||||
final int spells = (size*3)/5;
|
final int spells = (size*3)/5;
|
||||||
final int lands = profile.getNrOfNonBasicLands(size-spells);
|
final int lands = profile.getNrOfNonBasicLands(size-spells);
|
||||||
|
|
||||||
final int maxCreatures = (spells*2)/3;
|
final int maxCreatures = (spells*2)/3;
|
||||||
final int maxNonlandNoncreature = spells - maxCreatures;
|
final int maxNonlandNoncreature = spells - maxCreatures;
|
||||||
final int maxColorless = spells/6;
|
final int maxColorless = spells/6;
|
||||||
final int maxHigh = spells/6;
|
final int maxHigh = spells/6;
|
||||||
final int maxOther = (spells-maxHigh)/2;
|
final int maxOther = (spells-maxHigh)/2;
|
||||||
final int[] maxCost = {maxOther,maxOther+1,maxHigh};
|
final int[] maxCost = {maxOther,maxOther+1,maxHigh};
|
||||||
|
|
||||||
int countCreatures = 0;
|
int countCreatures = 0;
|
||||||
int countColorless = 0;
|
int countColorless = 0;
|
||||||
int countNonlandNoncreature = 0;
|
int countNonlandNoncreature = 0;
|
||||||
final int[] countCost = new int[3];
|
final int[] countCost = new int[3];
|
||||||
|
|
||||||
addRequiredSpells(condensedDeck);
|
addRequiredSpells(condensedDeck);
|
||||||
|
|
||||||
// count required cards added
|
// count required cards added
|
||||||
for(final MagicCardDefinition card : condensedDeck.toMagicDeck()) {
|
for(final MagicCardDefinition card : condensedDeck.toMagicDeck()) {
|
||||||
if(card.isCreature()) {
|
if(card.isCreature()) {
|
||||||
|
@ -108,41 +108,41 @@ public class DefaultDeckGenerator {
|
||||||
} else if(!card.isLand()) {
|
} else if(!card.isLand()) {
|
||||||
countNonlandNoncreature++;
|
countNonlandNoncreature++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(card.isColorless()) {
|
if(card.isColorless()) {
|
||||||
countColorless++;
|
countColorless++;
|
||||||
}
|
}
|
||||||
|
|
||||||
countCost[card.getCostBucket()]++;
|
countCost[card.getCostBucket()]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add spells to deck.
|
// Add spells to deck.
|
||||||
while (condensedDeck.getNumCards() < spells && spellCards.size() > 0) {
|
while (condensedDeck.getNumCards() < spells && spellCards.size() > 0) {
|
||||||
final int index=MagicRandom.nextInt(spellCards.size());
|
final int index=MagicRandom.nextInt(spellCards.size());
|
||||||
final MagicCardDefinition cardDefinition=spellCards.get(index);
|
final MagicCardDefinition cardDefinition=spellCards.get(index);
|
||||||
spellCards.remove(index);
|
spellCards.remove(index);
|
||||||
|
|
||||||
if (cardDefinition.isPlayable(profile)) {
|
if (cardDefinition.isPlayable(profile)) {
|
||||||
final boolean creature = cardDefinition.isCreature();
|
final boolean creature = cardDefinition.isCreature();
|
||||||
|
|
||||||
if(creature && countCreatures >= maxCreatures) {
|
if(creature && countCreatures >= maxCreatures) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!creature && countNonlandNoncreature >= maxNonlandNoncreature) {
|
if (!creature && countNonlandNoncreature >= maxNonlandNoncreature) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean colorless = cardDefinition.isColorless();
|
final boolean colorless = cardDefinition.isColorless();
|
||||||
if (!ignoreMaxColorless() && colorless && countColorless >= maxColorless) {
|
if (!ignoreMaxColorless() && colorless && countColorless >= maxColorless) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int bucket = cardDefinition.getCostBucket();
|
final int bucket = cardDefinition.getCostBucket();
|
||||||
if (!ignoreMaxCost() && countCost[bucket] >= maxCost[bucket]) {
|
if (!ignoreMaxCost() && countCost[bucket] >= maxCost[bucket]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(condensedDeck.addCard(cardDefinition, false)) {
|
if(condensedDeck.addCard(cardDefinition, false)) {
|
||||||
countCost[bucket]++;
|
countCost[bucket]++;
|
||||||
if(creature) {
|
if(creature) {
|
||||||
|
@ -154,29 +154,29 @@ public class DefaultDeckGenerator {
|
||||||
countColorless++;
|
countColorless++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spellCards.size() == 0) {
|
if (spellCards.size() == 0) {
|
||||||
genSpells();
|
genSpells();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add non basic lands to deck.
|
// Add non basic lands to deck.
|
||||||
addRequiredLands(condensedDeck);
|
addRequiredLands(condensedDeck);
|
||||||
|
|
||||||
while (condensedDeck.getNumCards() < spells+lands && landCards.size() > 0) {
|
while (condensedDeck.getNumCards() < spells+lands && landCards.size() > 0) {
|
||||||
final int index=MagicRandom.nextInt(landCards.size());
|
final int index=MagicRandom.nextInt(landCards.size());
|
||||||
final MagicCardDefinition cardDefinition=landCards.get(index);
|
final MagicCardDefinition cardDefinition=landCards.get(index);
|
||||||
landCards.remove(index);
|
landCards.remove(index);
|
||||||
|
|
||||||
if (cardDefinition.isPlayable(profile)) {
|
if (cardDefinition.isPlayable(profile)) {
|
||||||
condensedDeck.addCard(cardDefinition, false);
|
condensedDeck.addCard(cardDefinition, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deck.setContent(condensedDeck.toMagicDeck());
|
deck.setContent(condensedDeck.toMagicDeck());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void addRequiredCards(final MagicCondensedDeck deck, final String[] cards) {
|
protected void addRequiredCards(final MagicCondensedDeck deck, final String[] cards) {
|
||||||
for(final String name : cards) {
|
for(final String name : cards) {
|
||||||
final MagicCardDefinition cardDef = CardDefinitions.getCard(name);
|
final MagicCardDefinition cardDef = CardDefinitions.getCard(name);
|
||||||
|
@ -187,17 +187,17 @@ public class DefaultDeckGenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRequiredSpells(final MagicCondensedDeck deck) { }
|
public void addRequiredSpells(final MagicCondensedDeck deck) { }
|
||||||
|
|
||||||
public void addRequiredLands(final MagicCondensedDeck deck) { }
|
public void addRequiredLands(final MagicCondensedDeck deck) { }
|
||||||
|
|
||||||
public void setColors(final MagicPlayerProfile profile) { }
|
public void setColors(final MagicPlayerProfile profile) { }
|
||||||
|
|
||||||
public boolean ignoreMaxColorless() {
|
public boolean ignoreMaxColorless() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean ignoreMaxCost() {
|
public boolean ignoreMaxCost() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,45 +10,45 @@ public class Elf_Horde_DeckGenerator extends DefaultDeckGenerator {
|
||||||
|
|
||||||
private static final String colorText = "g";
|
private static final String colorText = "g";
|
||||||
private static final String[] cards = {
|
private static final String[] cards = {
|
||||||
"Joraga Warcaller",
|
"Joraga Warcaller",
|
||||||
"Joraga Warcaller",
|
"Joraga Warcaller",
|
||||||
"Elvish Champion",
|
"Elvish Champion",
|
||||||
"Elvish Champion",
|
"Elvish Champion",
|
||||||
"Imperious Perfect",
|
"Imperious Perfect",
|
||||||
"Imperious Perfect",
|
"Imperious Perfect",
|
||||||
"Imperious Perfect",
|
"Imperious Perfect",
|
||||||
"Imperious Perfect",
|
"Imperious Perfect",
|
||||||
"Ezuri, Renegade Leader",
|
"Ezuri, Renegade Leader",
|
||||||
"Llanowar Elves",
|
"Llanowar Elves",
|
||||||
"Llanowar Elves",
|
"Llanowar Elves",
|
||||||
"Llanowar Elves"
|
"Llanowar Elves"
|
||||||
};
|
};
|
||||||
|
|
||||||
public Elf_Horde_DeckGenerator() {
|
public Elf_Horde_DeckGenerator() {
|
||||||
super(null);
|
super(null);
|
||||||
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
|
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getColorText() {
|
public String getColorText() {
|
||||||
return colorText;
|
return colorText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMinRarity() {
|
public int getMinRarity() {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
|
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
|
||||||
return !card.isCreature() || card.hasSubType(MagicSubType.Elf);
|
return !card.isCreature() || card.hasSubType(MagicSubType.Elf);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRequiredSpells(final MagicCondensedDeck deck) {
|
public void addRequiredSpells(final MagicCondensedDeck deck) {
|
||||||
addRequiredCards(deck, cards);
|
addRequiredCards(deck, cards);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setColors(final MagicPlayerProfile profile) {
|
public void setColors(final MagicPlayerProfile profile) {
|
||||||
profile.setColors(getColorText());
|
profile.setColors(getColorText());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean ignoreMaxCost() {
|
public boolean ignoreMaxCost() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ public class Fairy_Horde_DeckGenerator extends DefaultDeckGenerator {
|
||||||
"Mistbind Clique",
|
"Mistbind Clique",
|
||||||
"Mistbind Clique"
|
"Mistbind Clique"
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final String[] lands = {
|
private static final String[] lands = {
|
||||||
"Mutavault",
|
"Mutavault",
|
||||||
"Mutavault",
|
"Mutavault",
|
||||||
|
@ -33,36 +33,36 @@ public class Fairy_Horde_DeckGenerator extends DefaultDeckGenerator {
|
||||||
"Watery Grave",
|
"Watery Grave",
|
||||||
"Watery Grave"
|
"Watery Grave"
|
||||||
};
|
};
|
||||||
|
|
||||||
public Fairy_Horde_DeckGenerator() {
|
public Fairy_Horde_DeckGenerator() {
|
||||||
super(null);
|
super(null);
|
||||||
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
|
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getColorText() {
|
public String getColorText() {
|
||||||
return colorText;
|
return colorText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMinRarity() {
|
public int getMinRarity() {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
|
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
|
||||||
return !card.isCreature() || card.hasSubType(MagicSubType.Faerie);
|
return !card.isCreature() || card.hasSubType(MagicSubType.Faerie);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRequiredSpells(final MagicCondensedDeck deck) {
|
public void addRequiredSpells(final MagicCondensedDeck deck) {
|
||||||
addRequiredCards(deck, spells);
|
addRequiredCards(deck, spells);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRequiredLands(final MagicCondensedDeck deck) {
|
public void addRequiredLands(final MagicCondensedDeck deck) {
|
||||||
addRequiredCards(deck, lands);
|
addRequiredCards(deck, lands);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setColors(final MagicPlayerProfile profile) {
|
public void setColors(final MagicPlayerProfile profile) {
|
||||||
profile.setColors(getColorText());
|
profile.setColors(getColorText());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean ignoreMaxCost() {
|
public boolean ignoreMaxCost() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,44 +10,44 @@ public class Human_Law_DeckGenerator extends DefaultDeckGenerator {
|
||||||
|
|
||||||
private static final String colorText = "w";
|
private static final String colorText = "w";
|
||||||
private static final String[] cards = {
|
private static final String[] cards = {
|
||||||
"Champion of the Parish",
|
"Champion of the Parish",
|
||||||
"Champion of the Parish",
|
"Champion of the Parish",
|
||||||
"Champion of the Parish",
|
"Champion of the Parish",
|
||||||
"Elite Vanguard",
|
"Elite Vanguard",
|
||||||
"Gideon's Lawkeeper",
|
"Gideon's Lawkeeper",
|
||||||
"Hero of Bladehold",
|
"Hero of Bladehold",
|
||||||
"Hero of Bladehold",
|
"Hero of Bladehold",
|
||||||
"Hero of Bladehold",
|
"Hero of Bladehold",
|
||||||
"Mirran Crusader",
|
"Mirran Crusader",
|
||||||
"Mirran Crusader",
|
"Mirran Crusader",
|
||||||
"Angelic Destiny",
|
"Angelic Destiny",
|
||||||
"Angelic Destiny",
|
"Angelic Destiny",
|
||||||
"Honor of the Pure",
|
"Honor of the Pure",
|
||||||
"Honor of the Pure",
|
"Honor of the Pure",
|
||||||
"Day of Judgment"
|
"Day of Judgment"
|
||||||
};
|
};
|
||||||
|
|
||||||
public Human_Law_DeckGenerator() {
|
public Human_Law_DeckGenerator() {
|
||||||
super(null);
|
super(null);
|
||||||
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
|
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getColorText() {
|
public String getColorText() {
|
||||||
return colorText;
|
return colorText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMinRarity() {
|
public int getMinRarity() {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
|
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
|
||||||
return !card.isCreature() || card.hasSubType(MagicSubType.Human);
|
return !card.isCreature() || card.hasSubType(MagicSubType.Human);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRequiredSpells(final MagicCondensedDeck deck) {
|
public void addRequiredSpells(final MagicCondensedDeck deck) {
|
||||||
addRequiredCards(deck, cards);
|
addRequiredCards(deck, cards);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setColors(final MagicPlayerProfile profile) {
|
public void setColors(final MagicPlayerProfile profile) {
|
||||||
profile.setColors(getColorText());
|
profile.setColors(getColorText());
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ public class Saint___Hero_DeckGenerator extends DefaultDeckGenerator {
|
||||||
"Oblivion Ring",
|
"Oblivion Ring",
|
||||||
"Sword of Feast and Famine"
|
"Sword of Feast and Famine"
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final String[] lands = {
|
private static final String[] lands = {
|
||||||
"Glacial Fortress",
|
"Glacial Fortress",
|
||||||
"Glacial Fortress",
|
"Glacial Fortress",
|
||||||
|
@ -34,28 +34,28 @@ public class Saint___Hero_DeckGenerator extends DefaultDeckGenerator {
|
||||||
"Seachrome Coast",
|
"Seachrome Coast",
|
||||||
"Seachrome Coast"
|
"Seachrome Coast"
|
||||||
};
|
};
|
||||||
|
|
||||||
public Saint___Hero_DeckGenerator() {
|
public Saint___Hero_DeckGenerator() {
|
||||||
super(null);
|
super(null);
|
||||||
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
|
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getColorText() {
|
public String getColorText() {
|
||||||
return colorText;
|
return colorText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMinRarity() {
|
public int getMinRarity() {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRequiredSpells(final MagicCondensedDeck deck) {
|
public void addRequiredSpells(final MagicCondensedDeck deck) {
|
||||||
addRequiredCards(deck, spells);
|
addRequiredCards(deck, spells);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRequiredLands(final MagicCondensedDeck deck) {
|
public void addRequiredLands(final MagicCondensedDeck deck) {
|
||||||
addRequiredCards(deck, lands);
|
addRequiredCards(deck, lands);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setColors(final MagicPlayerProfile profile) {
|
public void setColors(final MagicPlayerProfile profile) {
|
||||||
profile.setColors(getColorText());
|
profile.setColors(getColorText());
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,32 +40,32 @@ public class Token_Madness_DeckGenerator extends DefaultDeckGenerator {
|
||||||
"Sunpetal Grove",
|
"Sunpetal Grove",
|
||||||
"Sunpetal Grove"
|
"Sunpetal Grove"
|
||||||
};
|
};
|
||||||
|
|
||||||
public Token_Madness_DeckGenerator() {
|
public Token_Madness_DeckGenerator() {
|
||||||
super(null);
|
super(null);
|
||||||
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
|
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getColorText() {
|
public String getColorText() {
|
||||||
return colorText;
|
return colorText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMinRarity() {
|
public int getMinRarity() {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
|
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
|
||||||
return !card.isCreature() || card.hasText("token");
|
return !card.isCreature() || card.hasText("token");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRequiredSpells(final MagicCondensedDeck deck) {
|
public void addRequiredSpells(final MagicCondensedDeck deck) {
|
||||||
addRequiredCards(deck, spells);
|
addRequiredCards(deck, spells);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRequiredLands(final MagicCondensedDeck deck) {
|
public void addRequiredLands(final MagicCondensedDeck deck) {
|
||||||
addRequiredCards(deck, lands);
|
addRequiredCards(deck, lands);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setColors(final MagicPlayerProfile profile) {
|
public void setColors(final MagicPlayerProfile profile) {
|
||||||
profile.setColors(getColorText());
|
profile.setColors(getColorText());
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,23 +14,23 @@ import java.util.Random;
|
||||||
public class Tribal_Mono_DeckGenerator extends DefaultDeckGenerator {
|
public class Tribal_Mono_DeckGenerator extends DefaultDeckGenerator {
|
||||||
|
|
||||||
private static final int MIN_NUM_CARDS_WITH_SUBTYPE = 30;
|
private static final int MIN_NUM_CARDS_WITH_SUBTYPE = 30;
|
||||||
|
|
||||||
private static final Random randGen = new Random();
|
private static final Random randGen = new Random();
|
||||||
// all possible tribes - calculated once
|
// all possible tribes - calculated once
|
||||||
private static final ArrayList<MagicSubType> possibleTribes = new ArrayList<MagicSubType>();
|
private static final ArrayList<MagicSubType> possibleTribes = new ArrayList<MagicSubType>();
|
||||||
private static final ArrayList<ArrayList<String>> possibleColors = new ArrayList<ArrayList<String>>();
|
private static final ArrayList<ArrayList<String>> possibleColors = new ArrayList<ArrayList<String>>();
|
||||||
|
|
||||||
// random tribe from all possible for each instance
|
// random tribe from all possible for each instance
|
||||||
private final MagicSubType tribe;
|
private final MagicSubType tribe;
|
||||||
private final String colorText;
|
private final String colorText;
|
||||||
|
|
||||||
public Tribal_Mono_DeckGenerator() {
|
public Tribal_Mono_DeckGenerator() {
|
||||||
super(null);
|
super(null);
|
||||||
|
|
||||||
if(!hasChoice()) {
|
if(!hasChoice()) {
|
||||||
getPossibleTribes();
|
getPossibleTribes();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(hasChoice()) {
|
if(hasChoice()) {
|
||||||
final int i = randGen.nextInt(possibleTribes.size());
|
final int i = randGen.nextInt(possibleTribes.size());
|
||||||
tribe = possibleTribes.get(i);
|
tribe = possibleTribes.get(i);
|
||||||
|
@ -39,14 +39,14 @@ public class Tribal_Mono_DeckGenerator extends DefaultDeckGenerator {
|
||||||
tribe = null;
|
tribe = null;
|
||||||
colorText = "";
|
colorText = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
|
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasChoice() {
|
private boolean hasChoice() {
|
||||||
return possibleTribes.size() > 0 && possibleColors.size() == possibleTribes.size();
|
return possibleTribes.size() > 0 && possibleColors.size() == possibleTribes.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getPossibleTribes() {
|
private void getPossibleTribes() {
|
||||||
for(final MagicSubType s : MagicSubType.ALL_CREATURES) {
|
for(final MagicSubType s : MagicSubType.ALL_CREATURES) {
|
||||||
final HashMap<MagicColor, Integer> countColors = new HashMap<MagicColor, Integer>();
|
final HashMap<MagicColor, Integer> countColors = new HashMap<MagicColor, Integer>();
|
||||||
|
@ -55,12 +55,12 @@ public class Tribal_Mono_DeckGenerator extends DefaultDeckGenerator {
|
||||||
countColors.put(MagicColor.Green, new Integer(0));
|
countColors.put(MagicColor.Green, new Integer(0));
|
||||||
countColors.put(MagicColor.Red, new Integer(0));
|
countColors.put(MagicColor.Red, new Integer(0));
|
||||||
countColors.put(MagicColor.Blue, new Integer(0));
|
countColors.put(MagicColor.Blue, new Integer(0));
|
||||||
|
|
||||||
// count colors
|
// count colors
|
||||||
for(final MagicCardDefinition card : CardDefinitions.getCards()) {
|
for(final MagicCardDefinition card : CardDefinitions.getCards()) {
|
||||||
if(card.hasSubType(s)) {
|
if(card.hasSubType(s)) {
|
||||||
final int colorFlags = card.getColorFlags();
|
final int colorFlags = card.getColorFlags();
|
||||||
|
|
||||||
for(final MagicColor c : countColors.keySet()) {
|
for(final MagicColor c : countColors.keySet()) {
|
||||||
if (c.hasColor(colorFlags)) {
|
if (c.hasColor(colorFlags)) {
|
||||||
countColors.put(c, new Integer(countColors.get(c).intValue() + 1));
|
countColors.put(c, new Integer(countColors.get(c).intValue() + 1));
|
||||||
|
@ -68,37 +68,37 @@ public class Tribal_Mono_DeckGenerator extends DefaultDeckGenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final ArrayList<String> choiceColors = getPossibleColors(countColors);
|
final ArrayList<String> choiceColors = getPossibleColors(countColors);
|
||||||
|
|
||||||
if(choiceColors.size() > 0) {
|
if(choiceColors.size() > 0) {
|
||||||
possibleTribes.add(s);
|
possibleTribes.add(s);
|
||||||
possibleColors.add(choiceColors);
|
possibleColors.add(choiceColors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArrayList<String> getPossibleColors(final HashMap<MagicColor, Integer> countColors) {
|
private ArrayList<String> getPossibleColors(final HashMap<MagicColor, Integer> countColors) {
|
||||||
// monocolor
|
// monocolor
|
||||||
final ArrayList<String> a = new ArrayList<String>();
|
final ArrayList<String> a = new ArrayList<String>();
|
||||||
|
|
||||||
for(final MagicColor c : countColors.keySet()) {
|
for(final MagicColor c : countColors.keySet()) {
|
||||||
if(countColors.get(c).intValue() > MIN_NUM_CARDS_WITH_SUBTYPE) {
|
if(countColors.get(c).intValue() > MIN_NUM_CARDS_WITH_SUBTYPE) {
|
||||||
a.add("" + c.getSymbol());
|
a.add("" + c.getSymbol());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getColorText() {
|
public String getColorText() {
|
||||||
return colorText;
|
return colorText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMinRarity() {
|
public int getMinRarity() {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
|
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
|
||||||
if(hasChoice()) {
|
if(hasChoice()) {
|
||||||
return !card.isCreature() || card.hasSubType(tribe);
|
return !card.isCreature() || card.hasSubType(tribe);
|
||||||
|
@ -106,11 +106,11 @@ public class Tribal_Mono_DeckGenerator extends DefaultDeckGenerator {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setColors(final MagicPlayerProfile profile) {
|
public void setColors(final MagicPlayerProfile profile) {
|
||||||
profile.setColors(getColorText());
|
profile.setColors(getColorText());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean ignoreMaxCost() {
|
public boolean ignoreMaxCost() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,61 +10,61 @@ public class Vampire_Rage_DeckGenerator extends DefaultDeckGenerator {
|
||||||
|
|
||||||
private static final String colorText = "br";
|
private static final String colorText = "br";
|
||||||
private static final String[] spells = {
|
private static final String[] spells = {
|
||||||
"Falkenrath Marauders",
|
"Falkenrath Marauders",
|
||||||
"Falkenrath Noble",
|
"Falkenrath Noble",
|
||||||
"Markov Patrician",
|
"Markov Patrician",
|
||||||
"Markov Patrician",
|
"Markov Patrician",
|
||||||
"Rakish Heir",
|
"Rakish Heir",
|
||||||
"Rakish Heir",
|
"Rakish Heir",
|
||||||
"Rakish Heir",
|
"Rakish Heir",
|
||||||
"Stromkirk Noble",
|
"Stromkirk Noble",
|
||||||
"Stromkirk Noble",
|
"Stromkirk Noble",
|
||||||
"Stromkirk Noble",
|
"Stromkirk Noble",
|
||||||
"Doom Blade",
|
"Doom Blade",
|
||||||
"Go for the Throat",
|
"Go for the Throat",
|
||||||
"Go for the Throat",
|
"Go for the Throat",
|
||||||
"Mask of Avacyn"
|
"Mask of Avacyn"
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final String[] lands = {
|
private static final String[] lands = {
|
||||||
"Blackcleave Cliffs",
|
"Blackcleave Cliffs",
|
||||||
"Blackcleave Cliffs",
|
"Blackcleave Cliffs",
|
||||||
"Blackcleave Cliffs",
|
"Blackcleave Cliffs",
|
||||||
"Blackcleave Cliffs",
|
"Blackcleave Cliffs",
|
||||||
"Blood Crypt",
|
"Blood Crypt",
|
||||||
"Blood Crypt",
|
"Blood Crypt",
|
||||||
"Blood Crypt",
|
"Blood Crypt",
|
||||||
"Dragonskull Summit",
|
"Dragonskull Summit",
|
||||||
"Dragonskull Summit",
|
"Dragonskull Summit",
|
||||||
"Dragonskull Summit",
|
"Dragonskull Summit",
|
||||||
"Dragonskull Summit"
|
"Dragonskull Summit"
|
||||||
};
|
};
|
||||||
|
|
||||||
public Vampire_Rage_DeckGenerator() {
|
public Vampire_Rage_DeckGenerator() {
|
||||||
super(null);
|
super(null);
|
||||||
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
|
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getColorText() {
|
public String getColorText() {
|
||||||
return colorText;
|
return colorText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMinRarity() {
|
public int getMinRarity() {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
|
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
|
||||||
return !card.isCreature() || card.hasSubType(MagicSubType.Vampire);
|
return !card.isCreature() || card.hasSubType(MagicSubType.Vampire);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRequiredSpells(final MagicCondensedDeck deck) {
|
public void addRequiredSpells(final MagicCondensedDeck deck) {
|
||||||
addRequiredCards(deck, spells);
|
addRequiredCards(deck, spells);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRequiredLands(final MagicCondensedDeck deck) {
|
public void addRequiredLands(final MagicCondensedDeck deck) {
|
||||||
addRequiredCards(deck, lands);
|
addRequiredCards(deck, lands);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setColors(final MagicPlayerProfile profile) {
|
public void setColors(final MagicPlayerProfile profile) {
|
||||||
profile.setColors(getColorText());
|
profile.setColors(getColorText());
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,47 +10,47 @@ public class White_Knights_DeckGenerator extends DefaultDeckGenerator {
|
||||||
|
|
||||||
private static final String colorText = "w";
|
private static final String colorText = "w";
|
||||||
private static final String[] cards = {
|
private static final String[] cards = {
|
||||||
"Knight Exemplar",
|
"Knight Exemplar",
|
||||||
"Knight Exemplar",
|
"Knight Exemplar",
|
||||||
"Knight Exemplar",
|
"Knight Exemplar",
|
||||||
"Knight Exemplar",
|
"Knight Exemplar",
|
||||||
"Day of Judgment",
|
"Day of Judgment",
|
||||||
"Student of Warfare",
|
"Student of Warfare",
|
||||||
"Student of Warfare",
|
"Student of Warfare",
|
||||||
"Sun Titan",
|
"Sun Titan",
|
||||||
"Kinsbaile Cavalier",
|
"Kinsbaile Cavalier",
|
||||||
"Honor of the Pure",
|
"Honor of the Pure",
|
||||||
"Honor of the Pure",
|
"Honor of the Pure",
|
||||||
"Honor of the Pure",
|
"Honor of the Pure",
|
||||||
"Hero of Bladehold",
|
"Hero of Bladehold",
|
||||||
"Hero of Bladehold"
|
"Hero of Bladehold"
|
||||||
};
|
};
|
||||||
|
|
||||||
public White_Knights_DeckGenerator() {
|
public White_Knights_DeckGenerator() {
|
||||||
super(null);
|
super(null);
|
||||||
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
|
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getColorText() {
|
public String getColorText() {
|
||||||
return colorText;
|
return colorText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMinRarity() {
|
public int getMinRarity() {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
|
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
|
||||||
return !card.isCreature() || card.hasSubType(MagicSubType.Knight);
|
return !card.isCreature() || card.hasSubType(MagicSubType.Knight);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRequiredSpells(final MagicCondensedDeck deck) {
|
public void addRequiredSpells(final MagicCondensedDeck deck) {
|
||||||
addRequiredCards(deck, cards);
|
addRequiredCards(deck, cards);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setColors(final MagicPlayerProfile profile) {
|
public void setColors(final MagicPlayerProfile profile) {
|
||||||
profile.setColors(getColorText());
|
profile.setColors(getColorText());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean ignoreMaxCost() {
|
public boolean ignoreMaxCost() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,11 +29,11 @@ public class White_Metal_DeckGenerator extends DefaultDeckGenerator {
|
||||||
"Mox Opal",
|
"Mox Opal",
|
||||||
"Leonin Relic-Warder"
|
"Leonin Relic-Warder"
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final String[] lands = {
|
private static final String[] lands = {
|
||||||
"Inkmoth Nexus",
|
"Inkmoth Nexus",
|
||||||
"Inkmoth Nexus",
|
"Inkmoth Nexus",
|
||||||
"Inkmoth Nexus",
|
"Inkmoth Nexus",
|
||||||
"Inkmoth Nexus"
|
"Inkmoth Nexus"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -41,31 +41,31 @@ public class White_Metal_DeckGenerator extends DefaultDeckGenerator {
|
||||||
super(null);
|
super(null);
|
||||||
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
|
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getColorText() {
|
public String getColorText() {
|
||||||
return colorText;
|
return colorText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMinRarity() {
|
public int getMinRarity() {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
|
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
|
||||||
return !card.isCreature() || card.isArtifact();
|
return !card.isCreature() || card.isArtifact();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRequiredSpells(final MagicCondensedDeck deck) {
|
public void addRequiredSpells(final MagicCondensedDeck deck) {
|
||||||
addRequiredCards(deck, spells);
|
addRequiredCards(deck, spells);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRequiredLands(final MagicCondensedDeck deck) {
|
public void addRequiredLands(final MagicCondensedDeck deck) {
|
||||||
addRequiredCards(deck, lands);
|
addRequiredCards(deck, lands);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setColors(final MagicPlayerProfile profile) {
|
public void setColors(final MagicPlayerProfile profile) {
|
||||||
profile.setColors(getColorText());
|
profile.setColors(getColorText());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean ignoreMaxColorless() {
|
public boolean ignoreMaxColorless() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,43 +10,43 @@ public class Zombie_Madness_DeckGenerator extends DefaultDeckGenerator {
|
||||||
|
|
||||||
private static final String colorText = "b";
|
private static final String colorText = "b";
|
||||||
private static final String[] cards = {
|
private static final String[] cards = {
|
||||||
"Cemetery Reaper",
|
"Cemetery Reaper",
|
||||||
"Cemetery Reaper",
|
"Cemetery Reaper",
|
||||||
"Cemetery Reaper",
|
"Cemetery Reaper",
|
||||||
"Cemetery Reaper",
|
"Cemetery Reaper",
|
||||||
"Death Baron",
|
"Death Baron",
|
||||||
"Death Baron",
|
"Death Baron",
|
||||||
"Festering Goblin",
|
"Festering Goblin",
|
||||||
"Festering Goblin",
|
"Festering Goblin",
|
||||||
"Lord of the Undead",
|
"Lord of the Undead",
|
||||||
"Lord of the Undead",
|
"Lord of the Undead",
|
||||||
"Lord of the Undead",
|
"Lord of the Undead",
|
||||||
"Call to the Grave",
|
"Call to the Grave",
|
||||||
"Call to the Grave",
|
"Call to the Grave",
|
||||||
"Severed Legion"
|
"Severed Legion"
|
||||||
};
|
};
|
||||||
|
|
||||||
public Zombie_Madness_DeckGenerator() {
|
public Zombie_Madness_DeckGenerator() {
|
||||||
super(null);
|
super(null);
|
||||||
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
|
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getColorText() {
|
public String getColorText() {
|
||||||
return colorText;
|
return colorText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMinRarity() {
|
public int getMinRarity() {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
|
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
|
||||||
return !card.isCreature() || card.hasSubType(MagicSubType.Zombie);
|
return !card.isCreature() || card.hasSubType(MagicSubType.Zombie);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRequiredSpells(final MagicCondensedDeck deck) {
|
public void addRequiredSpells(final MagicCondensedDeck deck) {
|
||||||
addRequiredCards(deck, cards);
|
addRequiredCards(deck, cards);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setColors(final MagicPlayerProfile profile) {
|
public void setColors(final MagicPlayerProfile profile) {
|
||||||
profile.setColors(getColorText());
|
profile.setColors(getColorText());
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -24,10 +24,10 @@ class MagicSyntaxTree extends magic.grammar.SemanticsBase {
|
||||||
|
|
||||||
if (numRule == 0 ||
|
if (numRule == 0 ||
|
||||||
lhs().rule().startsWith("Select") ||
|
lhs().rule().startsWith("Select") ||
|
||||||
lhs().rule().endsWith("Number") ||
|
lhs().rule().endsWith("Number") ||
|
||||||
lhs().rule().endsWith("Count") ||
|
lhs().rule().endsWith("Count") ||
|
||||||
lhs().rule().endsWith("Duration") ||
|
lhs().rule().endsWith("Duration") ||
|
||||||
lhs().rule().endsWith("Keyword") ||
|
lhs().rule().endsWith("Keyword") ||
|
||||||
lhs().rule().equals("ManaCost")) {
|
lhs().rule().equals("ManaCost")) {
|
||||||
node.clear();
|
node.clear();
|
||||||
node.text = lhs().text();
|
node.text = lhs().text();
|
||||||
|
|
|
@ -20,7 +20,7 @@ public class Node {
|
||||||
sb.append(')');
|
sb.append(')');
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void show() {
|
public void show() {
|
||||||
show(0);
|
show(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ public enum MagicAbility {
|
||||||
CannotBeBlockedByFlying("can't be blocked by creatures with flying",20),
|
CannotBeBlockedByFlying("can't be blocked by creatures with flying",20),
|
||||||
CannotBeBlockedExceptWithFlying("can't be blocked except by creatures with flying",30),
|
CannotBeBlockedExceptWithFlying("can't be blocked except by creatures with flying",30),
|
||||||
CannotBeBlockedExceptWithFlyingOrReach("can't be blocked except by creatures with flying or reach",25),
|
CannotBeBlockedExceptWithFlyingOrReach("can't be blocked except by creatures with flying or reach",25),
|
||||||
CannotBeBlockedExceptBySliver("can't be blocked except by Slivers", 90),
|
CannotBeBlockedExceptBySliver("can't be blocked except by Slivers", 90),
|
||||||
CannotBeBlockedByHumans("can't be blocked by humans",10),
|
CannotBeBlockedByHumans("can't be blocked by humans",10),
|
||||||
CannotBeBlockedByBlack("can't be blocked by black creatures",10),
|
CannotBeBlockedByBlack("can't be blocked by black creatures",10),
|
||||||
CannotBeBlockedByBlue("can't be blocked by blue creatures",10),
|
CannotBeBlockedByBlue("can't be blocked by blue creatures",10),
|
||||||
|
@ -142,7 +142,7 @@ public enum MagicAbility {
|
||||||
Infect("infect",35),
|
Infect("infect",35),
|
||||||
Soulbond("soulbond",30),
|
Soulbond("soulbond",30),
|
||||||
CantActivateAbilities("can't activate abilities",-20),
|
CantActivateAbilities("can't activate abilities",-20),
|
||||||
|
|
||||||
Undying("undying",60) {
|
Undying("undying",60) {
|
||||||
public void addAbilityImpl(final MagicCardDefinition card, final String arg) {
|
public void addAbilityImpl(final MagicCardDefinition card, final String arg) {
|
||||||
assert arg.isEmpty() : this + " does not accept arg = " + arg;
|
assert arg.isEmpty() : this + " does not accept arg = " + arg;
|
||||||
|
@ -171,7 +171,7 @@ public enum MagicAbility {
|
||||||
|
|
||||||
// 63 core abilities that are tracked in MagicPermanent's abilityFlags
|
// 63 core abilities that are tracked in MagicPermanent's abilityFlags
|
||||||
// see MagicAbility.CORE
|
// see MagicAbility.CORE
|
||||||
|
|
||||||
Changeling("changeling",10) {
|
Changeling("changeling",10) {
|
||||||
public void addAbilityImpl(final MagicCardDefinition card, final String arg) {
|
public void addAbilityImpl(final MagicCardDefinition card, final String arg) {
|
||||||
assert arg.isEmpty() : this + " does not accept arg = " + arg;
|
assert arg.isEmpty() : this + " does not accept arg = " + arg;
|
||||||
|
@ -759,7 +759,7 @@ public enum MagicAbility {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None("",0);
|
None("",0);
|
||||||
|
|
||||||
public static final Set<MagicAbility> CORE = EnumSet.range(AttacksEachTurnIfAble, Flanking);
|
public static final Set<MagicAbility> CORE = EnumSet.range(AttacksEachTurnIfAble, Flanking);
|
||||||
|
|
||||||
public static final Set<MagicAbility> PROTECTION_FLAGS = EnumSet.of(
|
public static final Set<MagicAbility> PROTECTION_FLAGS = EnumSet.of(
|
||||||
|
@ -777,7 +777,7 @@ public enum MagicAbility {
|
||||||
ProtectionFromWerewolves,
|
ProtectionFromWerewolves,
|
||||||
ProtectionFromZombies
|
ProtectionFromZombies
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final Set<MagicAbility> LANDWALK_FLAGS = EnumSet.of(
|
public static final Set<MagicAbility> LANDWALK_FLAGS = EnumSet.of(
|
||||||
Forestwalk,
|
Forestwalk,
|
||||||
Islandwalk,
|
Islandwalk,
|
||||||
|
@ -785,17 +785,17 @@ public enum MagicAbility {
|
||||||
PlainsWalk,
|
PlainsWalk,
|
||||||
Swampwalk
|
Swampwalk
|
||||||
);
|
);
|
||||||
|
|
||||||
//public static final long EXCLUDE_MASK = Long.MAX_VALUE-Flash.getMask()-CannotBeCountered.getMask()-TotemArmor.getMask();
|
//public static final long EXCLUDE_MASK = Long.MAX_VALUE-Flash.getMask()-CannotBeCountered.getMask()-TotemArmor.getMask();
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final int score;
|
private final int score;
|
||||||
|
|
||||||
private MagicAbility(final String aName,final int aScore) {
|
private MagicAbility(final String aName,final int aScore) {
|
||||||
name = aName;
|
name = aName;
|
||||||
score = aScore;
|
score = aScore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
@ -803,7 +803,7 @@ public enum MagicAbility {
|
||||||
public void addAbilityImpl(final MagicCardDefinition card, final String arg) {
|
public void addAbilityImpl(final MagicCardDefinition card, final String arg) {
|
||||||
assert arg.isEmpty() : this + " does not accept arg = " + arg;
|
assert arg.isEmpty() : this + " does not accept arg = " + arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return name;
|
return name;
|
||||||
|
@ -812,7 +812,7 @@ public enum MagicAbility {
|
||||||
private int getScore() {
|
private int getScore() {
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getScore(final Set<MagicAbility> flags) {
|
public static int getScore(final Set<MagicAbility> flags) {
|
||||||
int score=0;
|
int score=0;
|
||||||
for (final MagicAbility ability : flags) {
|
for (final MagicAbility ability : flags) {
|
||||||
|
@ -820,7 +820,7 @@ public enum MagicAbility {
|
||||||
}
|
}
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MagicAbility getAbility(final String name) {
|
public static MagicAbility getAbility(final String name) {
|
||||||
MagicAbility match = None;
|
MagicAbility match = None;
|
||||||
for (final MagicAbility ability : values()) {
|
for (final MagicAbility ability : values()) {
|
||||||
|
@ -834,7 +834,7 @@ public enum MagicAbility {
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Set<MagicAbility> getAbilities(final String[] names) {
|
public static Set<MagicAbility> getAbilities(final String[] names) {
|
||||||
Set<MagicAbility> flags = EnumSet.noneOf(MagicAbility.class);
|
Set<MagicAbility> flags = EnumSet.noneOf(MagicAbility.class);
|
||||||
for (final String name : names) {
|
for (final String name : names) {
|
||||||
|
@ -846,7 +846,7 @@ public enum MagicAbility {
|
||||||
public static Set<MagicAbility> of(final MagicAbility first, MagicAbility... rest) {
|
public static Set<MagicAbility> of(final MagicAbility first, MagicAbility... rest) {
|
||||||
return EnumSet.of(first, rest);
|
return EnumSet.of(first, rest);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Set<MagicAbility> noneOf() {
|
public static Set<MagicAbility> noneOf() {
|
||||||
return EnumSet.noneOf(MagicAbility.class);
|
return EnumSet.noneOf(MagicAbility.class);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,6 @@ package magic.model;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class MagicBoosterPack extends ArrayList<MagicCardDefinition> {
|
public class MagicBoosterPack extends ArrayList<MagicCardDefinition> {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,14 +23,14 @@ public class MagicCard implements MagicSource,MagicTarget,Comparable<MagicCard>
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final int TOKEN_ID=-1;
|
private static final int TOKEN_ID=-1;
|
||||||
|
|
||||||
private final MagicCardDefinition cardDefinition;
|
private final MagicCardDefinition cardDefinition;
|
||||||
private final MagicPlayer owner;
|
private final MagicPlayer owner;
|
||||||
private final long id;
|
private final long id;
|
||||||
private final int imageIndex;
|
private final int imageIndex;
|
||||||
private boolean token;
|
private boolean token;
|
||||||
private boolean known=true;
|
private boolean known=true;
|
||||||
|
|
||||||
public MagicCard(final MagicCardDefinition aCardDefinition,final MagicPlayer aOwner,final long aId) {
|
public MagicCard(final MagicCardDefinition aCardDefinition,final MagicPlayer aOwner,final long aId) {
|
||||||
aCardDefinition.loadScript();
|
aCardDefinition.loadScript();
|
||||||
cardDefinition = aCardDefinition;
|
cardDefinition = aCardDefinition;
|
||||||
|
@ -41,7 +41,7 @@ public class MagicCard implements MagicSource,MagicTarget,Comparable<MagicCard>
|
||||||
|
|
||||||
private MagicCard(final MagicCopyMap copyMap, final MagicCard sourceCard) {
|
private MagicCard(final MagicCopyMap copyMap, final MagicCard sourceCard) {
|
||||||
copyMap.put(sourceCard, this);
|
copyMap.put(sourceCard, this);
|
||||||
|
|
||||||
cardDefinition = sourceCard.cardDefinition;
|
cardDefinition = sourceCard.cardDefinition;
|
||||||
owner = copyMap.copy(sourceCard.owner);
|
owner = copyMap.copy(sourceCard.owner);
|
||||||
id = sourceCard.id;
|
id = sourceCard.id;
|
||||||
|
@ -49,12 +49,12 @@ public class MagicCard implements MagicSource,MagicTarget,Comparable<MagicCard>
|
||||||
token = sourceCard.token;
|
token = sourceCard.token;
|
||||||
known = sourceCard.known;
|
known = sourceCard.known;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MagicCard copy(final MagicCopyMap copyMap) {
|
public MagicCard copy(final MagicCopyMap copyMap) {
|
||||||
return new MagicCard(copyMap, this);
|
return new MagicCard(copyMap, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MagicCard map(final MagicGame game) {
|
public MagicCard map(final MagicGame game) {
|
||||||
final MagicPlayer mappedOwner=owner.map(game);
|
final MagicPlayer mappedOwner=owner.map(game);
|
||||||
|
@ -76,15 +76,15 @@ public class MagicCard implements MagicSource,MagicTarget,Comparable<MagicCard>
|
||||||
}
|
}
|
||||||
return card;
|
return card;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getId() {
|
public long getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getStateId() {
|
public long getStateId() {
|
||||||
return getCardDefinition().getIndex();
|
return getCardDefinition().getIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getImageIndex() {
|
public int getImageIndex() {
|
||||||
return imageIndex;
|
return imageIndex;
|
||||||
}
|
}
|
||||||
|
@ -92,27 +92,27 @@ public class MagicCard implements MagicSource,MagicTarget,Comparable<MagicCard>
|
||||||
public MagicCardDefinition getCardDefinition() {
|
public MagicCardDefinition getCardDefinition() {
|
||||||
return known ? cardDefinition : MagicCardDefinition.UNKNOWN;
|
return known ? cardDefinition : MagicCardDefinition.UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicPlayer getOwner() {
|
public MagicPlayer getOwner() {
|
||||||
return owner;
|
return owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setToken() {
|
private void setToken() {
|
||||||
token = true;
|
token = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isToken() {
|
public boolean isToken() {
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getPower() {
|
public int getPower() {
|
||||||
return genPowerToughness().power();
|
return genPowerToughness().power();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getToughness() {
|
public int getToughness() {
|
||||||
return genPowerToughness().toughness();
|
return genPowerToughness().toughness();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicPowerToughness genPowerToughness() {
|
public MagicPowerToughness genPowerToughness() {
|
||||||
return genPowerToughness(MagicPermanent.NONE);
|
return genPowerToughness(MagicPermanent.NONE);
|
||||||
}
|
}
|
||||||
|
@ -120,24 +120,24 @@ public class MagicCard implements MagicSource,MagicTarget,Comparable<MagicCard>
|
||||||
public MagicPowerToughness genPowerToughness(final MagicPermanent perm) {
|
public MagicPowerToughness genPowerToughness(final MagicPermanent perm) {
|
||||||
final MagicPowerToughness pt = getCardDefinition().genPowerToughness();
|
final MagicPowerToughness pt = getCardDefinition().genPowerToughness();
|
||||||
getCardDefinition().applyCDAPowerToughness(
|
getCardDefinition().applyCDAPowerToughness(
|
||||||
getGame(),
|
getGame(),
|
||||||
perm.isValid() ? perm.getController() : getOwner(),
|
perm.isValid() ? perm.getController() : getOwner(),
|
||||||
perm,
|
perm,
|
||||||
pt
|
pt
|
||||||
);
|
);
|
||||||
return pt;
|
return pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicManaCost getCost() {
|
public MagicManaCost getCost() {
|
||||||
return getCardDefinition().getCost();
|
return getCardDefinition().getCost();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicEvent[] getCostEvent() {
|
public MagicEvent[] getCostEvent() {
|
||||||
return getCardDefinition().getCostEvent(this);
|
return getCardDefinition().getCostEvent(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MagicCard createTokenCard(final MagicCardDefinition cardDefinition,final MagicPlayer owner) {
|
public static MagicCard createTokenCard(final MagicCardDefinition cardDefinition,final MagicPlayer owner) {
|
||||||
final MagicCard card=new MagicCard(cardDefinition,owner,MagicCard.TOKEN_ID);
|
final MagicCard card=new MagicCard(cardDefinition,owner,MagicCard.TOKEN_ID);
|
||||||
card.setToken();
|
card.setToken();
|
||||||
return card;
|
return card;
|
||||||
}
|
}
|
||||||
|
@ -149,16 +149,16 @@ public class MagicCard implements MagicSource,MagicTarget,Comparable<MagicCard>
|
||||||
void setKnown(final boolean known) {
|
void setKnown(final boolean known) {
|
||||||
this.known=known;
|
this.known=known;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isKnown() {
|
public boolean isKnown() {
|
||||||
return known;
|
return known;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return getCardDefinition().getName();
|
return getCardDefinition().getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getName();
|
return getName();
|
||||||
|
@ -176,9 +176,9 @@ public class MagicCard implements MagicSource,MagicTarget,Comparable<MagicCard>
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setPreventDamage(final int amount) {
|
public void setPreventDamage(final int amount) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValidTarget(final MagicSource source) {
|
public boolean isValidTarget(final MagicSource source) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -188,12 +188,12 @@ public class MagicCard implements MagicSource,MagicTarget,Comparable<MagicCard>
|
||||||
public boolean isPermanent() {
|
public boolean isPermanent() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCreature() {
|
public boolean isCreature() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPlaneswalker() {
|
public boolean isPlaneswalker() {
|
||||||
return false;
|
return false;
|
||||||
|
@ -203,36 +203,36 @@ public class MagicCard implements MagicSource,MagicTarget,Comparable<MagicCard>
|
||||||
public boolean isPlayer() {
|
public boolean isPlayer() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSpell() {
|
public boolean isSpell() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getColorFlags() {
|
private int getColorFlags() {
|
||||||
return getCardDefinition().getColorFlags();
|
return getCardDefinition().getColorFlags();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasColor(final MagicColor color) {
|
public boolean hasColor(final MagicColor color) {
|
||||||
return color.hasColor(getColorFlags());
|
return color.hasColor(getColorFlags());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasAbility(final MagicAbility ability) {
|
public boolean hasAbility(final MagicAbility ability) {
|
||||||
return getCardDefinition().hasAbility(ability);
|
return getCardDefinition().hasAbility(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasType(final MagicType type) {
|
public boolean hasType(final MagicType type) {
|
||||||
return getCardDefinition().hasType(type);
|
return getCardDefinition().hasType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasSubType(final MagicSubType subType) {
|
public boolean hasSubType(final MagicSubType subType) {
|
||||||
return getCardDefinition().hasSubType(subType);
|
return getCardDefinition().hasSubType(subType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<MagicActivation> getActivations() {
|
public Collection<MagicActivation> getActivations() {
|
||||||
return getCardDefinition().getCardActivations();
|
return getCardDefinition().getCardActivations();
|
||||||
|
@ -247,32 +247,32 @@ public class MagicCard implements MagicSource,MagicTarget,Comparable<MagicCard>
|
||||||
return Long.signum(id - card.id);
|
return Long.signum(id - card.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MagicGame getGame() {
|
public MagicGame getGame() {
|
||||||
return owner.getGame();
|
return owner.getGame();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLegalTarget(final MagicPlayer player, final MagicTargetFilter<? extends MagicTarget> targetFilter) {
|
public boolean isLegalTarget(final MagicPlayer player, final MagicTargetFilter<? extends MagicTarget> targetFilter) {
|
||||||
// Card in graveyard
|
// Card in graveyard
|
||||||
if (targetFilter.acceptType(MagicTargetType.Graveyard) &&
|
if (targetFilter.acceptType(MagicTargetType.Graveyard) &&
|
||||||
player.getGraveyard().contains(this)) {
|
player.getGraveyard().contains(this)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Card in opponent's graveyard
|
// Card in opponent's graveyard
|
||||||
if (targetFilter.acceptType(MagicTargetType.OpponentsGraveyard) &&
|
if (targetFilter.acceptType(MagicTargetType.OpponentsGraveyard) &&
|
||||||
player.getOpponent().getGraveyard().contains(this)) {
|
player.getOpponent().getGraveyard().contains(this)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Card in hand
|
// Card in hand
|
||||||
if (targetFilter.acceptType(MagicTargetType.Hand) &&
|
if (targetFilter.acceptType(MagicTargetType.Hand) &&
|
||||||
player.getHand().contains(this)) {
|
player.getHand().contains(this)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,11 +108,11 @@ public class MagicCardDefinition {
|
||||||
private boolean excludeManaOrCombat;
|
private boolean excludeManaOrCombat;
|
||||||
|
|
||||||
private String requiresGroovy;
|
private String requiresGroovy;
|
||||||
|
|
||||||
public MagicCardDefinition() {
|
public MagicCardDefinition() {
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void initialize() {}
|
protected void initialize() {}
|
||||||
|
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ public class MagicCardDefinition {
|
||||||
requiresGroovy = null;
|
requiresGroovy = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void printStatistics() {
|
public static void printStatistics() {
|
||||||
System.err.println(numTriggers + " triggers");
|
System.err.println(numTriggers + " triggers");
|
||||||
System.err.println(numStatics + " statics");
|
System.err.println(numStatics + " statics");
|
||||||
|
@ -135,7 +135,7 @@ public class MagicCardDefinition {
|
||||||
System.err.println(numSpellEvent + " spell event");
|
System.err.println(numSpellEvent + " spell event");
|
||||||
System.err.println(numCDAs + " CDAs");
|
System.err.println(numCDAs + " CDAs");
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -151,15 +151,15 @@ public class MagicCardDefinition {
|
||||||
public boolean isIgnored(final long size) {
|
public boolean isIgnored(final long size) {
|
||||||
return ignore != null && ignore.contains(size);
|
return ignore != null && ignore.contains(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setName(final String name) {
|
public void setName(final String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFullName() {
|
public String getFullName() {
|
||||||
return fullName;
|
return fullName;
|
||||||
}
|
}
|
||||||
|
@ -167,15 +167,15 @@ public class MagicCardDefinition {
|
||||||
public void setFullName(final String name) {
|
public void setFullName(final String name) {
|
||||||
fullName = name;
|
fullName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIndex(final int index) {
|
public void setIndex(final int index) {
|
||||||
this.index=index;
|
this.index=index;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getIndex() {
|
public int getIndex() {
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getImageName() {
|
public String getImageName() {
|
||||||
return fullName;
|
return fullName;
|
||||||
}
|
}
|
||||||
|
@ -183,7 +183,7 @@ public class MagicCardDefinition {
|
||||||
public void setImageCount(final int count) {
|
public void setImageCount(final int count) {
|
||||||
this.imageCount = count;
|
this.imageCount = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getImageCount() {
|
public int getImageCount() {
|
||||||
return imageCount;
|
return imageCount;
|
||||||
}
|
}
|
||||||
|
@ -195,19 +195,19 @@ public class MagicCardDefinition {
|
||||||
public String getImageURL() {
|
public String getImageURL() {
|
||||||
return imageURL;
|
return imageURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCardInfoURL(final String url) {
|
public void setCardInfoURL(final String url) {
|
||||||
this.cardInfoUrl = url;
|
this.cardInfoUrl = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCardInfoURL() {
|
public String getCardInfoURL() {
|
||||||
return this.cardInfoUrl;
|
return this.cardInfoUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCardTextName() {
|
public String getCardTextName() {
|
||||||
return getImageName();
|
return getImageName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setValue(final double value) {
|
public void setValue(final double value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
@ -215,33 +215,33 @@ public class MagicCardDefinition {
|
||||||
public double getValue() {
|
public double getValue() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRemoval(final int removal) {
|
public void setRemoval(final int removal) {
|
||||||
this.removal=removal;
|
this.removal=removal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getRemoval() {
|
public int getRemoval() {
|
||||||
return removal;
|
return removal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getScore() {
|
public int getScore() {
|
||||||
if (score<0) {
|
if (score<0) {
|
||||||
score=ArtificialScoringSystem.getCardDefinitionScore(this);
|
score=ArtificialScoringSystem.getCardDefinitionScore(this);
|
||||||
}
|
}
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getFreeScore() {
|
public int getFreeScore() {
|
||||||
if (score<0) {
|
if (score<0) {
|
||||||
score=ArtificialScoringSystem.getFreeCardDefinitionScore(this);
|
score=ArtificialScoringSystem.getFreeCardDefinitionScore(this);
|
||||||
}
|
}
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRarity(final char c) {
|
public void setRarity(final char c) {
|
||||||
this.rarity = MagicRarity.getRarity(c);
|
this.rarity = MagicRarity.getRarity(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isRarity(final MagicRarity r) {
|
public boolean isRarity(final MagicRarity r) {
|
||||||
return this.rarity == r;
|
return this.rarity == r;
|
||||||
}
|
}
|
||||||
|
@ -249,11 +249,11 @@ public class MagicCardDefinition {
|
||||||
public int getRarity() {
|
public int getRarity() {
|
||||||
return rarity.ordinal();
|
return rarity.ordinal();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRarityString() {
|
public String getRarityString() {
|
||||||
return rarity.getName();
|
return rarity.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Color getRarityColor() {
|
public Color getRarityColor() {
|
||||||
final Theme theme=ThemeFactory.getInstance().getCurrentTheme();
|
final Theme theme=ThemeFactory.getInstance().getCurrentTheme();
|
||||||
switch (getRarity()) {
|
switch (getRarity()) {
|
||||||
|
@ -263,11 +263,11 @@ public class MagicCardDefinition {
|
||||||
default: return theme.getColor(Theme.COLOR_COMMON_FOREGROUND);
|
default: return theme.getColor(Theme.COLOR_COMMON_FOREGROUND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setToken() {
|
public void setToken() {
|
||||||
token=true;
|
token=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isToken() {
|
public boolean isToken() {
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
@ -275,67 +275,67 @@ public class MagicCardDefinition {
|
||||||
int getTypeFlags() {
|
int getTypeFlags() {
|
||||||
return typeFlags;
|
return typeFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addType(final MagicType type) {
|
public void addType(final MagicType type) {
|
||||||
typeFlags|=type.getMask();
|
typeFlags|=type.getMask();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasType(final MagicType type) {
|
public boolean hasType(final MagicType type) {
|
||||||
return (typeFlags&type.getMask())!=0;
|
return (typeFlags&type.getMask())!=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBasic() {
|
public boolean isBasic() {
|
||||||
return hasType(MagicType.Basic);
|
return hasType(MagicType.Basic);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLand() {
|
public boolean isLand() {
|
||||||
return hasType(MagicType.Land);
|
return hasType(MagicType.Land);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCreature() {
|
public boolean isCreature() {
|
||||||
return hasType(MagicType.Creature);
|
return hasType(MagicType.Creature);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isArtifact() {
|
public boolean isArtifact() {
|
||||||
return hasType(MagicType.Artifact);
|
return hasType(MagicType.Artifact);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEquipment() {
|
public boolean isEquipment() {
|
||||||
return isArtifact() && hasSubType(MagicSubType.Equipment);
|
return isArtifact() && hasSubType(MagicSubType.Equipment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPlaneswalker() {
|
public boolean isPlaneswalker() {
|
||||||
return hasType(MagicType.Planeswalker);
|
return hasType(MagicType.Planeswalker);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEnchantment() {
|
public boolean isEnchantment() {
|
||||||
return hasType(MagicType.Enchantment);
|
return hasType(MagicType.Enchantment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLegendary() {
|
public boolean isLegendary() {
|
||||||
return hasType(MagicType.Legendary);
|
return hasType(MagicType.Legendary);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTribal() {
|
public boolean isTribal() {
|
||||||
return hasType(MagicType.Tribal);
|
return hasType(MagicType.Tribal);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAura() {
|
public boolean isAura() {
|
||||||
return isEnchantment() && hasSubType(MagicSubType.Aura);
|
return isEnchantment() && hasSubType(MagicSubType.Aura);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInstant() {
|
public boolean isInstant() {
|
||||||
return hasType(MagicType.Instant);
|
return hasType(MagicType.Instant);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSorcery() {
|
public boolean isSorcery() {
|
||||||
return hasType(MagicType.Sorcery);
|
return hasType(MagicType.Sorcery);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSpell() {
|
public boolean isSpell() {
|
||||||
return isInstant()||isSorcery();
|
return isInstant()||isSorcery();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getLongTypeString() {
|
public String getLongTypeString() {
|
||||||
if (isBasic()) {
|
if (isBasic()) {
|
||||||
return "Basic " + getTypeString();
|
return "Basic " + getTypeString();
|
||||||
|
@ -343,56 +343,56 @@ public class MagicCardDefinition {
|
||||||
if (isLegendary()) {
|
if (isLegendary()) {
|
||||||
return "Legendary " + getTypeString();
|
return "Legendary " + getTypeString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isTribal()) {
|
if (isTribal()) {
|
||||||
return "Tribal " + getTypeString();
|
return "Tribal " + getTypeString();
|
||||||
}
|
}
|
||||||
return getTypeString();
|
return getTypeString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTypeString() {
|
public String getTypeString() {
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
if (isLand()) {
|
if (isLand()) {
|
||||||
sb.append(MagicType.Land.toString());
|
sb.append(MagicType.Land.toString());
|
||||||
}
|
}
|
||||||
if (isArtifact()) {
|
if (isArtifact()) {
|
||||||
if (sb.length() > 0) {
|
if (sb.length() > 0) {
|
||||||
sb.append(" ");
|
sb.append(" ");
|
||||||
}
|
}
|
||||||
sb.append(MagicType.Artifact.toString());
|
sb.append(MagicType.Artifact.toString());
|
||||||
}
|
}
|
||||||
if (isCreature()) {
|
if (isCreature()) {
|
||||||
if (sb.length() > 0) {
|
if (sb.length() > 0) {
|
||||||
sb.append(" ");
|
sb.append(" ");
|
||||||
}
|
}
|
||||||
sb.append(MagicType.Creature.toString());
|
sb.append(MagicType.Creature.toString());
|
||||||
}
|
}
|
||||||
if (isEnchantment()) {
|
if (isEnchantment()) {
|
||||||
if (sb.length() > 0) {
|
if (sb.length() > 0) {
|
||||||
sb.append(" ");
|
sb.append(" ");
|
||||||
}
|
}
|
||||||
sb.append(MagicType.Enchantment.toString());
|
sb.append(MagicType.Enchantment.toString());
|
||||||
}
|
}
|
||||||
if (isInstant()) {
|
if (isInstant()) {
|
||||||
if (sb.length() > 0) {
|
if (sb.length() > 0) {
|
||||||
sb.append(" ");
|
sb.append(" ");
|
||||||
}
|
}
|
||||||
sb.append(MagicType.Instant.toString());
|
sb.append(MagicType.Instant.toString());
|
||||||
}
|
}
|
||||||
if (isSorcery()) {
|
if (isSorcery()) {
|
||||||
if (sb.length() > 0) {
|
if (sb.length() > 0) {
|
||||||
sb.append(" ");
|
sb.append(" ");
|
||||||
}
|
}
|
||||||
sb.append(MagicType.Sorcery.toString());
|
sb.append(MagicType.Sorcery.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean usesStack() {
|
public boolean usesStack() {
|
||||||
return !isLand();
|
return !isLand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSubTypes(final String[] subTypeNames) {
|
public void setSubTypes(final String[] subTypeNames) {
|
||||||
subTypeFlags = MagicSubType.getSubTypes(subTypeNames);
|
subTypeFlags = MagicSubType.getSubTypes(subTypeNames);
|
||||||
}
|
}
|
||||||
|
@ -400,22 +400,22 @@ public class MagicCardDefinition {
|
||||||
EnumSet<MagicSubType> genSubTypeFlags() {
|
EnumSet<MagicSubType> genSubTypeFlags() {
|
||||||
return subTypeFlags.clone();
|
return subTypeFlags.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
EnumSet<MagicSubType> getSubTypeFlags() {
|
EnumSet<MagicSubType> getSubTypeFlags() {
|
||||||
final EnumSet<MagicSubType> subTypes = genSubTypeFlags();
|
final EnumSet<MagicSubType> subTypes = genSubTypeFlags();
|
||||||
applyCDASubType(null, null, subTypes);
|
applyCDASubType(null, null, subTypes);
|
||||||
return subTypes;
|
return subTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void applyCDASubType(
|
public void applyCDASubType(
|
||||||
final MagicGame game,
|
final MagicGame game,
|
||||||
final MagicPlayer player,
|
final MagicPlayer player,
|
||||||
final Set<MagicSubType> flags) {
|
final Set<MagicSubType> flags) {
|
||||||
for (final MagicCDA lv : CDAs) {
|
for (final MagicCDA lv : CDAs) {
|
||||||
lv.getSubTypeFlags(game, player, flags);
|
lv.getSubTypeFlags(game, player, flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSubTypeString() {
|
public String getSubTypeString() {
|
||||||
final String brackets = getSubTypeFlags().toString(); // [...,...]
|
final String brackets = getSubTypeFlags().toString(); // [...,...]
|
||||||
if (brackets.length() <= 2) {
|
if (brackets.length() <= 2) {
|
||||||
|
@ -423,15 +423,15 @@ public class MagicCardDefinition {
|
||||||
}
|
}
|
||||||
return brackets.substring(1, brackets.length() - 1);
|
return brackets.substring(1, brackets.length() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasSubType(final MagicSubType subType) {
|
public boolean hasSubType(final MagicSubType subType) {
|
||||||
return getSubTypeFlags().contains(subType);
|
return getSubTypeFlags().contains(subType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setColors(final String colors) {
|
public void setColors(final String colors) {
|
||||||
colorFlags=MagicColor.getFlags(colors);
|
colorFlags=MagicColor.getFlags(colors);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasColor(final MagicColor color) {
|
public boolean hasColor(final MagicColor color) {
|
||||||
return (colorFlags&color.getMask())!=0;
|
return (colorFlags&color.getMask())!=0;
|
||||||
}
|
}
|
||||||
|
@ -439,19 +439,19 @@ public class MagicCardDefinition {
|
||||||
public boolean isColorless() {
|
public boolean isColorless() {
|
||||||
return colorFlags == 0;
|
return colorFlags == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getColorFlags() {
|
public int getColorFlags() {
|
||||||
return colorFlags;
|
return colorFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getConvertedCost() {
|
public int getConvertedCost() {
|
||||||
return cost.getConvertedCost();
|
return cost.getConvertedCost();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasConvertedCost(final int c) {
|
public boolean hasConvertedCost(final int c) {
|
||||||
return getConvertedCost() == c;
|
return getConvertedCost() == c;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCostBucket() {
|
public int getCostBucket() {
|
||||||
switch (getConvertedCost()) {
|
switch (getConvertedCost()) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -461,11 +461,11 @@ public class MagicCardDefinition {
|
||||||
case 3:
|
case 3:
|
||||||
case 4:
|
case 4:
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
default:
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasX() {
|
public boolean hasX() {
|
||||||
return cost.hasX();
|
return cost.hasX();
|
||||||
}
|
}
|
||||||
|
@ -477,14 +477,14 @@ public class MagicCardDefinition {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void validate() {
|
public void validate() {
|
||||||
//every card should have a timing hint
|
//every card should have a timing hint
|
||||||
if (!isToken() && getTiming() == MagicTiming.None) {
|
if (!isToken() && getTiming() == MagicTiming.None) {
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
getName() + " does not have a timing hint"
|
getName() + " does not have a timing hint"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//check colorFlags is set
|
//check colorFlags is set
|
||||||
if (colorFlags == -1) {
|
if (colorFlags == -1) {
|
||||||
throw new RuntimeException(name + "'s color is not set");
|
throw new RuntimeException(name + "'s color is not set");
|
||||||
|
@ -494,7 +494,7 @@ public class MagicCardDefinition {
|
||||||
public MagicManaCost getCost() {
|
public MagicManaCost getCost() {
|
||||||
return cost;
|
return cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicEvent[] getCostEvent(final MagicCard source) {
|
public MagicEvent[] getCostEvent(final MagicCard source) {
|
||||||
final List<MagicEvent> costEvent = new ArrayList<MagicEvent>();
|
final List<MagicEvent> costEvent = new ArrayList<MagicEvent>();
|
||||||
if (cost != MagicManaCost.ZERO) {
|
if (cost != MagicManaCost.ZERO) {
|
||||||
|
@ -508,7 +508,7 @@ public class MagicCardDefinition {
|
||||||
}
|
}
|
||||||
return costEvent.toArray(new MagicEvent[0]);
|
return costEvent.toArray(new MagicEvent[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPlayable(final MagicPlayerProfile profile) {
|
public boolean isPlayable(final MagicPlayerProfile profile) {
|
||||||
if (isLand()) {
|
if (isLand()) {
|
||||||
int source = 0;
|
int source = 0;
|
||||||
|
@ -520,11 +520,11 @@ public class MagicCardDefinition {
|
||||||
return cost.getCostScore(profile) > 0;
|
return cost.getCostScore(profile) > 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEquipCost(final MagicManaCost equipCost) {
|
public void setEquipCost(final MagicManaCost equipCost) {
|
||||||
add(new MagicEquipActivation(equipCost));
|
add(new MagicEquipActivation(equipCost));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setManaSourceText(final String sourceText) {
|
public void setManaSourceText(final String sourceText) {
|
||||||
manaSourceText=sourceText;
|
manaSourceText=sourceText;
|
||||||
for (int index=0;index<sourceText.length();index+=2) {
|
for (int index=0;index<sourceText.length();index+=2) {
|
||||||
|
@ -534,20 +534,20 @@ public class MagicCardDefinition {
|
||||||
manaSource[color.ordinal()]=source;
|
manaSource[color.ordinal()]=source;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getManaSource(final MagicColor color) {
|
public int getManaSource(final MagicColor color) {
|
||||||
return manaSource[color.ordinal()];
|
return manaSource[color.ordinal()];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPowerToughness(final int aPower, final int aToughness) {
|
public void setPowerToughness(final int aPower, final int aToughness) {
|
||||||
power = aPower;
|
power = aPower;
|
||||||
toughness = aToughness;
|
toughness = aToughness;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCardPower() {
|
public int getCardPower() {
|
||||||
return power;
|
return power;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCardToughness() {
|
public int getCardToughness() {
|
||||||
return toughness;
|
return toughness;
|
||||||
}
|
}
|
||||||
|
@ -555,21 +555,21 @@ public class MagicCardDefinition {
|
||||||
public MagicPowerToughness genPowerToughness() {
|
public MagicPowerToughness genPowerToughness() {
|
||||||
return new MagicPowerToughness(power, toughness);
|
return new MagicPowerToughness(power, toughness);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void applyCDAPowerToughness(
|
public void applyCDAPowerToughness(
|
||||||
final MagicGame game,
|
final MagicGame game,
|
||||||
final MagicPlayer player,
|
final MagicPlayer player,
|
||||||
final MagicPermanent perm,
|
final MagicPermanent perm,
|
||||||
final MagicPowerToughness pt) {
|
final MagicPowerToughness pt) {
|
||||||
for (final MagicCDA lv : CDAs) {
|
for (final MagicCDA lv : CDAs) {
|
||||||
lv.modPowerToughness(game, player, perm, pt);
|
lv.modPowerToughness(game, player, perm, pt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addAbility(final MagicAbility ability) {
|
public void addAbility(final MagicAbility ability) {
|
||||||
addAbility(ability, "");
|
addAbility(ability, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addAbility(final MagicAbility ability, final String arg) {
|
public void addAbility(final MagicAbility ability, final String arg) {
|
||||||
ability.addAbilityImpl(this, arg);
|
ability.addAbilityImpl(this, arg);
|
||||||
abilityFlags.add(ability);
|
abilityFlags.add(ability);
|
||||||
|
@ -578,31 +578,31 @@ public class MagicCardDefinition {
|
||||||
public Set<MagicAbility> genAbilityFlags() {
|
public Set<MagicAbility> genAbilityFlags() {
|
||||||
return abilityFlags.clone();
|
return abilityFlags.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasAbility(final MagicAbility ability) {
|
public boolean hasAbility(final MagicAbility ability) {
|
||||||
return abilityFlags.contains(ability);
|
return abilityFlags.contains(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setText(final String text) {
|
public void setText(final String text) {
|
||||||
this.text = text;
|
this.text = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getText() {
|
public String getText() {
|
||||||
return this.text;
|
return this.text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStaticType(final MagicStaticType staticType) {
|
public void setStaticType(final MagicStaticType staticType) {
|
||||||
this.staticType=staticType;
|
this.staticType=staticType;
|
||||||
}
|
}
|
||||||
|
|
||||||
MagicStaticType getStaticType() {
|
MagicStaticType getStaticType() {
|
||||||
return staticType;
|
return staticType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTiming(final MagicTiming timing) {
|
public void setTiming(final MagicTiming timing) {
|
||||||
this.timing=timing;
|
this.timing=timing;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicTiming getTiming() {
|
public MagicTiming getTiming() {
|
||||||
return timing;
|
return timing;
|
||||||
}
|
}
|
||||||
|
@ -610,13 +610,13 @@ public class MagicCardDefinition {
|
||||||
public void add(final MagicChangeCardDefinition mod) {
|
public void add(final MagicChangeCardDefinition mod) {
|
||||||
mod.change(this);
|
mod.change(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEvent(final MagicCardEvent aCardEvent) {
|
public void setEvent(final MagicCardEvent aCardEvent) {
|
||||||
assert cardEvent == MagicPlayCardEvent.create() : "Attempting to set two MagicCardEvents for " + this;
|
assert cardEvent == MagicPlayCardEvent.create() : "Attempting to set two MagicCardEvents for " + this;
|
||||||
cardEvent = aCardEvent;
|
cardEvent = aCardEvent;
|
||||||
numSpellEvent++;
|
numSpellEvent++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicCardEvent getCardEvent() {
|
public MagicCardEvent getCardEvent() {
|
||||||
return cardEvent;
|
return cardEvent;
|
||||||
}
|
}
|
||||||
|
@ -624,22 +624,22 @@ public class MagicCardDefinition {
|
||||||
public MagicActivationHints getActivationHints() {
|
public MagicActivationHints getActivationHints() {
|
||||||
return new MagicActivationHints(timing,true);
|
return new MagicActivationHints(timing,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// cast card activation is the first element of cardActivations
|
// cast card activation is the first element of cardActivations
|
||||||
public MagicActivation getCastActivation() {
|
public MagicActivation getCastActivation() {
|
||||||
assert cardActivations.size() >= 1 : this + " has no card activations";
|
assert cardActivations.size() >= 1 : this + " has no card activations";
|
||||||
return cardActivations.getFirst();
|
return cardActivations.getFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<MagicActivation> getCardActivations() {
|
public Collection<MagicActivation> getCardActivations() {
|
||||||
return cardActivations;
|
return cardActivations;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addCDA(final MagicCDA cda) {
|
public void addCDA(final MagicCDA cda) {
|
||||||
CDAs.add(cda);
|
CDAs.add(cda);
|
||||||
numCDAs++;
|
numCDAs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addCostEvent(final MagicEventSource eventSource) {
|
public void addCostEvent(final MagicEventSource eventSource) {
|
||||||
costEventSources.add(eventSource);
|
costEventSources.add(eventSource);
|
||||||
}
|
}
|
||||||
|
@ -667,78 +667,78 @@ public class MagicCardDefinition {
|
||||||
drawnTriggers.add(trigger);
|
drawnTriggers.add(trigger);
|
||||||
numTriggers++;
|
numTriggers++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addTrigger(final MagicTrigger<?> trigger) {
|
public void addTrigger(final MagicTrigger<?> trigger) {
|
||||||
triggers.add(trigger);
|
triggers.add(trigger);
|
||||||
numTriggers++;
|
numTriggers++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addStatic(final MagicStatic mstatic) {
|
public void addStatic(final MagicStatic mstatic) {
|
||||||
statics.add(mstatic);
|
statics.add(mstatic);
|
||||||
numStatics++;
|
numStatics++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<MagicTrigger<?>> getTriggers() {
|
public Collection<MagicTrigger<?>> getTriggers() {
|
||||||
return triggers;
|
return triggers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<MagicStatic> getStatics() {
|
public Collection<MagicStatic> getStatics() {
|
||||||
return statics;
|
return statics;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<MagicWhenSpellIsCastTrigger> getSpellIsCastTriggers() {
|
public Collection<MagicWhenSpellIsCastTrigger> getSpellIsCastTriggers() {
|
||||||
return spellIsCastTriggers;
|
return spellIsCastTriggers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<MagicWhenComesIntoPlayTrigger> getComeIntoPlayTriggers() {
|
public Collection<MagicWhenComesIntoPlayTrigger> getComeIntoPlayTriggers() {
|
||||||
return comeIntoPlayTriggers;
|
return comeIntoPlayTriggers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<MagicWhenPutIntoGraveyardTrigger> getPutIntoGraveyardTriggers() {
|
public Collection<MagicWhenPutIntoGraveyardTrigger> getPutIntoGraveyardTriggers() {
|
||||||
return putIntoGraveyardTriggers;
|
return putIntoGraveyardTriggers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<MagicWhenDrawnTrigger> getDrawnTriggers() {
|
public Collection<MagicWhenDrawnTrigger> getDrawnTriggers() {
|
||||||
return drawnTriggers;
|
return drawnTriggers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addAct(final MagicPermanentActivation activation) {
|
public void addAct(final MagicPermanentActivation activation) {
|
||||||
activations.add(activation);
|
activations.add(activation);
|
||||||
numPermanentActivations++;
|
numPermanentActivations++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addCardAct(final MagicCardActivation activation) {
|
public void addCardAct(final MagicCardActivation activation) {
|
||||||
cardActivations.add(activation);
|
cardActivations.add(activation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<MagicActivation> getActivations() {
|
public Collection<MagicActivation> getActivations() {
|
||||||
return activations;
|
return activations;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addManaAct(final MagicManaActivation activation) {
|
public void addManaAct(final MagicManaActivation activation) {
|
||||||
manaActivations.add(activation);
|
manaActivations.add(activation);
|
||||||
numManaActivations++;
|
numManaActivations++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<MagicManaActivation> getManaActivations() {
|
public Collection<MagicManaActivation> getManaActivations() {
|
||||||
return manaActivations;
|
return manaActivations;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setExcludeManaOrCombat() {
|
public void setExcludeManaOrCombat() {
|
||||||
excludeManaOrCombat=true;
|
excludeManaOrCombat=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasExcludeManaOrCombat() {
|
public boolean hasExcludeManaOrCombat() {
|
||||||
return excludeManaOrCombat;
|
return excludeManaOrCombat;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImageIcon getIcon() {
|
public ImageIcon getIcon() {
|
||||||
if (isLand()) {
|
if (isLand()) {
|
||||||
return IconImages.LAND;
|
return IconImages.LAND;
|
||||||
} else if (isCreature()) {
|
} else if (isCreature()) {
|
||||||
return IconImages.CREATURE;
|
return IconImages.CREATURE;
|
||||||
} else if (isEquipment()) {
|
} else if (isEquipment()) {
|
||||||
return IconImages.EQUIPMENT;
|
return IconImages.EQUIPMENT;
|
||||||
} else if (isAura()) {
|
} else if (isAura()) {
|
||||||
return IconImages.AURA;
|
return IconImages.AURA;
|
||||||
} else if (isEnchantment()) {
|
} else if (isEnchantment()) {
|
||||||
|
@ -749,7 +749,7 @@ public class MagicCardDefinition {
|
||||||
return IconImages.SPELL;
|
return IconImages.SPELL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean subTypeHasText(final String s) {
|
private boolean subTypeHasText(final String s) {
|
||||||
final MagicSubType[] subTypeValues = MagicSubType.values();
|
final MagicSubType[] subTypeValues = MagicSubType.values();
|
||||||
for (final MagicSubType subtype : subTypeValues) {
|
for (final MagicSubType subtype : subTypeValues) {
|
||||||
|
@ -759,7 +759,7 @@ public class MagicCardDefinition {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean abilityHasText(final String s) {
|
private boolean abilityHasText(final String s) {
|
||||||
for (final MagicAbility ability : MagicAbility.CORE) {
|
for (final MagicAbility ability : MagicAbility.CORE) {
|
||||||
if(hasAbility(ability) && ability.getName().toLowerCase().contains(s)) {
|
if(hasAbility(ability) && ability.getName().toLowerCase().contains(s)) {
|
||||||
|
@ -768,7 +768,7 @@ public class MagicCardDefinition {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasText(String s) {
|
public boolean hasText(String s) {
|
||||||
s = s.toLowerCase();
|
s = s.toLowerCase();
|
||||||
return (
|
return (
|
||||||
|
@ -779,7 +779,7 @@ public class MagicCardDefinition {
|
||||||
getText().toLowerCase().contains(s)
|
getText().toLowerCase().contains(s)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getName();
|
return getName();
|
||||||
|
@ -798,7 +798,7 @@ public class MagicCardDefinition {
|
||||||
return NAME_COMPARATOR_DESC.compare(cardDefinition2, cardDefinition1);
|
return NAME_COMPARATOR_DESC.compare(cardDefinition2, cardDefinition1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final Comparator<MagicCardDefinition> CONVERTED_COMPARATOR_DESC=new Comparator<MagicCardDefinition>() {
|
public static final Comparator<MagicCardDefinition> CONVERTED_COMPARATOR_DESC=new Comparator<MagicCardDefinition>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(final MagicCardDefinition cardDefinition1,final MagicCardDefinition cardDefinition2) {
|
public int compare(final MagicCardDefinition cardDefinition1,final MagicCardDefinition cardDefinition2) {
|
||||||
|
@ -809,7 +809,7 @@ public class MagicCardDefinition {
|
||||||
return cardDefinition1.getName().compareTo(cardDefinition2.getName());
|
return cardDefinition1.getName().compareTo(cardDefinition2.getName());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final Comparator<MagicCardDefinition> CONVERTED_COMPARATOR_ASC=new Comparator<MagicCardDefinition>() {
|
public static final Comparator<MagicCardDefinition> CONVERTED_COMPARATOR_ASC=new Comparator<MagicCardDefinition>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(final MagicCardDefinition cardDefinition1,final MagicCardDefinition cardDefinition2) {
|
public int compare(final MagicCardDefinition cardDefinition1,final MagicCardDefinition cardDefinition2) {
|
||||||
|
@ -819,7 +819,7 @@ public class MagicCardDefinition {
|
||||||
|
|
||||||
public static final Comparator<MagicCardDefinition> TYPE_COMPARATOR_DESC=new Comparator<MagicCardDefinition>() {
|
public static final Comparator<MagicCardDefinition> TYPE_COMPARATOR_DESC=new Comparator<MagicCardDefinition>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(final MagicCardDefinition cardDefinition1,final MagicCardDefinition cardDefinition2) {
|
public int compare(final MagicCardDefinition cardDefinition1,final MagicCardDefinition cardDefinition2) {
|
||||||
final int c = cardDefinition1.getTypeString().compareTo(cardDefinition2.getTypeString());
|
final int c = cardDefinition1.getTypeString().compareTo(cardDefinition2.getTypeString());
|
||||||
if(c == 0) {
|
if(c == 0) {
|
||||||
return cardDefinition1.getLongTypeString().compareTo(cardDefinition2.getLongTypeString());
|
return cardDefinition1.getLongTypeString().compareTo(cardDefinition2.getLongTypeString());
|
||||||
|
@ -854,7 +854,7 @@ public class MagicCardDefinition {
|
||||||
public int compare(final MagicCardDefinition cardDefinition1,final MagicCardDefinition cardDefinition2) {
|
public int compare(final MagicCardDefinition cardDefinition1,final MagicCardDefinition cardDefinition2) {
|
||||||
final int p1 = cardDefinition1.isCreature() ? cardDefinition1.getCardPower() : -100;
|
final int p1 = cardDefinition1.isCreature() ? cardDefinition1.getCardPower() : -100;
|
||||||
final int p2 = cardDefinition2.isCreature() ? cardDefinition2.getCardPower() : -100;
|
final int p2 = cardDefinition2.isCreature() ? cardDefinition2.getCardPower() : -100;
|
||||||
|
|
||||||
if (p1 != p2) {
|
if (p1 != p2) {
|
||||||
return p1 - p2;
|
return p1 - p2;
|
||||||
} else {
|
} else {
|
||||||
|
@ -875,7 +875,7 @@ public class MagicCardDefinition {
|
||||||
public int compare(final MagicCardDefinition cardDefinition1,final MagicCardDefinition cardDefinition2) {
|
public int compare(final MagicCardDefinition cardDefinition1,final MagicCardDefinition cardDefinition2) {
|
||||||
final int t1 = cardDefinition1.isCreature() ? cardDefinition1.getCardToughness() : -100;
|
final int t1 = cardDefinition1.isCreature() ? cardDefinition1.getCardToughness() : -100;
|
||||||
final int t2 = cardDefinition2.isCreature() ? cardDefinition2.getCardToughness() : -100;
|
final int t2 = cardDefinition2.isCreature() ? cardDefinition2.getCardToughness() : -100;
|
||||||
|
|
||||||
if (t1 != t2) {
|
if (t1 != t2) {
|
||||||
return t1 - t2;
|
return t1 - t2;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -5,21 +5,21 @@ import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class MagicCardList extends ArrayList<MagicCard> {
|
public class MagicCardList extends ArrayList<MagicCard> {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
public MagicCardList() {}
|
public MagicCardList() {}
|
||||||
|
|
||||||
public MagicCardList(final MagicCardList cardList) {
|
public MagicCardList(final MagicCardList cardList) {
|
||||||
super(cardList);
|
super(cardList);
|
||||||
}
|
}
|
||||||
|
|
||||||
MagicCardList(final MagicCopyMap copyMap, final MagicCardList cardList) {
|
MagicCardList(final MagicCopyMap copyMap, final MagicCardList cardList) {
|
||||||
for (final MagicCard card : cardList) {
|
for (final MagicCard card : cardList) {
|
||||||
add(copyMap.copy(card));
|
add(copyMap.copy(card));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getStateId() {
|
public long getStateId() {
|
||||||
final long[] keys = new long[size()];
|
final long[] keys = new long[size()];
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
|
@ -29,7 +29,7 @@ public class MagicCardList extends ArrayList<MagicCard> {
|
||||||
}
|
}
|
||||||
return magic.MurmurHash3.hash(keys);
|
return magic.MurmurHash3.hash(keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getUnorderedStateId() {
|
public long getUnorderedStateId() {
|
||||||
final long[] keys = new long[size()];
|
final long[] keys = new long[size()];
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
|
@ -40,33 +40,33 @@ public class MagicCardList extends ArrayList<MagicCard> {
|
||||||
Arrays.sort(keys);
|
Arrays.sort(keys);
|
||||||
return magic.MurmurHash3.hash(keys);
|
return magic.MurmurHash3.hash(keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addToBottom(final MagicCard card) {
|
public void addToBottom(final MagicCard card) {
|
||||||
add(0,card);
|
add(0,card);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addToTop(final MagicCard card) {
|
public void addToTop(final MagicCard card) {
|
||||||
add(card);
|
add(card);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicCard getCardAtBottom() {
|
public MagicCard getCardAtBottom() {
|
||||||
return get(0);
|
return get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicCard getCardAtTop() {
|
public MagicCard getCardAtTop() {
|
||||||
final int size = this.size();
|
final int size = this.size();
|
||||||
return size > 0 ?
|
return size > 0 ?
|
||||||
this.get(size()-1) :
|
this.get(size()-1) :
|
||||||
MagicCard.NONE;
|
MagicCard.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicCard removeCardAtTop() {
|
public MagicCard removeCardAtTop() {
|
||||||
final int index=size()-1;
|
final int index=size()-1;
|
||||||
final MagicCard card=get(index);
|
final MagicCard card=get(index);
|
||||||
remove(index);
|
remove(index);
|
||||||
return card;
|
return card;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int removeCard(final MagicCard card) {
|
public int removeCard(final MagicCard card) {
|
||||||
final int index=indexOf(card);
|
final int index=indexOf(card);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
|
@ -85,18 +85,18 @@ public class MagicCardList extends ArrayList<MagicCard> {
|
||||||
}
|
}
|
||||||
return MagicCard.NONE;
|
return MagicCard.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCards(final MagicCardList cardList) {
|
public void setCards(final MagicCardList cardList) {
|
||||||
clear();
|
clear();
|
||||||
addAll(cardList);
|
addAll(cardList);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setKnown(final boolean known) {
|
void setKnown(final boolean known) {
|
||||||
for (final MagicCard card : this) {
|
for (final MagicCard card : this) {
|
||||||
card.setKnown(known);
|
card.setKnown(known);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getNrOfLands() {
|
private int getNrOfLands() {
|
||||||
int lands=0;
|
int lands=0;
|
||||||
for (final MagicCard card : this) {
|
for (final MagicCard card : this) {
|
||||||
|
@ -106,7 +106,7 @@ public class MagicCardList extends ArrayList<MagicCard> {
|
||||||
}
|
}
|
||||||
return lands;
|
return lands;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean useSmartShuffle() {
|
private boolean useSmartShuffle() {
|
||||||
final int lands = getNrOfLands();
|
final int lands = getNrOfLands();
|
||||||
final int total = size();
|
final int total = size();
|
||||||
|
@ -125,7 +125,7 @@ public class MagicCardList extends ArrayList<MagicCard> {
|
||||||
public void shuffle() {
|
public void shuffle() {
|
||||||
shuffle(getStateId());
|
shuffle(getStateId());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void shuffle(final long seed) {
|
public void shuffle(final long seed) {
|
||||||
final magic.MersenneTwisterFast rng = new magic.MersenneTwisterFast(seed);
|
final magic.MersenneTwisterFast rng = new magic.MersenneTwisterFast(seed);
|
||||||
final MagicCardList oldCards = new MagicCardList(this);
|
final MagicCardList oldCards = new MagicCardList(this);
|
||||||
|
@ -133,11 +133,11 @@ public class MagicCardList extends ArrayList<MagicCard> {
|
||||||
for (int size = oldCards.size(); size > 0; size--) {
|
for (int size = oldCards.size(); size > 0; size--) {
|
||||||
final int index=rng.nextInt(size);
|
final int index=rng.nextInt(size);
|
||||||
final MagicCard card=oldCards.get(index);
|
final MagicCard card=oldCards.get(index);
|
||||||
oldCards.remove(index);
|
oldCards.remove(index);
|
||||||
add(card);
|
add(card);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void smartShuffle(final long seed) {
|
private void smartShuffle(final long seed) {
|
||||||
final magic.MersenneTwisterFast rng = new magic.MersenneTwisterFast(seed);
|
final magic.MersenneTwisterFast rng = new magic.MersenneTwisterFast(seed);
|
||||||
final int size=size();
|
final int size=size();
|
||||||
|
@ -155,7 +155,7 @@ public class MagicCardList extends ArrayList<MagicCard> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
for (int blocks=size/5;blocks>0;blocks--) {
|
for (int blocks=size/5;blocks>0;blocks--) {
|
||||||
int landCount=0;
|
int landCount=0;
|
||||||
|
|
|
@ -15,40 +15,40 @@ public enum MagicColor {
|
||||||
Green("green",'g'),
|
Green("green",'g'),
|
||||||
Red("red",'r')
|
Red("red",'r')
|
||||||
;
|
;
|
||||||
|
|
||||||
public static final int NR_COLORS=values().length;
|
public static final int NR_COLORS=values().length;
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final char symbol;
|
private final char symbol;
|
||||||
private final int mask;
|
private final int mask;
|
||||||
|
|
||||||
private MagicColor(final String name,final char symbol) {
|
private MagicColor(final String name,final char symbol) {
|
||||||
this.name=name;
|
this.name=name;
|
||||||
this.symbol=symbol;
|
this.symbol=symbol;
|
||||||
this.mask=1<<ordinal();
|
this.mask=1<<ordinal();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public char getSymbol() {
|
public char getSymbol() {
|
||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMask() {
|
public int getMask() {
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasColor(final int flags) {
|
public boolean hasColor(final int flags) {
|
||||||
return (flags&mask)!=0;
|
return (flags&mask)!=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicAbility getProtectionAbility() {
|
public MagicAbility getProtectionAbility() {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case White: return MagicAbility.ProtectionFromWhite;
|
case White: return MagicAbility.ProtectionFromWhite;
|
||||||
|
@ -59,7 +59,7 @@ public enum MagicColor {
|
||||||
}
|
}
|
||||||
throw new RuntimeException("No protection ability for MagicColor " + this);
|
throw new RuntimeException("No protection ability for MagicColor " + this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicAbility getLandwalkAbility() {
|
public MagicAbility getLandwalkAbility() {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case White: return MagicAbility.PlainsWalk;
|
case White: return MagicAbility.PlainsWalk;
|
||||||
|
@ -67,10 +67,10 @@ public enum MagicColor {
|
||||||
case Black: return MagicAbility.Swampwalk;
|
case Black: return MagicAbility.Swampwalk;
|
||||||
case Green: return MagicAbility.Forestwalk;
|
case Green: return MagicAbility.Forestwalk;
|
||||||
case Red: return MagicAbility.Mountainwalk;
|
case Red: return MagicAbility.Mountainwalk;
|
||||||
}
|
}
|
||||||
throw new RuntimeException("No landwalk ability for MagicColor " + this);
|
throw new RuntimeException("No landwalk ability for MagicColor " + this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicAbility getCannotBeBlockedByAbility() {
|
public MagicAbility getCannotBeBlockedByAbility() {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case White: return MagicAbility.CannotBeBlockedByWhite;
|
case White: return MagicAbility.CannotBeBlockedByWhite;
|
||||||
|
@ -78,13 +78,13 @@ public enum MagicColor {
|
||||||
case Black: return MagicAbility.CannotBeBlockedByBlack;
|
case Black: return MagicAbility.CannotBeBlockedByBlack;
|
||||||
case Green: return MagicAbility.CannotBeBlockedByGreen;
|
case Green: return MagicAbility.CannotBeBlockedByGreen;
|
||||||
case Red: return MagicAbility.CannotBeBlockedByRed;
|
case Red: return MagicAbility.CannotBeBlockedByRed;
|
||||||
}
|
}
|
||||||
throw new RuntimeException("No CannotBeBlockedBy ability for MagicColor " + this);
|
throw new RuntimeException("No CannotBeBlockedBy ability for MagicColor " + this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicSubType getLandSubType() {
|
public MagicSubType getLandSubType() {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case White: return MagicSubType.Plains;
|
case White: return MagicSubType.Plains;
|
||||||
case Blue: return MagicSubType.Island;
|
case Blue: return MagicSubType.Island;
|
||||||
case Black: return MagicSubType.Swamp;
|
case Black: return MagicSubType.Swamp;
|
||||||
case Green: return MagicSubType.Forest;
|
case Green: return MagicSubType.Forest;
|
||||||
|
@ -92,7 +92,7 @@ public enum MagicColor {
|
||||||
}
|
}
|
||||||
throw new RuntimeException("No land subtype for MagicColor " + this);
|
throw new RuntimeException("No land subtype for MagicColor " + this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicManaType getManaType() {
|
public MagicManaType getManaType() {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case White: return MagicManaType.White;
|
case White: return MagicManaType.White;
|
||||||
|
@ -103,7 +103,7 @@ public enum MagicColor {
|
||||||
}
|
}
|
||||||
return MagicManaType.Colorless;
|
return MagicManaType.Colorless;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImageIcon getIcon() {
|
public ImageIcon getIcon() {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case White: return IconImages.WHITE;
|
case White: return IconImages.WHITE;
|
||||||
|
@ -124,7 +124,7 @@ public enum MagicColor {
|
||||||
}
|
}
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MagicColor getColor(final char symbol) {
|
public static MagicColor getColor(final char symbol) {
|
||||||
final char usymbol=Character.toLowerCase(symbol);
|
final char usymbol=Character.toLowerCase(symbol);
|
||||||
for (final MagicColor color : values()) {
|
for (final MagicColor color : values()) {
|
||||||
|
@ -133,14 +133,14 @@ public enum MagicColor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new RuntimeException("No corresponding MagicColor for " + symbol);
|
throw new RuntimeException("No corresponding MagicColor for " + symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getRandomColors(final int count) {
|
public static String getRandomColors(final int count) {
|
||||||
final List<MagicColor> colors = new ArrayList<MagicColor>(Arrays.asList(values()));
|
final List<MagicColor> colors = new ArrayList<MagicColor>(Arrays.asList(values()));
|
||||||
final StringBuilder colorText=new StringBuilder();
|
final StringBuilder colorText=new StringBuilder();
|
||||||
for (int c=count;c>0;c--) {
|
for (int c=count;c>0;c--) {
|
||||||
final int index=MagicRandom.nextInt(colors.size());
|
final int index=MagicRandom.nextInt(colors.size());
|
||||||
colorText.append(colors.remove(index).getSymbol());
|
colorText.append(colors.remove(index).getSymbol());
|
||||||
}
|
}
|
||||||
return colorText.toString();
|
return colorText.toString();
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ public enum MagicColor {
|
||||||
}
|
}
|
||||||
return numColors;
|
return numColors;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isColorless(final MagicSource source) {
|
private static boolean isColorless(final MagicSource source) {
|
||||||
return numColors(source) == 0;
|
return numColors(source) == 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,33 +6,33 @@ import java.util.Comparator;
|
||||||
public class MagicCondensedCardDefinition {
|
public class MagicCondensedCardDefinition {
|
||||||
private int copies;
|
private int copies;
|
||||||
private final MagicCardDefinition card;
|
private final MagicCardDefinition card;
|
||||||
|
|
||||||
public MagicCondensedCardDefinition(final MagicCardDefinition card) {
|
public MagicCondensedCardDefinition(final MagicCardDefinition card) {
|
||||||
this.card = card;
|
this.card = card;
|
||||||
copies = 1;
|
copies = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicCardDefinition getCard() {
|
public MagicCardDefinition getCard() {
|
||||||
return card;
|
return card;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void incrementNumCopies() {
|
public void incrementNumCopies() {
|
||||||
copies++;
|
copies++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void decrementNumCopies() {
|
public void decrementNumCopies() {
|
||||||
if (copies > 0) {
|
if (copies > 0) {
|
||||||
copies--;
|
copies--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNumCopies(final int i) {
|
public void setNumCopies(final int i) {
|
||||||
copies = i;
|
copies = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNumCopies() {
|
public int getNumCopies() {
|
||||||
return copies;
|
return copies;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Comparator<MagicCondensedCardDefinition> NUM_COPIES_COMPARATOR_DESC=new Comparator<MagicCondensedCardDefinition>() {
|
public static final Comparator<MagicCondensedCardDefinition> NUM_COPIES_COMPARATOR_DESC=new Comparator<MagicCondensedCardDefinition>() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -47,7 +47,7 @@ public class MagicCondensedCardDefinition {
|
||||||
return MagicCondensedCardDefinition.NUM_COPIES_COMPARATOR_DESC.compare(cardDefinition2, cardDefinition1);
|
return MagicCondensedCardDefinition.NUM_COPIES_COMPARATOR_DESC.compare(cardDefinition2, cardDefinition1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final Comparator<MagicCondensedCardDefinition> NAME_COMPARATOR_DESC=new Comparator<MagicCondensedCardDefinition>() {
|
public static final Comparator<MagicCondensedCardDefinition> NAME_COMPARATOR_DESC=new Comparator<MagicCondensedCardDefinition>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(final MagicCondensedCardDefinition cardDefinition1,final MagicCondensedCardDefinition cardDefinition2) {
|
public int compare(final MagicCondensedCardDefinition cardDefinition1,final MagicCondensedCardDefinition cardDefinition2) {
|
||||||
|
@ -61,14 +61,14 @@ public class MagicCondensedCardDefinition {
|
||||||
return MagicCardDefinition.NAME_COMPARATOR_ASC.compare(cardDefinition1.getCard(), cardDefinition2.getCard());
|
return MagicCardDefinition.NAME_COMPARATOR_ASC.compare(cardDefinition1.getCard(), cardDefinition2.getCard());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final Comparator<MagicCondensedCardDefinition> CONVERTED_COMPARATOR_DESC=new Comparator<MagicCondensedCardDefinition>() {
|
public static final Comparator<MagicCondensedCardDefinition> CONVERTED_COMPARATOR_DESC=new Comparator<MagicCondensedCardDefinition>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(final MagicCondensedCardDefinition cardDefinition1,final MagicCondensedCardDefinition cardDefinition2) {
|
public int compare(final MagicCondensedCardDefinition cardDefinition1,final MagicCondensedCardDefinition cardDefinition2) {
|
||||||
return MagicCardDefinition.CONVERTED_COMPARATOR_DESC.compare(cardDefinition1.getCard(), cardDefinition2.getCard());
|
return MagicCardDefinition.CONVERTED_COMPARATOR_DESC.compare(cardDefinition1.getCard(), cardDefinition2.getCard());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final Comparator<MagicCondensedCardDefinition> CONVERTED_COMPARATOR_ASC=new Comparator<MagicCondensedCardDefinition>() {
|
public static final Comparator<MagicCondensedCardDefinition> CONVERTED_COMPARATOR_ASC=new Comparator<MagicCondensedCardDefinition>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(final MagicCondensedCardDefinition cardDefinition1,final MagicCondensedCardDefinition cardDefinition2) {
|
public int compare(final MagicCondensedCardDefinition cardDefinition1,final MagicCondensedCardDefinition cardDefinition2) {
|
||||||
|
|
|
@ -7,9 +7,9 @@ import java.util.List;
|
||||||
public class MagicCondensedDeck extends ArrayList<MagicCondensedCardDefinition> {
|
public class MagicCondensedDeck extends ArrayList<MagicCondensedCardDefinition> {
|
||||||
|
|
||||||
private static final long serialVersionUID = 143L;
|
private static final long serialVersionUID = 143L;
|
||||||
|
|
||||||
private String name = "Unsaved Deck";
|
private String name = "Unsaved Deck";
|
||||||
|
|
||||||
private final HashMap<String, MagicCondensedCardDefinition> map = new HashMap<String, MagicCondensedCardDefinition>();
|
private final HashMap<String, MagicCondensedCardDefinition> map = new HashMap<String, MagicCondensedCardDefinition>();
|
||||||
|
|
||||||
public MagicCondensedDeck() {}
|
public MagicCondensedDeck() {}
|
||||||
|
@ -18,82 +18,82 @@ public class MagicCondensedDeck extends ArrayList<MagicCondensedCardDefinition>
|
||||||
super(deck);
|
super(deck);
|
||||||
name = deck.getName();
|
name = deck.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicCondensedDeck(final MagicDeck list) {
|
public MagicCondensedDeck(final MagicDeck list) {
|
||||||
this((List<MagicCardDefinition>) list);
|
this((List<MagicCardDefinition>) list);
|
||||||
|
|
||||||
name = list.getName();
|
name = list.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicCondensedDeck(final List<MagicCardDefinition> list) {
|
public MagicCondensedDeck(final List<MagicCardDefinition> list) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
for(final MagicCardDefinition card : list) {
|
for(final MagicCardDefinition card : list) {
|
||||||
addCard(card, true);
|
addCard(card, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getKey(final MagicCardDefinition card) {
|
private String getKey(final MagicCardDefinition card) {
|
||||||
return card.getName();
|
return card.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean addCard(final MagicCardDefinition card, final boolean ignoreCopiesLimit) {
|
public boolean addCard(final MagicCardDefinition card, final boolean ignoreCopiesLimit) {
|
||||||
if(!map.containsKey(getKey(card))) {
|
if(!map.containsKey(getKey(card))) {
|
||||||
// add to end
|
// add to end
|
||||||
add(new MagicCondensedCardDefinition(card));
|
add(new MagicCondensedCardDefinition(card));
|
||||||
map.put(getKey(card), get(size() - 1));
|
map.put(getKey(card), get(size() - 1));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
final MagicCondensedCardDefinition existingCard = map.get(getKey(card));
|
final MagicCondensedCardDefinition existingCard = map.get(getKey(card));
|
||||||
|
|
||||||
if(ignoreCopiesLimit || existingCard.getNumCopies() < MagicDeckConstructionRule.MAX_COPIES) {
|
if(ignoreCopiesLimit || existingCard.getNumCopies() < MagicDeckConstructionRule.MAX_COPIES) {
|
||||||
existingCard.incrementNumCopies();
|
existingCard.incrementNumCopies();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} // otherwise card can't be added because of copies limit
|
} // otherwise card can't be added because of copies limit
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setContent(final MagicCondensedDeck deck) {
|
public void setContent(final MagicCondensedDeck deck) {
|
||||||
clear();
|
clear();
|
||||||
addAll(deck);
|
addAll(deck);
|
||||||
|
|
||||||
name = deck.getName();
|
name = deck.getName();
|
||||||
|
|
||||||
map.clear();
|
map.clear();
|
||||||
map.putAll(deck.getMap());
|
map.putAll(deck.getMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setName(final String name) {
|
public void setName(final String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNumCards() {
|
public int getNumCards() {
|
||||||
return toMagicDeck().size();
|
return toMagicDeck().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public HashMap<String, MagicCondensedCardDefinition> getMap() {
|
public HashMap<String, MagicCondensedCardDefinition> getMap() {
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicDeck toMagicDeck() {
|
public MagicDeck toMagicDeck() {
|
||||||
final MagicDeck deck = new MagicDeck();
|
final MagicDeck deck = new MagicDeck();
|
||||||
|
|
||||||
for(int i = 0; i < size(); i++) {
|
for(int i = 0; i < size(); i++) {
|
||||||
final MagicCondensedCardDefinition card = get(i);
|
final MagicCondensedCardDefinition card = get(i);
|
||||||
|
|
||||||
for(int j = 0; j < card.getNumCopies(); j++) {
|
for(int j = 0; j < card.getNumCopies(); j++) {
|
||||||
deck.add(card.getCard());
|
deck.add(card.getCard());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return deck;
|
return deck;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,17 +10,17 @@ public class MagicCopyMap extends HashMap<MagicCopyable,MagicCopyable> {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <E extends MagicCopyable> E copy(final E source) {
|
public <E extends MagicCopyable> E copy(final E source) {
|
||||||
if (source == null) {
|
if (source == null) {
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
E target=(E)get(source);
|
E target=(E)get(source);
|
||||||
if (target==null) {
|
if (target==null) {
|
||||||
target=(E)source.copy(this);
|
target=(E)source.copy(this);
|
||||||
put(source,target);
|
put(source,target);
|
||||||
}
|
}
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object copyObject(final Object source) {
|
private Object copyObject(final Object source) {
|
||||||
if (source != null && source instanceof MagicCopyable) {
|
if (source != null && source instanceof MagicCopyable) {
|
||||||
return copy((MagicCopyable)source);
|
return copy((MagicCopyable)source);
|
||||||
|
@ -28,7 +28,7 @@ public class MagicCopyMap extends HashMap<MagicCopyable,MagicCopyable> {
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <E> E[] copyObjects(final E[] sources,final Class<E> clazz) {
|
public <E> E[] copyObjects(final E[] sources,final Class<E> clazz) {
|
||||||
if (sources==null||sources.length==0) {
|
if (sources==null||sources.length==0) {
|
||||||
|
@ -40,7 +40,7 @@ public class MagicCopyMap extends HashMap<MagicCopyable,MagicCopyable> {
|
||||||
}
|
}
|
||||||
return targets;
|
return targets;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <E> void copyCollection(final Collection<E> sourceCollection,final Collection<E> targetCollection) {
|
public <E> void copyCollection(final Collection<E> sourceCollection,final Collection<E> targetCollection) {
|
||||||
for (final E object : sourceCollection) {
|
for (final E object : sourceCollection) {
|
||||||
|
|
|
@ -22,18 +22,18 @@ public enum MagicCostManaType {
|
||||||
RedWhite("red/white","{R/W}",Arrays.asList(MagicManaType.Red,MagicManaType.White)),
|
RedWhite("red/white","{R/W}",Arrays.asList(MagicManaType.Red,MagicManaType.White)),
|
||||||
GreenWhite("green/white","{G/W}",Arrays.asList(MagicManaType.Green,MagicManaType.White)),
|
GreenWhite("green/white","{G/W}",Arrays.asList(MagicManaType.Green,MagicManaType.White)),
|
||||||
GreenBlue("green/blue","{G/U}",Arrays.asList(MagicManaType.Green,MagicManaType.Blue)),
|
GreenBlue("green/blue","{G/U}",Arrays.asList(MagicManaType.Green,MagicManaType.Blue)),
|
||||||
White("white","{W}",Arrays.asList(MagicManaType.White)),
|
White("white","{W}",Arrays.asList(MagicManaType.White)),
|
||||||
Blue("blue","{U}",Arrays.asList(MagicManaType.Blue)),
|
Blue("blue","{U}",Arrays.asList(MagicManaType.Blue)),
|
||||||
Black("black","{B}",Arrays.asList(MagicManaType.Black)),
|
Black("black","{B}",Arrays.asList(MagicManaType.Black)),
|
||||||
Red("red","{R}",Arrays.asList(MagicManaType.Red)),
|
Red("red","{R}",Arrays.asList(MagicManaType.Red)),
|
||||||
Green("green","{G}",Arrays.asList(MagicManaType.Green)),
|
Green("green","{G}",Arrays.asList(MagicManaType.Green)),
|
||||||
;
|
;
|
||||||
|
|
||||||
public static final int NR_OF_TYPES=values().length;
|
public static final int NR_OF_TYPES=values().length;
|
||||||
public static final EnumSet<MagicCostManaType> HYBRID = EnumSet.range(WhiteBlue, GreenBlue);
|
public static final EnumSet<MagicCostManaType> HYBRID = EnumSet.range(WhiteBlue, GreenBlue);
|
||||||
public static final EnumSet<MagicCostManaType> MONO = EnumSet.range(White, Green);
|
public static final EnumSet<MagicCostManaType> MONO = EnumSet.range(White, Green);
|
||||||
public static final EnumSet<MagicCostManaType> NON_MONO = EnumSet.range(Colorless, GreenBlue);
|
public static final EnumSet<MagicCostManaType> NON_MONO = EnumSet.range(Colorless, GreenBlue);
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final String text;
|
private final String text;
|
||||||
private final List<MagicManaType> types;
|
private final List<MagicManaType> types;
|
||||||
|
@ -43,7 +43,7 @@ public enum MagicCostManaType {
|
||||||
this.text=text;
|
this.text=text;
|
||||||
this.types=types;
|
this.types=types;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicCostManaType next() {
|
public MagicCostManaType next() {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case White: return Blue;
|
case White: return Blue;
|
||||||
|
@ -54,7 +54,7 @@ public enum MagicCostManaType {
|
||||||
default: throw new RuntimeException("No next mana cost type for " + this);
|
default: throw new RuntimeException("No next mana cost type for " + this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicCostManaType prev() {
|
public MagicCostManaType prev() {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case White: return Green;
|
case White: return Green;
|
||||||
|
@ -65,19 +65,19 @@ public enum MagicCostManaType {
|
||||||
default: throw new RuntimeException("No next mana cost type for " + this);
|
default: throw new RuntimeException("No next mana cost type for " + this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getText() {
|
public String getText() {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<MagicManaType> getTypes() {
|
public List<MagicManaType> getTypes() {
|
||||||
return types;
|
return types;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicManaType[] getTypes(final MagicPlayerProfile profile) {
|
public MagicManaType[] getTypes(final MagicPlayerProfile profile) {
|
||||||
int count=0;
|
int count=0;
|
||||||
final MagicManaType[] profileTypes=new MagicManaType[types.size()];
|
final MagicManaType[] profileTypes=new MagicManaType[types.size()];
|
||||||
|
@ -88,7 +88,7 @@ public enum MagicCostManaType {
|
||||||
}
|
}
|
||||||
return Arrays.copyOf(profileTypes,count);
|
return Arrays.copyOf(profileTypes,count);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImageIcon getIcon() {
|
public ImageIcon getIcon() {
|
||||||
return TextImages.getIcon(text);
|
return TextImages.getIcon(text);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package magic.model;
|
package magic.model;
|
||||||
|
|
||||||
public enum MagicCounterType {
|
public enum MagicCounterType {
|
||||||
|
|
||||||
PlusOne("+1/+1","{+}"),
|
PlusOne("+1/+1","{+}"),
|
||||||
MinusOne("-1/-1","{-}"),
|
MinusOne("-1/-1","{-}"),
|
||||||
Charge("charge","{C}"),
|
Charge("charge","{C}"),
|
||||||
|
@ -11,19 +11,19 @@ public enum MagicCounterType {
|
||||||
;
|
;
|
||||||
|
|
||||||
public static final int NR_COUNTERS=MagicCounterType.values().length;
|
public static final int NR_COUNTERS=MagicCounterType.values().length;
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final String text;
|
private final String text;
|
||||||
|
|
||||||
private MagicCounterType(final String name,final String text) {
|
private MagicCounterType(final String name,final String text) {
|
||||||
this.name=name;
|
this.name=name;
|
||||||
this.text=text;
|
this.text=text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getText() {
|
public String getText() {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,21 +5,21 @@ import java.util.HashSet;
|
||||||
public class MagicCubeDefinition extends HashSet<String> {
|
public class MagicCubeDefinition extends HashSet<String> {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
public MagicCubeDefinition(final String name) {
|
public MagicCubeDefinition(final String name) {
|
||||||
this.name=name;
|
this.name=name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean containsCard(final MagicCardDefinition cardDefinition) {
|
public boolean containsCard(final MagicCardDefinition cardDefinition) {
|
||||||
return contains(cardDefinition.getName());
|
return contains(cardDefinition.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name + " (" + size() + " cards)";
|
return name + " (" + size() + " cards)";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return name;
|
return name;
|
||||||
|
|
|
@ -3,7 +3,7 @@ package magic.model;
|
||||||
import magic.model.target.MagicTarget;
|
import magic.model.target.MagicTarget;
|
||||||
|
|
||||||
public class MagicDamage {
|
public class MagicDamage {
|
||||||
|
|
||||||
private final MagicSource source;
|
private final MagicSource source;
|
||||||
private MagicTarget target;
|
private MagicTarget target;
|
||||||
private int amount;
|
private int amount;
|
||||||
|
@ -18,7 +18,7 @@ public class MagicDamage {
|
||||||
this.amount=amount;
|
this.amount=amount;
|
||||||
this.combat=combat;
|
this.combat=combat;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicDamage(final MagicSource source,final MagicTarget target,final int amount) {
|
public MagicDamage(final MagicSource source,final MagicTarget target,final int amount) {
|
||||||
this(source, target, amount, false);
|
this(source, target, amount, false);
|
||||||
}
|
}
|
||||||
|
@ -26,23 +26,23 @@ public class MagicDamage {
|
||||||
public static final MagicDamage Combat(final MagicSource source,final MagicTarget target,final int amount) {
|
public static final MagicDamage Combat(final MagicSource source,final MagicTarget target,final int amount) {
|
||||||
return new MagicDamage(source, target, amount, true);
|
return new MagicDamage(source, target, amount, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicSource getSource() {
|
public MagicSource getSource() {
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTarget(final MagicTarget target) {
|
public void setTarget(final MagicTarget target) {
|
||||||
this.target=target;
|
this.target=target;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicTarget getTarget() {
|
public MagicTarget getTarget() {
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicPlayer getTargetPlayer() {
|
public MagicPlayer getTargetPlayer() {
|
||||||
return (MagicPlayer)target;
|
return (MagicPlayer)target;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAmount(final int amt) {
|
public void setAmount(final int amt) {
|
||||||
amount = amt;
|
amount = amt;
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ public class MagicDamage {
|
||||||
amount -= amt;
|
amount -= amt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getAmount() {
|
public int getAmount() {
|
||||||
return amount;
|
return amount;
|
||||||
}
|
}
|
||||||
|
@ -60,27 +60,27 @@ public class MagicDamage {
|
||||||
public void setDealtAmount(final int dealtAmount) {
|
public void setDealtAmount(final int dealtAmount) {
|
||||||
this.dealtAmount=dealtAmount;
|
this.dealtAmount=dealtAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getDealtAmount() {
|
public int getDealtAmount() {
|
||||||
return dealtAmount;
|
return dealtAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCombat() {
|
public boolean isCombat() {
|
||||||
return combat;
|
return combat;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUnpreventable() {
|
public void setUnpreventable() {
|
||||||
unpreventable=true;
|
unpreventable=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUnpreventable() {
|
public boolean isUnpreventable() {
|
||||||
return unpreventable;
|
return unpreventable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNoRegeneration() {
|
public void setNoRegeneration() {
|
||||||
noRegeneration=true;
|
noRegeneration=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasNoRegeneration() {
|
public boolean hasNoRegeneration() {
|
||||||
return noRegeneration;
|
return noRegeneration;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import java.util.ArrayList;
|
||||||
public class MagicDeck extends ArrayList<MagicCardDefinition> {
|
public class MagicDeck extends ArrayList<MagicCardDefinition> {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private String name="Unsaved Deck";
|
private String name="Unsaved Deck";
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
|
@ -21,11 +21,11 @@ public class MagicDeck extends ArrayList<MagicCardDefinition> {
|
||||||
addAll(deck);
|
addAll(deck);
|
||||||
name = deck.name;
|
name = deck.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setName(final String name) {
|
public void setName(final String name) {
|
||||||
this.name=name;
|
this.name=name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,31 +4,31 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public enum MagicDeckConstructionRule {
|
public enum MagicDeckConstructionRule {
|
||||||
|
|
||||||
MinDeckSize("Decks must have a least 40 cards."),
|
MinDeckSize("Decks must have a least 40 cards."),
|
||||||
FourCopyLimit("With the exception of basic lands, a deck must have no more than 4 copies of a card.")
|
FourCopyLimit("With the exception of basic lands, a deck must have no more than 4 copies of a card.")
|
||||||
;
|
;
|
||||||
|
|
||||||
public static final int MIN_DECK_SIZE = 40;
|
public static final int MIN_DECK_SIZE = 40;
|
||||||
public static final int MAX_COPIES = 4;
|
public static final int MAX_COPIES = 4;
|
||||||
|
|
||||||
private final String text;
|
private final String text;
|
||||||
|
|
||||||
private MagicDeckConstructionRule(final String text) {
|
private MagicDeckConstructionRule(final String text) {
|
||||||
this.text = text;
|
this.text = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getRuleText() {
|
private String getRuleText() {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<MagicDeckConstructionRule> checkDeck(final MagicDeck deck) {
|
public static List<MagicDeckConstructionRule> checkDeck(final MagicDeck deck) {
|
||||||
final ArrayList<MagicDeckConstructionRule> brokenRules = new ArrayList<MagicDeckConstructionRule>();
|
final ArrayList<MagicDeckConstructionRule> brokenRules = new ArrayList<MagicDeckConstructionRule>();
|
||||||
|
|
||||||
if(deck.size() < MIN_DECK_SIZE) {
|
if(deck.size() < MIN_DECK_SIZE) {
|
||||||
brokenRules.add(MinDeckSize);
|
brokenRules.add(MinDeckSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
final MagicCondensedDeck countedDeck = new MagicCondensedDeck(deck);
|
final MagicCondensedDeck countedDeck = new MagicCondensedDeck(deck);
|
||||||
for(final MagicCondensedCardDefinition countedCard : countedDeck) {
|
for(final MagicCondensedCardDefinition countedCard : countedDeck) {
|
||||||
if(countedCard.getNumCopies() > 4 && !countedCard.getCard().isBasic() && !"Relentless Rats".equals(countedCard.getCard().getName())) {
|
if(countedCard.getNumCopies() > 4 && !countedCard.getCard().isBasic() && !"Relentless Rats".equals(countedCard.getCard().getName())) {
|
||||||
|
@ -36,18 +36,18 @@ public enum MagicDeckConstructionRule {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return brokenRules;
|
return brokenRules;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getRulesText(final List<MagicDeckConstructionRule> rules) {
|
public static String getRulesText(final List<MagicDeckConstructionRule> rules) {
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
for(final MagicDeckConstructionRule rule : rules) {
|
for(final MagicDeckConstructionRule rule : rules) {
|
||||||
sb.append(rule.getRuleText());
|
sb.append(rule.getRuleText());
|
||||||
sb.append("\n");
|
sb.append("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,14 +20,14 @@ import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
public class MagicDuel {
|
public class MagicDuel {
|
||||||
|
|
||||||
private static final String OPPONENT="opponent";
|
private static final String OPPONENT="opponent";
|
||||||
private static final String GAME="game";
|
private static final String GAME="game";
|
||||||
private static final String PLAYED="played";
|
private static final String PLAYED="played";
|
||||||
private static final String WON="won";
|
private static final String WON="won";
|
||||||
private static final String START="start";
|
private static final String START="start";
|
||||||
private static final String COMPUTER="Computer";
|
private static final String COMPUTER="Computer";
|
||||||
|
|
||||||
private final DuelConfig configuration;
|
private final DuelConfig configuration;
|
||||||
private final History history;
|
private final History history;
|
||||||
private MagicPlayerDefinition[] playerDefinitions;
|
private MagicPlayerDefinition[] playerDefinitions;
|
||||||
|
@ -38,27 +38,27 @@ public class MagicDuel {
|
||||||
private int gamesWon;
|
private int gamesWon;
|
||||||
private int startPlayer;
|
private int startPlayer;
|
||||||
private final int[] difficulty = new int[2];
|
private final int[] difficulty = new int[2];
|
||||||
|
|
||||||
public MagicDuel(final DuelConfig configuration) {
|
public MagicDuel(final DuelConfig configuration) {
|
||||||
this.configuration=configuration;
|
this.configuration=configuration;
|
||||||
history = new History(this);
|
history = new History(this);
|
||||||
ais=configuration.getPlayerAIs();
|
ais=configuration.getPlayerAIs();
|
||||||
restart();
|
restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicDuel() {
|
public MagicDuel() {
|
||||||
this(new DuelConfig());
|
this(new DuelConfig());
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicDuel(final DuelConfig configuration,final MagicDuel duel) {
|
public MagicDuel(final DuelConfig configuration,final MagicDuel duel) {
|
||||||
this(configuration);
|
this(configuration);
|
||||||
playerDefinitions=duel.playerDefinitions;
|
playerDefinitions=duel.playerDefinitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DuelConfig getConfiguration() {
|
public DuelConfig getConfiguration() {
|
||||||
return configuration;
|
return configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MagicPlayerDefinition getOpponent() {
|
private MagicPlayerDefinition getOpponent() {
|
||||||
return playerDefinitions[opponentIndex];
|
return playerDefinitions[opponentIndex];
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ public class MagicDuel {
|
||||||
public int getGamesPlayed() {
|
public int getGamesPlayed() {
|
||||||
return gamesPlayed;
|
return gamesPlayed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getGamesTotal() {
|
public int getGamesTotal() {
|
||||||
return (playerDefinitions.length-1)*configuration.getNrOfGames();
|
return (playerDefinitions.length-1)*configuration.getNrOfGames();
|
||||||
}
|
}
|
||||||
|
@ -82,11 +82,11 @@ public class MagicDuel {
|
||||||
private void determineStartPlayer() {
|
private void determineStartPlayer() {
|
||||||
startPlayer=MagicRandom.nextInt(2);
|
startPlayer=MagicRandom.nextInt(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStartPlayer(final int startPlayer) {
|
public void setStartPlayer(final int startPlayer) {
|
||||||
this.startPlayer=startPlayer;
|
this.startPlayer=startPlayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getStartPlayer() {
|
private int getStartPlayer() {
|
||||||
return startPlayer;
|
return startPlayer;
|
||||||
}
|
}
|
||||||
|
@ -98,37 +98,37 @@ public class MagicDuel {
|
||||||
public MagicAI[] getAIs() {
|
public MagicAI[] getAIs() {
|
||||||
return ais;
|
return ais;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDifficulty(final int diff) {
|
public void setDifficulty(final int diff) {
|
||||||
setDifficulty(0,diff);
|
setDifficulty(0,diff);
|
||||||
setDifficulty(1,diff);
|
setDifficulty(1,diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDifficulty(final int idx, final int diff) {
|
public void setDifficulty(final int idx, final int diff) {
|
||||||
difficulty[idx] = diff;
|
difficulty[idx] = diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getDifficulty() {
|
int getDifficulty() {
|
||||||
return getDifficulty(0);
|
return getDifficulty(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int getDifficulty(final int idx) {
|
int getDifficulty(final int idx) {
|
||||||
return difficulty[idx];
|
return difficulty[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateDifficulty() {
|
public void updateDifficulty() {
|
||||||
difficulty[0] = GeneralConfig.getInstance().getDifficulty();
|
difficulty[0] = GeneralConfig.getInstance().getDifficulty();
|
||||||
difficulty[1] = GeneralConfig.getInstance().getDifficulty();
|
difficulty[1] = GeneralConfig.getInstance().getDifficulty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEditable() {
|
public boolean isEditable() {
|
||||||
return gameNr==1;
|
return gameNr==1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isFinished() {
|
public boolean isFinished() {
|
||||||
return getGamesPlayed()==getGamesTotal();
|
return getGamesPlayed()==getGamesTotal();
|
||||||
}
|
}
|
||||||
|
|
||||||
void advance(final boolean won, final MagicGame game) {
|
void advance(final boolean won, final MagicGame game) {
|
||||||
gamesPlayed++;
|
gamesPlayed++;
|
||||||
if (won) {
|
if (won) {
|
||||||
|
@ -147,11 +147,11 @@ public class MagicDuel {
|
||||||
history.update(won,game,configuration);
|
history.update(won,game,configuration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<Integer> getAvatarIndices(final int avatars) {
|
private static List<Integer> getAvatarIndices(final int avatars) {
|
||||||
final List<Integer> indices=new ArrayList<Integer>();
|
final List<Integer> indices=new ArrayList<Integer>();
|
||||||
for (int index=0;index<avatars;index++) {
|
for (int index=0;index<avatars;index++) {
|
||||||
|
|
||||||
indices.add(index);
|
indices.add(index);
|
||||||
}
|
}
|
||||||
return indices;
|
return indices;
|
||||||
|
@ -167,19 +167,19 @@ public class MagicDuel {
|
||||||
final MagicPlayerDefinition player=new MagicPlayerDefinition(configuration.getName(),false,configuration.getPlayerProfile(),playerFace);
|
final MagicPlayerDefinition player=new MagicPlayerDefinition(configuration.getName(),false,configuration.getPlayerProfile(),playerFace);
|
||||||
players[0]=player;
|
players[0]=player;
|
||||||
avatars.remove(playerFace);
|
avatars.remove(playerFace);
|
||||||
|
|
||||||
final int findex=MagicRandom.nextInt(avatars.size());
|
final int findex=MagicRandom.nextInt(avatars.size());
|
||||||
final Integer computerFace=avatars.get(findex);
|
final Integer computerFace=avatars.get(findex);
|
||||||
players[1]=new MagicPlayerDefinition(COMPUTER,true,configuration.getOpponentProfile(),computerFace);
|
players[1]=new MagicPlayerDefinition(COMPUTER,true,configuration.getOpponentProfile(),computerFace);
|
||||||
|
|
||||||
return players;
|
return players;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicGame nextGame(final boolean sound) {
|
public MagicGame nextGame(final boolean sound) {
|
||||||
//create players
|
//create players
|
||||||
final MagicPlayer player = new MagicPlayer(configuration.getStartLife(),playerDefinitions[0],0);
|
final MagicPlayer player = new MagicPlayer(configuration.getStartLife(),playerDefinitions[0],0);
|
||||||
final MagicPlayer opponent = new MagicPlayer(configuration.getStartLife(),playerDefinitions[opponentIndex],1);
|
final MagicPlayer opponent = new MagicPlayer(configuration.getStartLife(),playerDefinitions[opponentIndex],1);
|
||||||
|
|
||||||
//give the AI player extra life
|
//give the AI player extra life
|
||||||
opponent.setLife(opponent.getLife() + GeneralConfig.getInstance().getExtraLife());
|
opponent.setLife(opponent.getLife() + GeneralConfig.getInstance().getExtraLife());
|
||||||
|
|
||||||
|
@ -199,23 +199,23 @@ public class MagicDuel {
|
||||||
opponent.createHandAndLibrary(configuration.getHandSize());
|
opponent.createHandAndLibrary(configuration.getHandSize());
|
||||||
return game;
|
return game;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNrOfPlayers() {
|
public int getNrOfPlayers() {
|
||||||
return playerDefinitions.length;
|
return playerDefinitions.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicPlayerDefinition getPlayer(final int index) {
|
public MagicPlayerDefinition getPlayer(final int index) {
|
||||||
return playerDefinitions[index];
|
return playerDefinitions[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicPlayerDefinition[] getPlayers() {
|
public MagicPlayerDefinition[] getPlayers() {
|
||||||
return playerDefinitions;
|
return playerDefinitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPlayers(final MagicPlayerDefinition[] aPlayerDefinitions) {
|
public void setPlayers(final MagicPlayerDefinition[] aPlayerDefinitions) {
|
||||||
this.playerDefinitions=aPlayerDefinitions;
|
this.playerDefinitions=aPlayerDefinitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void buildDeck(final MagicPlayerDefinition player) {
|
public void buildDeck(final MagicPlayerDefinition player) {
|
||||||
final MagicCubeDefinition cubeDefinition = CubeDefinitions.getCubeDefinition(configuration.getCube());
|
final MagicCubeDefinition cubeDefinition = CubeDefinitions.getCubeDefinition(configuration.getCube());
|
||||||
final DefaultDeckGenerator generator = new DefaultDeckGenerator(cubeDefinition);
|
final DefaultDeckGenerator generator = new DefaultDeckGenerator(cubeDefinition);
|
||||||
|
@ -225,7 +225,7 @@ public class MagicDuel {
|
||||||
player.generateDeck(generator);
|
player.generateDeck(generator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildDecks() {
|
private void buildDecks() {
|
||||||
final MagicCubeDefinition cubeDefinition=CubeDefinitions.getCubeDefinition(configuration.getCube());
|
final MagicCubeDefinition cubeDefinition=CubeDefinitions.getCubeDefinition(configuration.getCube());
|
||||||
final DefaultDeckGenerator generator = new DefaultDeckGenerator(cubeDefinition);
|
final DefaultDeckGenerator generator = new DefaultDeckGenerator(cubeDefinition);
|
||||||
|
@ -237,55 +237,55 @@ public class MagicDuel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
playerDefinitions=createPlayers();
|
playerDefinitions=createPlayers();
|
||||||
buildDecks();
|
buildDecks();
|
||||||
history.loadHistory(configuration.getName());
|
history.loadHistory(configuration.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final File getDuelFile() {
|
public static final File getDuelFile() {
|
||||||
return new File(MagicMain.getGamePath(),"duel.txt");
|
return new File(MagicMain.getGamePath(),"duel.txt");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getPlayerPrefix(final int index) {
|
private static String getPlayerPrefix(final int index) {
|
||||||
return "p"+(index+1)+".";
|
return "p"+(index+1)+".";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void save(final Properties properties) {
|
private void save(final Properties properties) {
|
||||||
configuration.save(properties);
|
configuration.save(properties);
|
||||||
|
|
||||||
properties.setProperty(OPPONENT,Integer.toString(opponentIndex));
|
properties.setProperty(OPPONENT,Integer.toString(opponentIndex));
|
||||||
properties.setProperty(GAME,Integer.toString(gameNr));
|
properties.setProperty(GAME,Integer.toString(gameNr));
|
||||||
properties.setProperty(PLAYED,Integer.toString(gamesPlayed));
|
properties.setProperty(PLAYED,Integer.toString(gamesPlayed));
|
||||||
properties.setProperty(WON,Integer.toString(gamesWon));
|
properties.setProperty(WON,Integer.toString(gamesWon));
|
||||||
properties.setProperty(START,Integer.toString(startPlayer));
|
properties.setProperty(START,Integer.toString(startPlayer));
|
||||||
|
|
||||||
for (int index=0;index<playerDefinitions.length;index++) {
|
for (int index=0;index<playerDefinitions.length;index++) {
|
||||||
playerDefinitions[index].save(properties,getPlayerPrefix(index));
|
playerDefinitions[index].save(properties,getPlayerPrefix(index));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save(final File file) {
|
public void save(final File file) {
|
||||||
final Properties properties=new Properties();
|
final Properties properties=new Properties();
|
||||||
save(properties);
|
save(properties);
|
||||||
try { //save to file
|
try { //save to file
|
||||||
magic.data.FileIO.toFile(file, properties, "Duel");
|
magic.data.FileIO.toFile(file, properties, "Duel");
|
||||||
System.err.println("Saved duel");
|
System.err.println("Saved duel");
|
||||||
} catch (final IOException ex) {
|
} catch (final IOException ex) {
|
||||||
System.err.println("ERROR! Unable save duel to " + file);
|
System.err.println("ERROR! Unable save duel to " + file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void load(final Properties properties) {
|
private void load(final Properties properties) {
|
||||||
configuration.load(properties);
|
configuration.load(properties);
|
||||||
|
|
||||||
opponentIndex=Integer.parseInt(properties.getProperty(OPPONENT,"1"));
|
opponentIndex=Integer.parseInt(properties.getProperty(OPPONENT,"1"));
|
||||||
gameNr=Integer.parseInt(properties.getProperty(GAME,"1"));
|
gameNr=Integer.parseInt(properties.getProperty(GAME,"1"));
|
||||||
gamesPlayed=Integer.parseInt(properties.getProperty(PLAYED,"0"));
|
gamesPlayed=Integer.parseInt(properties.getProperty(PLAYED,"0"));
|
||||||
gamesWon=Integer.parseInt(properties.getProperty(WON,"0"));
|
gamesWon=Integer.parseInt(properties.getProperty(WON,"0"));
|
||||||
startPlayer=Integer.parseInt(properties.getProperty(START,"0"));
|
startPlayer=Integer.parseInt(properties.getProperty(START,"0"));
|
||||||
|
|
||||||
playerDefinitions=new MagicPlayerDefinition[2];
|
playerDefinitions=new MagicPlayerDefinition[2];
|
||||||
for (int index=0;index<playerDefinitions.length;index++) {
|
for (int index=0;index<playerDefinitions.length;index++) {
|
||||||
playerDefinitions[index]=new MagicPlayerDefinition();
|
playerDefinitions[index]=new MagicPlayerDefinition();
|
||||||
|
@ -293,11 +293,11 @@ public class MagicDuel {
|
||||||
}
|
}
|
||||||
history.loadHistory(configuration.getName());
|
history.loadHistory(configuration.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void load(final File file) {
|
public void load(final File file) {
|
||||||
load(magic.data.FileIO.toProp(file));
|
load(magic.data.FileIO.toProp(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void restart() {
|
public void restart() {
|
||||||
opponentIndex=1;
|
opponentIndex=1;
|
||||||
gameNr=1;
|
gameNr=1;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -10,12 +10,12 @@ import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
public class MagicGameLog {
|
public class MagicGameLog {
|
||||||
|
|
||||||
private static final String gameLog = MagicMain.getGamePath() + File.separator + "game.log";
|
private static final String gameLog = MagicMain.getGamePath() + File.separator + "game.log";
|
||||||
private static PrintWriter writer;
|
private static PrintWriter writer;
|
||||||
|
|
||||||
private MagicGameLog() {}
|
private MagicGameLog() {}
|
||||||
|
|
||||||
public static void initialize() {
|
public static void initialize() {
|
||||||
try {
|
try {
|
||||||
writer = new PrintWriter(gameLog);
|
writer = new PrintWriter(gameLog);
|
||||||
|
@ -35,14 +35,14 @@ public class MagicGameLog {
|
||||||
System.err.println("Unable to create game log");
|
System.err.println("Unable to create game log");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void log(final String message) {
|
public static void log(final String message) {
|
||||||
if (writer != null) {
|
if (writer != null) {
|
||||||
writer.println(message);
|
writer.println(message);
|
||||||
writer.flush();
|
writer.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void close() {
|
public static void close() {
|
||||||
if (writer != null) {
|
if (writer != null) {
|
||||||
writer.close();
|
writer.close();
|
||||||
|
|
|
@ -14,7 +14,7 @@ import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
public class MagicGameReport implements Thread.UncaughtExceptionHandler {
|
public class MagicGameReport implements Thread.UncaughtExceptionHandler {
|
||||||
|
|
||||||
public void uncaughtException(final Thread th, final Throwable ex) {
|
public void uncaughtException(final Thread th, final Throwable ex) {
|
||||||
MagicGameReport.buildReport(MagicGame.getInstance(), th, ex);
|
MagicGameReport.buildReport(MagicGame.getInstance(), th, ex);
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
|
@ -23,7 +23,7 @@ public class MagicGameReport implements Thread.UncaughtExceptionHandler {
|
||||||
private static void buildCard(final MagicGame game,final String place,final MagicCard card,final StringBuilder report) {
|
private static void buildCard(final MagicGame game,final String place,final MagicCard card,final StringBuilder report) {
|
||||||
report.append(" - ").append(place).append(" : ").append(card.getName()).append("\n");
|
report.append(" - ").append(place).append(" : ").append(card.getName()).append("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void buildPermanent(final MagicGame game,final MagicPermanent permanent,final StringBuilder report) {
|
private static void buildPermanent(final MagicGame game,final MagicPermanent permanent,final StringBuilder report) {
|
||||||
report.append(" - Permanent : ").append(permanent.getName());
|
report.append(" - Permanent : ").append(permanent.getName());
|
||||||
if (permanent.isCreature()) {
|
if (permanent.isCreature()) {
|
||||||
|
@ -40,7 +40,7 @@ public class MagicGameReport implements Thread.UncaughtExceptionHandler {
|
||||||
}
|
}
|
||||||
report.append("\n");
|
report.append("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void buildPlayer(final MagicGame game,final MagicPlayer player,final StringBuilder report) {
|
private static void buildPlayer(final MagicGame game,final MagicPlayer player,final StringBuilder report) {
|
||||||
report.append(player.getIndex()).append("] ");
|
report.append(player.getIndex()).append("] ");
|
||||||
report.append("Player : ").append(player.getName());
|
report.append("Player : ").append(player.getName());
|
||||||
|
@ -55,12 +55,12 @@ public class MagicGameReport implements Thread.UncaughtExceptionHandler {
|
||||||
for (final MagicCard card: player.getGraveyard()) {
|
for (final MagicCard card: player.getGraveyard()) {
|
||||||
buildCard(game,"Graveyard",card,report);
|
buildCard(game,"Graveyard",card,report);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final MagicPermanent permanent : player.getPermanents()) {
|
for (final MagicPermanent permanent : player.getPermanents()) {
|
||||||
buildPermanent(game,permanent,report);
|
buildPermanent(game,permanent,report);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void buildStack(final MagicGame game,final StringBuilder report) {
|
private static void buildStack(final MagicGame game,final StringBuilder report) {
|
||||||
report.append("Stack : ").append(game.getStack().size()).append('\n');
|
report.append("Stack : ").append(game.getStack().size()).append('\n');
|
||||||
for (final MagicItemOnStack itemOnStack : game.getStack()) {
|
for (final MagicItemOnStack itemOnStack : game.getStack()) {
|
||||||
|
@ -85,7 +85,7 @@ public class MagicGameReport implements Thread.UncaughtExceptionHandler {
|
||||||
}
|
}
|
||||||
report.append("Score = ").append(totalScore).append("\n");
|
report.append("Score = ").append(totalScore).append("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String buildReport(final MagicGame game) {
|
private static String buildReport(final MagicGame game) {
|
||||||
final StringBuilder report=new StringBuilder();
|
final StringBuilder report=new StringBuilder();
|
||||||
report.append("Turn : ").append(game.getTurn());
|
report.append("Turn : ").append(game.getTurn());
|
||||||
|
@ -94,13 +94,13 @@ public class MagicGameReport implements Thread.UncaughtExceptionHandler {
|
||||||
report.append(" Player : ").append(game.getTurnPlayer());
|
report.append(" Player : ").append(game.getTurnPlayer());
|
||||||
report.append(" Score : ").append(game.getScore());
|
report.append(" Score : ").append(game.getScore());
|
||||||
report.append("\n");
|
report.append("\n");
|
||||||
|
|
||||||
for (final MagicPlayer player : game.getPlayers()) {
|
for (final MagicPlayer player : game.getPlayers()) {
|
||||||
buildPlayer(game,player,report);
|
buildPlayer(game,player,report);
|
||||||
}
|
}
|
||||||
|
|
||||||
buildStack(game,report);
|
buildStack(game,report);
|
||||||
buildScore(game,report);
|
buildScore(game,report);
|
||||||
return report.toString();
|
return report.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ public class MagicGameReport implements Thread.UncaughtExceptionHandler {
|
||||||
//save a copy to a crash log file
|
//save a copy to a crash log file
|
||||||
final File clog = new File(MagicMain.getGamePath(), "crash.log");
|
final File clog = new File(MagicMain.getGamePath(), "crash.log");
|
||||||
try {
|
try {
|
||||||
FileIO.toFile(clog, sb.toString(), true);
|
FileIO.toFile(clog, sb.toString(), true);
|
||||||
} catch (final IOException ex3) {
|
} catch (final IOException ex3) {
|
||||||
System.err.println("Unable to save crash log");
|
System.err.println("Unable to save crash log");
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,6 @@ public enum MagicIdentifierType {
|
||||||
Permanent,
|
Permanent,
|
||||||
PermanentTrigger,
|
PermanentTrigger,
|
||||||
ItemOnStack;
|
ItemOnStack;
|
||||||
|
|
||||||
public static final int NR_OF_IDENTIFIERS=values().length;
|
public static final int NR_OF_IDENTIFIERS=values().length;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ public class MagicLogBook extends ArrayList<MagicMessage> {
|
||||||
}
|
}
|
||||||
return super.add(msg);
|
return super.add(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Removes all messages from end to given index, inclusive. */
|
/** Removes all messages from end to given index, inclusive. */
|
||||||
public synchronized void removeTo(final int toIndex) {
|
public synchronized void removeTo(final int toIndex) {
|
||||||
for (int index=size()-1;index>=toIndex;index--) {
|
for (int index=size()-1;index>=toIndex;index--) {
|
||||||
|
|
|
@ -4,12 +4,12 @@ public class MagicLogMessageBuilder {
|
||||||
|
|
||||||
private final MagicGame game;
|
private final MagicGame game;
|
||||||
private final StringBuilder[] messageBuilders;
|
private final StringBuilder[] messageBuilders;
|
||||||
|
|
||||||
MagicLogMessageBuilder(final MagicGame game) {
|
MagicLogMessageBuilder(final MagicGame game) {
|
||||||
this.game=game;
|
this.game=game;
|
||||||
messageBuilders=new StringBuilder[]{new StringBuilder(),new StringBuilder()};
|
messageBuilders=new StringBuilder[]{new StringBuilder(),new StringBuilder()};
|
||||||
}
|
}
|
||||||
|
|
||||||
void appendMessage(final MagicPlayer player,final String message) {
|
void appendMessage(final MagicPlayer player,final String message) {
|
||||||
final StringBuilder messageBuilder=messageBuilders[player.getIndex()];
|
final StringBuilder messageBuilder=messageBuilders[player.getIndex()];
|
||||||
if (messageBuilder.length()>0) {
|
if (messageBuilder.length()>0) {
|
||||||
|
@ -17,7 +17,7 @@ public class MagicLogMessageBuilder {
|
||||||
}
|
}
|
||||||
messageBuilder.append(message);
|
messageBuilder.append(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void logMessages() {
|
void logMessages() {
|
||||||
for (final MagicPlayer player : game.getPlayers()) {
|
for (final MagicPlayer player : game.getPlayers()) {
|
||||||
final StringBuilder messageBuilder=messageBuilders[player.getIndex()];
|
final StringBuilder messageBuilder=messageBuilders[player.getIndex()];
|
||||||
|
@ -27,7 +27,7 @@ public class MagicLogMessageBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearMessages() {
|
void clearMessages() {
|
||||||
messageBuilders[0].setLength(0);
|
messageBuilders[0].setLength(0);
|
||||||
messageBuilders[1].setLength(0);
|
messageBuilders[1].setLength(0);
|
||||||
|
|
|
@ -22,7 +22,7 @@ public class MagicManaCost {
|
||||||
|
|
||||||
private static final int[] SINGLE_PENALTY={0,1,1,3,6,9};
|
private static final int[] SINGLE_PENALTY={0,1,1,3,6,9};
|
||||||
private static final int[] DOUBLE_PENALTY={0,0,1,2,4,6};
|
private static final int[] DOUBLE_PENALTY={0,0,1,2,4,6};
|
||||||
|
|
||||||
private static final ImageIcon[] COLORLESS_ICONS={
|
private static final ImageIcon[] COLORLESS_ICONS={
|
||||||
IconImages.COST_ZERO,
|
IconImages.COST_ZERO,
|
||||||
IconImages.COST_ONE,
|
IconImages.COST_ONE,
|
||||||
|
@ -42,7 +42,7 @@ public class MagicManaCost {
|
||||||
IconImages.COST_FIFTEEN,
|
IconImages.COST_FIFTEEN,
|
||||||
IconImages.COST_SIXTEEN
|
IconImages.COST_SIXTEEN
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final MagicManaCost ZERO=MagicManaCost.create("{0}");
|
public static final MagicManaCost ZERO=MagicManaCost.create("{0}");
|
||||||
|
|
||||||
private final String costText;
|
private final String costText;
|
||||||
|
@ -65,13 +65,13 @@ public class MagicManaCost {
|
||||||
while (matcher.find()) {
|
while (matcher.find()) {
|
||||||
addType(matcher.group(), XCountArr, convertedArr);
|
addType(matcher.group(), XCountArr, convertedArr);
|
||||||
}
|
}
|
||||||
|
|
||||||
XCount = XCountArr[0];
|
XCount = XCountArr[0];
|
||||||
converted = convertedArr[0];
|
converted = convertedArr[0];
|
||||||
|
|
||||||
//assert getCanonicalText().equals(costText) : "canonical: " + getCanonicalText() + " != cost: " + costText;
|
//assert getCanonicalText().equals(costText) : "canonical: " + getCanonicalText() + " != cost: " + costText;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addType(final MagicCostManaType type,final int amount,final int[] convertedArr) {
|
private void addType(final MagicCostManaType type,final int amount,final int[] convertedArr) {
|
||||||
convertedArr[0] += amount;
|
convertedArr[0] += amount;
|
||||||
amounts[type.ordinal()] += amount;
|
amounts[type.ordinal()] += amount;
|
||||||
|
@ -79,7 +79,7 @@ public class MagicManaCost {
|
||||||
order.add(type);
|
order.add(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addType(final String typeText, final int[] XCountArr, final int[] convertedArr) {
|
private void addType(final String typeText, final int[] XCountArr, final int[] convertedArr) {
|
||||||
final String symbol = typeText.substring(1, typeText.length() - 1);
|
final String symbol = typeText.substring(1, typeText.length() - 1);
|
||||||
if ("X".equals(symbol)) {
|
if ("X".equals(symbol)) {
|
||||||
|
@ -96,7 +96,7 @@ public class MagicManaCost {
|
||||||
throw new RuntimeException("Invalid cost \"" + costText + "\"");
|
throw new RuntimeException("Invalid cost \"" + costText + "\"");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isNumeric(final String str) {
|
private static boolean isNumeric(final String str) {
|
||||||
for (final char c : str.toCharArray()) {
|
for (final char c : str.toCharArray()) {
|
||||||
if (!Character.isDigit(c)) {
|
if (!Character.isDigit(c)) {
|
||||||
|
@ -109,19 +109,19 @@ public class MagicManaCost {
|
||||||
public String getText() {
|
public String getText() {
|
||||||
return costText;
|
return costText;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return costText;
|
return costText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getXCount() {
|
public int getXCount() {
|
||||||
return XCount;
|
return XCount;
|
||||||
}
|
}
|
||||||
public boolean hasX() {
|
public boolean hasX() {
|
||||||
return XCount > 0;
|
return XCount > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<MagicCostManaType> getCostManaTypes(final int x) {
|
public List<MagicCostManaType> getCostManaTypes(final int x) {
|
||||||
final List<MagicCostManaType> types=new ArrayList<MagicCostManaType>();
|
final List<MagicCostManaType> types=new ArrayList<MagicCostManaType>();
|
||||||
int colorless=x;
|
int colorless=x;
|
||||||
|
@ -136,14 +136,14 @@ public class MagicManaCost {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;colorless>0;colorless--) {
|
for (;colorless>0;colorless--) {
|
||||||
types.add(MagicCostManaType.Colorless);
|
types.add(MagicCostManaType.Colorless);
|
||||||
}
|
}
|
||||||
|
|
||||||
return types;
|
return types;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getColorFlags() {
|
public int getColorFlags() {
|
||||||
int colorFlags = 0;
|
int colorFlags = 0;
|
||||||
for (final MagicCostManaType costType : order) {
|
for (final MagicCostManaType costType : order) {
|
||||||
|
@ -155,7 +155,7 @@ public class MagicManaCost {
|
||||||
}
|
}
|
||||||
return colorFlags;
|
return colorFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getCanonicalText() {
|
private String getCanonicalText() {
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
//add X
|
//add X
|
||||||
|
@ -248,9 +248,9 @@ public class MagicManaCost {
|
||||||
icons.add(icon);
|
icons.add(icon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ImageIcon> getIcons() {
|
public List<ImageIcon> getIcons() {
|
||||||
if (icons == null) {
|
if (icons == null) {
|
||||||
icons=new ArrayList<ImageIcon>();
|
icons=new ArrayList<ImageIcon>();
|
||||||
|
@ -258,7 +258,7 @@ public class MagicManaCost {
|
||||||
}
|
}
|
||||||
return icons;
|
return icons;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getCostScore(final MagicPlayerProfile profile) {
|
int getCostScore(final MagicPlayerProfile profile) {
|
||||||
final int[] singleCounts=new int[MagicManaType.NR_OF_TYPES];
|
final int[] singleCounts=new int[MagicManaType.NR_OF_TYPES];
|
||||||
int doubleCount=0;
|
int doubleCount=0;
|
||||||
|
@ -284,11 +284,11 @@ public class MagicManaCost {
|
||||||
}
|
}
|
||||||
return 2*converted+3*(10-SINGLE_PENALTY[maxSingleCount]-DOUBLE_PENALTY[doubleCount]);
|
return 2*converted+3*(10-SINGLE_PENALTY[maxSingleCount]-DOUBLE_PENALTY[doubleCount]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getConvertedCost() {
|
public int getConvertedCost() {
|
||||||
return converted;
|
return converted;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicBuilderManaCost getBuilderCost() {
|
public MagicBuilderManaCost getBuilderCost() {
|
||||||
if (builderCost == null) {
|
if (builderCost == null) {
|
||||||
builderCost=new MagicBuilderManaCost();
|
builderCost=new MagicBuilderManaCost();
|
||||||
|
@ -296,17 +296,17 @@ public class MagicManaCost {
|
||||||
}
|
}
|
||||||
return builderCost;
|
return builderCost;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addTo(final MagicBuilderManaCost aBuilderCost) {
|
public void addTo(final MagicBuilderManaCost aBuilderCost) {
|
||||||
for (final MagicCostManaType type : order) {
|
for (final MagicCostManaType type : order) {
|
||||||
aBuilderCost.addType(type,amounts[type.ordinal()]);
|
aBuilderCost.addType(type,amounts[type.ordinal()]);
|
||||||
}
|
}
|
||||||
if (hasX()) {
|
if (hasX()) {
|
||||||
aBuilderCost.setXCount(XCount);
|
aBuilderCost.setXCount(XCount);
|
||||||
}
|
}
|
||||||
aBuilderCost.compress();
|
aBuilderCost.compress();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addTo(final MagicBuilderManaCost aBuilderCost,final int x) {
|
public void addTo(final MagicBuilderManaCost aBuilderCost,final int x) {
|
||||||
for (final MagicCostManaType type : order) {
|
for (final MagicCostManaType type : order) {
|
||||||
aBuilderCost.addType(type,amounts[type.ordinal()]);
|
aBuilderCost.addType(type,amounts[type.ordinal()]);
|
||||||
|
@ -314,7 +314,7 @@ public class MagicManaCost {
|
||||||
aBuilderCost.addType(MagicCostManaType.Colorless,x);
|
aBuilderCost.addType(MagicCostManaType.Colorless,x);
|
||||||
aBuilderCost.compress();
|
aBuilderCost.compress();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicCondition getCondition() {
|
public MagicCondition getCondition() {
|
||||||
MagicCondition cond = CONDS_MAP.get(costText);
|
MagicCondition cond = CONDS_MAP.get(costText);
|
||||||
if (cond == null) {
|
if (cond == null) {
|
||||||
|
@ -323,7 +323,7 @@ public class MagicManaCost {
|
||||||
}
|
}
|
||||||
return cond;
|
return cond;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MagicManaCost create(final String costText) {
|
public static MagicManaCost create(final String costText) {
|
||||||
MagicManaCost cost = COSTS_MAP.get(costText);
|
MagicManaCost cost = COSTS_MAP.get(costText);
|
||||||
if (cost == null) {
|
if (cost == null) {
|
||||||
|
|
|
@ -17,17 +17,17 @@ public enum MagicManaType {
|
||||||
White("white","{W}"),
|
White("white","{W}"),
|
||||||
NONE("none","{N}"),
|
NONE("none","{N}"),
|
||||||
;
|
;
|
||||||
|
|
||||||
public static final List<MagicManaType> ALL_COLORS = Collections.unmodifiableList(Arrays.asList(
|
public static final List<MagicManaType> ALL_COLORS = Collections.unmodifiableList(Arrays.asList(
|
||||||
Black,Blue,Green,Red,White));
|
Black,Blue,Green,Red,White));
|
||||||
public static final List<MagicManaType> ALL_TYPES = Collections.unmodifiableList(Arrays.asList(
|
public static final List<MagicManaType> ALL_TYPES = Collections.unmodifiableList(Arrays.asList(
|
||||||
Colorless,Black,Blue,Green,Red,White)); // Colorless must be in front.
|
Colorless,Black,Blue,Green,Red,White)); // Colorless must be in front.
|
||||||
|
|
||||||
public static final int NR_OF_TYPES = ALL_TYPES.size();
|
public static final int NR_OF_TYPES = ALL_TYPES.size();
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private final String text;
|
private final String text;
|
||||||
|
|
||||||
private MagicManaType(final String name, final String text) {
|
private MagicManaType(final String name, final String text) {
|
||||||
this.name=name;
|
this.name=name;
|
||||||
this.text=text;
|
this.text=text;
|
||||||
|
@ -36,15 +36,15 @@ public enum MagicManaType {
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
return this != MagicManaType.NONE;
|
return this != MagicManaType.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getText() {
|
public String getText() {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MagicManaType get(final String name) {
|
public static MagicManaType get(final String name) {
|
||||||
for (final MagicManaType type : values()) {
|
for (final MagicManaType type : values()) {
|
||||||
if (type.toString().equalsIgnoreCase(name)) {
|
if (type.toString().equalsIgnoreCase(name)) {
|
||||||
|
@ -53,7 +53,7 @@ public enum MagicManaType {
|
||||||
}
|
}
|
||||||
throw new RuntimeException("Unknown mana type " + name);
|
throw new RuntimeException("Unknown mana type " + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<MagicManaType> getList(final String name) {
|
public static List<MagicManaType> getList(final String name) {
|
||||||
if ("{1}".equals(name)) {
|
if ("{1}".equals(name)) {
|
||||||
return Arrays.asList(Colorless);
|
return Arrays.asList(Colorless);
|
||||||
|
@ -74,7 +74,7 @@ public enum MagicManaType {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicColor getColor() {
|
public MagicColor getColor() {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case Black: return MagicColor.Black;
|
case Black: return MagicColor.Black;
|
||||||
|
@ -85,7 +85,7 @@ public enum MagicManaType {
|
||||||
}
|
}
|
||||||
throw new RuntimeException("No color available for MagicManaType " + this);
|
throw new RuntimeException("No color available for MagicManaType " + this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImageIcon getIcon(final boolean small) {
|
public ImageIcon getIcon(final boolean small) {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case Colorless: return small?IconImages.COST_ONE:IconImages.ONE;
|
case Colorless: return small?IconImages.COST_ONE:IconImages.ONE;
|
||||||
|
|
|
@ -12,7 +12,7 @@ public class MagicMessage {
|
||||||
private final int turn;
|
private final int turn;
|
||||||
private final MagicPhaseType phaseType;
|
private final MagicPhaseType phaseType;
|
||||||
private final String text;
|
private final String text;
|
||||||
|
|
||||||
MagicMessage(final MagicGame game,final MagicPlayer player,final String text) {
|
MagicMessage(final MagicGame game,final MagicPlayer player,final String text) {
|
||||||
this.player=player;
|
this.player=player;
|
||||||
this.life=player.getLife();
|
this.life=player.getLife();
|
||||||
|
@ -24,19 +24,19 @@ public class MagicMessage {
|
||||||
public MagicPlayer getPlayer() {
|
public MagicPlayer getPlayer() {
|
||||||
return player;
|
return player;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLife() {
|
public int getLife() {
|
||||||
return life;
|
return life;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTurn() {
|
public int getTurn() {
|
||||||
return turn;
|
return turn;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicPhaseType getPhaseType() {
|
public MagicPhaseType getPhaseType() {
|
||||||
return phaseType;
|
return phaseType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getText() {
|
public String getText() {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ public class MagicMessage {
|
||||||
final Iterator<String> iterator=names.iterator();
|
final Iterator<String> iterator=names.iterator();
|
||||||
do {
|
do {
|
||||||
final String name=iterator.next();
|
final String name=iterator.next();
|
||||||
next=iterator.hasNext();
|
next=iterator.hasNext();
|
||||||
if (first) {
|
if (first) {
|
||||||
first=false;
|
first=false;
|
||||||
} else if (next) {
|
} else if (next) {
|
||||||
|
@ -60,14 +60,14 @@ public class MagicMessage {
|
||||||
} while (next);
|
} while (next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String replaceName(final String sourceText,final Object source, final Object player, final Object ref) {
|
public static String replaceName(final String sourceText,final Object source, final Object player, final Object ref) {
|
||||||
return sourceText
|
return sourceText
|
||||||
.replaceAll("PN", player.toString())
|
.replaceAll("PN", player.toString())
|
||||||
.replaceAll("SN", source.toString())
|
.replaceAll("SN", source.toString())
|
||||||
.replaceAll("RN", ref.toString());
|
.replaceAll("RN", ref.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String replaceChoices(final String sourceText,final Object[] choices) {
|
public static String replaceChoices(final String sourceText,final Object[] choices) {
|
||||||
String result = sourceText;
|
String result = sourceText;
|
||||||
for (int idx = 0; result.indexOf('$') >= 0; idx++) {
|
for (int idx = 0; result.indexOf('$') >= 0; idx++) {
|
||||||
|
|
|
@ -8,49 +8,49 @@ import magic.model.MagicCopyable;
|
||||||
public class MagicPayedCost implements MagicCopyable {
|
public class MagicPayedCost implements MagicCopyable {
|
||||||
|
|
||||||
public static final MagicPayedCost NO_COST = new MagicPayedCost();
|
public static final MagicPayedCost NO_COST = new MagicPayedCost();
|
||||||
|
|
||||||
private MagicTarget target;
|
private MagicTarget target;
|
||||||
private int x;
|
private int x;
|
||||||
private int kicker;
|
private int kicker;
|
||||||
|
|
||||||
public MagicPayedCost() {
|
public MagicPayedCost() {
|
||||||
target = MagicTargetNone.getInstance();
|
target = MagicTargetNone.getInstance();
|
||||||
x = 0;
|
x = 0;
|
||||||
kicker = 0;
|
kicker = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicPayedCost(final MagicPayedCost payedCost) {
|
public MagicPayedCost(final MagicPayedCost payedCost) {
|
||||||
target = payedCost.target;
|
target = payedCost.target;
|
||||||
x = payedCost.x;
|
x = payedCost.x;
|
||||||
kicker = payedCost.kicker;
|
kicker = payedCost.kicker;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicPayedCost(final MagicCopyMap copyMap,final MagicPayedCost payedCost) {
|
public MagicPayedCost(final MagicCopyMap copyMap,final MagicPayedCost payedCost) {
|
||||||
target = copyMap.copy(payedCost.target);
|
target = copyMap.copy(payedCost.target);
|
||||||
x = payedCost.x;
|
x = payedCost.x;
|
||||||
kicker = payedCost.kicker;
|
kicker = payedCost.kicker;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicCopyable copy(final MagicCopyMap copyMap) {
|
public MagicCopyable copy(final MagicCopyMap copyMap) {
|
||||||
return new MagicPayedCost(copyMap, this);
|
return new MagicPayedCost(copyMap, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setTarget(final MagicTarget target) {
|
private void setTarget(final MagicTarget target) {
|
||||||
this.target = target;
|
this.target = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicTarget getTarget() {
|
public MagicTarget getTarget() {
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setX(final int x) {
|
private void setX(final int x) {
|
||||||
this.x = x;
|
this.x = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getX() {
|
public int getX() {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(final Object choiceResult) {
|
void set(final Object choiceResult) {
|
||||||
if (choiceResult instanceof MagicTarget) {
|
if (choiceResult instanceof MagicTarget) {
|
||||||
setTarget((MagicTarget)choiceResult);
|
setTarget((MagicTarget)choiceResult);
|
||||||
|
@ -58,7 +58,7 @@ public class MagicPayedCost implements MagicCopyable {
|
||||||
setX(((MagicPayManaCostResult)choiceResult).getX());
|
setX(((MagicPayManaCostResult)choiceResult).getX());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setKicker(final int aKicker) {
|
public void setKicker(final int aKicker) {
|
||||||
kicker = aKicker;
|
kicker = aKicker;
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ public class MagicPayedCost implements MagicCopyable {
|
||||||
public int getKicker() {
|
public int getKicker() {
|
||||||
return kicker;
|
return kicker;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isKicked() {
|
public boolean isKicked() {
|
||||||
return kicker > 0;
|
return kicker > 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,22 +36,22 @@ import java.util.Collections;
|
||||||
public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicPermanent> {
|
public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicPermanent> {
|
||||||
|
|
||||||
public static final int NO_COLOR_FLAGS=-1;
|
public static final int NO_COLOR_FLAGS=-1;
|
||||||
|
|
||||||
private final long id;
|
private final long id;
|
||||||
private final MagicCardDefinition cardDefinition;
|
private final MagicCardDefinition cardDefinition;
|
||||||
private final MagicCard card;
|
private final MagicCard card;
|
||||||
private final MagicPlayer firstController;
|
private final MagicPlayer firstController;
|
||||||
private MagicPermanent equippedCreature = MagicPermanent.NONE;
|
private MagicPermanent equippedCreature = MagicPermanent.NONE;
|
||||||
private final MagicPermanentSet equipmentPermanents;
|
private final MagicPermanentSet equipmentPermanents;
|
||||||
private MagicPermanent enchantedCreature = MagicPermanent.NONE;
|
private MagicPermanent enchantedCreature = MagicPermanent.NONE;
|
||||||
private final MagicPermanentSet auraPermanents;
|
private final MagicPermanentSet auraPermanents;
|
||||||
private MagicPermanent blockedCreature = MagicPermanent.NONE;
|
private MagicPermanent blockedCreature = MagicPermanent.NONE;
|
||||||
private final MagicPermanentList blockingCreatures;
|
private final MagicPermanentList blockingCreatures;
|
||||||
private MagicPermanent pairedCreature = MagicPermanent.NONE;
|
private MagicPermanent pairedCreature = MagicPermanent.NONE;
|
||||||
private final MagicCardList exiledCards;
|
private final MagicCardList exiledCards;
|
||||||
private MagicTarget chosenTarget = MagicTargetNone.getInstance();
|
private MagicTarget chosenTarget = MagicTargetNone.getInstance();
|
||||||
private int[] counters=new int[MagicCounterType.NR_COUNTERS];
|
private int[] counters=new int[MagicCounterType.NR_COUNTERS];
|
||||||
private int stateFlags =
|
private int stateFlags =
|
||||||
MagicPermanentState.Summoned.getMask() |
|
MagicPermanentState.Summoned.getMask() |
|
||||||
MagicPermanentState.MustPayEchoCost.getMask();
|
MagicPermanentState.MustPayEchoCost.getMask();
|
||||||
private int abilityPlayedThisTurn;
|
private int abilityPlayedThisTurn;
|
||||||
|
@ -78,7 +78,7 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
card = aCard;
|
card = aCard;
|
||||||
cardDefinition = card.getCardDefinition();
|
cardDefinition = card.getCardDefinition();
|
||||||
firstController = aController;
|
firstController = aController;
|
||||||
|
|
||||||
equipmentPermanents=new MagicPermanentSet();
|
equipmentPermanents=new MagicPermanentSet();
|
||||||
auraPermanents=new MagicPermanentSet();
|
auraPermanents=new MagicPermanentSet();
|
||||||
blockingCreatures=new MagicPermanentList();
|
blockingCreatures=new MagicPermanentList();
|
||||||
|
@ -88,9 +88,9 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
private MagicPermanent(final MagicCopyMap copyMap, final MagicPermanent sourcePermanent) {
|
private MagicPermanent(final MagicCopyMap copyMap, final MagicPermanent sourcePermanent) {
|
||||||
id = sourcePermanent.id;
|
id = sourcePermanent.id;
|
||||||
cardDefinition = sourcePermanent.cardDefinition;
|
cardDefinition = sourcePermanent.cardDefinition;
|
||||||
|
|
||||||
copyMap.put(sourcePermanent, this);
|
copyMap.put(sourcePermanent, this);
|
||||||
|
|
||||||
card = copyMap.copy(sourcePermanent.card);
|
card = copyMap.copy(sourcePermanent.card);
|
||||||
firstController = copyMap.copy(sourcePermanent.firstController);
|
firstController = copyMap.copy(sourcePermanent.firstController);
|
||||||
stateFlags=sourcePermanent.stateFlags;
|
stateFlags=sourcePermanent.stateFlags;
|
||||||
|
@ -110,7 +110,7 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
fixedScore=sourcePermanent.fixedScore;
|
fixedScore=sourcePermanent.fixedScore;
|
||||||
score=sourcePermanent.score;
|
score=sourcePermanent.score;
|
||||||
stateId=sourcePermanent.stateId;
|
stateId=sourcePermanent.stateId;
|
||||||
|
|
||||||
cachedController = copyMap.copy(sourcePermanent.cachedController);
|
cachedController = copyMap.copy(sourcePermanent.cachedController);
|
||||||
cachedTypeFlags = sourcePermanent.cachedTypeFlags;
|
cachedTypeFlags = sourcePermanent.cachedTypeFlags;
|
||||||
cachedSubTypeFlags = sourcePermanent.cachedSubTypeFlags;
|
cachedSubTypeFlags = sourcePermanent.cachedSubTypeFlags;
|
||||||
|
@ -118,18 +118,18 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
cachedAbilityFlags = sourcePermanent.cachedAbilityFlags;
|
cachedAbilityFlags = sourcePermanent.cachedAbilityFlags;
|
||||||
cachedPowerToughness = sourcePermanent.cachedPowerToughness;
|
cachedPowerToughness = sourcePermanent.cachedPowerToughness;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MagicPermanent copy(final MagicCopyMap copyMap) {
|
public MagicPermanent copy(final MagicCopyMap copyMap) {
|
||||||
return new MagicPermanent(copyMap, this);
|
return new MagicPermanent(copyMap, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MagicPermanent map(final MagicGame game) {
|
public MagicPermanent map(final MagicGame game) {
|
||||||
final MagicPlayer mappedController=getController().map(game);
|
final MagicPlayer mappedController=getController().map(game);
|
||||||
return mappedController.getPermanents().getPermanent(id);
|
return mappedController.getPermanents().getPermanent(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getId() {
|
public long getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
@ -137,11 +137,11 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInvalid() {
|
public boolean isInvalid() {
|
||||||
return !isValid();
|
return !isValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getStateId() {
|
public long getStateId() {
|
||||||
stateId = stateId != 0 ? stateId : magic.MurmurHash3.hash(new long[] {
|
stateId = stateId != 0 ? stateId : magic.MurmurHash3.hash(new long[] {
|
||||||
cardDefinition.getIndex(),
|
cardDefinition.getIndex(),
|
||||||
|
@ -170,39 +170,39 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
});
|
});
|
||||||
return stateId;
|
return stateId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Determines uniqueness of a mana permanent, e.g. for producing mana, all Mountains are equal. */
|
/** Determines uniqueness of a mana permanent, e.g. for producing mana, all Mountains are equal. */
|
||||||
public int getManaId() {
|
public int getManaId() {
|
||||||
// Creatures or lands that can be animated are unique by default.
|
// Creatures or lands that can be animated are unique by default.
|
||||||
if (cardDefinition.hasExcludeManaOrCombat()) {
|
if (cardDefinition.hasExcludeManaOrCombat()) {
|
||||||
return (int)id;
|
return (int)id;
|
||||||
}
|
}
|
||||||
// Uniqueness is determined by card definition and number of charge counters.
|
// Uniqueness is determined by card definition and number of charge counters.
|
||||||
return -((cardDefinition.getIndex()<<16)+getCounters(MagicCounterType.Charge));
|
return -((cardDefinition.getIndex()<<16)+getCounters(MagicCounterType.Charge));
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicCard getCard() {
|
public MagicCard getCard() {
|
||||||
return card;
|
return card;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isToken() {
|
public boolean isToken() {
|
||||||
return card.isToken();
|
return card.isToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isNonToken() {
|
public boolean isNonToken() {
|
||||||
return !card.isToken();
|
return !card.isToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MagicCardDefinition getCardDefinition() {
|
public MagicCardDefinition getCardDefinition() {
|
||||||
return cardDefinition;
|
return cardDefinition;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<MagicActivation> getActivations() {
|
public Collection<MagicActivation> getActivations() {
|
||||||
return cardDefinition.getActivations();
|
return cardDefinition.getActivations();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<MagicManaActivation> getManaActivations() {
|
public Collection<MagicManaActivation> getManaActivations() {
|
||||||
return cardDefinition.getManaActivations();
|
return cardDefinition.getManaActivations();
|
||||||
}
|
}
|
||||||
|
@ -210,11 +210,11 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
public Collection<MagicStatic> getStatics() {
|
public Collection<MagicStatic> getStatics() {
|
||||||
return cardDefinition.getStatics();
|
return cardDefinition.getStatics();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<MagicTrigger<?>> getTriggers() {
|
public Collection<MagicTrigger<?>> getTriggers() {
|
||||||
return cardDefinition.getTriggers();
|
return cardDefinition.getTriggers();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<MagicWhenComesIntoPlayTrigger> getComeIntoPlayTriggers() {
|
public Collection<MagicWhenComesIntoPlayTrigger> getComeIntoPlayTriggers() {
|
||||||
return cardDefinition.getComeIntoPlayTriggers();
|
return cardDefinition.getComeIntoPlayTriggers();
|
||||||
}
|
}
|
||||||
|
@ -226,15 +226,15 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
public boolean producesMana() {
|
public boolean producesMana() {
|
||||||
return !cardDefinition.getManaActivations().isEmpty();
|
return !cardDefinition.getManaActivations().isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int countManaActivations() {
|
public int countManaActivations() {
|
||||||
return cardDefinition.getManaActivations().size();
|
return cardDefinition.getManaActivations().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return card.getName();
|
return card.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getName();
|
return getName();
|
||||||
|
@ -252,12 +252,12 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
public MagicPlayer getFirstController() {
|
public MagicPlayer getFirstController() {
|
||||||
return firstController;
|
return firstController;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicPlayer getController() {
|
public MagicPlayer getController() {
|
||||||
assert cachedController != null : "cachedController is null in " + this;
|
assert cachedController != null : "cachedController is null in " + this;
|
||||||
return cachedController;
|
return cachedController;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicPlayer getOpponent() {
|
public MagicPlayer getOpponent() {
|
||||||
return getController().getOpponent();
|
return getController().getOpponent();
|
||||||
}
|
}
|
||||||
|
@ -265,35 +265,35 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
public boolean isFriend(final MagicObject other) {
|
public boolean isFriend(final MagicObject other) {
|
||||||
return getController() == other.getController();
|
return getController() == other.getController();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEnemy(final MagicObject other) {
|
public boolean isEnemy(final MagicObject other) {
|
||||||
return getController() != other.getController();
|
return getController() != other.getController();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isController(final MagicTarget player) {
|
public boolean isController(final MagicTarget player) {
|
||||||
return getController() == player;
|
return getController() == player;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isOwner(final MagicTarget player) {
|
public boolean isOwner(final MagicTarget player) {
|
||||||
return getOwner() == player;
|
return getOwner() == player;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isOpponent(final MagicTarget player) {
|
public boolean isOpponent(final MagicTarget player) {
|
||||||
return getOpponent() == player;
|
return getOpponent() == player;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void update(final MagicGame game) {
|
public static void update(final MagicGame game) {
|
||||||
MagicPermanent.updateProperties(game);
|
MagicPermanent.updateProperties(game);
|
||||||
MagicPermanent.updateScoreFixController(game);
|
MagicPermanent.updateScoreFixController(game);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void updateScoreFixController(final MagicGame game) {
|
public static void updateScoreFixController(final MagicGame game) {
|
||||||
for (final MagicPlayer player : game.getPlayers()) {
|
for (final MagicPlayer player : game.getPlayers()) {
|
||||||
for (final MagicPermanent perm : player.getPermanents()) {
|
for (final MagicPermanent perm : player.getPermanents()) {
|
||||||
final MagicPlayer curr = perm.getController();
|
final MagicPlayer curr = perm.getController();
|
||||||
if (!curr.controlsPermanent(perm)) {
|
if (!curr.controlsPermanent(perm)) {
|
||||||
game.addDelayedAction(new MagicChangeControlAction(curr, perm, perm.getScore()));
|
game.addDelayedAction(new MagicChangeControlAction(curr, perm, perm.getScore()));
|
||||||
}
|
}
|
||||||
perm.updateScore();
|
perm.updateScore();
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
@ -317,7 +317,7 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void apply(final MagicLayer layer) {
|
private void apply(final MagicLayer layer) {
|
||||||
switch (layer) {
|
switch (layer) {
|
||||||
case Card:
|
case Card:
|
||||||
|
@ -369,48 +369,48 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
public void setState(final MagicPermanentState state) {
|
public void setState(final MagicPermanentState state) {
|
||||||
stateFlags|=state.getMask();
|
stateFlags|=state.getMask();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearState(final MagicPermanentState state) {
|
public void clearState(final MagicPermanentState state) {
|
||||||
stateFlags&=Integer.MAX_VALUE-state.getMask();
|
stateFlags&=Integer.MAX_VALUE-state.getMask();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasState(final MagicPermanentState state) {
|
public boolean hasState(final MagicPermanentState state) {
|
||||||
return state.hasState(stateFlags);
|
return state.hasState(stateFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getStateFlags() {
|
public int getStateFlags() {
|
||||||
return stateFlags;
|
return stateFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStateFlags(final int flags) {
|
public void setStateFlags(final int flags) {
|
||||||
stateFlags=flags;
|
stateFlags=flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTapped() {
|
public boolean isTapped() {
|
||||||
return hasState(MagicPermanentState.Tapped);
|
return hasState(MagicPermanentState.Tapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUntapped() {
|
public boolean isUntapped() {
|
||||||
return !hasState(MagicPermanentState.Tapped);
|
return !hasState(MagicPermanentState.Tapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getColorFlags() {
|
private int getColorFlags() {
|
||||||
return cachedColorFlags;
|
return cachedColorFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasColor(final MagicColor color) {
|
public boolean hasColor(final MagicColor color) {
|
||||||
return color.hasColor(getColorFlags());
|
return color.hasColor(getColorFlags());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void changeCounters(final MagicCounterType counterType,final int amount) {
|
public void changeCounters(final MagicCounterType counterType,final int amount) {
|
||||||
counters[counterType.ordinal()]+=amount;
|
counters[counterType.ordinal()]+=amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCounters(final MagicCounterType counterType) {
|
public int getCounters(final MagicCounterType counterType) {
|
||||||
return counters[counterType.ordinal()];
|
return counters[counterType.ordinal()];
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasCounters() {
|
public boolean hasCounters() {
|
||||||
for (final int amount : counters) {
|
for (final int amount : counters) {
|
||||||
if (amount>0) {
|
if (amount>0) {
|
||||||
|
@ -419,7 +419,7 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasSubType(final MagicSubType subType) {
|
public boolean hasSubType(final MagicSubType subType) {
|
||||||
return cachedSubTypeFlags.contains(subType);
|
return cachedSubTypeFlags.contains(subType);
|
||||||
}
|
}
|
||||||
|
@ -431,15 +431,15 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
public MagicPowerToughness getPowerToughness() {
|
public MagicPowerToughness getPowerToughness() {
|
||||||
return cachedPowerToughness;
|
return cachedPowerToughness;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getPower() {
|
public int getPower() {
|
||||||
return getPowerToughness().getPositivePower();
|
return getPowerToughness().getPositivePower();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getToughness() {
|
public int getToughness() {
|
||||||
return getPowerToughness().getPositiveToughness();
|
return getPowerToughness().getPositiveToughness();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<MagicAbility> getAbilityFlags() {
|
public Set<MagicAbility> getAbilityFlags() {
|
||||||
return cachedAbilityFlags;
|
return cachedAbilityFlags;
|
||||||
}
|
}
|
||||||
|
@ -448,33 +448,33 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
public boolean hasAbility(final MagicAbility ability) {
|
public boolean hasAbility(final MagicAbility ability) {
|
||||||
return cachedAbilityFlags.contains(ability);
|
return cachedAbilityFlags.contains(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateScore() {
|
private void updateScore() {
|
||||||
stateId = 0;
|
stateId = 0;
|
||||||
fixedScore = ArtificialScoringSystem.getFixedPermanentScore(this);
|
fixedScore = ArtificialScoringSystem.getFixedPermanentScore(this);
|
||||||
score = fixedScore + ArtificialScoringSystem.getVariablePermanentScore(this);
|
score = fixedScore + ArtificialScoringSystem.getVariablePermanentScore(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getScore() {
|
public int getScore() {
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getStaticScore() {
|
public int getStaticScore() {
|
||||||
return cardDefinition.getStaticType().getScore(this);
|
return cardDefinition.getStaticType().getScore(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCardScore() {
|
public int getCardScore() {
|
||||||
return cardDefinition.getScore();
|
return cardDefinition.getScore();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getDamage() {
|
public int getDamage() {
|
||||||
return damage;
|
return damage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDamage(final int damage) {
|
public void setDamage(final int damage) {
|
||||||
this.damage=damage;
|
this.damage=damage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getPreventDamage() {
|
public int getPreventDamage() {
|
||||||
return preventDamage;
|
return preventDamage;
|
||||||
|
@ -488,49 +488,49 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
public int getLethalDamage(final int toughness) {
|
public int getLethalDamage(final int toughness) {
|
||||||
return toughness<=damage?0:toughness-damage;
|
return toughness<=damage?0:toughness-damage;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tap symbol.
|
// Tap symbol.
|
||||||
public boolean canTap() {
|
public boolean canTap() {
|
||||||
return !hasState(MagicPermanentState.Tapped) &&
|
return !hasState(MagicPermanentState.Tapped) &&
|
||||||
(!hasState(MagicPermanentState.Summoned) ||
|
(!hasState(MagicPermanentState.Summoned) ||
|
||||||
!isCreature() ||
|
!isCreature() ||
|
||||||
hasAbility(MagicAbility.Haste)
|
hasAbility(MagicAbility.Haste)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Untap symbol.
|
// Untap symbol.
|
||||||
public boolean canUntap() {
|
public boolean canUntap() {
|
||||||
return hasState(MagicPermanentState.Tapped) &&
|
return hasState(MagicPermanentState.Tapped) &&
|
||||||
(!hasState(MagicPermanentState.Summoned) ||
|
(!hasState(MagicPermanentState.Summoned) ||
|
||||||
!isCreature() ||
|
!isCreature() ||
|
||||||
hasAbility(MagicAbility.Haste)
|
hasAbility(MagicAbility.Haste)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canRegenerate() {
|
public boolean canRegenerate() {
|
||||||
return !hasState(MagicPermanentState.Regenerated)&&!hasState(MagicPermanentState.CannotBeRegenerated);
|
return !hasState(MagicPermanentState.Regenerated)&&!hasState(MagicPermanentState.CannotBeRegenerated);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isRegenerated() {
|
public boolean isRegenerated() {
|
||||||
return hasState(MagicPermanentState.Regenerated)&&!hasState(MagicPermanentState.CannotBeRegenerated);
|
return hasState(MagicPermanentState.Regenerated)&&!hasState(MagicPermanentState.CannotBeRegenerated);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAttacking() {
|
public boolean isAttacking() {
|
||||||
return hasState(MagicPermanentState.Attacking);
|
return hasState(MagicPermanentState.Attacking);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBlocked() {
|
public boolean isBlocked() {
|
||||||
return hasState(MagicPermanentState.Blocked);
|
return hasState(MagicPermanentState.Blocked);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBlocking() {
|
public boolean isBlocking() {
|
||||||
return hasState(MagicPermanentState.Blocking);
|
return hasState(MagicPermanentState.Blocking);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicPermanent getBlockedCreature() {
|
public MagicPermanent getBlockedCreature() {
|
||||||
return blockedCreature;
|
return blockedCreature;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBlockedCreature(final MagicPermanent creature) {
|
public void setBlockedCreature(final MagicPermanent creature) {
|
||||||
if (creature.isValid()) {
|
if (creature.isValid()) {
|
||||||
blockedName = creature.getName() + creature.getId() + (100 + creature.numBlockingCreatures());
|
blockedName = creature.getName() + creature.getId() + (100 + creature.numBlockingCreatures());
|
||||||
|
@ -545,67 +545,67 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
public MagicPermanentList getBlockingCreatures() {
|
public MagicPermanentList getBlockingCreatures() {
|
||||||
return blockingCreatures;
|
return blockingCreatures;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int numBlockingCreatures() {
|
public int numBlockingCreatures() {
|
||||||
return blockingCreatures.size();
|
return blockingCreatures.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBlockingCreatures(final MagicPermanentList creatures) {
|
public void setBlockingCreatures(final MagicPermanentList creatures) {
|
||||||
blockingCreatures.clear();
|
blockingCreatures.clear();
|
||||||
blockingCreatures.addAll(creatures);
|
blockingCreatures.addAll(creatures);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addBlockingCreature(final MagicPermanent creature) {
|
public void addBlockingCreature(final MagicPermanent creature) {
|
||||||
blockingCreatures.add(creature);
|
blockingCreatures.add(creature);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeBlockingCreature(final MagicPermanent creature) {
|
public void removeBlockingCreature(final MagicPermanent creature) {
|
||||||
blockingCreatures.remove(creature);
|
blockingCreatures.remove(creature);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeBlockingCreatures() {
|
public void removeBlockingCreatures() {
|
||||||
blockingCreatures.clear();
|
blockingCreatures.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicPermanent getPairedCreature() {
|
public MagicPermanent getPairedCreature() {
|
||||||
return pairedCreature;
|
return pairedCreature;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPairedCreature(final MagicPermanent creature) {
|
public void setPairedCreature(final MagicPermanent creature) {
|
||||||
pairedCreature = creature;
|
pairedCreature = creature;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPaired() {
|
public boolean isPaired() {
|
||||||
return pairedCreature != MagicPermanent.NONE;
|
return pairedCreature != MagicPermanent.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicCardList getExiledCards() {
|
public MagicCardList getExiledCards() {
|
||||||
return exiledCards;
|
return exiledCards;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addExiledCard(final MagicCard card) {
|
public void addExiledCard(final MagicCard card) {
|
||||||
// only non tokens can be added
|
// only non tokens can be added
|
||||||
if (!card.isToken()) {
|
if (!card.isToken()) {
|
||||||
exiledCards.add(card);
|
exiledCards.add(card);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeExiledCard(final MagicCard card) {
|
public void removeExiledCard(final MagicCard card) {
|
||||||
exiledCards.remove(card);
|
exiledCards.remove(card);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicTarget getChosenTarget() {
|
public MagicTarget getChosenTarget() {
|
||||||
return chosenTarget;
|
return chosenTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicPlayer getChosenPlayer() {
|
public MagicPlayer getChosenPlayer() {
|
||||||
return (MagicPlayer)chosenTarget;
|
return (MagicPlayer)chosenTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setChosenTarget(final MagicTarget target) {
|
public void setChosenTarget(final MagicTarget target) {
|
||||||
chosenTarget = target;
|
chosenTarget = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateStateBasedActions() {
|
void generateStateBasedActions() {
|
||||||
final MagicGame game = getGame();
|
final MagicGame game = getGame();
|
||||||
if (isCreature()) {
|
if (isCreature()) {
|
||||||
|
@ -619,26 +619,26 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
} else if (toughness-damage<=0) {
|
} else if (toughness-damage<=0) {
|
||||||
game.addDelayedAction(new MagicDestroyAction(this));
|
game.addDelayedAction(new MagicDestroyAction(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Soulbond
|
// Soulbond
|
||||||
if (pairedCreature.isValid() &&
|
if (pairedCreature.isValid() &&
|
||||||
!pairedCreature.isCreature()) {
|
!pairedCreature.isCreature()) {
|
||||||
game.doAction(new MagicSoulbondAction(this,pairedCreature,false));
|
game.doAction(new MagicSoulbondAction(this,pairedCreature,false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAura()) {
|
if (isAura()) {
|
||||||
final MagicPlayAuraEvent auraEvent = (MagicPlayAuraEvent)cardDefinition.getCardEvent();
|
final MagicPlayAuraEvent auraEvent = (MagicPlayAuraEvent)cardDefinition.getCardEvent();
|
||||||
//not targeting since Aura is already attached
|
//not targeting since Aura is already attached
|
||||||
final MagicTargetChoice tchoice = new MagicTargetChoice(auraEvent.getTargetChoice(), false);
|
final MagicTargetChoice tchoice = new MagicTargetChoice(auraEvent.getTargetChoice(), false);
|
||||||
if (!enchantedCreature.isValid() ||
|
if (!enchantedCreature.isValid() ||
|
||||||
!game.isLegalTarget(getController(),this,tchoice,enchantedCreature) ||
|
!game.isLegalTarget(getController(),this,tchoice,enchantedCreature) ||
|
||||||
enchantedCreature.hasProtectionFrom(this)) {
|
enchantedCreature.hasProtectionFrom(this)) {
|
||||||
game.logAppendMessage(getController(),getName()+" is put into its owner's graveyard.");
|
game.logAppendMessage(getController(),getName()+" is put into its owner's graveyard.");
|
||||||
game.addDelayedAction(new MagicRemoveFromPlayAction(this,MagicLocationType.Graveyard));
|
game.addDelayedAction(new MagicRemoveFromPlayAction(this,MagicLocationType.Graveyard));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isEquipment() && equippedCreature.isValid()) {
|
if (isEquipment() && equippedCreature.isValid()) {
|
||||||
if (isCreature() || !equippedCreature.isCreature() || equippedCreature.hasProtectionFrom(this)) {
|
if (isCreature() || !equippedCreature.isCreature() || equippedCreature.hasProtectionFrom(this)) {
|
||||||
game.addDelayedAction(new MagicAttachEquipmentAction(this,MagicPermanent.NONE));
|
game.addDelayedAction(new MagicAttachEquipmentAction(this,MagicPermanent.NONE));
|
||||||
|
@ -650,7 +650,7 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
game.logAppendMessage(getController(),getName()+" is put into its owner's graveyard.");
|
game.logAppendMessage(getController(),getName()+" is put into its owner's graveyard.");
|
||||||
game.addDelayedAction(new MagicRemoveFromPlayAction(this,MagicLocationType.Graveyard));
|
game.addDelayedAction(new MagicRemoveFromPlayAction(this,MagicLocationType.Graveyard));
|
||||||
}
|
}
|
||||||
|
|
||||||
// +1/+1 and -1/-1 counters cancel each other out.
|
// +1/+1 and -1/-1 counters cancel each other out.
|
||||||
final int plusCounters=getCounters(MagicCounterType.PlusOne);
|
final int plusCounters=getCounters(MagicCounterType.PlusOne);
|
||||||
if (plusCounters>0) {
|
if (plusCounters>0) {
|
||||||
|
@ -662,7 +662,7 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasProtectionFrom(final MagicSource source) {
|
public boolean hasProtectionFrom(final MagicSource source) {
|
||||||
// From a color.
|
// From a color.
|
||||||
int numColors = 0;
|
int numColors = 0;
|
||||||
|
@ -675,7 +675,7 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// From monocolored.
|
// From monocolored.
|
||||||
if (numColors == 1 &&
|
if (numColors == 1 &&
|
||||||
hasAbility(MagicAbility.ProtectionFromMonoColored)) {
|
hasAbility(MagicAbility.ProtectionFromMonoColored)) {
|
||||||
|
@ -687,7 +687,7 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
}
|
}
|
||||||
|
|
||||||
final MagicPermanent creature = (MagicPermanent)source;
|
final MagicPermanent creature = (MagicPermanent)source;
|
||||||
|
|
||||||
// From creatures.
|
// From creatures.
|
||||||
if (creature.hasType(MagicType.Creature) &&
|
if (creature.hasType(MagicType.Creature) &&
|
||||||
hasAbility(MagicAbility.ProtectionFromCreatures)) {
|
hasAbility(MagicAbility.ProtectionFromCreatures)) {
|
||||||
|
@ -723,48 +723,48 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
hasAbility(MagicAbility.ProtectionFromZombies)) {
|
hasAbility(MagicAbility.ProtectionFromZombies)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canAttack() {
|
public boolean canAttack() {
|
||||||
if (!isCreature() ||
|
if (!isCreature() ||
|
||||||
!canTap() ||
|
!canTap() ||
|
||||||
hasState(MagicPermanentState.ExcludeFromCombat) ||
|
hasState(MagicPermanentState.ExcludeFromCombat) ||
|
||||||
hasState(MagicPermanentState.CannotAttack)) {
|
hasState(MagicPermanentState.CannotAttack)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return !hasAbility(MagicAbility.CannotAttackOrBlock) &&
|
return !hasAbility(MagicAbility.CannotAttackOrBlock) &&
|
||||||
!hasAbility(MagicAbility.Defender);
|
!hasAbility(MagicAbility.Defender);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canBlock() {
|
public boolean canBlock() {
|
||||||
if (!isCreature() ||
|
if (!isCreature() ||
|
||||||
isTapped() ||
|
isTapped() ||
|
||||||
hasState(MagicPermanentState.ExcludeFromCombat)) {
|
hasState(MagicPermanentState.ExcludeFromCombat)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return !hasAbility(MagicAbility.CannotAttackOrBlock) &&
|
return !hasAbility(MagicAbility.CannotAttackOrBlock) &&
|
||||||
!hasAbility(MagicAbility.CannotBlock);
|
!hasAbility(MagicAbility.CannotBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canBeBlocked(final MagicPlayer defendingPlayer) {
|
public boolean canBeBlocked(final MagicPlayer defendingPlayer) {
|
||||||
// Unblockable
|
// Unblockable
|
||||||
if (hasAbility(MagicAbility.Unblockable)) {
|
if (hasAbility(MagicAbility.Unblockable)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Landwalk
|
// Landwalk
|
||||||
for (final MagicColor color : MagicColor.values()) {
|
for (final MagicColor color : MagicColor.values()) {
|
||||||
if (hasAbility(color.getLandwalkAbility()) &&
|
if (hasAbility(color.getLandwalkAbility()) &&
|
||||||
defendingPlayer.controlsPermanent(color.getLandSubType())) {
|
defendingPlayer.controlsPermanent(color.getLandSubType())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canBlock(final MagicPermanent attacker) {
|
public boolean canBlock(final MagicPermanent attacker) {
|
||||||
// Fear and Intimidate
|
// Fear and Intimidate
|
||||||
if (!isArtifact()) {
|
if (!isArtifact()) {
|
||||||
|
@ -777,7 +777,7 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shadow
|
// Shadow
|
||||||
if (attacker.hasAbility(MagicAbility.Shadow)) {
|
if (attacker.hasAbility(MagicAbility.Shadow)) {
|
||||||
if (!hasAbility(MagicAbility.Shadow) &&
|
if (!hasAbility(MagicAbility.Shadow) &&
|
||||||
|
@ -787,18 +787,18 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
} else if (hasAbility(MagicAbility.Shadow)) {
|
} else if (hasAbility(MagicAbility.Shadow)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flying
|
// Flying
|
||||||
if (attacker.hasAbility(MagicAbility.CannotBeBlockedByFlying) &&
|
if (attacker.hasAbility(MagicAbility.CannotBeBlockedByFlying) &&
|
||||||
hasAbility(MagicAbility.Flying)) {
|
hasAbility(MagicAbility.Flying)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attacker.hasAbility(MagicAbility.CannotBeBlockedExceptWithFlying) &&
|
if (attacker.hasAbility(MagicAbility.CannotBeBlockedExceptWithFlying) &&
|
||||||
!hasAbility(MagicAbility.Flying)) {
|
!hasAbility(MagicAbility.Flying)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!attacker.hasAbility(MagicAbility.Flying) &&
|
if (!attacker.hasAbility(MagicAbility.Flying) &&
|
||||||
hasAbility(MagicAbility.CannotBlockWithoutFlying)) {
|
hasAbility(MagicAbility.CannotBlockWithoutFlying)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -809,20 +809,20 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
!hasAbility(MagicAbility.Flying) &&
|
!hasAbility(MagicAbility.Flying) &&
|
||||||
!hasAbility(MagicAbility.Reach)) {
|
!hasAbility(MagicAbility.Reach)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attacker.hasAbility(MagicAbility.CannotBeBlockedExceptWithFlyingOrReach) &&
|
if (attacker.hasAbility(MagicAbility.CannotBeBlockedExceptWithFlyingOrReach) &&
|
||||||
!hasAbility(MagicAbility.Flying) &&
|
!hasAbility(MagicAbility.Flying) &&
|
||||||
!hasAbility(MagicAbility.Reach)) {
|
!hasAbility(MagicAbility.Reach)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subtype
|
// Subtype
|
||||||
if (attacker.hasAbility(MagicAbility.CannotBeBlockedByHumans) &&
|
if (attacker.hasAbility(MagicAbility.CannotBeBlockedByHumans) &&
|
||||||
hasSubType(MagicSubType.Human)) {
|
hasSubType(MagicSubType.Human)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attacker.hasAbility(MagicAbility.CannotBeBlockedExceptBySliver) &&
|
if (attacker.hasAbility(MagicAbility.CannotBeBlockedExceptBySliver) &&
|
||||||
!hasSubType(MagicSubType.Sliver)) {
|
!hasSubType(MagicSubType.Sliver)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -841,11 +841,11 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Protection
|
// Protection
|
||||||
return !attacker.hasProtectionFrom(this);
|
return !attacker.hasProtectionFrom(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicPermanent getEquippedCreature() {
|
public MagicPermanent getEquippedCreature() {
|
||||||
return equippedCreature;
|
return equippedCreature;
|
||||||
}
|
}
|
||||||
|
@ -853,23 +853,23 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
public void setEquippedCreature(final MagicPermanent creature) {
|
public void setEquippedCreature(final MagicPermanent creature) {
|
||||||
equippedCreature=creature;
|
equippedCreature=creature;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicPermanentSet getEquipmentPermanents() {
|
public MagicPermanentSet getEquipmentPermanents() {
|
||||||
return equipmentPermanents;
|
return equipmentPermanents;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addEquipment(final MagicPermanent equipment) {
|
public void addEquipment(final MagicPermanent equipment) {
|
||||||
equipmentPermanents.add(equipment);
|
equipmentPermanents.add(equipment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeEquipment(final MagicPermanent equipment) {
|
public void removeEquipment(final MagicPermanent equipment) {
|
||||||
equipmentPermanents.remove(equipment);
|
equipmentPermanents.remove(equipment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEquipped() {
|
public boolean isEquipped() {
|
||||||
return equipmentPermanents.size()>0;
|
return equipmentPermanents.size()>0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicPermanent getEnchantedCreature() {
|
public MagicPermanent getEnchantedCreature() {
|
||||||
return enchantedCreature;
|
return enchantedCreature;
|
||||||
}
|
}
|
||||||
|
@ -877,31 +877,31 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
public void setEnchantedCreature(final MagicPermanent creature) {
|
public void setEnchantedCreature(final MagicPermanent creature) {
|
||||||
enchantedCreature=creature;
|
enchantedCreature=creature;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicPermanentSet getAuraPermanents() {
|
public MagicPermanentSet getAuraPermanents() {
|
||||||
return auraPermanents;
|
return auraPermanents;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addAura(final MagicPermanent aura) {
|
public void addAura(final MagicPermanent aura) {
|
||||||
auraPermanents.add(aura);
|
auraPermanents.add(aura);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeAura(final MagicPermanent aura) {
|
public void removeAura(final MagicPermanent aura) {
|
||||||
auraPermanents.remove(aura);
|
auraPermanents.remove(aura);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEnchanted() {
|
public boolean isEnchanted() {
|
||||||
return auraPermanents.size()>0;
|
return auraPermanents.size()>0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getAbilityPlayedThisTurn() {
|
public int getAbilityPlayedThisTurn() {
|
||||||
return abilityPlayedThisTurn;
|
return abilityPlayedThisTurn;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAbilityPlayedThisTurn(final int amount) {
|
public void setAbilityPlayedThisTurn(final int amount) {
|
||||||
abilityPlayedThisTurn=amount;
|
abilityPlayedThisTurn=amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void incrementAbilityPlayedThisTurn() {
|
public void incrementAbilityPlayedThisTurn() {
|
||||||
abilityPlayedThisTurn++;
|
abilityPlayedThisTurn++;
|
||||||
}
|
}
|
||||||
|
@ -909,47 +909,47 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
public void decrementAbilityPlayedThisTurn() {
|
public void decrementAbilityPlayedThisTurn() {
|
||||||
abilityPlayedThisTurn--;
|
abilityPlayedThisTurn--;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getTypeFlags() {
|
private int getTypeFlags() {
|
||||||
return cachedTypeFlags;
|
return cachedTypeFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasType(final MagicType type) {
|
public boolean hasType(final MagicType type) {
|
||||||
return type.hasType(getTypeFlags());
|
return type.hasType(getTypeFlags());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isBasic() {
|
public boolean isBasic() {
|
||||||
return hasType(MagicType.Basic);
|
return hasType(MagicType.Basic);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLand() {
|
public boolean isLand() {
|
||||||
return hasType(MagicType.Land);
|
return hasType(MagicType.Land);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCreature() {
|
public boolean isCreature() {
|
||||||
return hasType(MagicType.Creature);
|
return hasType(MagicType.Creature);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEquipment() {
|
public boolean isEquipment() {
|
||||||
return isArtifact() && hasSubType(MagicSubType.Equipment);
|
return isArtifact() && hasSubType(MagicSubType.Equipment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isArtifact() {
|
public boolean isArtifact() {
|
||||||
return hasType(MagicType.Artifact);
|
return hasType(MagicType.Artifact);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEnchantment() {
|
public boolean isEnchantment() {
|
||||||
return hasType(MagicType.Enchantment);
|
return hasType(MagicType.Enchantment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAura() {
|
public boolean isAura() {
|
||||||
return isEnchantment() && hasSubType(MagicSubType.Aura);
|
return isEnchantment() && hasSubType(MagicSubType.Aura);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPlaneswalker() {
|
public boolean isPlaneswalker() {
|
||||||
return hasType(MagicType.Planeswalker);
|
return hasType(MagicType.Planeswalker);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSpell() {
|
public boolean isSpell() {
|
||||||
return false;
|
return false;
|
||||||
|
@ -959,12 +959,12 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
public boolean isPlayer() {
|
public boolean isPlayer() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPermanent() {
|
public boolean isPermanent() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValidTarget(final MagicSource source) {
|
public boolean isValidTarget(final MagicSource source) {
|
||||||
// Can't be the target of spells or abilities.
|
// Can't be the target of spells or abilities.
|
||||||
|
@ -981,7 +981,7 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
if (hasAbility(MagicAbility.CannotBeTheTarget0) && source.getController().getIndex() == 0) {
|
if (hasAbility(MagicAbility.CannotBeTheTarget0) && source.getController().getIndex() == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can't be the target of spells or abilities player 1 controls.
|
// Can't be the target of spells or abilities player 1 controls.
|
||||||
if (hasAbility(MagicAbility.CannotBeTheTarget1) && source.getController().getIndex() == 1) {
|
if (hasAbility(MagicAbility.CannotBeTheTarget1) && source.getController().getIndex() == 1) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1023,11 +1023,11 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImageIcon getIcon() {
|
public ImageIcon getIcon() {
|
||||||
if (isAttacking()) {
|
if (isAttacking()) {
|
||||||
return IconImages.ATTACK;
|
return IconImages.ATTACK;
|
||||||
}
|
}
|
||||||
if (isBlocking()) {
|
if (isBlocking()) {
|
||||||
return IconImages.BLOCK;
|
return IconImages.BLOCK;
|
||||||
}
|
}
|
||||||
|
@ -1036,12 +1036,12 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
|
||||||
}
|
}
|
||||||
return cardDefinition.getIcon();
|
return cardDefinition.getIcon();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLegalTarget(final MagicPlayer player, final MagicTargetFilter<? extends MagicTarget> targetFilter) {
|
public boolean isLegalTarget(final MagicPlayer player, final MagicTargetFilter<? extends MagicTarget> targetFilter) {
|
||||||
return getController().controlsPermanent(this);
|
return getController().controlsPermanent(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final MagicPermanent NONE = new MagicPermanent(-1L, MagicCard.NONE, MagicPlayer.NONE) {
|
public static final MagicPermanent NONE = new MagicPermanent(-1L, MagicCard.NONE, MagicPlayer.NONE) {
|
||||||
@Override
|
@Override
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
|
|
|
@ -7,11 +7,11 @@ public class MagicPermanentList extends ArrayList<MagicPermanent> implements Mag
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
public MagicPermanentList() {}
|
public MagicPermanentList() {}
|
||||||
|
|
||||||
public MagicPermanentList(final MagicPermanentList list) {
|
public MagicPermanentList(final MagicPermanentList list) {
|
||||||
addAll(list);
|
addAll(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
MagicPermanentList(final MagicCopyMap copyMap,final MagicPermanentList list) {
|
MagicPermanentList(final MagicCopyMap copyMap,final MagicPermanentList list) {
|
||||||
for (final MagicPermanent permanent : list) {
|
for (final MagicPermanent permanent : list) {
|
||||||
add(copyMap.copy(permanent));
|
add(copyMap.copy(permanent));
|
||||||
|
|
|
@ -7,13 +7,13 @@ public class MagicPermanentSet extends TreeSet<MagicPermanent> {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
MagicPermanentSet() {}
|
MagicPermanentSet() {}
|
||||||
|
|
||||||
MagicPermanentSet(final MagicCopyMap copyMap,final MagicPermanentSet source) {
|
MagicPermanentSet(final MagicCopyMap copyMap,final MagicPermanentSet source) {
|
||||||
for (final MagicPermanent permanent : source) {
|
for (final MagicPermanent permanent : source) {
|
||||||
add(copyMap.copy(permanent));
|
add(copyMap.copy(permanent));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MagicPermanent getPermanent(final long id) {
|
MagicPermanent getPermanent(final long id) {
|
||||||
for (final MagicPermanent permanent : this) {
|
for (final MagicPermanent permanent : this) {
|
||||||
if (permanent.getId() == id) {
|
if (permanent.getId() == id) {
|
||||||
|
@ -21,8 +21,8 @@ public class MagicPermanentSet extends TreeSet<MagicPermanent> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return MagicPermanent.NONE;
|
return MagicPermanent.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
long getStateId() {
|
long getStateId() {
|
||||||
final long[] keys = new long[size()];
|
final long[] keys = new long[size()];
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package magic.model;
|
package magic.model;
|
||||||
|
|
||||||
public enum MagicPermanentState {
|
public enum MagicPermanentState {
|
||||||
|
|
||||||
Tapped("tapped","{T}"),
|
Tapped("tapped","{T}"),
|
||||||
Summoned("summoned","{n}"),
|
Summoned("summoned","{n}"),
|
||||||
DoesNotUntapDuringNext("doesn't untap during its controller's next untap step","{s}"),
|
DoesNotUntapDuringNext("doesn't untap during its controller's next untap step","{s}"),
|
||||||
|
@ -39,29 +39,29 @@ public enum MagicPermanentState {
|
||||||
ExcludeFromCombat.getMask()|
|
ExcludeFromCombat.getMask()|
|
||||||
DestroyAtEndOfCombat.getMask()|
|
DestroyAtEndOfCombat.getMask()|
|
||||||
MustPayEchoCost.getMask();
|
MustPayEchoCost.getMask();
|
||||||
|
|
||||||
private final String description;
|
private final String description;
|
||||||
private final String text;
|
private final String text;
|
||||||
private final int mask;
|
private final int mask;
|
||||||
|
|
||||||
private MagicPermanentState(final String description,final String text) {
|
private MagicPermanentState(final String description,final String text) {
|
||||||
this.description=description;
|
this.description=description;
|
||||||
this.text=text;
|
this.text=text;
|
||||||
this.mask=1<<ordinal();
|
this.mask=1<<ordinal();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getText() {
|
public String getText() {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMask() {
|
public int getMask() {
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasState(final int flags) {
|
public boolean hasState(final int flags) {
|
||||||
return (flags&mask)!=0;
|
return (flags&mask)!=0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,10 +47,10 @@ public class MagicPlayer implements MagicTarget {
|
||||||
|
|
||||||
private static final int LOSING_POISON=10;
|
private static final int LOSING_POISON=10;
|
||||||
private static final long ID_FACTOR=31;
|
private static final long ID_FACTOR=31;
|
||||||
|
|
||||||
private final MagicPlayerDefinition playerDefinition;
|
private final MagicPlayerDefinition playerDefinition;
|
||||||
private final int index;
|
private final int index;
|
||||||
|
|
||||||
private int life;
|
private int life;
|
||||||
private int stateFlags;
|
private int stateFlags;
|
||||||
private int poison;
|
private int poison;
|
||||||
|
@ -76,7 +76,7 @@ public class MagicPlayer implements MagicTarget {
|
||||||
playerDefinition = aPlayerDefinition;
|
playerDefinition = aPlayerDefinition;
|
||||||
index = aIndex;
|
index = aIndex;
|
||||||
life = aLife;
|
life = aLife;
|
||||||
|
|
||||||
hand=new MagicCardList();
|
hand=new MagicCardList();
|
||||||
library=new MagicCardList();
|
library=new MagicCardList();
|
||||||
graveyard=new MagicCardList();
|
graveyard=new MagicCardList();
|
||||||
|
@ -87,10 +87,10 @@ public class MagicPlayer implements MagicTarget {
|
||||||
builderCost=new MagicBuilderManaCost();
|
builderCost=new MagicBuilderManaCost();
|
||||||
activationPriority=new MagicActivationPriority();
|
activationPriority=new MagicActivationPriority();
|
||||||
}
|
}
|
||||||
|
|
||||||
private MagicPlayer(final MagicCopyMap copyMap, final MagicPlayer sourcePlayer) {
|
private MagicPlayer(final MagicCopyMap copyMap, final MagicPlayer sourcePlayer) {
|
||||||
copyMap.put(sourcePlayer, this);
|
copyMap.put(sourcePlayer, this);
|
||||||
|
|
||||||
playerDefinition = sourcePlayer.playerDefinition;
|
playerDefinition = sourcePlayer.playerDefinition;
|
||||||
index = sourcePlayer.index;
|
index = sourcePlayer.index;
|
||||||
life = sourcePlayer.life;
|
life = sourcePlayer.life;
|
||||||
|
@ -111,12 +111,12 @@ public class MagicPlayer implements MagicTarget {
|
||||||
activationPriority=new MagicActivationPriority(sourcePlayer.activationPriority);
|
activationPriority=new MagicActivationPriority(sourcePlayer.activationPriority);
|
||||||
cachedAbilityFlags=sourcePlayer.cachedAbilityFlags;
|
cachedAbilityFlags=sourcePlayer.cachedAbilityFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MagicPlayer copy(final MagicCopyMap copyMap) {
|
public MagicPlayer copy(final MagicCopyMap copyMap) {
|
||||||
return new MagicPlayer(copyMap, this);
|
return new MagicPlayer(copyMap, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MagicPlayer map(final MagicGame game) {
|
public MagicPlayer map(final MagicGame game) {
|
||||||
return game.getPlayer(index);
|
return game.getPlayer(index);
|
||||||
|
@ -129,7 +129,7 @@ public class MagicPlayer implements MagicTarget {
|
||||||
public MagicGame getGame() {
|
public MagicGame getGame() {
|
||||||
return currGame;
|
return currGame;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getStateId() {
|
public long getStateId() {
|
||||||
keys = new long[] {
|
keys = new long[] {
|
||||||
life,
|
life,
|
||||||
|
@ -151,7 +151,7 @@ public class MagicPlayer implements MagicTarget {
|
||||||
};
|
};
|
||||||
return magic.MurmurHash3.hash(keys);
|
return magic.MurmurHash3.hash(keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
String getIdString() {
|
String getIdString() {
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
sb.append(keys[0]);
|
sb.append(keys[0]);
|
||||||
|
@ -161,7 +161,7 @@ public class MagicPlayer implements MagicTarget {
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
long getPlayerId(final long id) {
|
long getPlayerId(final long id) {
|
||||||
// Exile is not used for id.
|
// Exile is not used for id.
|
||||||
long playerId=id;
|
long playerId=id;
|
||||||
|
@ -173,20 +173,20 @@ public class MagicPlayer implements MagicTarget {
|
||||||
playerId=playerId*ID_FACTOR+graveyard.getStateId();
|
playerId=playerId*ID_FACTOR+graveyard.getStateId();
|
||||||
return playerId;
|
return playerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return playerDefinition.getName();
|
return playerDefinition.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicActivationMap getActivationMap() {
|
public MagicActivationMap getActivationMap() {
|
||||||
return activationMap;
|
return activationMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicPlayerDefinition getPlayerDefinition() {
|
public MagicPlayerDefinition getPlayerDefinition() {
|
||||||
return playerDefinition;
|
return playerDefinition;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getIndex() {
|
public int getIndex() {
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
@ -194,63 +194,63 @@ public class MagicPlayer implements MagicTarget {
|
||||||
public long getId() {
|
public long getId() {
|
||||||
return 1000000000L + index;
|
return 1000000000L + index;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setState(final MagicPlayerState state) {
|
public void setState(final MagicPlayerState state) {
|
||||||
stateFlags|=state.getMask();
|
stateFlags|=state.getMask();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearState(final MagicPlayerState state) {
|
public void clearState(final MagicPlayerState state) {
|
||||||
stateFlags&=Integer.MAX_VALUE-state.getMask();
|
stateFlags&=Integer.MAX_VALUE-state.getMask();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasState(final MagicPlayerState state) {
|
public boolean hasState(final MagicPlayerState state) {
|
||||||
return state.hasState(stateFlags);
|
return state.hasState(stateFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getStateFlags() {
|
public int getStateFlags() {
|
||||||
return stateFlags;
|
return stateFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStateFlags(final int flags) {
|
public void setStateFlags(final int flags) {
|
||||||
stateFlags=flags;
|
stateFlags=flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLife(final int life) {
|
public void setLife(final int life) {
|
||||||
this.life=life;
|
this.life=life;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLife() {
|
public int getLife() {
|
||||||
return life;
|
return life;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPoison(final int poison) {
|
public void setPoison(final int poison) {
|
||||||
this.poison=poison;
|
this.poison=poison;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getPoison() {
|
public int getPoison() {
|
||||||
return poison;
|
return poison;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void changeExtraTurns(final int amount) {
|
public void changeExtraTurns(final int amount) {
|
||||||
extraTurns+=amount;
|
extraTurns+=amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getExtraTurns() {
|
public int getExtraTurns() {
|
||||||
return extraTurns;
|
return extraTurns;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getHandSize() {
|
public int getHandSize() {
|
||||||
return hand.size();
|
return hand.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNumExcessCards() {
|
public int getNumExcessCards() {
|
||||||
return Math.max(0, getHandSize() - maxHandSize);
|
return Math.max(0, getHandSize() - maxHandSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void noMaxHandSize() {
|
public void noMaxHandSize() {
|
||||||
maxHandSize = Integer.MAX_VALUE;
|
maxHandSize = Integer.MAX_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicCardList getHand() {
|
public MagicCardList getHand() {
|
||||||
return hand;
|
return hand;
|
||||||
}
|
}
|
||||||
|
@ -259,17 +259,17 @@ public class MagicPlayer implements MagicTarget {
|
||||||
hand.addToTop(card);
|
hand.addToTop(card);
|
||||||
activationMap.addActivations(card);
|
activationMap.addActivations(card);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addCardToHand(final MagicCard card,final int aIndex) {
|
public void addCardToHand(final MagicCard card,final int aIndex) {
|
||||||
hand.add(aIndex,card);
|
hand.add(aIndex,card);
|
||||||
activationMap.addActivations(card);
|
activationMap.addActivations(card);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int removeCardFromHand(final MagicCard card) {
|
public int removeCardFromHand(final MagicCard card) {
|
||||||
activationMap.removeActivations(card);
|
activationMap.removeActivations(card);
|
||||||
return hand.removeCard(card);
|
return hand.removeCard(card);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setHandToUnknown() {
|
void setHandToUnknown() {
|
||||||
activationMap.removeActivations(hand);
|
activationMap.removeActivations(hand);
|
||||||
hand.setKnown(false);
|
hand.setKnown(false);
|
||||||
|
@ -292,7 +292,7 @@ public class MagicPlayer implements MagicTarget {
|
||||||
addCardToHand(library.removeCardAtTop());
|
addCardToHand(library.removeCardAtTop());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void createHandAndLibrary(final int handSize) {
|
void createHandAndLibrary(final int handSize) {
|
||||||
for (final MagicCardDefinition cardDefinition : playerDefinition.getDeck()) {
|
for (final MagicCardDefinition cardDefinition : playerDefinition.getDeck()) {
|
||||||
final long id = currGame.getUniqueId();
|
final long id = currGame.getUniqueId();
|
||||||
|
@ -303,8 +303,8 @@ public class MagicPlayer implements MagicTarget {
|
||||||
final long seed = magic.MurmurHash3.hash(new long[] {
|
final long seed = magic.MurmurHash3.hash(new long[] {
|
||||||
2 * index - 1,
|
2 * index - 1,
|
||||||
MagicGame.getCount(),
|
MagicGame.getCount(),
|
||||||
(System.getProperty("rndSeed") != null) ?
|
(System.getProperty("rndSeed") != null) ?
|
||||||
Long.parseLong(System.getProperty("rndSeed")) :
|
Long.parseLong(System.getProperty("rndSeed")) :
|
||||||
System.currentTimeMillis()
|
System.currentTimeMillis()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -318,15 +318,15 @@ public class MagicPlayer implements MagicTarget {
|
||||||
public MagicCardList getLibrary() {
|
public MagicCardList getLibrary() {
|
||||||
return library;
|
return library;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicCardList getGraveyard() {
|
public MagicCardList getGraveyard() {
|
||||||
return graveyard;
|
return graveyard;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicCardList getExile() {
|
public MagicCardList getExile() {
|
||||||
return exile;
|
return exile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicPermanentSet getPermanents() {
|
public MagicPermanentSet getPermanents() {
|
||||||
return permanents;
|
return permanents;
|
||||||
}
|
}
|
||||||
|
@ -348,15 +348,15 @@ public class MagicPlayer implements MagicTarget {
|
||||||
}
|
}
|
||||||
activationMap.removeActivations(permanent);
|
activationMap.removeActivations(permanent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<MagicSourceManaActivation> getManaActivations(final MagicGame game) {
|
public List<MagicSourceManaActivation> getManaActivations(final MagicGame game) {
|
||||||
final List<MagicSourceManaActivation> activations=new ArrayList<MagicSourceManaActivation>();
|
final List<MagicSourceManaActivation> activations=new ArrayList<MagicSourceManaActivation>();
|
||||||
for (final MagicPermanent permanent : manaPermanents) {
|
for (final MagicPermanent permanent : manaPermanents) {
|
||||||
|
|
||||||
if (game.isArtificial()&&permanent.hasState(MagicPermanentState.ExcludeManaSource)) {
|
if (game.isArtificial()&&permanent.hasState(MagicPermanentState.ExcludeManaSource)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
final MagicSourceManaActivation sourceActivation=new MagicSourceManaActivation(game,permanent);
|
final MagicSourceManaActivation sourceActivation=new MagicSourceManaActivation(game,permanent);
|
||||||
if (sourceActivation.available) {
|
if (sourceActivation.available) {
|
||||||
activations.add(sourceActivation);
|
activations.add(sourceActivation);
|
||||||
|
@ -364,7 +364,7 @@ public class MagicPlayer implements MagicTarget {
|
||||||
}
|
}
|
||||||
return activations;
|
return activations;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getManaActivationsCount(final MagicGame game) {
|
private int getManaActivationsCount(final MagicGame game) {
|
||||||
int count=0;
|
int count=0;
|
||||||
for (final MagicPermanent permanent : manaPermanents) {
|
for (final MagicPermanent permanent : manaPermanents) {
|
||||||
|
@ -376,11 +376,11 @@ public class MagicPlayer implements MagicTarget {
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBuilderCost(final MagicBuilderManaCost builderCost) {
|
public void setBuilderCost(final MagicBuilderManaCost builderCost) {
|
||||||
this.builderCost=builderCost;
|
this.builderCost=builderCost;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicBuilderManaCost getBuilderCost() {
|
public MagicBuilderManaCost getBuilderCost() {
|
||||||
return builderCost;
|
return builderCost;
|
||||||
}
|
}
|
||||||
|
@ -388,11 +388,11 @@ public class MagicPlayer implements MagicTarget {
|
||||||
public void setActivationPriority(final MagicActivationPriority abilityPriority) {
|
public void setActivationPriority(final MagicActivationPriority abilityPriority) {
|
||||||
this.activationPriority=abilityPriority;
|
this.activationPriority=abilityPriority;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicActivationPriority getActivationPriority() {
|
public MagicActivationPriority getActivationPriority() {
|
||||||
return activationPriority;
|
return activationPriority;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMaximumX(final MagicGame game,final MagicManaCost cost) {
|
public int getMaximumX(final MagicGame game,final MagicManaCost cost) {
|
||||||
return (getManaActivationsCount(game) -
|
return (getManaActivationsCount(game) -
|
||||||
builderCost.getMinimumAmount() -
|
builderCost.getMinimumAmount() -
|
||||||
|
@ -409,7 +409,7 @@ public class MagicPlayer implements MagicTarget {
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNrOfBlockers() {
|
public int getNrOfBlockers() {
|
||||||
int count=0;
|
int count=0;
|
||||||
for (final MagicPermanent permanent : permanents) {
|
for (final MagicPermanent permanent : permanents) {
|
||||||
|
@ -419,7 +419,7 @@ public class MagicPlayer implements MagicTarget {
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNrOfPermanentsWithType(final MagicType type) {
|
public int getNrOfPermanentsWithType(final MagicType type) {
|
||||||
int count=0;
|
int count=0;
|
||||||
for (final MagicPermanent permanent : permanents) {
|
for (final MagicPermanent permanent : permanents) {
|
||||||
|
@ -439,7 +439,7 @@ public class MagicPlayer implements MagicTarget {
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNrOfPermanents(final MagicTargetFilter<MagicPermanent> filter) {
|
public int getNrOfPermanents(final MagicTargetFilter<MagicPermanent> filter) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (final MagicPermanent permanent : permanents) {
|
for (final MagicPermanent permanent : permanents) {
|
||||||
|
@ -449,8 +449,8 @@ public class MagicPlayer implements MagicTarget {
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean controlsPermanent(final MagicTargetFilter<MagicPermanent> filter) {
|
public boolean controlsPermanent(final MagicTargetFilter<MagicPermanent> filter) {
|
||||||
for (final MagicPermanent permanent : permanents) {
|
for (final MagicPermanent permanent : permanents) {
|
||||||
if (filter.accept(currGame, this, permanent)) {
|
if (filter.accept(currGame, this, permanent)) {
|
||||||
|
@ -459,11 +459,11 @@ public class MagicPlayer implements MagicTarget {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean controlsPermanent(final MagicPermanent permanent) {
|
public boolean controlsPermanent(final MagicPermanent permanent) {
|
||||||
return permanents.contains(permanent);
|
return permanents.contains(permanent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean controlsPermanent(final MagicColor color) {
|
public boolean controlsPermanent(final MagicColor color) {
|
||||||
for (final MagicPermanent permanent : permanents) {
|
for (final MagicPermanent permanent : permanents) {
|
||||||
if (permanent.hasColor(color)) {
|
if (permanent.hasColor(color)) {
|
||||||
|
@ -472,7 +472,7 @@ public class MagicPlayer implements MagicTarget {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean controlsPermanent(final MagicType type) {
|
public boolean controlsPermanent(final MagicType type) {
|
||||||
for (final MagicPermanent permanent : permanents) {
|
for (final MagicPermanent permanent : permanents) {
|
||||||
if (permanent.hasType(type)) {
|
if (permanent.hasType(type)) {
|
||||||
|
@ -481,40 +481,40 @@ public class MagicPlayer implements MagicTarget {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean controlsPermanent(final MagicSubType subType) {
|
public boolean controlsPermanent(final MagicSubType subType) {
|
||||||
for (final MagicPermanent permanent : permanents) {
|
for (final MagicPermanent permanent : permanents) {
|
||||||
if (permanent.hasSubType(subType)) {
|
if (permanent.hasSubType(subType)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean controlsPermanent(final MagicAbility ability) {
|
public boolean controlsPermanent(final MagicAbility ability) {
|
||||||
for (final MagicPermanent permanent : permanents) {
|
for (final MagicPermanent permanent : permanents) {
|
||||||
if (permanent.hasAbility(ability)) {
|
if (permanent.hasAbility(ability)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MagicCardDefinition getCardDefinition() {
|
public MagicCardDefinition getCardDefinition() {
|
||||||
throw new RuntimeException("player has no card definition");
|
throw new RuntimeException("player has no card definition");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return playerDefinition.getName();
|
return playerDefinition.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPermanent() {
|
public boolean isPermanent() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCreature() {
|
public boolean isCreature() {
|
||||||
return false;
|
return false;
|
||||||
|
@ -524,7 +524,7 @@ public class MagicPlayer implements MagicTarget {
|
||||||
public boolean isPlayer() {
|
public boolean isPlayer() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPlaneswalker() {
|
public boolean isPlaneswalker() {
|
||||||
return false;
|
return false;
|
||||||
|
@ -566,22 +566,22 @@ public class MagicPlayer implements MagicTarget {
|
||||||
public boolean hasAbility(final MagicAbility ability) {
|
public boolean hasAbility(final MagicAbility ability) {
|
||||||
return cachedAbilityFlags.contains(ability);
|
return cachedAbilityFlags.contains(ability);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasType(final MagicType type) {
|
public boolean hasType(final MagicType type) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasSubType(final MagicSubType subType) {
|
public boolean hasSubType(final MagicSubType subType) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasColor(final MagicColor color) {
|
public boolean hasColor(final MagicColor color) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValidTarget(final MagicSource source) {
|
public boolean isValidTarget(final MagicSource source) {
|
||||||
// Can't be the target of spells or abilities your opponents controls.
|
// Can't be the target of spells or abilities your opponents controls.
|
||||||
|
@ -590,7 +590,7 @@ public class MagicPlayer implements MagicTarget {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLegalTarget(final MagicPlayer player, final MagicTargetFilter<? extends MagicTarget> targetFilter) {
|
public boolean isLegalTarget(final MagicPlayer player, final MagicTargetFilter<? extends MagicTarget> targetFilter) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -599,7 +599,7 @@ public class MagicPlayer implements MagicTarget {
|
||||||
public void incDrawnCards() {
|
public void incDrawnCards() {
|
||||||
drawnCards++;
|
drawnCards++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void decDrawnCards() {
|
public void decDrawnCards() {
|
||||||
drawnCards--;
|
drawnCards--;
|
||||||
}
|
}
|
||||||
|
@ -620,7 +620,7 @@ public class MagicPlayer implements MagicTarget {
|
||||||
currGame.addDelayedAction(new MagicLoseGameAction(this,MagicLoseGameAction.POISON_REASON));
|
currGame.addDelayedAction(new MagicLoseGameAction(this,MagicLoseGameAction.POISON_REASON));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void apply(final MagicLayer layer) {
|
public void apply(final MagicLayer layer) {
|
||||||
switch (layer) {
|
switch (layer) {
|
||||||
case Player:
|
case Player:
|
||||||
|
@ -632,7 +632,7 @@ public class MagicPlayer implements MagicTarget {
|
||||||
throw new RuntimeException("No case for " + layer + " in MagicPlayer.apply");
|
throw new RuntimeException("No case for " + layer + " in MagicPlayer.apply");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void apply(final MagicPermanent source, final MagicStatic mstatic) {
|
private void apply(final MagicPermanent source, final MagicStatic mstatic) {
|
||||||
final MagicLayer layer = mstatic.getLayer();
|
final MagicLayer layer = mstatic.getLayer();
|
||||||
switch (layer) {
|
switch (layer) {
|
||||||
|
|
|
@ -10,12 +10,12 @@ public class MagicPlayerDefinition {
|
||||||
|
|
||||||
private static final int DECK_SIZE=40;
|
private static final int DECK_SIZE=40;
|
||||||
private static final int MIN_SOURCE=16;
|
private static final int MIN_SOURCE=16;
|
||||||
|
|
||||||
private static final String NAME="name";
|
private static final String NAME="name";
|
||||||
private static final String ARTIFICIAL="artificial";
|
private static final String ARTIFICIAL="artificial";
|
||||||
private static final String COLORS="colors";
|
private static final String COLORS="colors";
|
||||||
private static final String FACE="face";
|
private static final String FACE="face";
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private boolean artificial;
|
private boolean artificial;
|
||||||
private MagicPlayerProfile profile;
|
private MagicPlayerProfile profile;
|
||||||
|
@ -23,14 +23,14 @@ public class MagicPlayerDefinition {
|
||||||
private final MagicDeck deck = new MagicDeck();
|
private final MagicDeck deck = new MagicDeck();
|
||||||
|
|
||||||
MagicPlayerDefinition() {}
|
MagicPlayerDefinition() {}
|
||||||
|
|
||||||
public MagicPlayerDefinition(final String name,final boolean artificial,final MagicPlayerProfile profile,final int face) {
|
public MagicPlayerDefinition(final String name,final boolean artificial,final MagicPlayerProfile profile,final int face) {
|
||||||
this.name=name;
|
this.name=name;
|
||||||
this.artificial=artificial;
|
this.artificial=artificial;
|
||||||
this.profile=profile;
|
this.profile=profile;
|
||||||
this.face=face;
|
this.face=face;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
@ -38,23 +38,23 @@ public class MagicPlayerDefinition {
|
||||||
public void setArtificial(final boolean art) {
|
public void setArtificial(final boolean art) {
|
||||||
this.artificial=art;
|
this.artificial=art;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isArtificial() {
|
public boolean isArtificial() {
|
||||||
return artificial;
|
return artificial;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setProfile(final MagicPlayerProfile profile) {
|
public void setProfile(final MagicPlayerProfile profile) {
|
||||||
this.profile=profile;
|
this.profile=profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicPlayerProfile getProfile() {
|
public MagicPlayerProfile getProfile() {
|
||||||
return profile;
|
return profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getFace() {
|
public int getFace() {
|
||||||
return face;
|
return face;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addBasicLandsToDeck() {
|
private void addBasicLandsToDeck() {
|
||||||
// Calculate statistics per color.
|
// Calculate statistics per color.
|
||||||
final int[] colorCount=new int[MagicColor.NR_COLORS];
|
final int[] colorCount=new int[MagicColor.NR_COLORS];
|
||||||
|
@ -70,10 +70,10 @@ public class MagicPlayerDefinition {
|
||||||
if (color.hasColor(colorFlags)) {
|
if (color.hasColor(colorFlags)) {
|
||||||
colorCount[color.ordinal()]++;
|
colorCount[color.ordinal()]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add optimal basic lands to deck.
|
// Add optimal basic lands to deck.
|
||||||
while (deck.size()<DECK_SIZE) {
|
while (deck.size()<DECK_SIZE) {
|
||||||
MagicColor bestColor=null;
|
MagicColor bestColor=null;
|
||||||
|
@ -100,41 +100,41 @@ public class MagicPlayerDefinition {
|
||||||
deck.add(landCard);
|
deck.add(landCard);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicDeck getDeck() {
|
public MagicDeck getDeck() {
|
||||||
return deck;
|
return deck;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDeck(final MagicDeck aDeck) {
|
public void setDeck(final MagicDeck aDeck) {
|
||||||
deck.setContent(aDeck);
|
deck.setContent(aDeck);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DefaultDeckGenerator getDeckGenerator() {
|
public DefaultDeckGenerator getDeckGenerator() {
|
||||||
final String name = getProfile().getDeckGeneratorName();
|
final String name = getProfile().getDeckGeneratorName();
|
||||||
|
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DeckGenerators.getInstance().getDeckGenerator(name);
|
return DeckGenerators.getInstance().getDeckGenerator(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateDeck(final DefaultDeckGenerator defaultGenerator) {
|
void generateDeck(final DefaultDeckGenerator defaultGenerator) {
|
||||||
final DefaultDeckGenerator customGenerator = getDeckGenerator();
|
final DefaultDeckGenerator customGenerator = getDeckGenerator();
|
||||||
|
|
||||||
if(customGenerator == null) {
|
if(customGenerator == null) {
|
||||||
defaultGenerator.generateDeck(DECK_SIZE, profile, deck);
|
defaultGenerator.generateDeck(DECK_SIZE, profile, deck);
|
||||||
} else {
|
} else {
|
||||||
customGenerator.generateDeck(DECK_SIZE, profile, deck);
|
customGenerator.generateDeck(DECK_SIZE, profile, deck);
|
||||||
}
|
}
|
||||||
|
|
||||||
addBasicLandsToDeck();
|
addBasicLandsToDeck();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getDeckPrefix(final String prefix,final int index) {
|
private static String getDeckPrefix(final String prefix,final int index) {
|
||||||
return prefix+"deck"+index;
|
return prefix+"deck"+index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void load(final Properties properties,final String prefix) {
|
void load(final Properties properties,final String prefix) {
|
||||||
name=properties.getProperty(prefix+NAME,"");
|
name=properties.getProperty(prefix+NAME,"");
|
||||||
artificial=Boolean.parseBoolean(properties.getProperty(prefix+ARTIFICIAL,"true"));
|
artificial=Boolean.parseBoolean(properties.getProperty(prefix+ARTIFICIAL,"true"));
|
||||||
|
@ -159,13 +159,13 @@ public class MagicPlayerDefinition {
|
||||||
|
|
||||||
magic.data.DeckUtils.showUnsupportedCards(unsupported);
|
magic.data.DeckUtils.showUnsupportedCards(unsupported);
|
||||||
}
|
}
|
||||||
|
|
||||||
void save(final Properties properties,final String prefix) {
|
void save(final Properties properties,final String prefix) {
|
||||||
properties.setProperty(prefix+NAME,name);
|
properties.setProperty(prefix+NAME,name);
|
||||||
properties.setProperty(prefix+ARTIFICIAL,Boolean.toString(artificial));
|
properties.setProperty(prefix+ARTIFICIAL,Boolean.toString(artificial));
|
||||||
properties.setProperty(prefix+COLORS,getProfile().getColorText());
|
properties.setProperty(prefix+COLORS,getProfile().getColorText());
|
||||||
properties.setProperty(prefix+FACE,Integer.toString(face));
|
properties.setProperty(prefix+FACE,Integer.toString(face));
|
||||||
|
|
||||||
int index=1;
|
int index=1;
|
||||||
for (final MagicCardDefinition cardDefinition : deck) {
|
for (final MagicCardDefinition cardDefinition : deck) {
|
||||||
properties.setProperty(getDeckPrefix(prefix,index++),cardDefinition.getFullName());
|
properties.setProperty(getDeckPrefix(prefix,index++),cardDefinition.getFullName());
|
||||||
|
|
|
@ -1,78 +1,78 @@
|
||||||
package magic.model;
|
package magic.model;
|
||||||
|
|
||||||
public class MagicPlayerProfile {
|
public class MagicPlayerProfile {
|
||||||
|
|
||||||
private String deckGeneratorName;
|
private String deckGeneratorName;
|
||||||
private String colorText;
|
private String colorText;
|
||||||
private MagicColor[] colors;
|
private MagicColor[] colors;
|
||||||
private boolean isPreConstructed;
|
private boolean isPreConstructed;
|
||||||
|
|
||||||
public MagicPlayerProfile(final String colorText) {
|
public MagicPlayerProfile(final String colorText) {
|
||||||
this(colorText, null);
|
this(colorText, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicPlayerProfile(final String colorText, final String deckGeneratorName) {
|
public MagicPlayerProfile(final String colorText, final String deckGeneratorName) {
|
||||||
setColors(colorText);
|
setColors(colorText);
|
||||||
setDeckGeneratorName(deckGeneratorName);
|
setDeckGeneratorName(deckGeneratorName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setColors(final String colorText) {
|
public void setColors(final String colorText) {
|
||||||
|
|
||||||
this.colorText=colorText;
|
this.colorText=colorText;
|
||||||
colors=new MagicColor[colorText.length()];
|
colors=new MagicColor[colorText.length()];
|
||||||
for (int i=0;i<colorText.length();i++) {
|
for (int i=0;i<colorText.length();i++) {
|
||||||
|
|
||||||
colors[i]=MagicColor.getColor(colorText.charAt(i));
|
colors[i]=MagicColor.getColor(colorText.charAt(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDeckGeneratorName(final String name) {
|
public void setDeckGeneratorName(final String name) {
|
||||||
this.deckGeneratorName = name;
|
this.deckGeneratorName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDeckGeneratorName() {
|
public String getDeckGeneratorName() {
|
||||||
return deckGeneratorName;
|
return deckGeneratorName;
|
||||||
}
|
}
|
||||||
|
|
||||||
String getColorText() {
|
String getColorText() {
|
||||||
|
|
||||||
return colorText;
|
return colorText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MagicColor[] getColors() {
|
public MagicColor[] getColors() {
|
||||||
|
|
||||||
return colors;
|
return colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getNrOfColors() {
|
int getNrOfColors() {
|
||||||
|
|
||||||
return colors.length;
|
return colors.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getNrOfNonBasicLands(final int amount) {
|
public int getNrOfNonBasicLands(final int amount) {
|
||||||
|
|
||||||
switch (colors.length) {
|
switch (colors.length) {
|
||||||
case 3: return amount/2;
|
case 3: return amount/2;
|
||||||
case 2: return amount/4;
|
case 2: return amount/4;
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean allowsManaType(final MagicManaType manaType) {
|
boolean allowsManaType(final MagicManaType manaType) {
|
||||||
|
|
||||||
for (final MagicColor color : colors) {
|
for (final MagicColor color : colors) {
|
||||||
|
|
||||||
if (color.getManaType()==manaType) {
|
if (color.getManaType()==manaType) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPreConstructed() {
|
public void setPreConstructed() {
|
||||||
isPreConstructed = true;
|
isPreConstructed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPreConstructed() {
|
public boolean isPreConstructed() {
|
||||||
return isPreConstructed;
|
return isPreConstructed;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,23 +9,23 @@ public enum MagicPlayerState {
|
||||||
CantCastSpells("can't cast spells this turn"),
|
CantCastSpells("can't cast spells this turn"),
|
||||||
CantActivateAbilities("can't activate abilities this turn"),
|
CantActivateAbilities("can't activate abilities this turn"),
|
||||||
;
|
;
|
||||||
|
|
||||||
private final String description;
|
private final String description;
|
||||||
private final int mask;
|
private final int mask;
|
||||||
|
|
||||||
private MagicPlayerState(final String description) {
|
private MagicPlayerState(final String description) {
|
||||||
this.description=description;
|
this.description=description;
|
||||||
this.mask=1<<ordinal();
|
this.mask=1<<ordinal();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMask() {
|
public int getMask() {
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasState(final int flags) {
|
public boolean hasState(final int flags) {
|
||||||
return (flags&mask)!=0;
|
return (flags&mask)!=0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,12 @@ public class MagicPowerToughness {
|
||||||
|
|
||||||
private int power;
|
private int power;
|
||||||
private int toughness;
|
private int toughness;
|
||||||
|
|
||||||
public MagicPowerToughness(final int aPower,final int aToughness) {
|
public MagicPowerToughness(final int aPower,final int aToughness) {
|
||||||
power = aPower;
|
power = aPower;
|
||||||
toughness = aToughness;
|
toughness = aToughness;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int power() {
|
public int power() {
|
||||||
return power;
|
return power;
|
||||||
}
|
}
|
||||||
|
@ -17,34 +17,34 @@ public class MagicPowerToughness {
|
||||||
public int toughness() {
|
public int toughness() {
|
||||||
return toughness;
|
return toughness;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getPositivePower() {
|
public int getPositivePower() {
|
||||||
return power>0?power:0;
|
return power>0?power:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getPositiveToughness() {
|
public int getPositiveToughness() {
|
||||||
return toughness>0?toughness:0;
|
return toughness>0?toughness:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(final MagicPowerToughness pt) {
|
public void add(final MagicPowerToughness pt) {
|
||||||
power += pt.power;
|
power += pt.power;
|
||||||
toughness += pt.toughness;
|
toughness += pt.toughness;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(final int pAmount, final int tAmount) {
|
public void add(final int pAmount, final int tAmount) {
|
||||||
power += pAmount;
|
power += pAmount;
|
||||||
toughness += tAmount;
|
toughness += tAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set(final int pAmount, final int tAmount) {
|
public void set(final int pAmount, final int tAmount) {
|
||||||
power = pAmount;
|
power = pAmount;
|
||||||
toughness = tAmount;
|
toughness = tAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPower(final int tAmount) {
|
public void setPower(final int tAmount) {
|
||||||
power = tAmount;
|
power = tAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setToughness(final int tAmount) {
|
public void setToughness(final int tAmount) {
|
||||||
toughness = tAmount;
|
toughness = tAmount;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import magic.MersenneTwisterFast;
|
||||||
public class MagicRandom {
|
public class MagicRandom {
|
||||||
|
|
||||||
private static final MersenneTwisterFast RNG;
|
private static final MersenneTwisterFast RNG;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
final String seedStr = System.getProperty("rndSeed");
|
final String seedStr = System.getProperty("rndSeed");
|
||||||
if (seedStr != null) {
|
if (seedStr != null) {
|
||||||
|
@ -17,7 +17,7 @@ public class MagicRandom {
|
||||||
}
|
}
|
||||||
|
|
||||||
private MagicRandom() {}
|
private MagicRandom() {}
|
||||||
|
|
||||||
public static int nextInt(final int n) {
|
public static int nextInt(final int n) {
|
||||||
return RNG.nextInt(n);
|
return RNG.nextInt(n);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ public enum MagicRarity {
|
||||||
Mythic_Rare('M');
|
Mythic_Rare('M');
|
||||||
|
|
||||||
public static final int length = values().length;
|
public static final int length = values().length;
|
||||||
|
|
||||||
private final char c;
|
private final char c;
|
||||||
|
|
||||||
private MagicRarity(final char c) {
|
private MagicRarity(final char c) {
|
||||||
|
@ -22,7 +22,7 @@ public enum MagicRarity {
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return toString().replace('_',' ');
|
return toString().replace('_',' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MagicRarity getRarity(final char c) {
|
public static MagicRarity getRarity(final char c) {
|
||||||
for (final MagicRarity type : values()) {
|
for (final MagicRarity type : values()) {
|
||||||
if (type.c == c) {
|
if (type.c == c) {
|
||||||
|
|
|
@ -7,17 +7,17 @@ public enum MagicStaticType {
|
||||||
Player("player"),
|
Player("player"),
|
||||||
Opponent("opponent")
|
Opponent("opponent")
|
||||||
;
|
;
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
private MagicStaticType(final String name) {
|
private MagicStaticType(final String name) {
|
||||||
this.name=name;
|
this.name=name;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getName() {
|
private String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getScore(final MagicPermanent scorePermanent) {
|
public int getScore(final MagicPermanent scorePermanent) {
|
||||||
if (this==None) {
|
if (this==None) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -41,7 +41,7 @@ public enum MagicStaticType {
|
||||||
}
|
}
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MagicStaticType getStaticTypeFor(final String name) {
|
public static MagicStaticType getStaticTypeFor(final String name) {
|
||||||
for (final MagicStaticType type : values()) {
|
for (final MagicStaticType type : values()) {
|
||||||
if (type.getName().equalsIgnoreCase(name)) {
|
if (type.getName().equalsIgnoreCase(name)) {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue