remove extraneous whitespace

master
melvin 2013-06-24 09:33:35 +08:00
parent cd385a4be8
commit 64368e1b9a
633 changed files with 6466 additions and 6466 deletions

View File

@ -12,7 +12,7 @@ import magic.ui.GameController;
import java.io.File;
public class DeckStrCal {
private static int games = 10;
private static int repeat = 1;
private static int str1 = 6;
@ -95,14 +95,14 @@ public class DeckStrCal {
validArgs = false;
}
}
if (deck1.length() == 0) {
System.err.println("Using player profile to generate deck 1");
} else if (!(new File(deck1)).exists()) {
System.err.println("Error: file " + deck1 + " does not exist");
validArgs = false;
}
if (deck2.length() == 0) {
System.err.println("Using player profile to generate deck 2");
} else if (!(new File(deck2)).exists()) {
@ -130,7 +130,7 @@ public class DeckStrCal {
testDuel.initialize();
testDuel.setDifficulty(0, str1);
testDuel.setDifficulty(1, str2);
// Set the AI
testDuel.setAIs(new MagicAI[]{ai1.getAI(), ai2.getAI()});
testDuel.getPlayer(0).setArtificial(true);
@ -138,7 +138,7 @@ public class DeckStrCal {
// Set the deck.
if (deck1.length() > 0) {
DeckUtils.loadDeck(deck1, testDuel.getPlayer(0));
DeckUtils.loadDeck(deck1, testDuel.getPlayer(0));
}
if (deck2.length() > 0) {
DeckUtils.loadDeck(deck2, testDuel.getPlayer(1));
@ -146,11 +146,11 @@ public class DeckStrCal {
return testDuel;
}
public static void main(final String[] args) {
// setup the handler for any uncaught exception
Thread.setDefaultUncaughtExceptionHandler(new magic.model.MagicGameReport());
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("Options:");
@ -160,7 +160,7 @@ public class DeckStrCal {
System.err.println("--games <1-*> (number of games to play, default 10)");
System.exit(1);
}
// Load cards and cubes.
MagicMain.initializeEngine();
@ -168,10 +168,10 @@ public class DeckStrCal {
runDuel();
}
}
private static void runDuel() {
final MagicDuel testDuel = setupDuel();
System.out.println(
"#deck1" +
"\tai1" +
@ -181,15 +181,15 @@ public class DeckStrCal {
"\tstr2" +
"\tgames" +
"\td1win"+
"\td1lose"
);
"\td1lose"
);
int played = 0;
while (!testDuel.isFinished()) {
final MagicGame game=testDuel.nextGame(false);
game.setArtificial(true);
final GameController controller=new GameController(game);
//maximum duration of a game is 60 minutes
controller.setMaxTestGameDuration(3600000);
@ -199,13 +199,13 @@ public class DeckStrCal {
deck1 + "\t" +
ai1 + "\t" +
str1 + "\t" +
deck2 + "\t" +
deck2 + "\t" +
ai2 + "\t" +
str2 + "\t" +
testDuel.getGamesTotal() + "\t" +
testDuel.getGamesWon() + "\t" +
(testDuel.getGamesPlayed() - testDuel.getGamesWon())
);
);
played = testDuel.getGamesPlayed();
}
}
@ -213,12 +213,12 @@ public class DeckStrCal {
deck1 + "\t" +
ai1 + "\t" +
str1 + "\t" +
deck2 + "\t" +
deck2 + "\t" +
ai2 + "\t" +
str2 + "\t" +
testDuel.getGamesTotal() + "\t" +
testDuel.getGamesWon() + "\t" +
(testDuel.getGamesPlayed() - testDuel.getGamesWon())
);
);
}
}

View File

@ -43,14 +43,14 @@ import java.awt.image.BufferedImage;
/**
* <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 rbair
* @author Karl Schaefer
*/
public class GraphicsUtilities {
public static BufferedImage scale(
final BufferedImage img,
final int targetWidth,
@ -59,10 +59,10 @@ public class GraphicsUtilities {
return img;
} else {
return scale(
img,
targetWidth,
targetHeight,
RenderingHints.VALUE_INTERPOLATION_BILINEAR,
img,
targetWidth,
targetHeight,
RenderingHints.VALUE_INTERPOLATION_BILINEAR,
true);
}
}
@ -111,7 +111,7 @@ public class GraphicsUtilities {
w = targetWidth;
h = targetHeight;
}
do {
if (higherQuality && w > targetWidth) {
w /= 2;

View File

@ -15,27 +15,27 @@ import javax.swing.UIManager.LookAndFeelInfo;
import java.io.File;
public class MagicMain {
private static final String GAME_FOLDER = "Magarena";
private static final String MODS_PATH = "mods";
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") :
System.getProperty("user.dir")) +
File.separatorChar +
GAME_FOLDER;
public static void main(final String[] args) {
// setup the handler for any uncaught exception
Thread.setDefaultUncaughtExceptionHandler(new magic.model.MagicGameReport());
// setup the game log
MagicGameLog.initialize();
// show the data folder being used
System.err.println("Data folder : "+GAME_PATH);
// try to set the look and feel
try {
for (final LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
@ -44,17 +44,17 @@ public class MagicMain {
break;
}
}
// customize nimbus look
UIManager.getLookAndFeelDefaults().put("Table.showGrid", true);
// removes hardcoded border
UIManager.getLookAndFeelDefaults().put("ScrollPane[Enabled].borderPainter", null);
}
UIManager.getLookAndFeelDefaults().put("ScrollPane[Enabled].borderPainter", null);
}
catch (Exception e) {
System.err.println("Unable to set look and feel. Probably missing the latest version of Java 6.");
e.printStackTrace();
}
final long start_time = System.currentTimeMillis();
initialize();
final double duration = (double)(System.currentTimeMillis() - start_time) / 1000;
@ -64,21 +64,21 @@ public class MagicMain {
new MagicFrame();
}
});
}
}
public static String getGamePath() {
return GAME_PATH;
}
public static String getGameFolder() {
return GAME_FOLDER;
}
public static String getModsPath() {
return getGamePath()+File.separatorChar+MODS_PATH;
}
public static String getScriptsPath() {
return getGamePath()+File.separatorChar+SCRIPTS_PATH;
}
@ -90,7 +90,7 @@ public class MagicMain {
KeywordDefinitions.getInstance().loadKeywordDefinitions();
DeckGenerators.getInstance().loadDeckGenerators();
}
private static void initialize() {
final File gamePathFile = new File(getGamePath());
if (!gamePathFile.exists() && !gamePathFile.mkdir()) {
@ -101,7 +101,7 @@ public class MagicMain {
if (!modsPathFile.exists() && !modsPathFile.mkdir()) {
System.err.println("Unable to create directory " + getModsPath());
}
DeckUtils.createDeckFolder();
History.createHistoryFolder();
initializeEngine();

View File

@ -22,7 +22,7 @@ public class MagicTools {
System.out.println(name);
}
}
private static void checkCards() {
final String[] filenames = new File(MagicMain.getGamePath(),"cards").list();
final Set<MagicCardDefinition> remaining = new HashSet<MagicCardDefinition>(CardDefinitions.getCards());
@ -37,7 +37,7 @@ public class MagicTools {
}
}
}
public static void main(final String[] args) {
MagicMain.initializeEngine();
checkCards();

View File

@ -5,15 +5,15 @@ import java.io.DataOutputStream;
import java.io.IOException;
import java.io.Serializable;
/**
/**
* <h3>MersenneTwister and MersenneTwisterFast</h3>
* <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">
* The Mersenne Twister Home Page</a>, with the initialization
* improved using the new 2002/1/26 initialization algorithm
* By Sean Luke, October 2004.
*
*
* <p><b>MersenneTwister</b> is a drop-in subclass replacement
* for java.util.Random. It is properly synchronized and
* 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
* 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
* 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
* than MersenneTwisterFast (which should be the case, as it's a less complex
* algorithm but is synchronized).
*
*
* <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
* milliseconds.
@ -100,17 +100,17 @@ import java.io.Serializable;
* (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>)
*
* <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,
* with suggestions from Topher Cooper and Marc Rieffel, July 1997.
* The code was originally translated into Java by Michael Lecuyer,
* January 1999, and the original code is Copyright (c) 1999 by Michael Lecuyer.
*
* <h3>Java notes</h3>
*
*
* <p>This implementation implements the bug fixes made
* 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">
* the JDK 1.2 java.util.Random documentation</a> for further documentation
* 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).
* 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
* java.util.Random; only MersenneTwisterFast (and not MersenneTwister nor
* java.util.Random) should be used with them.
@ -133,28 +133,28 @@ import java.io.Serializable;
* Portions copyright (c) 1993 by Michael Lecuyer. <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:
* <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.
* <li> Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* <li> Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* <li> Neither the name of the copyright owners, their employers, nor the
* names of its contributors may be used to endorse or promote products
* <li> Neither the name of the copyright owners, their employers, nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
* </ul>
* <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
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNERS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* <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
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNERS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
@version 17
@ -170,7 +170,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
{
// Serialization
private static final long serialVersionUID = -8219700664442619525L; // locked as of Version 15
// Period parameters
private static final int N = 624;
private static final int M = 397;
@ -182,17 +182,17 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
// Tempering parameters
private static final int TEMPERING_MASK_B = 0x9d2c5680;
private static final int TEMPERING_MASK_C = 0xefc60000;
private int[] mt; // the array for the state vector
private int mti; // mti==N+1 means mt[N] is not initialized
private int[] mag01;
// a good initial seed (of int size, though stored in a long)
//private static final long GOOD_SEED = 4357;
private double __nextNextGaussian;
private boolean __haveNextNextGaussian;
/* We're overriding all internal data, to my knowledge, so this should be okay */
public Object clone()
{
@ -205,7 +205,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
}
catch (CloneNotSupportedException e) { throw new InternalError(); } // should never happen
}
public boolean stateEquals(final Object o)
{
if (o==this) return true;
@ -225,24 +225,24 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
{
int len = mt.length;
for(int x=0;x<len;x++) mt[x] = stream.readInt();
len = mag01.length;
for(int x=0;x<len;x++) mag01[x] = stream.readInt();
mti = stream.readInt();
__nextNextGaussian = stream.readDouble();
__haveNextNextGaussian = stream.readBoolean();
}
/** Writes the entire state of the MersenneTwister RNG to the stream */
public void writeState(final DataOutputStream stream) throws IOException
{
int len = mt.length;
for(int x=0;x<len;x++) stream.writeInt(mt[x]);
len = mag01.length;
for(int x=0;x<len;x++) stream.writeInt(mag01[x]);
stream.writeInt(mti);
stream.writeDouble(__nextNextGaussian);
stream.writeBoolean(__haveNextNextGaussian);
@ -255,7 +255,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
{
this(System.currentTimeMillis());
}
/**
* 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.
@ -265,7 +265,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
{
setSeed(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
* 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)
@ -292,16 +292,16 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
__haveNextNextGaussian = false;
mt = new int[N];
mag01 = new int[2];
mag01[0] = 0x0;
mag01[1] = MATRIX_A;
mt[0]= (int)(seed & 0xffffffff);
for (mti=1; mti<N; mti++)
for (mti=1; mti<N; mti++)
{
mt[mti] =
(1812433253 * (mt[mti-1] ^ (mt[mti-1] >>> 30)) + mti);
mt[mti] =
(1812433253 * (mt[mti-1] ^ (mt[mti-1] >>> 30)) + mti);
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
/* In the previous versions, MSBs of the seed affect */
/* only MSBs of the array mt[]. */
@ -327,7 +327,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
setSeed(19650218);
i=1; j=0;
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] &= 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 (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] &= 0xffffffff; /* for WORDSIZE > 32 machines */
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()
{
int y;
if (mti >= N) // generate N words at one time
{
int kk;
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
for (kk = 0; kk < N - M; kk++)
{
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
@ -375,7 +375,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
mti = 0;
}
y = mt[mti++];
y ^= y >>> 11; // TEMPERING_SHIFT_U(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()
{
int y;
if (mti >= N) // generate N words at one time
{
int kk;
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
for (kk = 0; kk < N - M; kk++)
{
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
@ -412,7 +412,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
mti = 0;
}
y = mt[mti++];
y ^= y >>> 11; // TEMPERING_SHIFT_U(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()
{
int y;
if (mti >= N) // generate N words at one time
{
int kk;
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
for (kk = 0; kk < N - M; kk++)
{
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
@ -449,7 +449,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
mti = 0;
}
y = mt[mti++];
y ^= y >>> 11; // TEMPERING_SHIFT_U(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()
{
int y;
if (mti >= N) // generate N words at one time
{
int kk;
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
for (kk = 0; kk < N - M; kk++)
{
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
@ -485,7 +485,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
mti = 0;
}
y = mt[mti++];
y ^= y >>> 11; // TEMPERING_SHIFT_U(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)
{
int y;
if (probability < 0.0f || probability > 1.0f)
throw new IllegalArgumentException ("probability must be between 0.0 and 1.0 inclusive.");
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
{
int kk;
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
for (kk = 0; kk < N - M; kk++)
{
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
@ -532,7 +532,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
mti = 0;
}
y = mt[mti++];
y ^= y >>> 11; // TEMPERING_SHIFT_U(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
{
int kk;
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
for (kk = 0; kk < N - M; kk++)
{
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
@ -577,7 +577,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
mti = 0;
}
y = mt[mti++];
y ^= y >>> 11; // TEMPERING_SHIFT_U(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
{
int kk;
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
for (kk = 0; kk < N - M; kk++)
{
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);
mt[N-1] = mt[M-1] ^ (z >>> 1) ^ mag01[z & 0x1];
mti = 0;
}
z = mt[mti++];
z ^= z >>> 11; // TEMPERING_SHIFT_U(z)
z ^= (z << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(z)
z ^= (z << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(z)
z ^= (z >>> 18); // TEMPERING_SHIFT_L(z)
/* derived from nextDouble documentation in jdk 1.2 docs, see top */
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()
{
int y;
if (mti >= N) // generate N words at one time
{
int kk;
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
for (kk = 0; kk < N - M; kk++)
{
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
@ -642,7 +642,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
mti = 0;
}
y = mt[mti++];
y ^= y >>> 11; // TEMPERING_SHIFT_U(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)
{
int y;
for (int x=0;x<bytes.length;x++)
{
if (mti >= N) // generate N words at one time
{
int kk;
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
for (kk = 0; kk < N - M; kk++)
{
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);
mt[N-1] = mt[M-1] ^ (y >>> 1) ^ mag01[y & 0x1];
mti = 0;
}
y = mt[mti++];
y ^= y >>> 11; // TEMPERING_SHIFT_U(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
{
int kk;
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
for (kk = 0; kk < N - M; kk++)
{
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
@ -718,7 +718,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
mti = 0;
}
y = mt[mti++];
y ^= y >>> 11; // TEMPERING_SHIFT_U(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
{
int kk;
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
for (kk = 0; kk < N - M; kk++)
{
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);
mt[N-1] = mt[M-1] ^ (z >>> 1) ^ mag01[z & 0x1];
mti = 0;
}
z = mt[mti++];
z ^= z >>> 11; // TEMPERING_SHIFT_U(z)
z ^= (z << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(z)
z ^= (z << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(z)
z ^= (z >>> 18); // TEMPERING_SHIFT_L(z)
return (((long)y) << 32) + (long)z;
}
@ -764,19 +764,19 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
{
if (n<=0)
throw new IllegalArgumentException("n must be positive, got: " + n);
long bits, val;
do
do
{
int y;
int z;
if (mti >= N) // generate N words at one time
{
int kk;
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
for (kk = 0; kk < N - M; kk++)
{
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);
mt[N-1] = mt[M-1] ^ (y >>> 1) ^ mag01[y & 0x1];
mti = 0;
}
y = mt[mti++];
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
y ^= (y << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(y)
y ^= (y >>> 18); // TEMPERING_SHIFT_L(y)
if (mti >= N) // generate N words at one time
{
int kk;
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
for (kk = 0; kk < N - M; kk++)
{
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);
mt[N-1] = mt[M-1] ^ (z >>> 1) ^ mag01[z & 0x1];
mti = 0;
}
z = mt[mti++];
z ^= z >>> 11; // TEMPERING_SHIFT_U(z)
z ^= (z << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(z)
z ^= (z << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(z)
z ^= (z >>> 18); // TEMPERING_SHIFT_L(z)
bits = (((((long)y) << 32) + (long)z) >>> 1);
val = bits % n;
} 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
{
int kk;
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
for (kk = 0; kk < N - M; kk++)
{
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
@ -861,7 +861,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
mti = 0;
}
y = mt[mti++];
y ^= y >>> 11; // TEMPERING_SHIFT_U(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
{
int kk;
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
for (kk = 0; kk < N - M; kk++)
{
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);
mt[N-1] = mt[M-1] ^ (z >>> 1) ^ mag01[z & 0x1];
mti = 0;
}
z = mt[mti++];
z ^= z >>> 11; // TEMPERING_SHIFT_U(z)
z ^= (z << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(z)
z ^= (z << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(z)
z ^= (z >>> 18); // TEMPERING_SHIFT_L(z)
/* derived from nextDouble documentation in jdk 1.2 docs, see top */
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(true, true)<td>[0.0, 1.0]
</table>
<p>This version preserves all possible random values in the double range.
*/
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)
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
(!includeZero && d == 0.0)); // if we're not including zero, 0.0 is invalid
return d;
@ -935,23 +935,23 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
{
__haveNextNextGaussian = false;
return __nextNextGaussian;
}
else
}
else
{
double v1, v2, s;
do
{
do
{
int y;
int z;
int a;
int b;
if (mti >= N) // generate N words at one time
{
int kk;
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
for (kk = 0; kk < N - M; kk++)
{
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);
mt[N-1] = mt[M-1] ^ (y >>> 1) ^ mag01[y & 0x1];
mti = 0;
}
y = mt[mti++];
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
y ^= (y << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(y)
y ^= (y >>> 18); // TEMPERING_SHIFT_L(y)
if (mti >= N) // generate N words at one time
{
int kk;
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
for (kk = 0; kk < N - M; kk++)
{
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);
mt[N-1] = mt[M-1] ^ (z >>> 1) ^ mag01[z & 0x1];
mti = 0;
}
z = mt[mti++];
z ^= z >>> 11; // TEMPERING_SHIFT_U(z)
z ^= (z << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(z)
z ^= (z << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(z)
z ^= (z >>> 18); // TEMPERING_SHIFT_L(z)
if (mti >= N) // generate N words at one time
{
int kk;
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
for (kk = 0; kk < N - M; kk++)
{
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);
mt[N-1] = mt[M-1] ^ (a >>> 1) ^ mag01[a & 0x1];
mti = 0;
}
a = mt[mti++];
a ^= a >>> 11; // TEMPERING_SHIFT_U(a)
a ^= (a << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(a)
a ^= (a << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(a)
a ^= (a >>> 18); // TEMPERING_SHIFT_L(a)
if (mti >= N) // generate N words at one time
{
int kk;
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
for (kk = 0; kk < N - M; kk++)
{
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);
mt[N-1] = mt[M-1] ^ (b >>> 1) ^ mag01[b & 0x1];
mti = 0;
}
b = mt[mti++];
b ^= b >>> 11; // TEMPERING_SHIFT_U(b)
b ^= (b << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(b)
b ^= (b << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(b)
b ^= (b >>> 18); // TEMPERING_SHIFT_L(b)
/* derived from nextDouble documentation in jdk 1.2 docs, see top */
v1 = 2 *
(((((long)(y >>> 6)) << 27) + (z >>> 5)) / (double)(1L << 53))
@ -1072,23 +1072,23 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
return v1 * multiplier;
}
}
/** 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. */
public final float nextFloat()
{
int y;
if (mti >= N) // generate N words at one time
{
int kk;
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
for (kk = 0; kk < N - M; kk++)
{
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
@ -1104,7 +1104,7 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
mti = 0;
}
y = mt[mti++];
y ^= y >>> 11; // TEMPERING_SHIFT_U(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(true, true)<td>[0.0f, 1.0f]
</table>
<p>This version preserves all possible random values in the float range.
*/
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)
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
(!includeZero && d == 0.0f)); // if we're not including zero, 0.0f is invalid
return d;
@ -1148,17 +1148,17 @@ public strictfp class MersenneTwisterFast implements Serializable, Cloneable
{
if (n<=0)
throw new IllegalArgumentException("n must be positive, got: " + n);
if ((n & -n) == n) // i.e., n is a power of 2
{
int y;
if (mti >= N) // generate N words at one time
{
int kk;
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
for (kk = 0; kk < N - M; kk++)
{
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);
mt[N-1] = mt[M-1] ^ (y >>> 1) ^ mag01[y & 0x1];
mti = 0;
}
y = mt[mti++];
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
y ^= (y << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(y)
y ^= (y >>> 18); // TEMPERING_SHIFT_L(y)
return (int)((n * (long) (y >>> 1) ) >> 31);
}
int bits, val;
do
do
{
int y;
if (mti >= N) // generate N words at one time
{
int kk;
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
final int[] mt = this.mt; // locals are slightly faster
final int[] mag01 = this.mag01; // locals are slightly faster
for (kk = 0; kk < N - M; kk++)
{
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);
mt[N-1] = mt[M-1] ^ (y >>> 1) ^ mag01[y & 0x1];
mti = 0;
}
y = mt[mti++];
y ^= y >>> 11; // TEMPERING_SHIFT_U(y)
y ^= (y << 7) & TEMPERING_MASK_B; // TEMPERING_SHIFT_S(y)
y ^= (y << 15) & TEMPERING_MASK_C; // TEMPERING_SHIFT_T(y)
y ^= (y >>> 18); // TEMPERING_SHIFT_L(y)
bits = (y >>> 1);
val = bits % n;
} while(bits - val + (n-1) < 0);

View File

@ -27,11 +27,11 @@ package magic;
* MurmurHash3 implementation in Java, based on Austin Appleby's <a href=
* "https://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp"
* >original in C</a>
*
*
* 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
* be as fast or faster than the x86 version on some modern 32 bit processors.
*
*
* @author Patrick McFarland
* @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>
@ -96,7 +96,7 @@ public class MurmurHash3 {
/**
* Hash a value using the x64 128 bit variant of MurmurHash3
*
*
* @param key value to hash
* @param seed random value
* @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
*
*
* @param key value to hash
* @param seed random value
* @return 64 bit hashed key
@ -170,7 +170,7 @@ public class MurmurHash3 {
/**
* Hash a value using the x64 32 bit variant of MurmurHash3
*
*
* @param key value to hash
* @param seed random value
* @return 32 bit hashed key
@ -181,7 +181,7 @@ public class MurmurHash3 {
/**
* Hash a value using the x64 128 bit variant of MurmurHash3
*
*
* @param key value to hash
* @param seed random value
* @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
*
*
* @param key value to hash
* @param seed random value
* @return 64 bit hashed key
@ -236,7 +236,7 @@ public class MurmurHash3 {
/**
* Hash a value using the x64 32 bit variant of MurmurHash3
*
*
* @param key value to hash
* @param seed random value
* @return 32 bit hashed key

View File

@ -1,7 +1,7 @@
package magic.ai;
public class ArtificialChoiceResults {
final Object[] choiceResults;
ArtificialScore aiScore=ArtificialScore.INVALID_SCORE;
int worker=-1;
@ -10,7 +10,7 @@ public class ArtificialChoiceResults {
ArtificialChoiceResults(final Object[] choiceResults) {
this.choiceResults=choiceResults;
}
public String toString() {
final StringBuilder buffer=new StringBuilder();
buffer.append("[").append(worker).append('/').append(gameCount).append('/').append(aiScore).append("]");

View File

@ -1,24 +1,24 @@
package magic.ai;
public class ArtificialMultiPruneScore implements ArtificialPruneScore {
private final int maxBest;
private final int minWorst;
private ArtificialMultiPruneScore(final int maxBest,final int minWorst) {
this.maxBest=maxBest;
this.minWorst=minWorst;
}
ArtificialMultiPruneScore() {
this(Integer.MIN_VALUE,Integer.MAX_VALUE);
}
@Override
public int getScore() {
return maxBest; // Does matter for game id.
}
@Override
public boolean pruneScore(final int score,final boolean best) {
return best?score>minWorst:score<maxBest;
@ -32,7 +32,7 @@ public class ArtificialMultiPruneScore implements ArtificialPruneScore {
return score<minWorst?new ArtificialMultiPruneScore(maxBest,score):this;
}
}
@Override
public String toString() {
return maxBest+" / "+minWorst;

View File

@ -1,10 +1,10 @@
package magic.ai;
public interface ArtificialPruneScore {
int getScore();
boolean pruneScore(final int score,final boolean best);
ArtificialPruneScore getPruneScore(final int score,final boolean best);
ArtificialPruneScore getPruneScore(final int score,final boolean best);
}

View File

@ -1,5 +1,5 @@
package magic.ai;
class ArtificialPruneScoreRef {
private ArtificialPruneScore pruneScore;
@ -7,11 +7,11 @@ class ArtificialPruneScoreRef {
public ArtificialPruneScoreRef(final ArtificialPruneScore pScore) {
pruneScore = pScore;
}
public void update(final int score) {
pruneScore = pruneScore.getPruneScore(score,true);
}
public ArtificialPruneScore get() {
return pruneScore;
}

View File

@ -5,10 +5,10 @@ public class ArtificialScore {
static final ArtificialScore INVALID_SCORE=new ArtificialScore(0,0);
static final int MAX = 99900000;
static final int MIN = -MAX;
private final int score;
private final int depth;
ArtificialScore(final int aScore,final int aDepth) {
int boundedScore = Math.min(MAX,aScore);
score = Math.max(MIN,boundedScore);
@ -25,7 +25,7 @@ public class ArtificialScore {
int getScore() {
return score;
}
boolean isBetter(final ArtificialScore other,final boolean max) {
if (other==INVALID_SCORE) {
return false;
@ -44,11 +44,11 @@ public class ArtificialScore {
return other.score < score;
}
}
@Override
public String toString() {
if (this==INVALID_SCORE) {
return "none";
return "none";
}
final StringBuilder buffer=new StringBuilder();
buffer.append(score).append(" at ").append(depth);

View File

@ -5,7 +5,7 @@ import magic.data.LRUCache;
public class ArtificialScoreBoard {
private final LRUCache<Long,ArtificialScore> gameScoresMap;
ArtificialScoreBoard() {
gameScoresMap=new LRUCache<Long,ArtificialScore>(100000);
}
@ -13,11 +13,11 @@ public class ArtificialScoreBoard {
synchronized void setGameScore(final long gameId,final ArtificialScore aiScore) {
gameScoresMap.put(gameId,aiScore);
}
synchronized ArtificialScore getGameScore(final long gameId) {
return gameScoresMap.get(gameId);
}
}
synchronized void clear() {
gameScoresMap.clear();
}

View File

@ -19,15 +19,15 @@ public class ArtificialScoringSystem {
public static final int ITEM_ON_STACK_SCORE=-1;
public static final int UNEQUIP_SCORE=-100;
public static final int UNNECESSARY_EQUIP_SCORE=-1000;
private static final int[] LIFE_SCORES={
0,1000,2000,3000,4000,
4500,5000,5500,6000,6500,
7000,7400,7800,8200,8600,
9000,9200,9400,9600,9800,
0,1000,2000,3000,4000,
4500,5000,5500,6000,6500,
7000,7400,7800,8200,8600,
9000,9200,9400,9600,9800,
10000
};
private static final int[] POISON_SCORES={
5000,4700,4400,4100,3800,
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_POISON=10;
private static final int LIFE_ABOVE_MULTIPLIER=100;
private static final int UNKNOWN_CARD_SCORE=300;
private static final int PERMANENT_SCORE=300;
public static int getTurnScore(final MagicGame game) {
return Math.max(0,10-(game.getTurn()-1)>>1);
}
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.
return LOSE_GAME_SCORE+game.getTurn()*2500+game.getPhase().getType().ordinal()*200;
}
public static int getCardDefinitionScore(final MagicCardDefinition cardDefinition) {
return getCardDefinitionScore(cardDefinition, 1);
}
// score for a card that gets put into play without paying the mana cost
public static int getFreeCardDefinitionScore(final MagicCardDefinition cardDefinition) {
return getCardDefinitionScore(cardDefinition, 0);
}
private static int getCardDefinitionScore(final MagicCardDefinition cardDefinition, final int costFactor) {
if (cardDefinition.isLand()) {
int score=(int)(cardDefinition.getValue()*50);
@ -77,11 +77,11 @@ public class ArtificialScoringSystem {
return score+cardDefinition.getRemoval()*50+cardDefinition.getRarity()*30;
}
}
public static int getCardScore(final MagicCard card) {
return card.isKnown()?card.getCardDefinition().getScore():UNKNOWN_CARD_SCORE;
}
public static int getFreeCardScore(final MagicCard card) {
return card.isKnown()?card.getCardDefinition().getFreeScore():UNKNOWN_CARD_SCORE;
}
@ -90,16 +90,16 @@ public class ArtificialScoringSystem {
int score = permanent.getCardScore();
if (permanent.isCreature()) {
score+=permanent.getActivations().size()*50;
score+=permanent.getManaActivations().size()*80;
score+=permanent.getManaActivations().size()*80;
} else {
score+=PERMANENT_SCORE;
if (permanent.isEquipment()) {
score+=100;
}
}
}
return score;
}
public static int getVariablePermanentScore(final MagicPermanent permanent) {
int score=permanent.getCounters(MagicCounterType.Charge)*30;
if (!permanent.canTap()) {
@ -111,14 +111,14 @@ public class ArtificialScoringSystem {
final Set<MagicAbility> abilityFlags=permanent.getAbilityFlags();
score+=pt.power()*300+pt.getPositiveToughness()*200+MagicAbility.getScore(abilityFlags)*(pt.getPositivePower()+1)/2;
score+=permanent.getEquipmentPermanents().size()*50+permanent.getAuraPermanents().size()*100;
}
}
return score;
}
public static int getTappedScore(final MagicPermanent permanent) {
return permanent.isCreature()?-10:-5;
}
public static int getLifeScore(final int life) {
if (life>MAX_LIFE) {
return LIFE_SCORES[MAX_LIFE]+(life-MAX_LIFE)*LIFE_ABOVE_MULTIPLIER;
@ -128,42 +128,42 @@ public class ArtificialScoringSystem {
return 0;
}
}
public static int getPoisonScore(final int poison) {
if (poison>MAX_POISON) {
return POISON_SCORES[MAX_POISON];
}
return POISON_SCORES[poison];
}
public static int getManaScore(final int amount) {
return -amount;
}
public static int getAttackerScore(final MagicCombatCreature attacker) {
int score=attacker.power*5+attacker.lethalDamage*2-attacker.candidateBlockers.length;
for (final MagicCombatCreature blocker : attacker.candidateBlockers) {
score-=blocker.power;
}
// Dedicated attacker.
if (attacker.hasAbility(MagicAbility.AttacksEachTurnIfAble) ||
if (attacker.hasAbility(MagicAbility.AttacksEachTurnIfAble) ||
attacker.hasAbility(MagicAbility.CannotBlock)) {
score+=10;
}
// Abilities for attacking.
if (attacker.hasAbility(MagicAbility.Trample) ||
if (attacker.hasAbility(MagicAbility.Trample) ||
attacker.hasAbility(MagicAbility.Vigilance)) {
score+=8;
}
// Dangerous to block.
if (!attacker.normalDamage ||
attacker.hasAbility(MagicAbility.FirstStrike) ||
if (!attacker.normalDamage ||
attacker.hasAbility(MagicAbility.FirstStrike) ||
attacker.hasAbility(MagicAbility.Indestructible)) {
score+=7;
}
return score;
}
public static int getMillScore(final int amount) {
return -amount;
}

View File

@ -24,7 +24,7 @@ Classical MCTS (UCT)
- score = XX% (25000 matches against MMAB-1)
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 = 2.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
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
secure child formula for decision v + A/sqrt(n)
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
*/
public class MCTSAI implements MagicAI {
private static int MIN_SCORE = Integer.MAX_VALUE;
static int MIN_SIM = Integer.MAX_VALUE;
private static final int MAX_ACTIONS = 10000;
@ -72,12 +72,12 @@ public class MCTSAI implements MagicAI {
MIN_SCORE = Integer.parseInt(System.getProperty("min_score"));
System.err.println("MIN_SCORE = " + MIN_SCORE);
}
if (System.getProperty("ucb1_c") != null) {
UCB1_C = Double.parseDouble(System.getProperty("ucb1_c"));
System.err.println("UCB1_C = " + UCB1_C);
}
if (System.getProperty("ratio_k") != null) {
RATIO_K = Double.parseDouble(System.getProperty("ratio_k"));
System.err.println("RATIO_K = " + RATIO_K);
@ -105,7 +105,7 @@ public class MCTSAI implements MagicAI {
}
public Object[] findNextEventChoiceResults(
final MagicGame startGame,
final MagicGame startGame,
final MagicPlayer scorePlayer) {
// Determine possible choices
@ -115,21 +115,21 @@ public class MCTSAI implements MagicAI {
choiceGame = null;
final int size = RCHOICES.size();
// No choice
assert size > 0 : "ERROR! No choice found at start of MCTS";
// Single choice
if (size == 1) {
return startGame.map(RCHOICES.get(0));
}
//normal: max time is 1000 * level
int MAX_TIME = 1000 * startGame.getArtificialLevel(scorePlayer.getIndex());
int MAX_SIM = Integer.MAX_VALUE;
final long START_TIME = System.currentTimeMillis();
//root represents the start state
final MCTSGameTree root = MCTSGameTree.getNode(CACHE, startGame, RCHOICES);
@ -139,29 +139,29 @@ public class MCTSAI implements MagicAI {
int sims;
for (sims = 0;
System.currentTimeMillis() - START_TIME < MAX_TIME &&
sims < MAX_SIM &&
!root.isAIWin();
sims < MAX_SIM &&
!root.isAIWin();
sims++) {
//clone the MagicGame object for simulation
final MagicGame rootGame = new MagicGame(startGame, scorePlayer);
if (!CHEAT) {
rootGame.hideHiddenCards();
}
//pass in a clone of the state,
//pass in a clone of the state,
//genNewTreeNode grows the tree by one node
//and returns the path from the root to the new node
final LinkedList<MCTSGameTree> path = growTree(root, rootGame);
assert path.size() >= 2 : "ERROR! length of MCTS path is " + path.size();
// 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);
// update score and game theoretic value along the chosen path
MCTSGameTree child = null;
MCTSGameTree child = null;
MCTSGameTree parent = null;
while (!path.isEmpty()) {
child = parent;
@ -179,8 +179,8 @@ public class MCTSAI implements MagicAI {
parent.incLose(steps);
} else if (parent.isOpp() && child.isAIWin()) {
parent.incLose(steps);
}
}
}
}
}
}
@ -193,7 +193,7 @@ public class MCTSAI implements MagicAI {
for (final MCTSGameTree node : root) {
final double D = node.getDecision();
final int C = node.getChoice();
if (D > maxD) {
if (D > maxD) {
maxD = D;
bestC = C;
}
@ -203,22 +203,22 @@ public class MCTSAI implements MagicAI {
return startGame.map(RCHOICES.get(bestC));
}
private String outputChoice(
final MagicPlayer scorePlayer,
final MCTSGameTree root,
final long START_TIME,
final int bestC,
final MCTSGameTree root,
final long START_TIME,
final int bestC,
final int sims) {
final StringBuilder out = new StringBuilder();
final long duration = System.currentTimeMillis() - START_TIME;
out.append("MCTS" +
" cheat=" + CHEAT +
" index=" + scorePlayer.getIndex() +
" index=" + scorePlayer.getIndex() +
" life=" + scorePlayer.getLife() +
" time=" + duration +
" time=" + duration +
" sims=" + sims);
out.append('\n');
@ -262,16 +262,16 @@ public class MCTSAI implements MagicAI {
choices = getNextChoices(game, false)) {
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" +
game + " " +
printPath(path) + " " +
game + " " +
printPath(path) + " " +
MCTSGameTree.printNode(curr, choices);
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
if (!curr.hasDetails()) {
curr.setIsAI(game.getScorePlayer() == event.getPlayer());
@ -292,17 +292,17 @@ public class MCTSAI implements MagicAI {
final int idx = curr.size();
final Object[] choice = choices.get(idx);
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);
curr.addChild(child);
path.add(child);
return path;
//all the children are in the tree, find the "best" child to explore
} else {
assert curr.size() == choices.size() : "ERROR! Different number of choices in node and game" +
printPath(path) + MCTSGameTree.printNode(curr, choices);
assert curr.size() == choices.size() : "ERROR! Different number of choices in node and game" +
printPath(path) + MCTSGameTree.printNode(curr, choices);
MCTSGameTree next = null;
double bestS = Double.NEGATIVE_INFINITY ;
@ -317,13 +317,13 @@ public class MCTSAI implements MagicAI {
//move down the tree
curr = next;
//update the game state and path
game.executeNextEvent(choices.get(curr.getChoice()));
path.add(curr);
}
}
}
return path;
}
@ -339,7 +339,7 @@ public class MCTSAI implements MagicAI {
return 1.0;
}
}
if (!CHEAT) {
game.showRandomizedHiddenCards();
}
@ -355,16 +355,16 @@ public class MCTSAI implements MagicAI {
return 1.0 - actions/(2.0 * MAX_ACTIONS);
}
}
private List<Object[]> getNextChoices(final MagicGame game, final boolean sim) {
final int startActions = game.getNumActions();
//use fast choices during simulation
game.setFastChoices(sim);
// simulate game until it is finished or simulated MAX_ACTIONS actions
while (!game.isFinished() &&
while (!game.isFinished() &&
(game.getNumActions() - startActions) < MAX_ACTIONS) {
//do not accumulate score down the tree when not in simulation
@ -384,7 +384,7 @@ public class MCTSAI implements MagicAI {
game.executeNextEvent();
continue;
}
//event has choice
if (sim) {
@ -413,10 +413,10 @@ public class MCTSAI implements MagicAI {
choices = event.getArtificialChoiceResults(game);
}
assert choices != null;
final int size = choices.size();
assert size > 0 : "ERROR! No choice found during MCTS getACR";
if (size == 1) {
//single choice
game.executeNextEvent(choices.get(0));
@ -426,11 +426,11 @@ public class MCTSAI implements MagicAI {
}
}
}
//game is finished or number of actions > MAX_ACTIONS
return Collections.emptyList();
}
private static String CR2String(final Object[] choiceResults) {
final StringBuilder buffer=new StringBuilder();
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
class MCTSGameTree implements Iterable<MCTSGameTree> {
private final MCTSGameTree parent;
private final LinkedList<MCTSGameTree> children = new LinkedList<MCTSGameTree>();
private final int choice;
@ -476,21 +476,21 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
private double S;
String desc;
private String[] choicesStr;
//min sim for using robust max
private int maxChildSim = MCTSAI.MIN_SIM;
MCTSGameTree(final MCTSGameTree parent, final int choice, final int evalScore) {
private int maxChildSim = MCTSAI.MIN_SIM;
MCTSGameTree(final MCTSGameTree parent, final int choice, final int evalScore) {
this.evalScore = evalScore;
this.choice = choice;
this.parent = parent;
}
private static boolean log(final String message) {
System.err.println(message);
return true;
}
private static int obj2StringHash(final Object obj) {
return obj2String(obj).hashCode();
}
@ -504,10 +504,10 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
return obj.toString();
}
}
static void addNode(
final LRUCache<Long, MCTSGameTree> cache,
final MagicGame game,
final LRUCache<Long, MCTSGameTree> cache,
final MagicGame game,
final MCTSGameTree node) {
if (node.isCached()) {
return;
@ -519,13 +519,13 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
}
static MCTSGameTree getNode(
final LRUCache<Long, MCTSGameTree> cache,
final MagicGame game,
final LRUCache<Long, MCTSGameTree> cache,
final MagicGame game,
final List<Object[]> choices) {
final long gid = game.getStateId();
final MCTSGameTree candidate = cache.get(gid);
if (candidate != null) {
if (candidate != null) {
assert log("CACHE HIT");
assert log("HIT : " + game.getIdString());
assert printNode(candidate, choices);
@ -538,7 +538,7 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
return root;
}
}
static boolean checkNode(final MCTSGameTree curr, final List<Object[]> choices) {
if (curr.getMaxChildren() != choices.size()) {
return false;
@ -557,8 +557,8 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
}
return true;
}
static boolean printNode(final MCTSGameTree curr, final List<Object[]> choices) {
if (curr.choicesStr != null) {
for (final String str : curr.choicesStr) {
@ -600,7 +600,7 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
void setMaxChildren(final int mc) {
maxChildren = mc;
}
private int getMaxChildren() {
return maxChildren;
}
@ -612,7 +612,7 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
boolean isOpp() {
return !isAI;
}
void setIsAI(final boolean ai) {
this.isAI = ai;
}
@ -620,13 +620,13 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
boolean isSolved() {
return evalScore == Integer.MAX_VALUE || evalScore == Integer.MIN_VALUE;
}
void updateScore(final MCTSGameTree child, final double delta) {
final double oldMean = (numSim > 0) ? sum/numSim : 0;
sum += delta;
numSim += 1;
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 != null && child.getNumSim() > maxChildSim) {
@ -635,11 +635,11 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
numSim = child.numSim;
}
}
double getUCT() {
return getV() + MCTSAI.UCB1_C * Math.sqrt(Math.log(parent.getNumSim()) / getNumSim());
}
private double getRatio() {
return (getSum() + MCTSAI.RATIO_K)/(getNumSim() + 2*MCTSAI.RATIO_K);
}
@ -647,7 +647,7 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
private double getNormal() {
return Math.max(1.0, getV() + 2 * Math.sqrt(getVar()));
}
//decrease score of lose node, boost score of win nodes
double modify(final double sc) {
if ((!parent.isAI() && isAIWin()) || (parent.isAI() && isAILose())) {
@ -655,8 +655,8 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
} else if ((parent.isAI() && isAIWin()) || (!parent.isAI() && isAILose())) {
return sc + 2.0;
} else {
return sc;
}
return sc;
}
}
private double getVar() {
@ -671,7 +671,7 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
boolean isAIWin() {
return evalScore == Integer.MAX_VALUE;
}
boolean isAILose() {
return evalScore == Integer.MIN_VALUE;
}
@ -691,7 +691,7 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
int getChoice() {
return choice;
}
int getSteps() {
return steps;
}
@ -709,9 +709,9 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
private int getEvalScore() {
return evalScore;
}
double getDecision() {
//boost decision score of win nodes by BOOST
//boost decision score of win nodes by BOOST
final int BOOST = 1000000;
if (isAIWin()) {
return BOOST + getNumSim();
@ -721,16 +721,16 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
return getNumSim();
}
}
int getNumSim() {
return numSim;
}
private double getSum() {
// AI is max player, other is min player
return parent.isAI() ? sum : -sum;
}
public double getAvg() {
return sum / numSim;
}
@ -738,7 +738,7 @@ class MCTSGameTree implements Iterable<MCTSGameTree> {
double getV() {
return getSum() / numSim;
}
private double getSecureScore() {
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";
children.add(child);
}
MCTSGameTree first() {
return children.get(0);
}
public Iterator<MCTSGameTree> iterator() {
return children.iterator();
}

View File

@ -24,7 +24,7 @@ Classical MCTS (UCT)
- score = XX% (25000 matches against MMAB-1)
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 = 2.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
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
secure child formula for decision v + A/sqrt(n)
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
*/
public class MCTSAI2 implements MagicAI {
private static int MIN_SCORE = Integer.MAX_VALUE;
static int MIN_SIM = Integer.MAX_VALUE;
private static final int MAX_ACTIONS = 10000;
@ -72,12 +72,12 @@ public class MCTSAI2 implements MagicAI {
MIN_SCORE = Integer.parseInt(System.getProperty("min_score"));
System.err.println("MIN_SCORE = " + MIN_SCORE);
}
if (System.getProperty("ucb1_c") != null) {
UCB1_C = Double.parseDouble(System.getProperty("ucb1_c"));
System.err.println("UCB1_C = " + UCB1_C);
}
if (System.getProperty("ratio_k") != null) {
RATIO_K = Double.parseDouble(System.getProperty("ratio_k"));
System.err.println("RATIO_K = " + RATIO_K);
@ -105,7 +105,7 @@ public class MCTSAI2 implements MagicAI {
}
public Object[] findNextEventChoiceResults(
final MagicGame startGame,
final MagicGame startGame,
final MagicPlayer scorePlayer) {
// Determine possible choices
@ -115,21 +115,21 @@ public class MCTSAI2 implements MagicAI {
choiceGame = null;
final int size = RCHOICES.size();
// No choice
assert size > 0 : "ERROR! No choice found at start of MCTS";
// Single choice
if (size == 1) {
return startGame.map(RCHOICES.get(0));
}
//normal: max time is 1000 * level
int MAX_TIME = 1000 * startGame.getArtificialLevel(scorePlayer.getIndex());
int MAX_SIM = Integer.MAX_VALUE;
final long START_TIME = System.currentTimeMillis();
//root represents the start state
final MCTSGameTree root = MCTSGameTree.getNode(CACHE, startGame, RCHOICES);
@ -139,29 +139,29 @@ public class MCTSAI2 implements MagicAI {
int sims;
for (sims = 0;
System.currentTimeMillis() - START_TIME < MAX_TIME &&
sims < MAX_SIM &&
!root.isAIWin();
sims < MAX_SIM &&
!root.isAIWin();
sims++) {
//clone the MagicGame object for simulation
final MagicGame rootGame = new MagicGame(startGame, scorePlayer);
if (!CHEAT) {
rootGame.hideHiddenCards();
}
//pass in a clone of the state,
//pass in a clone of the state,
//genNewTreeNode grows the tree by one node
//and returns the path from the root to the new node
final LinkedList<MCTSGameTree> path = growTree(root, rootGame);
assert path.size() >= 2 : "ERROR! length of MCTS path is " + path.size();
// 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);
// update score and game theoretic value along the chosen path
MCTSGameTree child = null;
MCTSGameTree child = null;
MCTSGameTree parent = null;
while (!path.isEmpty()) {
child = parent;
@ -179,8 +179,8 @@ public class MCTSAI2 implements MagicAI {
parent.incLose(steps);
} else if (parent.isOpp() && child.isAIWin()) {
parent.incLose(steps);
}
}
}
}
}
}
@ -193,7 +193,7 @@ public class MCTSAI2 implements MagicAI {
for (final MCTSGameTree node : root) {
final double D = node.getDecision();
final int C = node.getChoice();
if (D > maxD) {
if (D > maxD) {
maxD = D;
bestC = C;
}
@ -203,22 +203,22 @@ public class MCTSAI2 implements MagicAI {
return startGame.map(RCHOICES.get(bestC));
}
private String outputChoice(
final MagicPlayer scorePlayer,
final MCTSGameTree root,
final long START_TIME,
final int bestC,
final MCTSGameTree root,
final long START_TIME,
final int bestC,
final int sims) {
final StringBuilder out = new StringBuilder();
final long duration = System.currentTimeMillis() - START_TIME;
out.append("MCTS2" +
" cheat=" + CHEAT +
" index=" + scorePlayer.getIndex() +
" index=" + scorePlayer.getIndex() +
" life=" + scorePlayer.getLife() +
" time=" + duration +
" time=" + duration +
" sims=" + sims);
out.append('\n');
@ -262,16 +262,16 @@ public class MCTSAI2 implements MagicAI {
choices = getNextChoices(game, false)) {
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" +
game + " " +
printPath(path) + " " +
game + " " +
printPath(path) + " " +
MCTSGameTree.printNode(curr, choices);
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
if (!curr.hasDetails()) {
curr.setIsAI(game.getScorePlayer() == event.getPlayer());
@ -292,23 +292,23 @@ public class MCTSAI2 implements MagicAI {
final int idx = curr.size();
final Object[] choice = choices.get(idx);
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);
curr.addChild(child);
path.add(child);
return path;
//all the children are in the tree, find the "best" child to explore
} else {
assert curr.size() == choices.size() : "ERROR! Different number of choices in node and game" +
printPath(path) + MCTSGameTree.printNode(curr, choices);
assert curr.size() == choices.size() : "ERROR! Different number of choices in node and game" +
printPath(path) + MCTSGameTree.printNode(curr, choices);
MCTSGameTree next = null;
double bestS = Double.NEGATIVE_INFINITY ;
for (final MCTSGameTree child : curr) {
final double raw =
child.getAvg() * (curr.isAI() ? 1 : -1) +
final double raw =
child.getAvg() * (curr.isAI() ? 1 : -1) +
MCTSAI.UCB1_C * Math.sqrt(Math.log(curr.getNumSim()) / child.getNumSim());
final double S = child.modify(raw);
if (S > bestS) {
@ -319,13 +319,13 @@ public class MCTSAI2 implements MagicAI {
//move down the tree
curr = next;
//update the game state and path
game.executeNextEvent(choices.get(curr.getChoice()));
path.add(curr);
}
}
}
return path;
}
@ -341,7 +341,7 @@ public class MCTSAI2 implements MagicAI {
return 1.0;
}
}
if (!CHEAT) {
game.showRandomizedHiddenCards();
}
@ -357,16 +357,16 @@ public class MCTSAI2 implements MagicAI {
return 1.0 - actions/(2.0 * MAX_ACTIONS);
}
}
private List<Object[]> getNextChoices(final MagicGame game, final boolean sim) {
final int startActions = game.getNumActions();
//use fast choices during simulation
game.setFastChoices(sim);
// simulate game until it is finished or simulated MAX_ACTIONS actions
while (!game.isFinished() &&
while (!game.isFinished() &&
(game.getNumActions() - startActions) < MAX_ACTIONS) {
//do not accumulate score down the tree when not in simulation
@ -386,7 +386,7 @@ public class MCTSAI2 implements MagicAI {
game.executeNextEvent();
continue;
}
//event has choice
if (sim) {
@ -415,10 +415,10 @@ public class MCTSAI2 implements MagicAI {
choices = event.getArtificialChoiceResults(game);
}
assert choices != null;
final int size = choices.size();
assert size > 0 : "ERROR! No choice found during MCTS getACR";
if (size == 1) {
//single choice
game.executeNextEvent(choices.get(0));
@ -428,11 +428,11 @@ public class MCTSAI2 implements MagicAI {
}
}
}
//game is finished or number of actions > MAX_ACTIONS
return Collections.emptyList();
}
private static String CR2String(final Object[] choiceResults) {
final StringBuilder buffer=new StringBuilder();
if (choiceResults!=null) {

View File

@ -14,10 +14,10 @@ import magic.model.event.MagicEvent;
import magic.model.phase.MagicPhase;
public class MMAB implements MagicAI {
private static final long SEC_TO_NANO=1000000000L;
private static final int THREADS = Runtime.getRuntime().availableProcessors();
private final boolean LOGGING = Boolean.getBoolean("debug");
private final boolean CHEAT;
private final boolean DECKSTR;
@ -34,32 +34,32 @@ public class MMAB implements MagicAI {
CHEAT = cheat;
DECKSTR = deckStr;
}
private void log(final String message) {
MagicGameLog.log(message);
if (LOGGING) {
System.err.println(message);
}
}
public Object[] findNextEventChoiceResults(final MagicGame sourceGame, final MagicPlayer scorePlayer) {
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.
MagicGame choiceGame = new MagicGame(sourceGame,scorePlayer);
final MagicEvent event = choiceGame.getNextEvent();
final List<Object[]> choices = event.getArtificialChoiceResults(choiceGame);
final int size = choices.size();
choiceGame = null;
assert size != 0 : "ERROR: no choices available for MMAB";
// single choice result.
if (size == 1) {
return sourceGame.map(choices.get(0));
}
// submit jobs
final ArtificialPruneScoreRef scoreRef = new ArtificialPruneScoreRef(new ArtificialMultiPruneScore());
final ArtificialScoreBoard scoreBoard = new ArtificialScoreBoard();
@ -103,14 +103,14 @@ public class MMAB implements MagicAI {
// force termination of workers
executor.shutdownNow();
}
// select the best scoring choice result.
ArtificialScore bestScore = ArtificialScore.INVALID_SCORE;
ArtificialChoiceResults bestAchoice = achoices.get(0);
for (final ArtificialChoiceResults achoice : achoices) {
if (bestScore.isBetter(achoice.aiScore,true)) {
bestScore = achoice.aiScore;
bestAchoice = achoice;
bestAchoice = achoice;
}
}
@ -120,7 +120,7 @@ public class MMAB implements MagicAI {
" cheat=" + CHEAT +
" index=" + scorePlayer.getIndex() +
" life=" + scorePlayer.getLife() +
" phase=" + sourceGame.getPhase().getType() +
" phase=" + sourceGame.getPhase().getType() +
" slice=" + (slice/1000000) +
" time=" + timeTaken
);
@ -139,21 +139,21 @@ class MMABWorker {
private final ArtificialScoreBoard scoreBoard;
private int gameCount;
MMABWorker(final int id,final MagicGame game,final ArtificialScoreBoard scoreBoard, final boolean CHEAT) {
this.id=id;
this.game=game;
this.scoreBoard=scoreBoard;
this.CHEAT=CHEAT;
}
private ArtificialScore runGame(final Object[] nextChoiceResults, final ArtificialPruneScore pruneScore, final int depth, final long maxTime) {
game.startActions();
if (nextChoiceResults!=null) {
game.executeNextEvent(nextChoiceResults);
}
if (System.nanoTime() > maxTime || Thread.currentThread().isInterrupted()) {
final ArtificialScore aiScore=new ArtificialScore(game.getScore(),depth);
game.undoActions();
@ -165,7 +165,7 @@ class MMABWorker {
while (!game.isFinished()) {
if (!game.hasNextEvent()) {
game.executePhase();
// Caching of best score for game situations.
if (game.cacheState()) {
final long gameId=game.getGameId(pruneScore.getScore());
@ -181,7 +181,7 @@ class MMABWorker {
}
continue;
}
final MagicEvent event=game.getNextEvent();
if (!event.hasChoice()) {
@ -203,14 +203,14 @@ class MMABWorker {
*/
final int nrOfChoices=choiceResultsList.size();
assert nrOfChoices > 0 : "nrOfChoices is 0";
if (nrOfChoices==1) {
game.executeNextEvent(choiceResultsList.get(0));
continue;
}
final boolean best=game.getScorePlayer()==event.getPlayer();
ArtificialScore bestScore=ArtificialScore.INVALID_SCORE;
ArtificialPruneScore newPruneScore=pruneScore;
@ -241,7 +241,7 @@ class MMABWorker {
void evaluateGame(final ArtificialChoiceResults aiChoiceResults, final ArtificialPruneScore pruneScore, long maxTime) {
gameCount = 0;
aiChoiceResults.worker = id;
aiChoiceResults.aiScore = runGame(game.map(aiChoiceResults.choiceResults),pruneScore,0,maxTime);
aiChoiceResults.gameCount = gameCount;

View File

@ -14,10 +14,10 @@ import magic.model.event.MagicEvent;
import magic.model.phase.MagicPhase;
public class MMAB2 implements MagicAI {
private static final long SEC_TO_NANO=1000000000L;
private static final int THREADS = Runtime.getRuntime().availableProcessors();
private final boolean LOGGING;
private final boolean CHEAT;
private ArtificialPruneScore pruneScore = new ArtificialMultiPruneScore();
@ -26,37 +26,37 @@ public class MMAB2 implements MagicAI {
//default: no logging, no cheats
this(false, false);
}
MMAB2(final boolean log, final boolean cheat) {
LOGGING = log || Boolean.getBoolean("debug");
CHEAT = cheat;
}
private void log(final String message) {
MagicGameLog.log(message);
if (LOGGING) {
System.err.println(message);
}
}
public Object[] findNextEventChoiceResults(final MagicGame sourceGame, final MagicPlayer scorePlayer) {
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.
MagicGame choiceGame = new MagicGame(sourceGame,scorePlayer);
final MagicEvent event = choiceGame.getNextEvent();
final List<Object[]> choices = event.getArtificialChoiceResults(choiceGame);
final int size = choices.size();
choiceGame = null;
assert size != 0 : "ERROR: no choices available for MMAB2";
// single choice result.
if (size == 1) {
return sourceGame.map(choices.get(0));
}
// submit jobs
final ArtificialScoreBoard scoreBoard = new ArtificialScoreBoard();
final ExecutorService executor = Executors.newFixedThreadPool(THREADS);
@ -96,14 +96,14 @@ public class MMAB2 implements MagicAI {
// force termination of workers
executor.shutdownNow();
}
// select the best scoring choice result.
ArtificialScore bestScore = ArtificialScore.INVALID_SCORE;
ArtificialChoiceResults bestAchoice = achoices.get(0);
for (final ArtificialChoiceResults achoice : achoices) {
if (bestScore.isBetter(achoice.aiScore,true)) {
bestScore = achoice.aiScore;
bestAchoice = achoice;
bestAchoice = achoice;
}
}
@ -113,7 +113,7 @@ public class MMAB2 implements MagicAI {
" cheat=" + CHEAT +
" index=" + scorePlayer.getIndex() +
" life=" + scorePlayer.getLife() +
" phase=" + sourceGame.getPhase().getType() +
" phase=" + sourceGame.getPhase().getType() +
" slice=" + (slice/1000000) +
" time=" + timeTaken
);
@ -127,7 +127,7 @@ public class MMAB2 implements MagicAI {
private void updatePruneScore(final int score) {
pruneScore = pruneScore.getPruneScore(score,true);
}
private ArtificialPruneScore getPruneScore() {
return pruneScore;
}
@ -140,21 +140,21 @@ class MMABWorker {
private final ArtificialScoreBoard scoreBoard;
private int gameCount;
MMABWorker(final int id,final MagicGame game,final ArtificialScoreBoard scoreBoard, final boolean CHEAT) {
this.id=id;
this.game=game;
this.scoreBoard=scoreBoard;
this.CHEAT=CHEAT;
}
private ArtificialScore runGame(final Object[] nextChoiceResults, final ArtificialPruneScore pruneScore, final int depth, final long maxTime) {
game.startActions();
if (nextChoiceResults!=null) {
game.executeNextEvent(nextChoiceResults);
}
if (System.nanoTime() > maxTime || Thread.currentThread().isInterrupted()) {
final ArtificialScore aiScore=new ArtificialScore(game.getScore(),depth);
game.undoActions();
@ -166,7 +166,7 @@ class MMABWorker {
while (!game.isFinished()) {
if (!game.hasNextEvent()) {
game.executePhase();
// Caching of best score for game situations.
if (game.cacheState()) {
final long gameId=game.getGameId(pruneScore.getScore());
@ -182,7 +182,7 @@ class MMABWorker {
}
continue;
}
final MagicEvent event=game.getNextEvent();
if (!event.hasChoice()) {
@ -204,14 +204,14 @@ class MMABWorker {
*/
final int nrOfChoices=choiceResultsList.size();
assert nrOfChoices > 0 : "nrOfChoices is 0";
if (nrOfChoices==1) {
game.executeNextEvent(choiceResultsList.get(0));
continue;
}
final boolean best=game.getScorePlayer()==event.getPlayer();
ArtificialScore bestScore=ArtificialScore.INVALID_SCORE;
ArtificialPruneScore newPruneScore=pruneScore;
@ -242,7 +242,7 @@ class MMABWorker {
void evaluateGame(final ArtificialChoiceResults aiChoiceResults, final ArtificialPruneScore pruneScore, long maxTime) {
gameCount = 0;
aiChoiceResults.worker = id;
aiChoiceResults.aiScore = runGame(game.map(aiChoiceResults.choiceResults),pruneScore,0,maxTime);
aiChoiceResults.gameCount = gameCount;

View File

@ -5,5 +5,5 @@ import magic.model.MagicPlayer;
public interface MagicAI {
int MAX_LEVEL = 8;
Object[] findNextEventChoiceResults(final MagicGame game, final MagicPlayer player);
Object[] findNextEventChoiceResults(final MagicGame game, final MagicPlayer player);
}

View File

@ -1,21 +1,21 @@
package magic.ai;
public enum MagicAIImpl {
MMAB("minimax", new MMAB(false)),
MMABC("minimax (cheat)", new MMAB(true)),
MMAB("minimax", new MMAB(false)),
MMABC("minimax (cheat)", new MMAB(true)),
MCTS("monte carlo tree search", new MCTSAI(false)),
MCTSC("monte carlo tree search (cheat)", new MCTSAI(true)),
VEGAS("vegas", new VegasAI(false)),
VEGASC("vegas (cheat)", new VegasAI(true)),
RND("random", new RandomAI()),
MMABFast("minimax (deck strength)", magic.ai.MMAB.DeckStrAI()),
MCTS2("monte carlo tree search", new MCTSAI2(false)),
MCTSC2("monte carlo tree search (cheat)", new MCTSAI2(true)),
;
private static final MagicAIImpl[] SUPPORTED_AIS = {MMAB, MMABC, MCTS, MCTSC, VEGAS, VEGASC};
private final String name;
private final MagicAI ai;
@ -23,15 +23,15 @@ public enum MagicAIImpl {
this.name=name;
this.ai=ai;
}
private String getName() {
return name;
}
public MagicAI getAI() {
return ai;
return ai;
}
public static MagicAIImpl getAI(final String name) {
for (final MagicAIImpl ai : values()) {
if (ai.getName().equals(name)) {
@ -40,7 +40,7 @@ public enum MagicAIImpl {
}
return MMAB;
}
public static String[] getNames() {
final String[] names=new String[SUPPORTED_AIS.length];
int index=0;

View File

@ -11,9 +11,9 @@ import java.util.List;
//AI that plays randomly
public class RandomAI implements MagicAI {
private final boolean LOGGING;
public RandomAI() {
this(false);
}
@ -21,24 +21,24 @@ public class RandomAI implements MagicAI {
private RandomAI(final boolean log) {
LOGGING = log || Boolean.getBoolean("debug");
}
private void log(final String message) {
MagicGameLog.log(message);
if (LOGGING) {
System.err.println(message);
}
}
public Object[] findNextEventChoiceResults(final MagicGame game, final MagicPlayer scorePlayer) {
//get a list of choices
MagicGame choiceGame = new MagicGame(game, scorePlayer);
final MagicEvent event=choiceGame.getNextEvent();
final List<Object[]> choices=event.getArtificialChoiceResults(choiceGame);
choiceGame = null;
final int size = choices.size();
final String info = "RandomAI " + scorePlayer.getIndex() + " (" + scorePlayer.getLife() + ")";
if (size == 0) {
throw new RuntimeException("No choice results");
}
@ -48,17 +48,17 @@ public class RandomAI implements MagicAI {
for (final Object[] choice : choices) {
achoices.add(new ArtificialChoiceResults(choice));
}
// Select a random artificial choice result
final int idx = MagicRandom.nextInt(size);
final ArtificialChoiceResults selected=achoices.get(idx);
if (size >= 2) {
log(info);
log(info);
for (final ArtificialChoiceResults achoice : achoices) {
log((achoice==selected?"* ":" ")+achoice);
}
} else {
//log(info + " " + selected);
//log(info + " " + selected);
}
return game.map(selected.choiceResults);
}

View File

@ -17,21 +17,21 @@ public class VegasAI implements MagicAI {
private static final long SEC_TO_NANO=1000000000L;
private static final int THREADS=Runtime.getRuntime().availableProcessors();
private final boolean LOGGING = Boolean.getBoolean("debug");
private final boolean CHEAT;
VegasAI(final boolean cheat) {
CHEAT = cheat;
}
private void log(final String message) {
MagicGameLog.log(message);
if (LOGGING) {
System.err.println(message);
}
}
@Override
public Object[] findNextEventChoiceResults(final MagicGame sourceGame,final MagicPlayer scorePlayer) {
final long startTime = System.currentTimeMillis();
@ -42,18 +42,18 @@ public class VegasAI implements MagicAI {
}
final MagicEvent event=choiceGame.getNextEvent();
final List<Object[]> choiceResultsList=event.getArtificialChoiceResults(choiceGame);
// No choices
final int size=choiceResultsList.size();
if (size==0) {
throw new RuntimeException("No choice results");
}
// Single choice
}
// Single choice
if (size==1) {
return sourceGame.map(choiceResultsList.get(0));
}
// Multiple choices
final ExecutorService executor = Executors.newFixedThreadPool(THREADS);
final List<VegasScore> scores=new ArrayList<VegasScore>();
@ -80,7 +80,7 @@ public class VegasAI implements MagicAI {
// force termination of workers
executor.shutdownNow();
}
// Return best choice
VegasScore bestScore=scores.get(0);
for (final VegasScore score : scores) {
@ -88,14 +88,14 @@ public class VegasAI implements MagicAI {
bestScore = score;
}
}
// Logging.
final long timeTaken = System.currentTimeMillis() - startTime;
log("VEGAS" +
" cheat=" + CHEAT +
" index=" + scorePlayer.getIndex() +
" life=" + scorePlayer.getLife() +
" phase=" + sourceGame.getPhase().getType() +
" phase=" + sourceGame.getPhase().getType() +
" slice=" + (slice/1000000) +
" time=" + timeTaken
);

View File

@ -5,11 +5,11 @@ public class VegasScore {
private final Object[] choiceResults;
private long totalScore;
private int count;
VegasScore(final Object[] choiceResults) {
this.choiceResults=choiceResults;
}
void incrementScore(final int score) {
totalScore+=score;
count++;
@ -18,7 +18,7 @@ public class VegasScore {
Object[] getChoiceResults() {
return choiceResults;
}
public String toString() {
final StringBuilder buffer=new StringBuilder();
buffer.append("[").append(getScore()).append('/').append(count).append("]");
@ -37,7 +37,7 @@ public class VegasScore {
}
return buffer.toString();
}
int getScore() {
return count>0?(int)(totalScore/count):ArtificialScoringSystem.LOSE_GAME_SCORE;
}

View File

@ -10,14 +10,14 @@ import java.util.Random;
public class VegasWorker implements Runnable {
private static final int MAIN_PHASES=6;
private final MagicGame sourceGame;
private final VegasScore score;
private final Object[] choiceResults;
private final Random random;
private final long slice;
private final boolean CHEAT;
VegasWorker(final boolean cheat, final MagicGame sourceGame, final VegasScore score,final Random random,final long slice) {
this.CHEAT = cheat;
this.sourceGame=sourceGame;
@ -36,21 +36,21 @@ public class VegasWorker implements Runnable {
}
final MagicEvent event=game.getNextEvent();
if (!event.hasChoice()) {
game.executeNextEvent();
continue;
}
final List<Object[]> choiceResultsList=event.getArtificialChoiceResults(game);
final int nrOfChoices=choiceResultsList.size();
assert nrOfChoices != 0 : "ERROR: no choices available for VegasWorker";
game.executeNextEvent(choiceResultsList.get(random.nextInt(nrOfChoices)));
}
}
}
@Override
public void run() {
final long endTime = System.nanoTime() + slice;
@ -64,5 +64,5 @@ public class VegasWorker implements Runnable {
runGame(game);
score.incrementScore(game.getScore());
}
}
}
}

View File

@ -11,12 +11,12 @@ import java.util.Vector;
public class AvatarImages {
private static final AvatarImages INSTANCE = new AvatarImages();
private final File avatarPath;
private final Vector<String> names;
private String current = "";
private PlayerAvatar[] avatars;
private AvatarImages() {
avatarPath=new File(MagicMain.getGamePath(),"avatars");
final File[] files=avatarPath.listFiles();
@ -29,15 +29,15 @@ public class AvatarImages {
}
}
}
public Vector<String> getNames() {
return names;
}
private static PlayerAvatar loadAvatar(final File file) {
return new PlayerAvatar(FileIO.toImg(file, IconImages.MISSING));
}
private synchronized void loadAvatars() {
final String avatar=GeneralConfig.getInstance().getAvatar();
if (!avatar.equals(current)) {
@ -48,7 +48,7 @@ public class AvatarImages {
avatars=new PlayerAvatar[files.length];
for (int index=0;index<files.length;index++) {
avatars[index]=loadAvatar(files[index]);
}
}
} else {
avatars=new PlayerAvatar[2];
avatars[0]=loadAvatar(new File(""));
@ -56,7 +56,7 @@ public class AvatarImages {
}
}
}
public synchronized ImageIcon getAvatarIcon(int index,final int size) {
loadAvatars();
if (index < 0) {
@ -66,7 +66,7 @@ public class AvatarImages {
}
return avatars[index].getIcon(size);
}
public synchronized int getNumberOfAvatars() {
loadAvatars();
return avatars.length;

View File

@ -35,7 +35,7 @@ public class CardDefinitions {
public static final String TOKEN_IMAGE_FOLDER = "tokens";
public static final String CARD_IMAGE_EXT = CardImagesProvider.IMAGE_EXTENSION;
public static final String CARD_TEXT_EXT = ".txt";
private static final List<MagicCardDefinition> cards = new ArrayList<MagicCardDefinition>();
private static final List<MagicCardDefinition> landCards = new ArrayList<MagicCardDefinition>();
private static final List<MagicCardDefinition> spellCards = new ArrayList<MagicCardDefinition>();
@ -51,7 +51,7 @@ public class CardDefinitions {
new ImportCustomizer().addStarImports(
"java.util",
"magic.data",
"magic.model",
"magic.model",
"magic.model.action",
"magic.model.choice",
"magic.model.condition",
@ -73,7 +73,7 @@ public class CardDefinitions {
throw new RuntimeException("Unsupported card property: " + property);
}
}
private static void filterCards() {
for (final MagicCardDefinition card : cards) {
if (!card.isLand() && !card.isToken()) {
@ -100,7 +100,7 @@ public class CardDefinitions {
CubeDefinitions.getCubeDefinition("all").add(cardDefinition.getName());
}
}
private static MagicCardDefinition prop2carddef(final Properties content) {
final MagicCardDefinition cardDefinition=new MagicCardDefinition();
@ -124,11 +124,11 @@ public class CardDefinitions {
throw new RuntimeException(ex);
}
}
private static String getCanonicalName(String fullName) {
return fullName.replaceAll("[^A-Za-z0-9]", "_");
}
private static void loadCardDefinition(final File file) {
try {
final MagicCardDefinition cdef = prop2carddef(FileIO.toProp(file));
@ -141,7 +141,7 @@ public class CardDefinitions {
throw new RuntimeException("Error loading " + file, cause);
}
}
public static void loadCardDefinitions() {
//load all files in card directory
final File[] files = cardDir.listFiles(new FilenameFilter() {
@ -152,24 +152,24 @@ public class CardDefinitions {
for (final File file : files) {
loadCardDefinition(file);
}
filterCards();
printStatistics();
addDefinition(MagicCardDefinition.UNKNOWN);
System.err.println(getNumberOfCards()+ " card definitions");
MagicCardDefinition.printStatistics();
}
public static int getNumberOfCards() {
return cards.size();
}
public static MagicCardDefinition getCard(final int cindex) {
return cards.get(cindex);
}
public static MagicCardDefinition getCard(final String name) {
final MagicCardDefinition cardDefinition=cardsMap.get(name);
if (cardDefinition == null) {
@ -177,7 +177,7 @@ public class CardDefinitions {
}
return cardDefinition;
}
public static void loadCardTexts() {
executor.execute(new Runnable() {
@Override
@ -190,21 +190,21 @@ public class CardDefinitions {
}
});
}
private static void loadCardText(final MagicCardDefinition card) {
// try to load text from file
final StringBuilder buffer = new StringBuilder();
buffer.append(MagicMain.getGamePath());
buffer.append(File.separator);
buffer.append(CARD_TEXT_FOLDER);
buffer.append(File.separator);
buffer.append(File.separator);
buffer.append(card.getCardTextName());
buffer.append(CARD_TEXT_EXT);
try {
final String text = FileIO.toStr(new File(buffer.toString()));
if (text != null) {
card.setText(text);
card.setText(text);
}
} catch (IOException e) {
// text not downloaded or missing
@ -229,15 +229,15 @@ public class CardDefinitions {
public static List<MagicCardDefinition> getCards() {
return cards;
}
public static List<MagicCardDefinition> getLandCards() {
return landCards;
}
public static List<MagicCardDefinition> getSpellCards() {
return spellCards;
}
private static void printStatistics() {
final CardStatistics statistics=new CardStatistics(cards);
statistics.printStatictics(System.err);

View File

@ -5,7 +5,7 @@ import magic.model.MagicCardDefinition;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
/**
/**
* Interface for getting image of a card
*/
public interface CardImagesProvider {
@ -15,7 +15,7 @@ public interface CardImagesProvider {
//native resolution of images from magiccards.info
int CARD_WIDTH=312;
int CARD_HEIGHT=445;
Dimension CARD_DIMENSION = new Dimension(CARD_WIDTH, CARD_HEIGHT);
BufferedImage getImage(

View File

@ -191,7 +191,7 @@ public enum CardProperty {
}
},
;
public void setProperty(final MagicCardDefinition card, final String value) {
//do nothing
}

View File

@ -29,7 +29,7 @@ public class CardStatistics {
IconImages.COST_NINE
));
public static final int MANA_CURVE_SIZE=MANA_CURVE_TEXT.size();
private static final List<String> TYPE_NAMES = Collections.unmodifiableList(Arrays.asList(
"Land","Spell","Creature","Equipment","Aura","Enchantment","Artifact"));
public static final List<ImageIcon> TYPE_ICONS = Collections.unmodifiableList(Arrays.asList(
@ -37,22 +37,22 @@ public class CardStatistics {
IconImages.SPELL,
IconImages.CREATURE,
IconImages.EQUIPMENT,
IconImages.AURA,
IconImages.AURA,
IconImages.ENCHANTMENT,
IconImages.ARTIFACT
));
public static final int NR_OF_TYPES=TYPE_NAMES.size();
private final Collection<MagicCardDefinition> cards;
private int totalCards;
public final int[] totalTypes=new int[NR_OF_TYPES];
private final int[] totalRarity=new int[MagicRarity.length];
private double averageCost;
private double averageValue;
public final int[] colorCount=new int[MagicColor.NR_COLORS];
public final int[] colorMono=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 multiColor;
public int colorless;
public CardStatistics(final Collection<MagicCardDefinition> cards) {
this.cards=cards;
createStatistics();
}
private void createStatistics() {
for (final MagicCardDefinition card : cards) {
//ignore tokens
@ -74,16 +74,16 @@ public class CardStatistics {
}
totalCards++;
totalRarity[card.getRarity()]++;
if (card.isLand()) {
totalTypes[0]++;
for (final MagicColor color : MagicColor.values()) {
if (card.getManaSource(color) > 0) {
colorLands[color.ordinal()]++;
}
}
}
} else {
if (card.hasX()) {
manaCurve[0]++;
@ -91,10 +91,10 @@ public class CardStatistics {
final int convertedCost=card.getConvertedCost();
manaCurve[convertedCost+1>=MANA_CURVE_SIZE?MANA_CURVE_SIZE-1:convertedCost+1]++;
}
averageCost+=card.getConvertedCost();
averageValue+=card.getValue();
if (card.isCreature()) {
totalTypes[2]++;
} else if (card.isEquipment()) {
@ -108,11 +108,11 @@ public class CardStatistics {
} else {
totalTypes[1]++;
}
int count=0;
int index=-1;
for (final MagicColor color : MagicColor.values()) {
if (color.hasColor(card.getColorFlags())) {
index=color.ordinal();
colorCount[index]++;
@ -129,14 +129,14 @@ public class CardStatistics {
}
}
}
final int total=totalCards-totalTypes[0];
if (total>0) {
averageValue /= total;
averageCost /= total;
}
}
void printStatictics(final PrintStream stream) {
stream.print("Cards : "+totalCards);
@ -144,9 +144,9 @@ public class CardStatistics {
stream.print(" "+TYPE_NAMES.get(index)+" : "+totalTypes[index]);
}
stream.println();
for (int index=0;index<MagicRarity.length;index++) {
stream.print(MagicRarity.values()[index].getName() + " : " + totalRarity[index] + " ");
}
stream.println();
@ -154,16 +154,16 @@ public class CardStatistics {
stream.println("Monocolor : "+monoColor+" Multicolor : "+multiColor+" Colorless : "+colorless);
for (final MagicColor color : MagicColor.values()) {
final int index=color.ordinal();
stream.print("Color "+color.getName()+" : "+colorCount[index]);
stream.print(" Mono : "+colorMono[index]);
stream.print(" Lands : "+colorLands[index]);
stream.println();
}
stream.println();
}
for (int index=0;index<MANA_CURVE_SIZE;index++) {
stream.print(MANA_CURVE_TEXT.get(index)+" = "+manaCurve[index]+" ");
}
stream.println();

View File

@ -11,28 +11,28 @@ import java.util.List;
import java.util.Scanner;
public class CubeDefinitions {
private static final String[] INCLUDED_CUBES={"all"};
private static final String CUBE_FILE_EXTENSION="_cube.txt";
static final String DEFAULT_NAME=INCLUDED_CUBES[0];
private static final FileFilter CUBE_FILE_FILTER=new FileFilter() {
@Override
public boolean accept(final File file) {
return file.isFile()&&file.getName().endsWith(CUBE_FILE_EXTENSION);
}
};
private static final List<MagicCubeDefinition> cubeDefinitions;
static {
cubeDefinitions=new ArrayList<MagicCubeDefinition>();
for (final String cubeName : INCLUDED_CUBES) {
cubeDefinitions.add(new MagicCubeDefinition(cubeName));
}
}
public static String[] getCubeNames() {
final String[] names=new String[cubeDefinitions.size()];
for (int index=0;index<names.length;index++) {
@ -40,7 +40,7 @@ public class CubeDefinitions {
}
return names;
}
public static MagicCubeDefinition getCubeDefinition(final String name) {
for (final MagicCubeDefinition cubeDefinition : cubeDefinitions) {
if (cubeDefinition.getName().equals(name)) {
@ -49,7 +49,7 @@ public class CubeDefinitions {
}
return cubeDefinitions.get(0);
}
private static void loadCubeDefinition(final String name,final File file) {
String content = "";
try { //load cube
@ -70,7 +70,7 @@ public class CubeDefinitions {
}
cubeDefinitions.add(cubeDefinition);
}
public static void loadCubeDefinitions() {
final File[] cubeFiles=new File(MagicMain.getModsPath()).listFiles(CUBE_FILE_FILTER);
if (cubeFiles!=null) {
@ -80,7 +80,7 @@ public class CubeDefinitions {
loadCubeDefinition(name.substring(0,index),file);
}
}
System.err.println(cubeDefinitions.size()+" cube definitions");
for (final MagicCubeDefinition cubeDefinition : cubeDefinitions) {
System.err.println("Cube "+cubeDefinition.getName());

View File

@ -15,47 +15,47 @@ import java.util.TreeMap;
public class DeckGenerators {
private static final DeckGenerators INSTANCE = new DeckGenerators();
private static final String FILENAME = "deckgenerators.txt";
private final Map<String, Class> generatorsMap;
private DeckGenerators() {
generatorsMap = new TreeMap<String, Class>();
}
public Set<String> getGeneratorNames() {
return generatorsMap.keySet();
}
private void addDeckGenerator(final String name, final Class c) {
generatorsMap.put(name, c);
}
private void addDeckGenerator(final String name) {
// find class
final String cname = name.replaceAll("[^A-Za-z0-9]", "_");
try { // reflection
final Class c = Class.forName("magic.generator." + cname + "_DeckGenerator");
addDeckGenerator(name, c);
System.err.println("added deck generator " + name);
} catch (final ClassNotFoundException ex) {
// no class found
} catch (final ClassCastException ex) {
throw new RuntimeException(ex);
}
}
public DefaultDeckGenerator getDeckGenerator(final String name) {
return getDeckGenerator(generatorsMap.get(name));
}
private DefaultDeckGenerator getDeckGenerator(final Class c) {
DefaultDeckGenerator gen = null;
if(c != null) {
try {
gen = (DefaultDeckGenerator) c.newInstance();
@ -67,10 +67,10 @@ public class DeckGenerators {
throw new RuntimeException(ex);
}
}
return gen;
}
private void loadDeckGenerators(final String filename) {
final InputStream stream = this.getClass().getResourceAsStream(filename);
String content = null;
@ -92,17 +92,17 @@ public class DeckGenerators {
}
}
}
public void loadDeckGenerators() {
loadDeckGenerators(FILENAME);
System.err.println(getNrGenerators()+ " deck generators loaded");
}
public int getNrGenerators() {
return generatorsMap.size();
}
public static DeckGenerators getInstance() {
return INSTANCE;
}

View File

@ -24,7 +24,7 @@ import java.util.TreeMap;
public class DeckUtils {
public static final String DECK_EXTENSION=".dec";
public static final FileFilter DECK_FILEFILTER=new FileFilter() {
@Override
public boolean accept(final File file) {
@ -35,20 +35,20 @@ public class DeckUtils {
return "Magarena deck";
}
};
private static final String[] CARD_TYPES={"creatures","spells","lands"};
public static String getDeckFolder() {
return MagicMain.getGamePath()+File.separator+"decks";
}
public static void createDeckFolder() {
final File deckFolderFile=new File(getDeckFolder());
if (!deckFolderFile.exists() && !deckFolderFile.mkdir()) {
System.err.println("WARNING. Unable to create " + getDeckFolder());
}
}
public static boolean saveDeck(final String filename,final MagicPlayerDefinition player) {
final List<SortedMap<String,Integer>> cardMaps=new ArrayList<SortedMap<String,Integer>>();
boolean isSuccessful = true;
@ -56,7 +56,7 @@ public class DeckUtils {
for (int count=3;count>0;count--) {
cardMaps.add(new TreeMap<String, Integer>());
}
for (final MagicCardDefinition cardDefinition : player.getDeck()) {
final String name=cardDefinition.getName();
final int index;
@ -71,9 +71,9 @@ public class DeckUtils {
final Integer count=cardMap.get(name);
cardMap.put(name,count==null?Integer.valueOf(1):Integer.valueOf(count+1));
}
BufferedWriter writer = null;
try { //save deck
try { //save deck
writer = new BufferedWriter(new FileWriter(filename));
for (int index=0;index<=2;index++) {
final SortedMap<String,Integer> cardMap=cardMaps.get(index);
@ -99,10 +99,10 @@ public class DeckUtils {
} finally {
magic.data.FileIO.close(writer);
}
return isSuccessful;
}
public static void loadDeck(final String filename,final MagicPlayerDefinition player) {
String content = "";
try { //load deck
@ -118,7 +118,7 @@ public class DeckUtils {
final int[] colorCount = new int[MagicColor.NR_COLORS];
final MagicDeck deck = player.getDeck();
final MagicDeck unsupported = new MagicDeck();
deck.setName(new File(filename).getName());
deck.clear(); // remove previous cards
@ -173,7 +173,7 @@ public class DeckUtils {
profile.setPreConstructed();
player.setProfile(profile);
}
public static void showUnsupportedCards(final MagicDeck unsupported) {
if (unsupported.isEmpty()) {
return;
@ -182,7 +182,7 @@ public class DeckUtils {
// show error message for unsupported cards
final StringBuilder sb = new StringBuilder();
sb.append("The loaded deck contained unsupported card(s): ");
// generate list of unsupported cards
for (int i = 0; i < unsupported.size(); i++) {
if(i > 0) {
@ -190,27 +190,27 @@ public class DeckUtils {
}
sb.append(unsupported.get(i).getName());
}
// options panel doesn't have automatic text wrapping
// because the method that provides max char limit isn't
// options panel doesn't have automatic text wrapping
// because the method that provides max char limit isn't
// coded, so override that method
final JOptionPane cleanupPane = new JOptionPane(sb.toString(), JOptionPane.ERROR_MESSAGE) {
private static final long serialVersionUID = 232L;
@Override
public int getMaxCharactersPerLineCount() {
return 70;
}
public int getMaxCharactersPerLineCount() {
return 70;
}
};
cleanupPane.createDialog(null, "Unsupported Cards").setVisible(true);
unsupported.clear();
}
private static void retrieveDeckFiles(final File folder,final List<File> deckFiles) {
final File[] files=folder.listFiles();
for (final File file : files) {
if (file.isDirectory()) {
retrieveDeckFiles(file,deckFiles);
} else if (file.getName().endsWith(DECK_EXTENSION)) {
@ -218,11 +218,11 @@ public class DeckUtils {
}
}
}
public static void loadRandomDeck(final MagicPlayerDefinition player) {
final File deckFile=new File(getDeckFolder());
final List<File> deckFiles=new ArrayList<File>();
retrieveDeckFiles(deckFile,deckFiles);
retrieveDeckFiles(deckFile,deckFiles);
final int size=deckFiles.size();
if (size==0) {
// Creates a simple default deck.

View File

@ -9,19 +9,19 @@ import java.net.URL;
public class DownloadCardTextFile extends WebDownloader {
private static final String startPattern = "ctext\">";
private static final String endPattern = "</p>";
private final File file;
private final URL url;
DownloadCardTextFile(final File file, final URL url) {
this.file = file;
this.url = url;
}
public String getFilename() {
return file.getName();
}
public File getFile() {
return file;
}
@ -29,10 +29,10 @@ public class DownloadCardTextFile extends WebDownloader {
public boolean exists() {
return file.exists();
}
public void download(final Proxy proxy) {
final String html = WebDownloader.getHTML(proxy, url);
// find text in html
int iStart = html.indexOf(startPattern);
String foundText = null;
@ -40,12 +40,12 @@ public class DownloadCardTextFile extends WebDownloader {
iStart += startPattern.length();
final int iEnd = html.indexOf(endPattern, iStart);
foundText = html.substring(iStart, iEnd) + " ";
foundText = foundText.replace((char) 195, 'A').replace((char) 8224, 'E');; // replace Æ character with AE
foundText = foundText.replaceAll("\\<br\\>", " "); // replace newlines
foundText = foundText.replaceAll("\\<[^\\>]*\\>", ""); // remove other html tags
}
// 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
if(foundText != null) {
@ -66,6 +66,6 @@ public class DownloadCardTextFile extends WebDownloader {
}
} else {
System.err.println("ERROR! Unable to download card text for " + file);
}
}
}
}

View File

@ -11,17 +11,17 @@ public class DownloadImageFile extends WebDownloader {
private final File file;
private final URL url;
private final MagicCardDefinition cdef;
DownloadImageFile(final File file, final URL url) {
this(file, url, MagicCardDefinition.UNKNOWN);
}
DownloadImageFile(final File file, final URL url, final MagicCardDefinition cdef) {
this.file=file;
this.url=url;
this.cdef=cdef;
}
public String getFilename() {
return file.getName();
}
@ -29,7 +29,7 @@ public class DownloadImageFile extends WebDownloader {
public File getFile() {
return file;
}
public void download(final Proxy proxy) {
WebDownloader.downloadToFile(proxy, url, file);
}

View File

@ -12,7 +12,7 @@ import java.net.URL;
import java.util.ArrayList;
import java.util.Scanner;
/**
/**
* Download the necessary images and files from the WWW
*/
public class DownloadMissingFiles extends ArrayList<WebDownloader> {
@ -21,11 +21,11 @@ public class DownloadMissingFiles extends ArrayList<WebDownloader> {
public DownloadMissingFiles(final String filename) {
loadDownloadImageFiles(filename);
}
}
private void loadDownloadImageFiles(final String filename) {
final InputStream stream;
// download additional images
if (filename.startsWith("file://")) {
try { //create file input stream
@ -73,27 +73,27 @@ public class DownloadMissingFiles extends ArrayList<WebDownloader> {
}
}
}
// download card images and texts
final File cardsPathFile=new File(gamePathFile, CardDefinitions.CARD_IMAGE_FOLDER);
final File tokensPathFile = new File(gamePathFile, CardDefinitions.TOKEN_IMAGE_FOLDER);
final File textPathFile = new File(gamePathFile, CardDefinitions.CARD_TEXT_FOLDER);
if (!tokensPathFile.exists() && !tokensPathFile.mkdir()) {
System.err.println("WARNING. Unable to create " + tokensPathFile);
}
if (!textPathFile.exists() && !textPathFile.mkdir()) {
System.err.println("WARNING. Unable to create " + textPathFile);
}
for (final MagicCardDefinition cardDefinition : CardDefinitions.getCards()) {
// card image
final String imageURL = cardDefinition.getImageURL();
if (imageURL != null) {
final File imageFile = cardDefinition.isToken()?
new File(tokensPathFile,
final File imageFile = cardDefinition.isToken()?
new File(tokensPathFile,
cardDefinition.getImageName() + CardDefinitions.CARD_IMAGE_EXT) :
new File(cardsPathFile,
new File(cardsPathFile,
cardDefinition.getImageName() + CardDefinitions.CARD_IMAGE_EXT);
try { //create URL
@ -105,15 +105,15 @@ public class DownloadMissingFiles extends ArrayList<WebDownloader> {
System.err.println("ERROR! URL malformed " + imageURL);
}
}
// card text
final String textUrl = cardDefinition.getCardInfoURL();
if (textUrl != null && textUrl.length() > 0) {
final File textFile = new File(textPathFile,
final File textFile = new File(textPathFile,
cardDefinition.getCardTextName() + CardDefinitions.CARD_TEXT_EXT);
// 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 ||
cardDefinition.isIgnored(textFile.length())) {
try { // create URL

View File

@ -18,7 +18,7 @@ public class DuelConfig {
private static final String ANY_THREE="***";
private static final String ANY_TWO="**";
private static final String ANY_ONE="*";
private static final String CONFIG_FILENAME="duel.cfg";
private static final String AVATAR="avatar";
private static final String NAME="name";
@ -39,11 +39,11 @@ public class DuelConfig {
private String opponentColors=ANY_THREE;
private String cube=CubeDefinitions.DEFAULT_NAME;
private String ai="minimax";
public DuelConfig() {
}
public DuelConfig(final DuelConfig duelConfig) {
avatar=duelConfig.avatar;
startLife=duelConfig.startLife;
@ -53,7 +53,7 @@ public class DuelConfig {
opponentColors=duelConfig.opponentColors;
ai=duelConfig.ai;
}
public int getAvatar() {
return avatar;
}
@ -61,11 +61,11 @@ public class DuelConfig {
public void setAvatar(final int avatar) {
this.avatar = avatar;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name=name;
}
@ -85,15 +85,15 @@ public class DuelConfig {
public void setHandSize(final int handSize) {
this.handSize = handSize;
}
public void setNrOfGames(final int aGames) {
this.games = aGames;
this.games = aGames;
}
public int getNrOfGames() {
return games;
}
private static MagicPlayerProfile getProfile(final String colorText) {
if (ANY_DECK.equals(colorText)) {
return new MagicPlayerProfile("");
@ -109,48 +109,48 @@ public class DuelConfig {
}
return new MagicPlayerProfile(colorText);
}
public String getPlayerColors() {
return playerColors;
}
public void setPlayerColors(final String colors) {
playerColors=colors;
}
public MagicPlayerProfile getPlayerProfile() {
return getProfile(playerColors);
}
public String getOpponentColors() {
return opponentColors;
}
public void setOpponentColors(final String colors) {
opponentColors=colors;
}
public MagicPlayerProfile getOpponentProfile() {
return getProfile(opponentColors);
}
public String getCube() {
return cube;
}
public void setCube(final String cube) {
this.cube=cube;
}
public MagicAI[] getPlayerAIs() {
final MagicAI playerAI = MagicAIImpl.getAI(ai).getAI();
return new MagicAI[]{playerAI, playerAI};
}
public String getAI() {
return ai;
}
public void setAI(final String ai) {
this.ai=ai;
}
@ -166,11 +166,11 @@ public class DuelConfig {
cube=properties.getProperty(CUBE,cube);
ai=properties.getProperty(AI,ai);
}
public void load() {
load(FileIO.toProp(getConfigFile()));
}
public void save(final Properties properties) {
properties.setProperty(AVATAR,Integer.toString(avatar));
properties.setProperty(NAME,name);
@ -182,22 +182,22 @@ public class DuelConfig {
properties.setProperty(CUBE,cube);
properties.setProperty(AI,ai);
}
public void save() {
final Properties properties=new Properties();
save(properties);
try { //save config
FileIO.toFile(getConfigFile(), properties, "Duel configuration");
FileIO.toFile(getConfigFile(), properties, "Duel configuration");
System.err.println("Saved duel config");
} catch (final IOException ex) {
System.err.println("ERROR! Unable to save duel config");
}
}
private static File getConfigFile() {
return new File(MagicMain.getGamePath(),CONFIG_FILENAME);
}
public static DuelConfig getInstance() {
return INSTANCE;
}

View File

@ -31,7 +31,7 @@ public class FileIO {
close(stream);
}
}
private static String toStr(final BufferedReader input) throws IOException {
final StringBuilder contents = new StringBuilder();
try {
@ -55,7 +55,7 @@ public class FileIO {
public static String toStr(final File aFile) throws IOException {
return toStr(new FileInputStream(aFile));
}
static String toStr(final InputStream ins) throws IOException {
return toStr(new BufferedReader(new InputStreamReader(ins)));
}
@ -66,10 +66,10 @@ public class FileIO {
properties = toProp(new FileInputStream(aFile));
} catch (final IOException ex) {
System.err.println("ERROR! Unable to load from " + aFile + ", " + ex.getMessage());
}
}
return properties;
}
public static Properties toProp(final InputStream ins) {
final Properties properties = new Properties();
try {
@ -84,7 +84,7 @@ public class FileIO {
public static BufferedImage toImg(final File input, final BufferedImage def) {
BufferedImage img = def;
try {
img = ImageIO.read(input);
} catch (final IOException ex) {
@ -92,16 +92,16 @@ public class FileIO {
} catch (final IllegalArgumentException ex) {
System.err.println("ERROR! Unable to read from null");
}
// no registered ImageReader able to read the file, likely file is corrupted
if (img == null) {
img = def;
input.delete();
}
return img;
}
static BufferedImage toImg(final URL input, final BufferedImage def) {
BufferedImage img = def;
try {
@ -113,7 +113,7 @@ public class FileIO {
}
return img;
}
public static BufferedImage toImg(final InputStream input, final BufferedImage def) {
BufferedImage img = def;
try {
@ -127,7 +127,7 @@ public class FileIO {
}
return img;
}
public static void toFile(final File aFile, final String aContents, final boolean append) throws IOException {
Writer output = null;
try {
@ -137,10 +137,10 @@ public class FileIO {
close(output);
}
}
public static void toFile(
final File aFile,
final Properties properties,
final File aFile,
final Properties properties,
final String name) throws IOException {
FileOutputStream fos = null;
try {
@ -199,4 +199,4 @@ public class FileIO {
}
}
}
}
}

View File

@ -9,7 +9,7 @@ import java.util.Properties;
public class GeneralConfig {
private static final GeneralConfig INSTANCE=new GeneralConfig();
private static final String CONFIG_FILENAME="general.cfg";
private static final String LEFT="left";
private static final String TOP="top";
@ -79,9 +79,9 @@ public class GeneralConfig {
private boolean sound=DEFAULT_SOUND;
private boolean confirmExit = DEFAULT_CONFIRM_EXIT;
private boolean touchscreen = DEFAULT_TOUCHSCREEN;
private GeneralConfig() {}
public int getLeft() {
return left;
}
@ -121,51 +121,51 @@ public class GeneralConfig {
public void setMaximized(final boolean maximized) {
this.maximized=maximized;
}
public String getTheme() {
return theme;
}
public void setTheme(final String theme) {
this.theme=theme;
}
public String getAvatar() {
return avatar;
}
public void setAvatar(final String avatar) {
this.avatar=avatar;
}
public boolean isHighlightNone() {
return "none".equals(highlight);
}
public boolean isHighlightOverlay() {
return "overlay".equals(highlight);
}
public boolean isHighlightTheme() {
return "theme".equals(highlight);
}
public String getHighlight() {
return highlight;
}
public void setHighlight(final String highlight) {
this.highlight = highlight;
}
public boolean getTextView() {
return textView;
}
public void setTextView(final boolean textView) {
this.textView=textView;
}
public boolean getSkipSingle() {
return skipSingle;
}
@ -173,19 +173,19 @@ public class GeneralConfig {
public void setSkipSingle(final boolean skipSingle) {
this.skipSingle=skipSingle;
}
public boolean getAlwaysPass() {
return alwaysPass;
}
public void setAlwaysPass(final boolean alwaysPass) {
this.alwaysPass=alwaysPass;
}
public boolean getSmartTarget() {
public boolean getSmartTarget() {
return smartTarget;
}
public void setSmartTarget(final boolean smartTarget) {
this.smartTarget=smartTarget;
}
@ -193,83 +193,83 @@ public class GeneralConfig {
public int getDifficulty() {
return difficulty;
}
public void setDifficulty(final int difficulty) {
this.difficulty=difficulty;
}
public int getExtraLife() {
return extraLife;
}
public void setExtraLife(final int extraLife) {
this.extraLife=extraLife;
}
public int getPopupDelay() {
return popupDelay;
}
public void setPopupDelay(final int popupDelay) {
this.popupDelay=popupDelay;
}
public int getMessageDelay() {
return messageDelay;
}
public void setMessageDelay(final int messageDelay) {
this.messageDelay = messageDelay;
}
public int getStrengthDifficulty() {
return strengthDifficulty;
}
public void setStrengthDifficulty(final int strengthDifficulty) {
this.strengthDifficulty=strengthDifficulty;
}
public int getStrengthGames() {
return strengthGames;
}
public void setStrengthGames(final int strengthGames) {
this.strengthGames=strengthGames;
}
public boolean isHighQuality() {
return highQuality;
}
public void setHighQuality(final boolean highQuality) {
this.highQuality=highQuality;
}
public boolean isSound() {
return sound;
}
public void setSound(final boolean sound) {
this.sound=sound;
}
public boolean isConfirmExit() {
return confirmExit;
}
public void setConfirmExit(final boolean confirmExit) {
public void setConfirmExit(final boolean confirmExit) {
this.confirmExit = confirmExit;
}
public boolean isTouchscreen() {
return touchscreen;
}
public void setTouchscreen(final boolean touchscreen) {
public void setTouchscreen(final boolean touchscreen) {
this.touchscreen = touchscreen;
}
private void load(final Properties properties) {
left=Integer.parseInt(properties.getProperty(LEFT,""+DEFAULT_LEFT));
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));
touchscreen = Boolean.parseBoolean(properties.getProperty(TOUCHSCREEN,""+DEFAULT_TOUCHSCREEN));
}
public void load() {
load(FileIO.toProp(getConfigFile()));
}
private void save(final Properties properties) {
properties.setProperty(LEFT,String.valueOf(left));
properties.setProperty(TOP,String.valueOf(top));
@ -323,7 +323,7 @@ public class GeneralConfig {
properties.setProperty(CONFIRM_EXIT,String.valueOf(confirmExit));
properties.setProperty(TOUCHSCREEN,String.valueOf(touchscreen));
}
public void save() {
final Properties properties=new Properties();
save(properties);

View File

@ -12,17 +12,17 @@ import java.util.Map;
* the cards directory
*/
public class HighQualityCardImagesProvider implements CardImagesProvider {
private static final CardImagesProvider INSTANCE=new HighQualityCardImagesProvider();
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);
private final Map<String,BufferedImage> origImages =
private final Map<String,BufferedImage> origImages =
new magic.data.LRUCache<String,BufferedImage>(MAX_IMAGES);
private HighQualityCardImagesProvider() {}
private static final String getFilename(
final MagicCardDefinition cardDefinition,
final int index) {
@ -35,11 +35,11 @@ public class HighQualityCardImagesProvider implements CardImagesProvider {
buffer.append(IMAGE_EXTENSION);
return buffer.toString();
}
private static BufferedImage loadCardImage(final String filename) {
return FileIO.toImg(new File(filename), IconImages.MISSING_CARD);
}
@Override
public BufferedImage getImage(
final MagicCardDefinition cardDefinition,
@ -56,10 +56,10 @@ public class HighQualityCardImagesProvider implements CardImagesProvider {
}
if (!scaledImages.containsKey(filename)) {
scaledImages.put(filename,
scaledImages.put(filename,
magic.GraphicsUtilities.scale(
origImages.get(filename),
CARD_WIDTH,
origImages.get(filename),
CARD_WIDTH,
CARD_HEIGHT
)
);
@ -67,12 +67,12 @@ public class HighQualityCardImagesProvider implements CardImagesProvider {
return orig ? origImages.get(filename) : scaledImages.get(filename);
}
public static CardImagesProvider getInstance() {
return INSTANCE;
}
public void clearCache() {
public void clearCache() {
origImages.clear();
scaledImages.clear();
}

View File

@ -12,10 +12,10 @@ import java.io.IOException;
import java.util.Properties;
public class History {
public static final String HISTORY_FOLDER = "history";
private static final String HISTORY_EXTENSION = ".hist";
private static final String GAMES_PLAYED = "gamesPlayed";
private static final String GAMES_WON = "gamesWon";
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_RED = "colorRed";
private static final String COLOR_WHITE = "colorWhite";
private static int gamesPlayed;
private static int gamesWon;
private static int turnsPlayed;
@ -41,25 +41,25 @@ public class History {
private static int colorGreen;
private static int colorRed;
private static int colorWhite;
private static String name = "";
private final MagicDuel duel;
public History(final MagicDuel duel) {
this.duel = duel;
}
private static String getHistoryFolder() {
return MagicMain.getGamePath() + File.separator + HISTORY_FOLDER;
}
public static void createHistoryFolder() {
final File HistoryFolderFile = new File(getHistoryFolder());
if (!HistoryFolderFile.exists() && !HistoryFolderFile.mkdir()) {
System.err.println("WARNING. Unable to create " + getHistoryFolder());
}
}
public void update(final boolean won,final MagicGame game,final DuelConfig configuration) {
gamesPlayed++;
if (won) {
@ -107,7 +107,7 @@ public class History {
}
saveHistory(name + HISTORY_EXTENSION);
}
private void load(final Properties properties) {
gamesPlayed = Integer.parseInt(properties.getProperty(GAMES_PLAYED,"0"));
gamesWon = Integer.parseInt(properties.getProperty(GAMES_WON,"0"));
@ -122,13 +122,13 @@ public class History {
colorRed = Integer.parseInt(properties.getProperty(COLOR_RED,"0"));
colorWhite = Integer.parseInt(properties.getProperty(COLOR_WHITE,"0"));
}
public void loadHistory(final String name) {
setName(name);
load(FileIO.toProp(new File(getHistoryFolder() +
File.separator + name + HISTORY_EXTENSION)));
}
private void save(final Properties properties) {
properties.setProperty(GAMES_PLAYED,String.valueOf(gamesPlayed));
properties.setProperty(GAMES_WON,String.valueOf(gamesWon));
@ -143,7 +143,7 @@ public class History {
properties.setProperty(COLOR_RED,String.valueOf(colorRed));
properties.setProperty(COLOR_WHITE,String.valueOf(colorWhite));
}
private void saveHistory(final String filename) {
final Properties properties = new Properties();
save(properties);
@ -160,11 +160,11 @@ public class History {
private static void setName(final String aName) {
History.name = aName;
}
public static String getName() {
return name;
}
public static int getGamesPlayed() {
return gamesPlayed;
}
@ -176,19 +176,19 @@ public class History {
public static int getTurnsPlayed() {
return turnsPlayed;
}
public static int getDuelsPlayed() {
return duelsPlayed;
}
public static int getDuelsWon() {
return duelsWon;
}
public static int getLifeLeftPlayer() {
return lifeLeftPlayer;
}
public static int getLifeLeftAI() {
return lifeLeftAI;
}
@ -196,19 +196,19 @@ public class History {
public static int getColorBlack() {
return colorBlack;
}
public static int getColorBlue() {
return colorBlue;
}
public static int getColorGreen() {
return colorGreen;
}
public static int getColorRed() {
return colorRed;
}
public static int getColorWhite() {
return colorWhite;
}

View File

@ -11,14 +11,14 @@ public class IconImages {
public static final BufferedImage MISSING2=loadImage("icons/missing2.png");
public static final BufferedImage MISSING_CARD=loadImage("icons/missing_card.png");
public static final ImageIcon MISSING_ICON=loadIcon("missing2.png");
private static final BufferedImage MANA = loadImage("icons/Mana.png");
public static final BufferedImage LOGO=loadImage("textures/logo.jpg");
public static final BufferedImage WIZARD=loadImage("icons/wizard.png");
public static final BufferedImage WOOD=loadImage("textures/wood.jpg");
public static final BufferedImage MARBLE=loadImage("textures/marble.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 OPAL2=loadImage("textures/opal2.jpg");
@ -80,7 +80,7 @@ public class IconImages {
public static final ImageIcon DAMAGE=loadIcon("damage.gif");
public static final ImageIcon COMBAT=loadIcon("combat.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 MESSAGE=loadIcon("message.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 PICTURE=loadIcon("picture.png");
public static final ImageIcon AVATAR=loadIcon("avatar.gif");
public static final ImageIcon FLYING=loadIcon("flying.png");
public static final ImageIcon TRAMPLE=loadIcon("trample.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 BLACK=loadSymbolIcon(26, 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_BLUE=loadSymbolIcon(25, false);
public static final ImageIcon COST_BLACK=loadSymbolIcon(26, 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_BLACK=loadSymbolIcon(31, 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_NINE_OR_MORE=loadIcon("nineplus.gif");
public static final ImageIcon COST_X=loadSymbolIcon(21, false);
private static BufferedImage loadImage(final String name) {
return FileIO.toImg(IconImages.class.getResource(name), MISSING2);
}
private static ImageIcon loadIcon(final String name) {
final BufferedImage image=loadImage("icons/"+name);
return new ImageIcon(image);
@ -171,7 +171,7 @@ public class IconImages {
return new ImageIcon(magic.GraphicsUtilities.scale(subimage,icoW,icoH));
}
}
private static ImageIcon loadAnimatedIcon(final String name) {
final byte[] data = new byte[1<<16];
int size = 0;

View File

@ -10,13 +10,13 @@ public class KeywordDefinitions {
private static final KeywordDefinitions INSTANCE=new KeywordDefinitions();
private static final String KEYWORDS_FILENAME="keywords.txt";
private final List<KeywordDefinition> keywordDefinitions;
private KeywordDefinitions() {
keywordDefinitions=new ArrayList<KeywordDefinition>();
}
public void loadKeywordDefinitions() {
keywordDefinitions.clear();
String content = null;
@ -44,15 +44,15 @@ public class KeywordDefinitions {
}
}
}
public List<KeywordDefinition> getKeywordDefinitions() {
return keywordDefinitions;
}
public static KeywordDefinitions getInstance() {
return INSTANCE;
}
public static class KeywordDefinition {
public String name;
public String description="";

View File

@ -4,16 +4,16 @@ File: OSXAdapter.java
Abstract: Hooks existing preferences/about/quit functionality from an
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.Application object. This allows the complete project
to be both built and run on any platform without any stubs or
placeholders. Useful for developers looking to implement Mac OS X
to be both built and run on any platform without any stubs or
placeholders. Useful for developers looking to implement Mac OS X
features while supporting multiple platforms with minimal impact.
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
following terms, and your use, installation, modification or
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;
provided that if you redistribute the Apple Software in its entirety and
without modifications, you must retain this notice and the following
text and disclaimers in all such redistributions of the Apple Software.
Neither the name, trademarks, service marks or logos of Apple Inc.
text and disclaimers in all such redistributions of the Apple Software.
Neither the name, trademarks, service marks or logos of Apple Inc.
may be used to endorse or promote products derived from the Apple
Software without specific prior written permission from Apple. Except
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 Method targetMethod;
protected String proxySignature;
static Object macOSXApplication;
// 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) {
setHandler(new OSXAdapter("handleQuit", target, quitHandler));
}
// 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
public static void setAboutHandler(final Object target, final Method aboutHandler) {
@ -94,7 +94,7 @@ public class OSXAdapter implements InvocationHandler {
ex.printStackTrace();
}
}
// 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
public static void setPreferencesHandler(final Object target, final Method prefsHandler) {
@ -112,9 +112,9 @@ public class OSXAdapter implements InvocationHandler {
ex.printStackTrace();
}
}
// 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
public static void setFileHandler(final Object target, final Method 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);
this.targetMethod.invoke(this.targetObject, filename);
} catch (Exception ex) {
}
}
return true;
}
});
}
// setHandler creates a Proxy object from the passed OSXAdapter and adds it as an ApplicationListener
public static void setHandler(final OSXAdapter adapter) {
try {
@ -162,8 +162,8 @@ public class OSXAdapter implements InvocationHandler {
this.targetObject = target;
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
// See setFileHandler above for an example
public boolean callTarget(final Object appleEvent) throws InvocationTargetException, IllegalAccessException {
@ -173,7 +173,7 @@ public class OSXAdapter implements InvocationHandler {
}
return Boolean.valueOf(result.toString()).booleanValue();
}
// InvocationHandler implementation
// 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 {
@ -184,13 +184,13 @@ public class OSXAdapter implements InvocationHandler {
// All of the ApplicationListener methods are void; return null regardless of what happens
return null;
}
// Compare the method that was called to the intended method when the OSXAdapter instance was created
// (e.g. handleAbout, handleQuit, handleOpenFile, etc.)
protected boolean isCorrectMethod(final Method method, final Object[] args) {
return (targetMethod != null && proxySignature.equals(method.getName()) && args.length == 1);
}
// 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
protected void setApplicationEventHandled(final Object event, final boolean handled) {

View File

@ -20,12 +20,12 @@ public class SoundEffects implements LineListener {
public static final String TURN_SOUND="turn.au";
public static final String RESOLVE_SOUND="resolve.au";
public static final String COMBAT_SOUND="combat.au";
private static final File SOUNDS_PATH=new File(MagicMain.getGamePath(),"sounds");
private static final SoundEffects INSTANCE=new SoundEffects();
private SoundEffects() {}
public static void playClip(final String name) {
if (GeneralConfig.getInstance().isSound()) {
Clip clip = null;
@ -60,4 +60,4 @@ public class SoundEffects implements LineListener {
event.getLine().close();
}
}
}
}

View File

@ -5,9 +5,9 @@ import java.util.HashMap;
import java.util.Map;
public class TextImages {
private static final Map<String,ImageIcon> TEXT_ICONS=new HashMap<String,ImageIcon>();
static {
TEXT_ICONS.put("{0}",IconImages.COST_ZERO);
TEXT_ICONS.put("{1}",IconImages.COST_ONE);
@ -27,7 +27,7 @@ public class TextImages {
TEXT_ICONS.put("{15}",IconImages.COST_FIFTEEN);
TEXT_ICONS.put("{16}",IconImages.COST_SIXTEEN);
TEXT_ICONS.put("{X}",IconImages.COST_X);
TEXT_ICONS.put("{B}",IconImages.COST_BLACK);
TEXT_ICONS.put("{U}",IconImages.COST_BLUE);
TEXT_ICONS.put("{G}",IconImages.COST_GREEN);
@ -63,7 +63,7 @@ public class TextImages {
TEXT_ICONS.put("{br}",IconImages.BRIBECOUNTER);
TEXT_ICONS.put("{L}",IconImages.LOSE);
}
public static ImageIcon getIcon(final String text) {
if (!TEXT_ICONS.containsKey(text)) {
throw new RuntimeException("No corresponding icon for " + text);

View File

@ -13,7 +13,7 @@ public class TokenCardDefinitions {
public static Collection<MagicCardDefinition> getAll() {
return tokensMap.values();
}
public static MagicCardDefinition get(final String name) {
if (tokensMap.containsKey(name)) {
return tokensMap.get(name);
@ -21,7 +21,7 @@ public class TokenCardDefinitions {
throw new RuntimeException("token " + name + " not found");
}
}
public static void add(final MagicCardDefinition token) {
tokensMap.put(token.getFullName(), token);
}

View File

@ -6,7 +6,7 @@ import java.net.URI;
import java.net.URISyntaxException;
public class URLUtils {
public static void openURL(final String url) {
try {
Desktop desktop = null;

View File

@ -11,15 +11,15 @@ import java.io.OutputStream;
import java.net.Proxy;
import java.net.URL;
public abstract class WebDownloader {
public abstract class WebDownloader {
public abstract void download(final Proxy proxy);
public abstract String getFilename();
public abstract File getFile();
public abstract boolean exists();
public static void downloadToFile(final Proxy proxy, final URL url, final File file) {
OutputStream outputStream = null;
InputStream inputStream = null;
@ -47,17 +47,17 @@ public abstract class WebDownloader {
magic.data.FileIO.close(outputStream);
}
}
public static String getHTML(final Proxy proxy, final URL url) {
InputStream inputStream = null;
BufferedReader dataStream = null;
final StringBuilder sb = new StringBuilder();
String line;
try {
inputStream = url.openConnection(proxy).getInputStream();
dataStream = new BufferedReader(new InputStreamReader(inputStream));
while( (line = dataStream.readLine()) != null) {
sb.append(line);
sb.append("\n");
@ -70,7 +70,7 @@ public abstract class WebDownloader {
magic.data.FileIO.close(inputStream);
magic.data.FileIO.close(dataStream);
}
return sb.toString();
}
}

View File

@ -14,23 +14,23 @@ import java.util.Random;
public class Ability_Mono_DeckGenerator extends DefaultDeckGenerator {
private static final int MIN_NUM_CARDS_WITH_SUBTYPE = 30;
private static final Random randGen = new Random();
// all possible tribes - calculated once
private static final ArrayList<MagicAbility> possibleAbilities = new ArrayList<MagicAbility>();
private static final ArrayList<ArrayList<String>> possibleColors = new ArrayList<ArrayList<String>>();
// random tribe from all possible for each instance
private final MagicAbility ability;
private final String colorText;
public Ability_Mono_DeckGenerator() {
super(null);
if(!hasChoice()) {
getPossibleTribes();
}
if(hasChoice()) {
final int i = randGen.nextInt(possibleAbilities.size());
ability = possibleAbilities.get(i);
@ -39,14 +39,14 @@ public class Ability_Mono_DeckGenerator extends DefaultDeckGenerator {
ability = null;
colorText = "";
}
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
}
private boolean hasChoice() {
return possibleAbilities.size() > 0 && possibleColors.size() == possibleAbilities.size();
}
private void getPossibleTribes() {
for(final MagicAbility ab : MagicAbility.CORE) {
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.Red, 0);
countColors.put(MagicColor.Blue, 0);
// count colors
for(final MagicCardDefinition card : CardDefinitions.getCards()) {
if (card.hasAbility(ab)) {
@ -67,37 +67,37 @@ public class Ability_Mono_DeckGenerator extends DefaultDeckGenerator {
}
}
}
final ArrayList<String> choiceColors = getPossibleColors(countColors);
if(choiceColors.size() > 0) {
possibleAbilities.add(ab);
possibleColors.add(choiceColors);
}
}
}
private ArrayList<String> getPossibleColors(final HashMap<MagicColor, Integer> countColors) {
// monocolor
final ArrayList<String> a = new ArrayList<String>();
for(final MagicColor c : countColors.keySet()) {
if(countColors.get(c).intValue() > MIN_NUM_CARDS_WITH_SUBTYPE) {
a.add("" + c.getSymbol());
}
}
return a;
}
public String getColorText() {
return colorText;
}
public int getMinRarity() {
return 1;
}
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
if(hasChoice()) {
return !card.isCreature() || card.hasAbility(ability);
@ -105,11 +105,11 @@ public class Ability_Mono_DeckGenerator extends DefaultDeckGenerator {
return true;
}
}
public void setColors(final MagicPlayerProfile profile) {
profile.setColors(getColorText());
}
public boolean ignoreMaxCost() {
return false;
}

View File

@ -12,16 +12,16 @@ import java.util.ArrayList;
import java.util.List;
public class DefaultDeckGenerator {
private final List<MagicCardDefinition> spellCards = new ArrayList<MagicCardDefinition>();
private final List<MagicCardDefinition> landCards = new ArrayList<MagicCardDefinition>();
private MagicCubeDefinition cubeDefinition;
public DefaultDeckGenerator(final MagicCubeDefinition cubeDefinition) {
this.cubeDefinition = cubeDefinition;
}
public void setCubeDefinition(final MagicCubeDefinition cube) {
cubeDefinition = cube;
}
@ -30,7 +30,7 @@ public class DefaultDeckGenerator {
if(cubeDefinition == null) {
return;
}
spellCards.clear();
for (int rarity = getMinRarity(); rarity <= getMaxRarity(); rarity++) {
for (final MagicCardDefinition card : CardDefinitions.getSpellCards()) {
@ -42,15 +42,15 @@ public class DefaultDeckGenerator {
}
}
}
public int getMinRarity() {
return 1;
}
public int getMaxRarity() {
return 4;
}
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
return true;
}
@ -59,7 +59,7 @@ public class DefaultDeckGenerator {
if(cubeDefinition == null) {
return;
}
landCards.clear();
for (final MagicCardDefinition card : CardDefinitions.getLandCards()) {
if (cubeDefinition.containsCard(card)) {
@ -69,38 +69,38 @@ public class DefaultDeckGenerator {
}
}
}
}
}
}
public boolean acceptPossibleLandCard(final MagicCardDefinition card) {
return true;
}
public void generateDeck(final int size, final MagicPlayerProfile profile, final MagicDeck deck) {
setColors(profile);
final MagicCondensedDeck condensedDeck = new MagicCondensedDeck();
genSpells();
genLands();
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 maxNonlandNoncreature = spells - maxCreatures;
final int maxColorless = spells/6;
final int maxHigh = spells/6;
final int maxOther = (spells-maxHigh)/2;
final int[] maxCost = {maxOther,maxOther+1,maxHigh};
int countCreatures = 0;
int countColorless = 0;
int countNonlandNoncreature = 0;
final int[] countCost = new int[3];
addRequiredSpells(condensedDeck);
// count required cards added
for(final MagicCardDefinition card : condensedDeck.toMagicDeck()) {
if(card.isCreature()) {
@ -108,41 +108,41 @@ public class DefaultDeckGenerator {
} else if(!card.isLand()) {
countNonlandNoncreature++;
}
if(card.isColorless()) {
countColorless++;
}
countCost[card.getCostBucket()]++;
}
// Add spells to deck.
while (condensedDeck.getNumCards() < spells && spellCards.size() > 0) {
final int index=MagicRandom.nextInt(spellCards.size());
final MagicCardDefinition cardDefinition=spellCards.get(index);
spellCards.remove(index);
if (cardDefinition.isPlayable(profile)) {
final boolean creature = cardDefinition.isCreature();
if(creature && countCreatures >= maxCreatures) {
continue;
}
if (!creature && countNonlandNoncreature >= maxNonlandNoncreature) {
continue;
}
final boolean colorless = cardDefinition.isColorless();
if (!ignoreMaxColorless() && colorless && countColorless >= maxColorless) {
continue;
}
final int bucket = cardDefinition.getCostBucket();
if (!ignoreMaxCost() && countCost[bucket] >= maxCost[bucket]) {
continue;
}
if(condensedDeck.addCard(cardDefinition, false)) {
countCost[bucket]++;
if(creature) {
@ -154,29 +154,29 @@ public class DefaultDeckGenerator {
countColorless++;
}
}
}
}
if (spellCards.size() == 0) {
genSpells();
}
}
// Add non basic lands to deck.
addRequiredLands(condensedDeck);
while (condensedDeck.getNumCards() < spells+lands && landCards.size() > 0) {
final int index=MagicRandom.nextInt(landCards.size());
final MagicCardDefinition cardDefinition=landCards.get(index);
landCards.remove(index);
if (cardDefinition.isPlayable(profile)) {
condensedDeck.addCard(cardDefinition, false);
}
}
deck.setContent(condensedDeck.toMagicDeck());
}
protected void addRequiredCards(final MagicCondensedDeck deck, final String[] cards) {
for(final String name : cards) {
final MagicCardDefinition cardDef = CardDefinitions.getCard(name);
@ -187,17 +187,17 @@ public class DefaultDeckGenerator {
}
}
}
public void addRequiredSpells(final MagicCondensedDeck deck) { }
public void addRequiredLands(final MagicCondensedDeck deck) { }
public void setColors(final MagicPlayerProfile profile) { }
public boolean ignoreMaxColorless() {
return false;
}
public boolean ignoreMaxCost() {
return false;
}

View File

@ -10,45 +10,45 @@ public class Elf_Horde_DeckGenerator extends DefaultDeckGenerator {
private static final String colorText = "g";
private static final String[] cards = {
"Joraga Warcaller",
"Joraga Warcaller",
"Elvish Champion",
"Elvish Champion",
"Imperious Perfect",
"Imperious Perfect",
"Imperious Perfect",
"Imperious Perfect",
"Ezuri, Renegade Leader",
"Llanowar Elves",
"Llanowar Elves",
"Joraga Warcaller",
"Joraga Warcaller",
"Elvish Champion",
"Elvish Champion",
"Imperious Perfect",
"Imperious Perfect",
"Imperious Perfect",
"Imperious Perfect",
"Ezuri, Renegade Leader",
"Llanowar Elves",
"Llanowar Elves",
"Llanowar Elves"
};
public Elf_Horde_DeckGenerator() {
super(null);
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
}
public String getColorText() {
return colorText;
}
public int getMinRarity() {
return 2;
}
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
return !card.isCreature() || card.hasSubType(MagicSubType.Elf);
}
public void addRequiredSpells(final MagicCondensedDeck deck) {
addRequiredCards(deck, cards);
}
public void setColors(final MagicPlayerProfile profile) {
profile.setColors(getColorText());
}
public boolean ignoreMaxCost() {
return true;
}

View File

@ -23,7 +23,7 @@ public class Fairy_Horde_DeckGenerator extends DefaultDeckGenerator {
"Mistbind Clique",
"Mistbind Clique"
};
private static final String[] lands = {
"Mutavault",
"Mutavault",
@ -33,36 +33,36 @@ public class Fairy_Horde_DeckGenerator extends DefaultDeckGenerator {
"Watery Grave",
"Watery Grave"
};
public Fairy_Horde_DeckGenerator() {
super(null);
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
}
public String getColorText() {
return colorText;
}
public int getMinRarity() {
return 2;
}
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
return !card.isCreature() || card.hasSubType(MagicSubType.Faerie);
}
public void addRequiredSpells(final MagicCondensedDeck deck) {
addRequiredCards(deck, spells);
}
public void addRequiredLands(final MagicCondensedDeck deck) {
addRequiredCards(deck, lands);
}
public void setColors(final MagicPlayerProfile profile) {
profile.setColors(getColorText());
}
public boolean ignoreMaxCost() {
return true;
}

View File

@ -10,44 +10,44 @@ public class Human_Law_DeckGenerator extends DefaultDeckGenerator {
private static final String colorText = "w";
private static final String[] cards = {
"Champion of the Parish",
"Champion of the Parish",
"Champion of the Parish",
"Elite Vanguard",
"Gideon's Lawkeeper",
"Hero of Bladehold",
"Hero of Bladehold",
"Hero of Bladehold",
"Mirran Crusader",
"Mirran Crusader",
"Angelic Destiny",
"Angelic Destiny",
"Honor of the Pure",
"Honor of the Pure",
"Champion of the Parish",
"Champion of the Parish",
"Champion of the Parish",
"Elite Vanguard",
"Gideon's Lawkeeper",
"Hero of Bladehold",
"Hero of Bladehold",
"Hero of Bladehold",
"Mirran Crusader",
"Mirran Crusader",
"Angelic Destiny",
"Angelic Destiny",
"Honor of the Pure",
"Honor of the Pure",
"Day of Judgment"
};
public Human_Law_DeckGenerator() {
super(null);
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
}
public String getColorText() {
return colorText;
}
public int getMinRarity() {
return 2;
}
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
return !card.isCreature() || card.hasSubType(MagicSubType.Human);
}
public void addRequiredSpells(final MagicCondensedDeck deck) {
addRequiredCards(deck, cards);
}
public void setColors(final MagicPlayerProfile profile) {
profile.setColors(getColorText());
}

View File

@ -25,7 +25,7 @@ public class Saint___Hero_DeckGenerator extends DefaultDeckGenerator {
"Oblivion Ring",
"Sword of Feast and Famine"
};
private static final String[] lands = {
"Glacial Fortress",
"Glacial Fortress",
@ -34,28 +34,28 @@ public class Saint___Hero_DeckGenerator extends DefaultDeckGenerator {
"Seachrome Coast",
"Seachrome Coast"
};
public Saint___Hero_DeckGenerator() {
super(null);
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
}
public String getColorText() {
return colorText;
}
public int getMinRarity() {
return 2;
}
public void addRequiredSpells(final MagicCondensedDeck deck) {
addRequiredCards(deck, spells);
}
public void addRequiredLands(final MagicCondensedDeck deck) {
addRequiredCards(deck, lands);
}
public void setColors(final MagicPlayerProfile profile) {
profile.setColors(getColorText());
}

View File

@ -40,32 +40,32 @@ public class Token_Madness_DeckGenerator extends DefaultDeckGenerator {
"Sunpetal Grove",
"Sunpetal Grove"
};
public Token_Madness_DeckGenerator() {
super(null);
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
}
public String getColorText() {
return colorText;
}
public int getMinRarity() {
return 2;
}
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
return !card.isCreature() || card.hasText("token");
}
public void addRequiredSpells(final MagicCondensedDeck deck) {
addRequiredCards(deck, spells);
}
public void addRequiredLands(final MagicCondensedDeck deck) {
addRequiredCards(deck, lands);
}
public void setColors(final MagicPlayerProfile profile) {
profile.setColors(getColorText());
}

View File

@ -14,23 +14,23 @@ import java.util.Random;
public class Tribal_Mono_DeckGenerator extends DefaultDeckGenerator {
private static final int MIN_NUM_CARDS_WITH_SUBTYPE = 30;
private static final Random randGen = new Random();
// all possible tribes - calculated once
private static final ArrayList<MagicSubType> possibleTribes = new ArrayList<MagicSubType>();
private static final ArrayList<ArrayList<String>> possibleColors = new ArrayList<ArrayList<String>>();
// random tribe from all possible for each instance
private final MagicSubType tribe;
private final String colorText;
public Tribal_Mono_DeckGenerator() {
super(null);
if(!hasChoice()) {
getPossibleTribes();
}
if(hasChoice()) {
final int i = randGen.nextInt(possibleTribes.size());
tribe = possibleTribes.get(i);
@ -39,14 +39,14 @@ public class Tribal_Mono_DeckGenerator extends DefaultDeckGenerator {
tribe = null;
colorText = "";
}
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
}
private boolean hasChoice() {
return possibleTribes.size() > 0 && possibleColors.size() == possibleTribes.size();
}
private void getPossibleTribes() {
for(final MagicSubType s : MagicSubType.ALL_CREATURES) {
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.Red, new Integer(0));
countColors.put(MagicColor.Blue, new Integer(0));
// count colors
for(final MagicCardDefinition card : CardDefinitions.getCards()) {
if(card.hasSubType(s)) {
final int colorFlags = card.getColorFlags();
for(final MagicColor c : countColors.keySet()) {
if (c.hasColor(colorFlags)) {
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);
if(choiceColors.size() > 0) {
possibleTribes.add(s);
possibleColors.add(choiceColors);
}
}
}
private ArrayList<String> getPossibleColors(final HashMap<MagicColor, Integer> countColors) {
// monocolor
final ArrayList<String> a = new ArrayList<String>();
for(final MagicColor c : countColors.keySet()) {
if(countColors.get(c).intValue() > MIN_NUM_CARDS_WITH_SUBTYPE) {
a.add("" + c.getSymbol());
}
}
return a;
}
public String getColorText() {
return colorText;
}
public int getMinRarity() {
return 1;
}
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
if(hasChoice()) {
return !card.isCreature() || card.hasSubType(tribe);
@ -106,11 +106,11 @@ public class Tribal_Mono_DeckGenerator extends DefaultDeckGenerator {
return true;
}
}
public void setColors(final MagicPlayerProfile profile) {
profile.setColors(getColorText());
}
public boolean ignoreMaxCost() {
return false;
}

View File

@ -10,61 +10,61 @@ public class Vampire_Rage_DeckGenerator extends DefaultDeckGenerator {
private static final String colorText = "br";
private static final String[] spells = {
"Falkenrath Marauders",
"Falkenrath Noble",
"Markov Patrician",
"Markov Patrician",
"Rakish Heir",
"Rakish Heir",
"Rakish Heir",
"Stromkirk Noble",
"Stromkirk Noble",
"Stromkirk Noble",
"Doom Blade",
"Go for the Throat",
"Go for the Throat",
"Falkenrath Marauders",
"Falkenrath Noble",
"Markov Patrician",
"Markov Patrician",
"Rakish Heir",
"Rakish Heir",
"Rakish Heir",
"Stromkirk Noble",
"Stromkirk Noble",
"Stromkirk Noble",
"Doom Blade",
"Go for the Throat",
"Go for the Throat",
"Mask of Avacyn"
};
private static final String[] lands = {
"Blackcleave Cliffs",
"Blackcleave Cliffs",
"Blackcleave Cliffs",
"Blackcleave Cliffs",
"Blood Crypt",
"Blood Crypt",
"Blood Crypt",
"Dragonskull Summit",
"Dragonskull Summit",
"Dragonskull Summit",
"Blackcleave Cliffs",
"Blackcleave Cliffs",
"Blackcleave Cliffs",
"Blackcleave Cliffs",
"Blood Crypt",
"Blood Crypt",
"Blood Crypt",
"Dragonskull Summit",
"Dragonskull Summit",
"Dragonskull Summit",
"Dragonskull Summit"
};
public Vampire_Rage_DeckGenerator() {
super(null);
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
}
public String getColorText() {
return colorText;
}
public int getMinRarity() {
return 2;
}
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
return !card.isCreature() || card.hasSubType(MagicSubType.Vampire);
}
public void addRequiredSpells(final MagicCondensedDeck deck) {
addRequiredCards(deck, spells);
}
public void addRequiredLands(final MagicCondensedDeck deck) {
addRequiredCards(deck, lands);
}
public void setColors(final MagicPlayerProfile profile) {
profile.setColors(getColorText());
}

View File

@ -10,47 +10,47 @@ public class White_Knights_DeckGenerator extends DefaultDeckGenerator {
private static final String colorText = "w";
private static final String[] cards = {
"Knight Exemplar",
"Knight Exemplar",
"Knight Exemplar",
"Knight Exemplar",
"Day of Judgment",
"Student of Warfare",
"Student of Warfare",
"Sun Titan",
"Kinsbaile Cavalier",
"Honor of the Pure",
"Honor of the Pure",
"Honor of the Pure",
"Hero of Bladehold",
"Knight Exemplar",
"Knight Exemplar",
"Knight Exemplar",
"Knight Exemplar",
"Day of Judgment",
"Student of Warfare",
"Student of Warfare",
"Sun Titan",
"Kinsbaile Cavalier",
"Honor of the Pure",
"Honor of the Pure",
"Honor of the Pure",
"Hero of Bladehold",
"Hero of Bladehold"
};
public White_Knights_DeckGenerator() {
super(null);
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
}
public String getColorText() {
return colorText;
}
public int getMinRarity() {
return 2;
}
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
return !card.isCreature() || card.hasSubType(MagicSubType.Knight);
}
public void addRequiredSpells(final MagicCondensedDeck deck) {
addRequiredCards(deck, cards);
}
public void setColors(final MagicPlayerProfile profile) {
profile.setColors(getColorText());
}
public boolean ignoreMaxCost() {
return true;
}

View File

@ -29,11 +29,11 @@ public class White_Metal_DeckGenerator extends DefaultDeckGenerator {
"Mox Opal",
"Leonin Relic-Warder"
};
private static final String[] lands = {
"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);
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
}
public String getColorText() {
return colorText;
}
public int getMinRarity() {
return 2;
}
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
return !card.isCreature() || card.isArtifact();
}
public void addRequiredSpells(final MagicCondensedDeck deck) {
addRequiredCards(deck, spells);
}
public void addRequiredLands(final MagicCondensedDeck deck) {
addRequiredCards(deck, lands);
}
public void setColors(final MagicPlayerProfile profile) {
profile.setColors(getColorText());
}
public boolean ignoreMaxColorless() {
return true;
}

View File

@ -10,43 +10,43 @@ public class Zombie_Madness_DeckGenerator extends DefaultDeckGenerator {
private static final String colorText = "b";
private static final String[] cards = {
"Cemetery Reaper",
"Cemetery Reaper",
"Cemetery Reaper",
"Cemetery Reaper",
"Death Baron",
"Death Baron",
"Festering Goblin",
"Festering Goblin",
"Lord of the Undead",
"Lord of the Undead",
"Lord of the Undead",
"Call to the Grave",
"Call to the Grave",
"Cemetery Reaper",
"Cemetery Reaper",
"Cemetery Reaper",
"Cemetery Reaper",
"Death Baron",
"Death Baron",
"Festering Goblin",
"Festering Goblin",
"Lord of the Undead",
"Lord of the Undead",
"Lord of the Undead",
"Call to the Grave",
"Call to the Grave",
"Severed Legion"
};
public Zombie_Madness_DeckGenerator() {
super(null);
setCubeDefinition(CubeDefinitions.getCubeDefinition(getColorText()));
}
public String getColorText() {
return colorText;
}
public int getMinRarity() {
return 2;
}
public boolean acceptPossibleSpellCard(final MagicCardDefinition card) {
return !card.isCreature() || card.hasSubType(MagicSubType.Zombie);
}
public void addRequiredSpells(final MagicCondensedDeck deck) {
addRequiredCards(deck, cards);
}
public void setColors(final MagicPlayerProfile profile) {
profile.setColors(getColorText());
}

File diff suppressed because it is too large Load Diff

View File

@ -24,10 +24,10 @@ class MagicSyntaxTree extends magic.grammar.SemanticsBase {
if (numRule == 0 ||
lhs().rule().startsWith("Select") ||
lhs().rule().endsWith("Number") ||
lhs().rule().endsWith("Count") ||
lhs().rule().endsWith("Duration") ||
lhs().rule().endsWith("Keyword") ||
lhs().rule().endsWith("Number") ||
lhs().rule().endsWith("Count") ||
lhs().rule().endsWith("Duration") ||
lhs().rule().endsWith("Keyword") ||
lhs().rule().equals("ManaCost")) {
node.clear();
node.text = lhs().text();

View File

@ -20,7 +20,7 @@ public class Node {
sb.append(')');
return sb.toString();
}
public void show() {
show(0);
}

View File

@ -87,7 +87,7 @@ public enum MagicAbility {
CannotBeBlockedByFlying("can't be blocked by creatures with flying",20),
CannotBeBlockedExceptWithFlying("can't be blocked except by creatures with flying",30),
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),
CannotBeBlockedByBlack("can't be blocked by black creatures",10),
CannotBeBlockedByBlue("can't be blocked by blue creatures",10),
@ -142,7 +142,7 @@ public enum MagicAbility {
Infect("infect",35),
Soulbond("soulbond",30),
CantActivateAbilities("can't activate abilities",-20),
Undying("undying",60) {
public void addAbilityImpl(final MagicCardDefinition card, final String 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
// see MagicAbility.CORE
Changeling("changeling",10) {
public void addAbilityImpl(final MagicCardDefinition card, final String arg) {
assert arg.isEmpty() : this + " does not accept arg = " + arg;
@ -759,7 +759,7 @@ public enum MagicAbility {
}
},
None("",0);
public static final Set<MagicAbility> CORE = EnumSet.range(AttacksEachTurnIfAble, Flanking);
public static final Set<MagicAbility> PROTECTION_FLAGS = EnumSet.of(
@ -777,7 +777,7 @@ public enum MagicAbility {
ProtectionFromWerewolves,
ProtectionFromZombies
);
public static final Set<MagicAbility> LANDWALK_FLAGS = EnumSet.of(
Forestwalk,
Islandwalk,
@ -785,17 +785,17 @@ public enum MagicAbility {
PlainsWalk,
Swampwalk
);
//public static final long EXCLUDE_MASK = Long.MAX_VALUE-Flash.getMask()-CannotBeCountered.getMask()-TotemArmor.getMask();
private final String name;
private final int score;
private MagicAbility(final String aName,final int aScore) {
name = aName;
score = aScore;
}
public String getName() {
return name;
}
@ -803,7 +803,7 @@ public enum MagicAbility {
public void addAbilityImpl(final MagicCardDefinition card, final String arg) {
assert arg.isEmpty() : this + " does not accept arg = " + arg;
}
@Override
public String toString() {
return name;
@ -812,7 +812,7 @@ public enum MagicAbility {
private int getScore() {
return score;
}
public static int getScore(final Set<MagicAbility> flags) {
int score=0;
for (final MagicAbility ability : flags) {
@ -820,7 +820,7 @@ public enum MagicAbility {
}
return score;
}
public static MagicAbility getAbility(final String name) {
MagicAbility match = None;
for (final MagicAbility ability : values()) {
@ -834,7 +834,7 @@ public enum MagicAbility {
return match;
}
}
public static Set<MagicAbility> getAbilities(final String[] names) {
Set<MagicAbility> flags = EnumSet.noneOf(MagicAbility.class);
for (final String name : names) {
@ -846,7 +846,7 @@ public enum MagicAbility {
public static Set<MagicAbility> of(final MagicAbility first, MagicAbility... rest) {
return EnumSet.of(first, rest);
}
public static Set<MagicAbility> noneOf() {
return EnumSet.noneOf(MagicAbility.class);
}

View File

@ -3,6 +3,6 @@ package magic.model;
import java.util.ArrayList;
public class MagicBoosterPack extends ArrayList<MagicCardDefinition> {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L;
}

View File

@ -23,14 +23,14 @@ public class MagicCard implements MagicSource,MagicTarget,Comparable<MagicCard>
};
private static final int TOKEN_ID=-1;
private final MagicCardDefinition cardDefinition;
private final MagicPlayer owner;
private final long id;
private final int imageIndex;
private boolean token;
private boolean known=true;
public MagicCard(final MagicCardDefinition aCardDefinition,final MagicPlayer aOwner,final long aId) {
aCardDefinition.loadScript();
cardDefinition = aCardDefinition;
@ -41,7 +41,7 @@ public class MagicCard implements MagicSource,MagicTarget,Comparable<MagicCard>
private MagicCard(final MagicCopyMap copyMap, final MagicCard sourceCard) {
copyMap.put(sourceCard, this);
cardDefinition = sourceCard.cardDefinition;
owner = copyMap.copy(sourceCard.owner);
id = sourceCard.id;
@ -49,12 +49,12 @@ public class MagicCard implements MagicSource,MagicTarget,Comparable<MagicCard>
token = sourceCard.token;
known = sourceCard.known;
}
@Override
public MagicCard copy(final MagicCopyMap copyMap) {
return new MagicCard(copyMap, this);
return new MagicCard(copyMap, this);
}
@Override
public MagicCard map(final MagicGame game) {
final MagicPlayer mappedOwner=owner.map(game);
@ -76,15 +76,15 @@ public class MagicCard implements MagicSource,MagicTarget,Comparable<MagicCard>
}
return card;
}
public long getId() {
return id;
}
public long getStateId() {
return getCardDefinition().getIndex();
}
public int getImageIndex() {
return imageIndex;
}
@ -92,27 +92,27 @@ public class MagicCard implements MagicSource,MagicTarget,Comparable<MagicCard>
public MagicCardDefinition getCardDefinition() {
return known ? cardDefinition : MagicCardDefinition.UNKNOWN;
}
public MagicPlayer getOwner() {
return owner;
}
private void setToken() {
token = true;
}
public boolean isToken() {
return token;
}
public int getPower() {
return genPowerToughness().power();
}
public int getToughness() {
return genPowerToughness().toughness();
}
}
public MagicPowerToughness genPowerToughness() {
return genPowerToughness(MagicPermanent.NONE);
}
@ -120,24 +120,24 @@ public class MagicCard implements MagicSource,MagicTarget,Comparable<MagicCard>
public MagicPowerToughness genPowerToughness(final MagicPermanent perm) {
final MagicPowerToughness pt = getCardDefinition().genPowerToughness();
getCardDefinition().applyCDAPowerToughness(
getGame(),
getGame(),
perm.isValid() ? perm.getController() : getOwner(),
perm,
pt
);
return pt;
}
public MagicManaCost getCost() {
return getCardDefinition().getCost();
}
public MagicEvent[] getCostEvent() {
return getCardDefinition().getCostEvent(this);
}
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();
return card;
}
@ -149,16 +149,16 @@ public class MagicCard implements MagicSource,MagicTarget,Comparable<MagicCard>
void setKnown(final boolean known) {
this.known=known;
}
public boolean isKnown() {
return known;
}
@Override
public String getName() {
return getCardDefinition().getName();
}
@Override
public String toString() {
return getName();
@ -176,9 +176,9 @@ public class MagicCard implements MagicSource,MagicTarget,Comparable<MagicCard>
@Override
public void setPreventDamage(final int amount) {
}
@Override
public boolean isValidTarget(final MagicSource source) {
return true;
@ -188,12 +188,12 @@ public class MagicCard implements MagicSource,MagicTarget,Comparable<MagicCard>
public boolean isPermanent() {
return false;
}
@Override
public boolean isCreature() {
return false;
}
@Override
public boolean isPlaneswalker() {
return false;
@ -203,36 +203,36 @@ public class MagicCard implements MagicSource,MagicTarget,Comparable<MagicCard>
public boolean isPlayer() {
return false;
}
@Override
public boolean isSpell() {
return true;
}
private int getColorFlags() {
return getCardDefinition().getColorFlags();
}
@Override
public boolean hasColor(final MagicColor color) {
return color.hasColor(getColorFlags());
return color.hasColor(getColorFlags());
}
@Override
public boolean hasAbility(final MagicAbility ability) {
return getCardDefinition().hasAbility(ability);
}
@Override
public boolean hasType(final MagicType type) {
return getCardDefinition().hasType(type);
}
@Override
public boolean hasSubType(final MagicSubType subType) {
return getCardDefinition().hasSubType(subType);
}
@Override
public Collection<MagicActivation> getActivations() {
return getCardDefinition().getCardActivations();
@ -247,32 +247,32 @@ public class MagicCard implements MagicSource,MagicTarget,Comparable<MagicCard>
return Long.signum(id - card.id);
}
}
@Override
public MagicGame getGame() {
return owner.getGame();
}
@Override
public boolean isLegalTarget(final MagicPlayer player, final MagicTargetFilter<? extends MagicTarget> targetFilter) {
// Card in graveyard
if (targetFilter.acceptType(MagicTargetType.Graveyard) &&
if (targetFilter.acceptType(MagicTargetType.Graveyard) &&
player.getGraveyard().contains(this)) {
return true;
}
// Card in opponent's graveyard
if (targetFilter.acceptType(MagicTargetType.OpponentsGraveyard) &&
if (targetFilter.acceptType(MagicTargetType.OpponentsGraveyard) &&
player.getOpponent().getGraveyard().contains(this)) {
return true;
}
// Card in hand
if (targetFilter.acceptType(MagicTargetType.Hand) &&
if (targetFilter.acceptType(MagicTargetType.Hand) &&
player.getHand().contains(this)) {
return true;
}
return false;
}
}

View File

@ -108,11 +108,11 @@ public class MagicCardDefinition {
private boolean excludeManaOrCombat;
private String requiresGroovy;
public MagicCardDefinition() {
initialize();
initialize();
}
protected void initialize() {}
@ -126,7 +126,7 @@ public class MagicCardDefinition {
requiresGroovy = null;
}
}
public static void printStatistics() {
System.err.println(numTriggers + " triggers");
System.err.println(numStatics + " statics");
@ -135,7 +135,7 @@ public class MagicCardDefinition {
System.err.println(numSpellEvent + " spell event");
System.err.println(numCDAs + " CDAs");
}
public boolean isValid() {
return true;
}
@ -151,15 +151,15 @@ public class MagicCardDefinition {
public boolean isIgnored(final long size) {
return ignore != null && ignore.contains(size);
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
public String getFullName() {
return fullName;
}
@ -167,15 +167,15 @@ public class MagicCardDefinition {
public void setFullName(final String name) {
fullName = name;
}
public void setIndex(final int index) {
this.index=index;
}
public int getIndex() {
return index;
}
public String getImageName() {
return fullName;
}
@ -183,7 +183,7 @@ public class MagicCardDefinition {
public void setImageCount(final int count) {
this.imageCount = count;
}
public int getImageCount() {
return imageCount;
}
@ -195,19 +195,19 @@ public class MagicCardDefinition {
public String getImageURL() {
return imageURL;
}
public void setCardInfoURL(final String url) {
this.cardInfoUrl = url;
}
public String getCardInfoURL() {
return this.cardInfoUrl;
}
public String getCardTextName() {
return getImageName();
}
public void setValue(final double value) {
this.value = value;
}
@ -215,33 +215,33 @@ public class MagicCardDefinition {
public double getValue() {
return value;
}
public void setRemoval(final int removal) {
this.removal=removal;
}
public int getRemoval() {
return removal;
}
public int getScore() {
if (score<0) {
score=ArtificialScoringSystem.getCardDefinitionScore(this);
}
return score;
}
public int getFreeScore() {
if (score<0) {
score=ArtificialScoringSystem.getFreeCardDefinitionScore(this);
}
return score;
}
public void setRarity(final char c) {
this.rarity = MagicRarity.getRarity(c);
}
public boolean isRarity(final MagicRarity r) {
return this.rarity == r;
}
@ -249,11 +249,11 @@ public class MagicCardDefinition {
public int getRarity() {
return rarity.ordinal();
}
public String getRarityString() {
return rarity.getName();
}
public Color getRarityColor() {
final Theme theme=ThemeFactory.getInstance().getCurrentTheme();
switch (getRarity()) {
@ -263,11 +263,11 @@ public class MagicCardDefinition {
default: return theme.getColor(Theme.COLOR_COMMON_FOREGROUND);
}
}
public void setToken() {
token=true;
}
public boolean isToken() {
return token;
}
@ -275,67 +275,67 @@ public class MagicCardDefinition {
int getTypeFlags() {
return typeFlags;
}
public void addType(final MagicType type) {
typeFlags|=type.getMask();
}
public boolean hasType(final MagicType type) {
return (typeFlags&type.getMask())!=0;
}
public boolean isBasic() {
return hasType(MagicType.Basic);
}
public boolean isLand() {
return hasType(MagicType.Land);
}
public boolean isCreature() {
return hasType(MagicType.Creature);
}
public boolean isArtifact() {
return hasType(MagicType.Artifact);
}
public boolean isEquipment() {
return isArtifact() && hasSubType(MagicSubType.Equipment);
}
public boolean isPlaneswalker() {
return hasType(MagicType.Planeswalker);
}
public boolean isEnchantment() {
return hasType(MagicType.Enchantment);
}
public boolean isLegendary() {
return hasType(MagicType.Legendary);
}
public boolean isTribal() {
return hasType(MagicType.Tribal);
}
public boolean isAura() {
return isEnchantment() && hasSubType(MagicSubType.Aura);
}
public boolean isInstant() {
return hasType(MagicType.Instant);
}
public boolean isSorcery() {
return hasType(MagicType.Sorcery);
}
public boolean isSpell() {
return isInstant()||isSorcery();
}
public String getLongTypeString() {
if (isBasic()) {
return "Basic " + getTypeString();
@ -343,56 +343,56 @@ public class MagicCardDefinition {
if (isLegendary()) {
return "Legendary " + getTypeString();
}
if (isTribal()) {
return "Tribal " + getTypeString();
}
return getTypeString();
return getTypeString();
}
public String getTypeString() {
final StringBuilder sb = new StringBuilder();
if (isLand()) {
sb.append(MagicType.Land.toString());
}
}
if (isArtifact()) {
if (sb.length() > 0) {
sb.append(" ");
}
sb.append(MagicType.Artifact.toString());
}
}
if (isCreature()) {
if (sb.length() > 0) {
sb.append(" ");
}
sb.append(MagicType.Creature.toString());
}
}
if (isEnchantment()) {
if (sb.length() > 0) {
sb.append(" ");
}
sb.append(MagicType.Enchantment.toString());
}
}
if (isInstant()) {
if (sb.length() > 0) {
sb.append(" ");
}
sb.append(MagicType.Instant.toString());
}
}
if (isSorcery()) {
if (sb.length() > 0) {
sb.append(" ");
}
sb.append(MagicType.Sorcery.toString());
}
return sb.toString();
return sb.toString();
}
public boolean usesStack() {
return !isLand();
}
public void setSubTypes(final String[] subTypeNames) {
subTypeFlags = MagicSubType.getSubTypes(subTypeNames);
}
@ -400,22 +400,22 @@ public class MagicCardDefinition {
EnumSet<MagicSubType> genSubTypeFlags() {
return subTypeFlags.clone();
}
EnumSet<MagicSubType> getSubTypeFlags() {
final EnumSet<MagicSubType> subTypes = genSubTypeFlags();
applyCDASubType(null, null, subTypes);
return subTypes;
}
public void applyCDASubType(
final MagicGame game,
final MagicPlayer player,
final MagicGame game,
final MagicPlayer player,
final Set<MagicSubType> flags) {
for (final MagicCDA lv : CDAs) {
lv.getSubTypeFlags(game, player, flags);
}
}
public String getSubTypeString() {
final String brackets = getSubTypeFlags().toString(); // [...,...]
if (brackets.length() <= 2) {
@ -423,15 +423,15 @@ public class MagicCardDefinition {
}
return brackets.substring(1, brackets.length() - 1);
}
public boolean hasSubType(final MagicSubType subType) {
return getSubTypeFlags().contains(subType);
}
public void setColors(final String colors) {
colorFlags=MagicColor.getFlags(colors);
colorFlags=MagicColor.getFlags(colors);
}
public boolean hasColor(final MagicColor color) {
return (colorFlags&color.getMask())!=0;
}
@ -439,19 +439,19 @@ public class MagicCardDefinition {
public boolean isColorless() {
return colorFlags == 0;
}
public int getColorFlags() {
return colorFlags;
}
public int getConvertedCost() {
return cost.getConvertedCost();
}
public boolean hasConvertedCost(final int c) {
return getConvertedCost() == c;
}
public int getCostBucket() {
switch (getConvertedCost()) {
case 0:
@ -461,11 +461,11 @@ public class MagicCardDefinition {
case 3:
case 4:
return 1;
default:
default:
return 2;
}
}
public boolean hasX() {
return cost.hasX();
}
@ -477,14 +477,14 @@ public class MagicCardDefinition {
}
}
public void validate() {
//every card should have a timing hint
public void validate() {
//every card should have a timing hint
if (!isToken() && getTiming() == MagicTiming.None) {
throw new RuntimeException(
getName() + " does not have a timing hint"
);
}
//check colorFlags is set
if (colorFlags == -1) {
throw new RuntimeException(name + "'s color is not set");
@ -494,7 +494,7 @@ public class MagicCardDefinition {
public MagicManaCost getCost() {
return cost;
}
public MagicEvent[] getCostEvent(final MagicCard source) {
final List<MagicEvent> costEvent = new ArrayList<MagicEvent>();
if (cost != MagicManaCost.ZERO) {
@ -508,7 +508,7 @@ public class MagicCardDefinition {
}
return costEvent.toArray(new MagicEvent[0]);
}
public boolean isPlayable(final MagicPlayerProfile profile) {
if (isLand()) {
int source = 0;
@ -520,11 +520,11 @@ public class MagicCardDefinition {
return cost.getCostScore(profile) > 0;
}
}
public void setEquipCost(final MagicManaCost equipCost) {
add(new MagicEquipActivation(equipCost));
}
public void setManaSourceText(final String sourceText) {
manaSourceText=sourceText;
for (int index=0;index<sourceText.length();index+=2) {
@ -534,20 +534,20 @@ public class MagicCardDefinition {
manaSource[color.ordinal()]=source;
}
}
public int getManaSource(final MagicColor color) {
return manaSource[color.ordinal()];
}
public void setPowerToughness(final int aPower, final int aToughness) {
power = aPower;
toughness = aToughness;
}
public int getCardPower() {
return power;
}
public int getCardToughness() {
return toughness;
}
@ -555,21 +555,21 @@ public class MagicCardDefinition {
public MagicPowerToughness genPowerToughness() {
return new MagicPowerToughness(power, toughness);
}
public void applyCDAPowerToughness(
final MagicGame game,
final MagicPlayer player,
final MagicGame game,
final MagicPlayer player,
final MagicPermanent perm,
final MagicPowerToughness pt) {
for (final MagicCDA lv : CDAs) {
lv.modPowerToughness(game, player, perm, pt);
}
}
public void addAbility(final MagicAbility ability) {
addAbility(ability, "");
}
public void addAbility(final MagicAbility ability, final String arg) {
ability.addAbilityImpl(this, arg);
abilityFlags.add(ability);
@ -578,31 +578,31 @@ public class MagicCardDefinition {
public Set<MagicAbility> genAbilityFlags() {
return abilityFlags.clone();
}
public boolean hasAbility(final MagicAbility ability) {
return abilityFlags.contains(ability);
}
public void setText(final String text) {
this.text = text;
}
public String getText() {
return this.text;
}
public void setStaticType(final MagicStaticType staticType) {
this.staticType=staticType;
}
MagicStaticType getStaticType() {
return staticType;
}
public void setTiming(final MagicTiming timing) {
this.timing=timing;
}
public MagicTiming getTiming() {
return timing;
}
@ -610,13 +610,13 @@ public class MagicCardDefinition {
public void add(final MagicChangeCardDefinition mod) {
mod.change(this);
}
public void setEvent(final MagicCardEvent aCardEvent) {
assert cardEvent == MagicPlayCardEvent.create() : "Attempting to set two MagicCardEvents for " + this;
cardEvent = aCardEvent;
numSpellEvent++;
}
public MagicCardEvent getCardEvent() {
return cardEvent;
}
@ -624,22 +624,22 @@ public class MagicCardDefinition {
public MagicActivationHints getActivationHints() {
return new MagicActivationHints(timing,true);
}
// cast card activation is the first element of cardActivations
public MagicActivation getCastActivation() {
assert cardActivations.size() >= 1 : this + " has no card activations";
return cardActivations.getFirst();
}
public Collection<MagicActivation> getCardActivations() {
return cardActivations;
}
public void addCDA(final MagicCDA cda) {
CDAs.add(cda);
numCDAs++;
}
public void addCostEvent(final MagicEventSource eventSource) {
costEventSources.add(eventSource);
}
@ -667,78 +667,78 @@ public class MagicCardDefinition {
drawnTriggers.add(trigger);
numTriggers++;
}
public void addTrigger(final MagicTrigger<?> trigger) {
triggers.add(trigger);
numTriggers++;
}
public void addStatic(final MagicStatic mstatic) {
statics.add(mstatic);
numStatics++;
}
public Collection<MagicTrigger<?>> getTriggers() {
return triggers;
}
public Collection<MagicStatic> getStatics() {
return statics;
}
public Collection<MagicWhenSpellIsCastTrigger> getSpellIsCastTriggers() {
return spellIsCastTriggers;
}
public Collection<MagicWhenComesIntoPlayTrigger> getComeIntoPlayTriggers() {
return comeIntoPlayTriggers;
}
public Collection<MagicWhenPutIntoGraveyardTrigger> getPutIntoGraveyardTriggers() {
return putIntoGraveyardTriggers;
}
public Collection<MagicWhenDrawnTrigger> getDrawnTriggers() {
return drawnTriggers;
}
public void addAct(final MagicPermanentActivation activation) {
activations.add(activation);
numPermanentActivations++;
}
public void addCardAct(final MagicCardActivation activation) {
cardActivations.add(activation);
}
public Collection<MagicActivation> getActivations() {
return activations;
}
public void addManaAct(final MagicManaActivation activation) {
manaActivations.add(activation);
numManaActivations++;
}
public Collection<MagicManaActivation> getManaActivations() {
return manaActivations;
}
public void setExcludeManaOrCombat() {
excludeManaOrCombat=true;
}
public boolean hasExcludeManaOrCombat() {
return excludeManaOrCombat;
}
public ImageIcon getIcon() {
if (isLand()) {
return IconImages.LAND;
return IconImages.LAND;
} else if (isCreature()) {
return IconImages.CREATURE;
} else if (isEquipment()) {
return IconImages.EQUIPMENT;
return IconImages.EQUIPMENT;
} else if (isAura()) {
return IconImages.AURA;
} else if (isEnchantment()) {
@ -749,7 +749,7 @@ public class MagicCardDefinition {
return IconImages.SPELL;
}
}
private boolean subTypeHasText(final String s) {
final MagicSubType[] subTypeValues = MagicSubType.values();
for (final MagicSubType subtype : subTypeValues) {
@ -759,7 +759,7 @@ public class MagicCardDefinition {
}
return false;
}
private boolean abilityHasText(final String s) {
for (final MagicAbility ability : MagicAbility.CORE) {
if(hasAbility(ability) && ability.getName().toLowerCase().contains(s)) {
@ -768,7 +768,7 @@ public class MagicCardDefinition {
}
return false;
}
public boolean hasText(String s) {
s = s.toLowerCase();
return (
@ -779,7 +779,7 @@ public class MagicCardDefinition {
getText().toLowerCase().contains(s)
);
}
@Override
public String toString() {
return getName();
@ -798,7 +798,7 @@ public class MagicCardDefinition {
return NAME_COMPARATOR_DESC.compare(cardDefinition2, cardDefinition1);
}
};
public static final Comparator<MagicCardDefinition> CONVERTED_COMPARATOR_DESC=new Comparator<MagicCardDefinition>() {
@Override
public int compare(final MagicCardDefinition cardDefinition1,final MagicCardDefinition cardDefinition2) {
@ -809,7 +809,7 @@ public class MagicCardDefinition {
return cardDefinition1.getName().compareTo(cardDefinition2.getName());
}
};
public static final Comparator<MagicCardDefinition> CONVERTED_COMPARATOR_ASC=new Comparator<MagicCardDefinition>() {
@Override
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>() {
@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());
if(c == 0) {
return cardDefinition1.getLongTypeString().compareTo(cardDefinition2.getLongTypeString());
@ -854,7 +854,7 @@ public class MagicCardDefinition {
public int compare(final MagicCardDefinition cardDefinition1,final MagicCardDefinition cardDefinition2) {
final int p1 = cardDefinition1.isCreature() ? cardDefinition1.getCardPower() : -100;
final int p2 = cardDefinition2.isCreature() ? cardDefinition2.getCardPower() : -100;
if (p1 != p2) {
return p1 - p2;
} else {
@ -875,7 +875,7 @@ public class MagicCardDefinition {
public int compare(final MagicCardDefinition cardDefinition1,final MagicCardDefinition cardDefinition2) {
final int t1 = cardDefinition1.isCreature() ? cardDefinition1.getCardToughness() : -100;
final int t2 = cardDefinition2.isCreature() ? cardDefinition2.getCardToughness() : -100;
if (t1 != t2) {
return t1 - t2;
} else {

View File

@ -5,21 +5,21 @@ import java.util.Arrays;
import java.util.List;
public class MagicCardList extends ArrayList<MagicCard> {
private static final long serialVersionUID = 1L;
public MagicCardList() {}
public MagicCardList(final MagicCardList cardList) {
super(cardList);
}
MagicCardList(final MagicCopyMap copyMap, final MagicCardList cardList) {
for (final MagicCard card : cardList) {
add(copyMap.copy(card));
}
}
public long getStateId() {
final long[] keys = new long[size()];
int idx = 0;
@ -29,7 +29,7 @@ public class MagicCardList extends ArrayList<MagicCard> {
}
return magic.MurmurHash3.hash(keys);
}
public long getUnorderedStateId() {
final long[] keys = new long[size()];
int idx = 0;
@ -40,33 +40,33 @@ public class MagicCardList extends ArrayList<MagicCard> {
Arrays.sort(keys);
return magic.MurmurHash3.hash(keys);
}
public void addToBottom(final MagicCard card) {
add(0,card);
}
public void addToTop(final MagicCard card) {
add(card);
}
public MagicCard getCardAtBottom() {
return get(0);
}
public MagicCard getCardAtTop() {
final int size = this.size();
return size > 0 ?
return size > 0 ?
this.get(size()-1) :
MagicCard.NONE;
}
public MagicCard removeCardAtTop() {
final int index=size()-1;
final MagicCard card=get(index);
remove(index);
return card;
}
public int removeCard(final MagicCard card) {
final int index=indexOf(card);
if (index >= 0) {
@ -85,18 +85,18 @@ public class MagicCardList extends ArrayList<MagicCard> {
}
return MagicCard.NONE;
}
public void setCards(final MagicCardList cardList) {
clear();
addAll(cardList);
}
void setKnown(final boolean known) {
for (final MagicCard card : this) {
card.setKnown(known);
}
}
private int getNrOfLands() {
int lands=0;
for (final MagicCard card : this) {
@ -106,7 +106,7 @@ public class MagicCardList extends ArrayList<MagicCard> {
}
return lands;
}
private boolean useSmartShuffle() {
final int lands = getNrOfLands();
final int total = size();
@ -125,7 +125,7 @@ public class MagicCardList extends ArrayList<MagicCard> {
public void shuffle() {
shuffle(getStateId());
}
public void shuffle(final long seed) {
final magic.MersenneTwisterFast rng = new magic.MersenneTwisterFast(seed);
final MagicCardList oldCards = new MagicCardList(this);
@ -133,11 +133,11 @@ public class MagicCardList extends ArrayList<MagicCard> {
for (int size = oldCards.size(); size > 0; size--) {
final int index=rng.nextInt(size);
final MagicCard card=oldCards.get(index);
oldCards.remove(index);
oldCards.remove(index);
add(card);
}
}
private void smartShuffle(final long seed) {
final magic.MersenneTwisterFast rng = new magic.MersenneTwisterFast(seed);
final int size=size();
@ -155,7 +155,7 @@ public class MagicCardList extends ArrayList<MagicCard> {
}
}
}
clear();
for (int blocks=size/5;blocks>0;blocks--) {
int landCount=0;

View File

@ -15,40 +15,40 @@ public enum MagicColor {
Green("green",'g'),
Red("red",'r')
;
public static final int NR_COLORS=values().length;
private final String name;
private final char symbol;
private final int mask;
private MagicColor(final String name,final char symbol) {
this.name=name;
this.name=name;
this.symbol=symbol;
this.mask=1<<ordinal();
}
public String getName() {
return name;
}
@Override
public String toString() {
return name;
}
public char getSymbol() {
return symbol;
}
public int getMask() {
return mask;
}
public boolean hasColor(final int flags) {
return (flags&mask)!=0;
}
public MagicAbility getProtectionAbility() {
switch (this) {
case White: return MagicAbility.ProtectionFromWhite;
@ -59,7 +59,7 @@ public enum MagicColor {
}
throw new RuntimeException("No protection ability for MagicColor " + this);
}
public MagicAbility getLandwalkAbility() {
switch (this) {
case White: return MagicAbility.PlainsWalk;
@ -67,10 +67,10 @@ public enum MagicColor {
case Black: return MagicAbility.Swampwalk;
case Green: return MagicAbility.Forestwalk;
case Red: return MagicAbility.Mountainwalk;
}
}
throw new RuntimeException("No landwalk ability for MagicColor " + this);
}
public MagicAbility getCannotBeBlockedByAbility() {
switch (this) {
case White: return MagicAbility.CannotBeBlockedByWhite;
@ -78,13 +78,13 @@ public enum MagicColor {
case Black: return MagicAbility.CannotBeBlockedByBlack;
case Green: return MagicAbility.CannotBeBlockedByGreen;
case Red: return MagicAbility.CannotBeBlockedByRed;
}
}
throw new RuntimeException("No CannotBeBlockedBy ability for MagicColor " + this);
}
public MagicSubType getLandSubType() {
switch (this) {
case White: return MagicSubType.Plains;
case White: return MagicSubType.Plains;
case Blue: return MagicSubType.Island;
case Black: return MagicSubType.Swamp;
case Green: return MagicSubType.Forest;
@ -92,7 +92,7 @@ public enum MagicColor {
}
throw new RuntimeException("No land subtype for MagicColor " + this);
}
public MagicManaType getManaType() {
switch (this) {
case White: return MagicManaType.White;
@ -103,7 +103,7 @@ public enum MagicColor {
}
return MagicManaType.Colorless;
}
public ImageIcon getIcon() {
switch (this) {
case White: return IconImages.WHITE;
@ -124,7 +124,7 @@ public enum MagicColor {
}
return flags;
}
public static MagicColor getColor(final char symbol) {
final char usymbol=Character.toLowerCase(symbol);
for (final MagicColor color : values()) {
@ -133,14 +133,14 @@ public enum MagicColor {
}
}
throw new RuntimeException("No corresponding MagicColor for " + symbol);
}
}
public static String getRandomColors(final int count) {
final List<MagicColor> colors = new ArrayList<MagicColor>(Arrays.asList(values()));
final StringBuilder colorText=new StringBuilder();
for (int c=count;c>0;c--) {
final int index=MagicRandom.nextInt(colors.size());
colorText.append(colors.remove(index).getSymbol());
colorText.append(colors.remove(index).getSymbol());
}
return colorText.toString();
}
@ -154,7 +154,7 @@ public enum MagicColor {
}
return numColors;
}
private static boolean isColorless(final MagicSource source) {
return numColors(source) == 0;
}

View File

@ -6,33 +6,33 @@ import java.util.Comparator;
public class MagicCondensedCardDefinition {
private int copies;
private final MagicCardDefinition card;
public MagicCondensedCardDefinition(final MagicCardDefinition card) {
this.card = card;
copies = 1;
}
public MagicCardDefinition getCard() {
return card;
}
public void incrementNumCopies() {
copies++;
}
public void decrementNumCopies() {
if (copies > 0) {
copies--;
}
}
public void setNumCopies(final int i) {
copies = i;
}
public int getNumCopies() {
return copies;
}
}
public static final Comparator<MagicCondensedCardDefinition> NUM_COPIES_COMPARATOR_DESC=new Comparator<MagicCondensedCardDefinition>() {
@Override
@ -47,7 +47,7 @@ public class MagicCondensedCardDefinition {
return MagicCondensedCardDefinition.NUM_COPIES_COMPARATOR_DESC.compare(cardDefinition2, cardDefinition1);
}
};
public static final Comparator<MagicCondensedCardDefinition> NAME_COMPARATOR_DESC=new Comparator<MagicCondensedCardDefinition>() {
@Override
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());
}
};
public static final Comparator<MagicCondensedCardDefinition> CONVERTED_COMPARATOR_DESC=new Comparator<MagicCondensedCardDefinition>() {
@Override
public int compare(final MagicCondensedCardDefinition cardDefinition1,final MagicCondensedCardDefinition cardDefinition2) {
return MagicCardDefinition.CONVERTED_COMPARATOR_DESC.compare(cardDefinition1.getCard(), cardDefinition2.getCard());
}
};
public static final Comparator<MagicCondensedCardDefinition> CONVERTED_COMPARATOR_ASC=new Comparator<MagicCondensedCardDefinition>() {
@Override
public int compare(final MagicCondensedCardDefinition cardDefinition1,final MagicCondensedCardDefinition cardDefinition2) {

View File

@ -7,9 +7,9 @@ import java.util.List;
public class MagicCondensedDeck extends ArrayList<MagicCondensedCardDefinition> {
private static final long serialVersionUID = 143L;
private String name = "Unsaved Deck";
private final HashMap<String, MagicCondensedCardDefinition> map = new HashMap<String, MagicCondensedCardDefinition>();
public MagicCondensedDeck() {}
@ -18,82 +18,82 @@ public class MagicCondensedDeck extends ArrayList<MagicCondensedCardDefinition>
super(deck);
name = deck.getName();
}
public MagicCondensedDeck(final MagicDeck list) {
this((List<MagicCardDefinition>) list);
name = list.getName();
}
public MagicCondensedDeck(final List<MagicCardDefinition> list) {
super();
for(final MagicCardDefinition card : list) {
addCard(card, true);
}
}
private String getKey(final MagicCardDefinition card) {
return card.getName();
}
public boolean addCard(final MagicCardDefinition card, final boolean ignoreCopiesLimit) {
if(!map.containsKey(getKey(card))) {
// add to end
add(new MagicCondensedCardDefinition(card));
map.put(getKey(card), get(size() - 1));
return true;
} else {
final MagicCondensedCardDefinition existingCard = map.get(getKey(card));
if(ignoreCopiesLimit || existingCard.getNumCopies() < MagicDeckConstructionRule.MAX_COPIES) {
existingCard.incrementNumCopies();
return true;
} // otherwise card can't be added because of copies limit
}
return false;
}
public void setContent(final MagicCondensedDeck deck) {
clear();
addAll(deck);
name = deck.getName();
map.clear();
map.putAll(deck.getMap());
}
public void setName(final String name) {
this.name = name;
}
public String getName() {
return name;
}
public int getNumCards() {
return toMagicDeck().size();
}
public HashMap<String, MagicCondensedCardDefinition> getMap() {
return map;
}
public MagicDeck toMagicDeck() {
final MagicDeck deck = new MagicDeck();
for(int i = 0; i < size(); i++) {
final MagicCondensedCardDefinition card = get(i);
for(int j = 0; j < card.getNumCopies(); j++) {
deck.add(card.getCard());
}
}
return deck;
}
}

View File

@ -10,17 +10,17 @@ public class MagicCopyMap extends HashMap<MagicCopyable,MagicCopyable> {
@SuppressWarnings("unchecked")
public <E extends MagicCopyable> E copy(final E source) {
if (source == null) {
if (source == null) {
return source;
}
}
E target=(E)get(source);
if (target==null) {
if (target==null) {
target=(E)source.copy(this);
put(source,target);
}
return target;
}
private Object copyObject(final Object source) {
if (source != null && source instanceof MagicCopyable) {
return copy((MagicCopyable)source);
@ -28,7 +28,7 @@ public class MagicCopyMap extends HashMap<MagicCopyable,MagicCopyable> {
return source;
}
}
@SuppressWarnings("unchecked")
public <E> E[] copyObjects(final E[] sources,final Class<E> clazz) {
if (sources==null||sources.length==0) {
@ -40,7 +40,7 @@ public class MagicCopyMap extends HashMap<MagicCopyable,MagicCopyable> {
}
return targets;
}
@SuppressWarnings("unchecked")
public <E> void copyCollection(final Collection<E> sourceCollection,final Collection<E> targetCollection) {
for (final E object : sourceCollection) {

View File

@ -22,18 +22,18 @@ public enum MagicCostManaType {
RedWhite("red/white","{R/W}",Arrays.asList(MagicManaType.Red,MagicManaType.White)),
GreenWhite("green/white","{G/W}",Arrays.asList(MagicManaType.Green,MagicManaType.White)),
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)),
Black("black","{B}",Arrays.asList(MagicManaType.Black)),
Red("red","{R}",Arrays.asList(MagicManaType.Red)),
Green("green","{G}",Arrays.asList(MagicManaType.Green)),
;
public static final int NR_OF_TYPES=values().length;
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> NON_MONO = EnumSet.range(Colorless, GreenBlue);
private final String name;
private final String text;
private final List<MagicManaType> types;
@ -43,7 +43,7 @@ public enum MagicCostManaType {
this.text=text;
this.types=types;
}
public MagicCostManaType next() {
switch (this) {
case White: return Blue;
@ -54,7 +54,7 @@ public enum MagicCostManaType {
default: throw new RuntimeException("No next mana cost type for " + this);
}
}
public MagicCostManaType prev() {
switch (this) {
case White: return Green;
@ -65,19 +65,19 @@ public enum MagicCostManaType {
default: throw new RuntimeException("No next mana cost type for " + this);
}
}
public String getName() {
return name;
}
public String getText() {
return text;
}
public List<MagicManaType> getTypes() {
return types;
}
public MagicManaType[] getTypes(final MagicPlayerProfile profile) {
int count=0;
final MagicManaType[] profileTypes=new MagicManaType[types.size()];
@ -88,7 +88,7 @@ public enum MagicCostManaType {
}
return Arrays.copyOf(profileTypes,count);
}
public ImageIcon getIcon() {
return TextImages.getIcon(text);
}

View File

@ -1,7 +1,7 @@
package magic.model;
public enum MagicCounterType {
PlusOne("+1/+1","{+}"),
MinusOne("-1/-1","{-}"),
Charge("charge","{C}"),
@ -11,19 +11,19 @@ public enum MagicCounterType {
;
public static final int NR_COUNTERS=MagicCounterType.values().length;
private final String name;
private final String text;
private MagicCounterType(final String name,final String text) {
this.name=name;
this.text=text;
}
public String getName() {
return name;
}
public String getText() {
return text;
}

View File

@ -5,21 +5,21 @@ import java.util.HashSet;
public class MagicCubeDefinition extends HashSet<String> {
private static final long serialVersionUID = 1L;
private final String name;
public MagicCubeDefinition(final String name) {
this.name=name;
}
public boolean containsCard(final MagicCardDefinition cardDefinition) {
return contains(cardDefinition.getName());
}
public String getName() {
return name + " (" + size() + " cards)";
}
@Override
public String toString() {
return name;

View File

@ -3,7 +3,7 @@ package magic.model;
import magic.model.target.MagicTarget;
public class MagicDamage {
private final MagicSource source;
private MagicTarget target;
private int amount;
@ -18,7 +18,7 @@ public class MagicDamage {
this.amount=amount;
this.combat=combat;
}
public MagicDamage(final MagicSource source,final MagicTarget target,final int amount) {
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) {
return new MagicDamage(source, target, amount, true);
}
public MagicSource getSource() {
return source;
}
public void setTarget(final MagicTarget target) {
this.target=target;
}
public MagicTarget getTarget() {
return target;
}
public MagicPlayer getTargetPlayer() {
return (MagicPlayer)target;
}
public void setAmount(final int amt) {
amount = amt;
}
@ -52,7 +52,7 @@ public class MagicDamage {
amount -= amt;
}
}
public int getAmount() {
return amount;
}
@ -60,27 +60,27 @@ public class MagicDamage {
public void setDealtAmount(final int dealtAmount) {
this.dealtAmount=dealtAmount;
}
public int getDealtAmount() {
return dealtAmount;
}
public boolean isCombat() {
return combat;
}
public void setUnpreventable() {
unpreventable=true;
}
public boolean isUnpreventable() {
return unpreventable;
}
public void setNoRegeneration() {
noRegeneration=true;
}
public boolean hasNoRegeneration() {
return noRegeneration;
}

View File

@ -5,7 +5,7 @@ import java.util.ArrayList;
public class MagicDeck extends ArrayList<MagicCardDefinition> {
private static final long serialVersionUID = 1L;
private String name="Unsaved Deck";
private String description;
@ -21,11 +21,11 @@ public class MagicDeck extends ArrayList<MagicCardDefinition> {
addAll(deck);
name = deck.name;
}
public void setName(final String name) {
this.name=name;
}
public String getName() {
return name;
}

View File

@ -4,31 +4,31 @@ import java.util.ArrayList;
import java.util.List;
public enum MagicDeckConstructionRule {
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.")
;
public static final int MIN_DECK_SIZE = 40;
public static final int MIN_DECK_SIZE = 40;
public static final int MAX_COPIES = 4;
private final String text;
private MagicDeckConstructionRule(final String text) {
this.text = text;
}
private String getRuleText() {
return text;
}
public static List<MagicDeckConstructionRule> checkDeck(final MagicDeck deck) {
final ArrayList<MagicDeckConstructionRule> brokenRules = new ArrayList<MagicDeckConstructionRule>();
if(deck.size() < MIN_DECK_SIZE) {
brokenRules.add(MinDeckSize);
}
final MagicCondensedDeck countedDeck = new MagicCondensedDeck(deck);
for(final MagicCondensedCardDefinition countedCard : countedDeck) {
if(countedCard.getNumCopies() > 4 && !countedCard.getCard().isBasic() && !"Relentless Rats".equals(countedCard.getCard().getName())) {
@ -36,18 +36,18 @@ public enum MagicDeckConstructionRule {
break;
}
}
return brokenRules;
}
public static String getRulesText(final List<MagicDeckConstructionRule> rules) {
final StringBuilder sb = new StringBuilder();
for(final MagicDeckConstructionRule rule : rules) {
sb.append(rule.getRuleText());
sb.append("\n");
}
return sb.toString();
}
}

View File

@ -20,14 +20,14 @@ import java.util.List;
import java.util.Properties;
public class MagicDuel {
private static final String OPPONENT="opponent";
private static final String GAME="game";
private static final String PLAYED="played";
private static final String WON="won";
private static final String START="start";
private static final String COMPUTER="Computer";
private final DuelConfig configuration;
private final History history;
private MagicPlayerDefinition[] playerDefinitions;
@ -38,27 +38,27 @@ public class MagicDuel {
private int gamesWon;
private int startPlayer;
private final int[] difficulty = new int[2];
public MagicDuel(final DuelConfig configuration) {
this.configuration=configuration;
history = new History(this);
ais=configuration.getPlayerAIs();
restart();
}
public MagicDuel() {
this(new DuelConfig());
}
public MagicDuel(final DuelConfig configuration,final MagicDuel duel) {
this(configuration);
playerDefinitions=duel.playerDefinitions;
}
public DuelConfig getConfiguration() {
return configuration;
}
private MagicPlayerDefinition getOpponent() {
return playerDefinitions[opponentIndex];
}
@ -70,7 +70,7 @@ public class MagicDuel {
public int getGamesPlayed() {
return gamesPlayed;
}
public int getGamesTotal() {
return (playerDefinitions.length-1)*configuration.getNrOfGames();
}
@ -82,11 +82,11 @@ public class MagicDuel {
private void determineStartPlayer() {
startPlayer=MagicRandom.nextInt(2);
}
public void setStartPlayer(final int startPlayer) {
this.startPlayer=startPlayer;
}
private int getStartPlayer() {
return startPlayer;
}
@ -98,37 +98,37 @@ public class MagicDuel {
public MagicAI[] getAIs() {
return ais;
}
public void setDifficulty(final int diff) {
setDifficulty(0,diff);
setDifficulty(1,diff);
}
public void setDifficulty(final int idx, final int diff) {
difficulty[idx] = diff;
}
int getDifficulty() {
return getDifficulty(0);
}
int getDifficulty(final int idx) {
return difficulty[idx];
}
public void updateDifficulty() {
difficulty[0] = GeneralConfig.getInstance().getDifficulty();
difficulty[1] = GeneralConfig.getInstance().getDifficulty();
}
public boolean isEditable() {
return gameNr==1;
}
public boolean isFinished() {
return getGamesPlayed()==getGamesTotal();
}
void advance(final boolean won, final MagicGame game) {
gamesPlayed++;
if (won) {
@ -147,11 +147,11 @@ public class MagicDuel {
history.update(won,game,configuration);
}
}
private static List<Integer> getAvatarIndices(final int avatars) {
final List<Integer> indices=new ArrayList<Integer>();
for (int index=0;index<avatars;index++) {
indices.add(index);
}
return indices;
@ -167,19 +167,19 @@ public class MagicDuel {
final MagicPlayerDefinition player=new MagicPlayerDefinition(configuration.getName(),false,configuration.getPlayerProfile(),playerFace);
players[0]=player;
avatars.remove(playerFace);
final int findex=MagicRandom.nextInt(avatars.size());
final Integer computerFace=avatars.get(findex);
players[1]=new MagicPlayerDefinition(COMPUTER,true,configuration.getOpponentProfile(),computerFace);
return players;
}
public MagicGame nextGame(final boolean sound) {
//create players
final MagicPlayer player = new MagicPlayer(configuration.getStartLife(),playerDefinitions[0],0);
final MagicPlayer opponent = new MagicPlayer(configuration.getStartLife(),playerDefinitions[opponentIndex],1);
//give the AI player extra life
opponent.setLife(opponent.getLife() + GeneralConfig.getInstance().getExtraLife());
@ -199,23 +199,23 @@ public class MagicDuel {
opponent.createHandAndLibrary(configuration.getHandSize());
return game;
}
public int getNrOfPlayers() {
return playerDefinitions.length;
}
public MagicPlayerDefinition getPlayer(final int index) {
return playerDefinitions[index];
}
public MagicPlayerDefinition[] getPlayers() {
return playerDefinitions;
}
public void setPlayers(final MagicPlayerDefinition[] aPlayerDefinitions) {
this.playerDefinitions=aPlayerDefinitions;
}
public void buildDeck(final MagicPlayerDefinition player) {
final MagicCubeDefinition cubeDefinition = CubeDefinitions.getCubeDefinition(configuration.getCube());
final DefaultDeckGenerator generator = new DefaultDeckGenerator(cubeDefinition);
@ -225,7 +225,7 @@ public class MagicDuel {
player.generateDeck(generator);
}
}
private void buildDecks() {
final MagicCubeDefinition cubeDefinition=CubeDefinitions.getCubeDefinition(configuration.getCube());
final DefaultDeckGenerator generator = new DefaultDeckGenerator(cubeDefinition);
@ -237,55 +237,55 @@ public class MagicDuel {
}
}
}
public void initialize() {
playerDefinitions=createPlayers();
buildDecks();
history.loadHistory(configuration.getName());
}
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) {
return "p"+(index+1)+".";
}
private void save(final Properties properties) {
configuration.save(properties);
properties.setProperty(OPPONENT,Integer.toString(opponentIndex));
properties.setProperty(GAME,Integer.toString(gameNr));
properties.setProperty(PLAYED,Integer.toString(gamesPlayed));
properties.setProperty(WON,Integer.toString(gamesWon));
properties.setProperty(START,Integer.toString(startPlayer));
for (int index=0;index<playerDefinitions.length;index++) {
playerDefinitions[index].save(properties,getPlayerPrefix(index));
}
}
public void save(final File file) {
final Properties properties=new Properties();
save(properties);
try { //save to file
try { //save to file
magic.data.FileIO.toFile(file, properties, "Duel");
System.err.println("Saved duel");
} catch (final IOException ex) {
System.err.println("ERROR! Unable save duel to " + file);
}
}
private void load(final Properties properties) {
configuration.load(properties);
opponentIndex=Integer.parseInt(properties.getProperty(OPPONENT,"1"));
gameNr=Integer.parseInt(properties.getProperty(GAME,"1"));
gamesPlayed=Integer.parseInt(properties.getProperty(PLAYED,"0"));
gamesWon=Integer.parseInt(properties.getProperty(WON,"0"));
startPlayer=Integer.parseInt(properties.getProperty(START,"0"));
playerDefinitions=new MagicPlayerDefinition[2];
for (int index=0;index<playerDefinitions.length;index++) {
playerDefinitions[index]=new MagicPlayerDefinition();
@ -293,11 +293,11 @@ public class MagicDuel {
}
history.loadHistory(configuration.getName());
}
public void load(final File file) {
load(magic.data.FileIO.toProp(file));
}
public void restart() {
opponentIndex=1;
gameNr=1;

File diff suppressed because it is too large Load Diff

View File

@ -10,12 +10,12 @@ import java.text.SimpleDateFormat;
import java.util.Date;
public class MagicGameLog {
private static final String gameLog = MagicMain.getGamePath() + File.separator + "game.log";
private static PrintWriter writer;
private MagicGameLog() {}
public static void initialize() {
try {
writer = new PrintWriter(gameLog);
@ -35,14 +35,14 @@ public class MagicGameLog {
System.err.println("Unable to create game log");
}
}
public static void log(final String message) {
if (writer != null) {
writer.println(message);
writer.flush();
}
}
}
public static void close() {
if (writer != null) {
writer.close();

View File

@ -14,7 +14,7 @@ import java.text.SimpleDateFormat;
import java.util.Date;
public class MagicGameReport implements Thread.UncaughtExceptionHandler {
public void uncaughtException(final Thread th, final Throwable ex) {
MagicGameReport.buildReport(MagicGame.getInstance(), th, ex);
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) {
report.append(" - ").append(place).append(" : ").append(card.getName()).append("\n");
}
private static void buildPermanent(final MagicGame game,final MagicPermanent permanent,final StringBuilder report) {
report.append(" - Permanent : ").append(permanent.getName());
if (permanent.isCreature()) {
@ -40,7 +40,7 @@ public class MagicGameReport implements Thread.UncaughtExceptionHandler {
}
report.append("\n");
}
private static void buildPlayer(final MagicGame game,final MagicPlayer player,final StringBuilder report) {
report.append(player.getIndex()).append("] ");
report.append("Player : ").append(player.getName());
@ -55,12 +55,12 @@ public class MagicGameReport implements Thread.UncaughtExceptionHandler {
for (final MagicCard card: player.getGraveyard()) {
buildCard(game,"Graveyard",card,report);
}
for (final MagicPermanent permanent : player.getPermanents()) {
buildPermanent(game,permanent,report);
}
}
private static void buildStack(final MagicGame game,final StringBuilder report) {
report.append("Stack : ").append(game.getStack().size()).append('\n');
for (final MagicItemOnStack itemOnStack : game.getStack()) {
@ -85,7 +85,7 @@ public class MagicGameReport implements Thread.UncaughtExceptionHandler {
}
report.append("Score = ").append(totalScore).append("\n");
}
private static String buildReport(final MagicGame game) {
final StringBuilder report=new StringBuilder();
report.append("Turn : ").append(game.getTurn());
@ -94,13 +94,13 @@ public class MagicGameReport implements Thread.UncaughtExceptionHandler {
report.append(" Player : ").append(game.getTurnPlayer());
report.append(" Score : ").append(game.getScore());
report.append("\n");
for (final MagicPlayer player : game.getPlayers()) {
buildPlayer(game,player,report);
}
buildStack(game,report);
buildScore(game,report);
buildScore(game,report);
return report.toString();
}
@ -145,7 +145,7 @@ public class MagicGameReport implements Thread.UncaughtExceptionHandler {
//save a copy to a crash log file
final File clog = new File(MagicMain.getGamePath(), "crash.log");
try {
FileIO.toFile(clog, sb.toString(), true);
FileIO.toFile(clog, sb.toString(), true);
} catch (final IOException ex3) {
System.err.println("Unable to save crash log");
}

View File

@ -4,6 +4,6 @@ public enum MagicIdentifierType {
Permanent,
PermanentTrigger,
ItemOnStack;
public static final int NR_OF_IDENTIFIERS=values().length;
}

View File

@ -17,7 +17,7 @@ public class MagicLogBook extends ArrayList<MagicMessage> {
}
return super.add(msg);
}
/** Removes all messages from end to given index, inclusive. */
public synchronized void removeTo(final int toIndex) {
for (int index=size()-1;index>=toIndex;index--) {

View File

@ -4,12 +4,12 @@ public class MagicLogMessageBuilder {
private final MagicGame game;
private final StringBuilder[] messageBuilders;
MagicLogMessageBuilder(final MagicGame game) {
this.game=game;
messageBuilders=new StringBuilder[]{new StringBuilder(),new StringBuilder()};
}
void appendMessage(final MagicPlayer player,final String message) {
final StringBuilder messageBuilder=messageBuilders[player.getIndex()];
if (messageBuilder.length()>0) {
@ -17,7 +17,7 @@ public class MagicLogMessageBuilder {
}
messageBuilder.append(message);
}
void logMessages() {
for (final MagicPlayer player : game.getPlayers()) {
final StringBuilder messageBuilder=messageBuilders[player.getIndex()];
@ -27,7 +27,7 @@ public class MagicLogMessageBuilder {
}
}
}
void clearMessages() {
messageBuilders[0].setLength(0);
messageBuilders[1].setLength(0);

View File

@ -22,7 +22,7 @@ public class MagicManaCost {
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 ImageIcon[] COLORLESS_ICONS={
IconImages.COST_ZERO,
IconImages.COST_ONE,
@ -42,7 +42,7 @@ public class MagicManaCost {
IconImages.COST_FIFTEEN,
IconImages.COST_SIXTEEN
};
public static final MagicManaCost ZERO=MagicManaCost.create("{0}");
private final String costText;
@ -65,13 +65,13 @@ public class MagicManaCost {
while (matcher.find()) {
addType(matcher.group(), XCountArr, convertedArr);
}
XCount = XCountArr[0];
converted = convertedArr[0];
//assert getCanonicalText().equals(costText) : "canonical: " + getCanonicalText() + " != cost: " + costText;
}
private void addType(final MagicCostManaType type,final int amount,final int[] convertedArr) {
convertedArr[0] += amount;
amounts[type.ordinal()] += amount;
@ -79,7 +79,7 @@ public class MagicManaCost {
order.add(type);
}
}
private void addType(final String typeText, final int[] XCountArr, final int[] convertedArr) {
final String symbol = typeText.substring(1, typeText.length() - 1);
if ("X".equals(symbol)) {
@ -96,7 +96,7 @@ public class MagicManaCost {
throw new RuntimeException("Invalid cost \"" + costText + "\"");
}
}
private static boolean isNumeric(final String str) {
for (final char c : str.toCharArray()) {
if (!Character.isDigit(c)) {
@ -109,19 +109,19 @@ public class MagicManaCost {
public String getText() {
return costText;
}
@Override
public String toString() {
return costText;
}
public int getXCount() {
return XCount;
}
public boolean hasX() {
return XCount > 0;
}
public List<MagicCostManaType> getCostManaTypes(final int x) {
final List<MagicCostManaType> types=new ArrayList<MagicCostManaType>();
int colorless=x;
@ -136,14 +136,14 @@ public class MagicManaCost {
}
}
}
for (;colorless>0;colorless--) {
types.add(MagicCostManaType.Colorless);
}
return types;
}
public int getColorFlags() {
int colorFlags = 0;
for (final MagicCostManaType costType : order) {
@ -155,7 +155,7 @@ public class MagicManaCost {
}
return colorFlags;
}
private String getCanonicalText() {
final StringBuilder sb = new StringBuilder();
//add X
@ -248,9 +248,9 @@ public class MagicManaCost {
icons.add(icon);
}
}
}
}
}
public List<ImageIcon> getIcons() {
if (icons == null) {
icons=new ArrayList<ImageIcon>();
@ -258,7 +258,7 @@ public class MagicManaCost {
}
return icons;
}
int getCostScore(final MagicPlayerProfile profile) {
final int[] singleCounts=new int[MagicManaType.NR_OF_TYPES];
int doubleCount=0;
@ -284,11 +284,11 @@ public class MagicManaCost {
}
return 2*converted+3*(10-SINGLE_PENALTY[maxSingleCount]-DOUBLE_PENALTY[doubleCount]);
}
public int getConvertedCost() {
return converted;
}
public MagicBuilderManaCost getBuilderCost() {
if (builderCost == null) {
builderCost=new MagicBuilderManaCost();
@ -296,17 +296,17 @@ public class MagicManaCost {
}
return builderCost;
}
public void addTo(final MagicBuilderManaCost aBuilderCost) {
for (final MagicCostManaType type : order) {
aBuilderCost.addType(type,amounts[type.ordinal()]);
}
if (hasX()) {
aBuilderCost.setXCount(XCount);
}
}
aBuilderCost.compress();
}
public void addTo(final MagicBuilderManaCost aBuilderCost,final int x) {
for (final MagicCostManaType type : order) {
aBuilderCost.addType(type,amounts[type.ordinal()]);
@ -314,7 +314,7 @@ public class MagicManaCost {
aBuilderCost.addType(MagicCostManaType.Colorless,x);
aBuilderCost.compress();
}
public MagicCondition getCondition() {
MagicCondition cond = CONDS_MAP.get(costText);
if (cond == null) {
@ -323,7 +323,7 @@ public class MagicManaCost {
}
return cond;
}
public static MagicManaCost create(final String costText) {
MagicManaCost cost = COSTS_MAP.get(costText);
if (cost == null) {

View File

@ -17,17 +17,17 @@ public enum MagicManaType {
White("white","{W}"),
NONE("none","{N}"),
;
public static final List<MagicManaType> ALL_COLORS = Collections.unmodifiableList(Arrays.asList(
Black,Blue,Green,Red,White));
public static final List<MagicManaType> ALL_TYPES = Collections.unmodifiableList(Arrays.asList(
Colorless,Black,Blue,Green,Red,White)); // Colorless must be in front.
public static final int NR_OF_TYPES = ALL_TYPES.size();
private final String name;
private final String text;
private MagicManaType(final String name, final String text) {
this.name=name;
this.text=text;
@ -36,15 +36,15 @@ public enum MagicManaType {
public boolean isValid() {
return this != MagicManaType.NONE;
}
public String getName() {
return name;
}
public String getText() {
return text;
}
public static MagicManaType get(final String name) {
for (final MagicManaType type : values()) {
if (type.toString().equalsIgnoreCase(name)) {
@ -53,7 +53,7 @@ public enum MagicManaType {
}
throw new RuntimeException("Unknown mana type " + name);
}
public static List<MagicManaType> getList(final String name) {
if ("{1}".equals(name)) {
return Arrays.asList(Colorless);
@ -74,7 +74,7 @@ public enum MagicManaType {
public String toString() {
return text;
}
public MagicColor getColor() {
switch (this) {
case Black: return MagicColor.Black;
@ -85,7 +85,7 @@ public enum MagicManaType {
}
throw new RuntimeException("No color available for MagicManaType " + this);
}
public ImageIcon getIcon(final boolean small) {
switch (this) {
case Colorless: return small?IconImages.COST_ONE:IconImages.ONE;

View File

@ -12,7 +12,7 @@ public class MagicMessage {
private final int turn;
private final MagicPhaseType phaseType;
private final String text;
MagicMessage(final MagicGame game,final MagicPlayer player,final String text) {
this.player=player;
this.life=player.getLife();
@ -24,19 +24,19 @@ public class MagicMessage {
public MagicPlayer getPlayer() {
return player;
}
public int getLife() {
return life;
}
public int getTurn() {
return turn;
}
public MagicPhaseType getPhaseType() {
return phaseType;
}
public String getText() {
return text;
}
@ -48,7 +48,7 @@ public class MagicMessage {
final Iterator<String> iterator=names.iterator();
do {
final String name=iterator.next();
next=iterator.hasNext();
next=iterator.hasNext();
if (first) {
first=false;
} else if (next) {
@ -60,14 +60,14 @@ public class MagicMessage {
} while (next);
}
}
public static String replaceName(final String sourceText,final Object source, final Object player, final Object ref) {
return sourceText
.replaceAll("PN", player.toString())
.replaceAll("SN", source.toString())
.replaceAll("RN", ref.toString());
}
public static String replaceChoices(final String sourceText,final Object[] choices) {
String result = sourceText;
for (int idx = 0; result.indexOf('$') >= 0; idx++) {

View File

@ -8,49 +8,49 @@ import magic.model.MagicCopyable;
public class MagicPayedCost implements MagicCopyable {
public static final MagicPayedCost NO_COST = new MagicPayedCost();
private MagicTarget target;
private int x;
private int kicker;
public MagicPayedCost() {
target = MagicTargetNone.getInstance();
x = 0;
kicker = 0;
}
public MagicPayedCost(final MagicPayedCost payedCost) {
target = payedCost.target;
x = payedCost.x;
kicker = payedCost.kicker;
}
public MagicPayedCost(final MagicCopyMap copyMap,final MagicPayedCost payedCost) {
target = copyMap.copy(payedCost.target);
x = payedCost.x;
kicker = payedCost.kicker;
}
public MagicCopyable copy(final MagicCopyMap copyMap) {
return new MagicPayedCost(copyMap, this);
}
private void setTarget(final MagicTarget target) {
this.target = target;
}
public MagicTarget getTarget() {
return target;
}
private void setX(final int x) {
this.x = x;
this.x = x;
}
public int getX() {
return x;
}
}
void set(final Object choiceResult) {
if (choiceResult instanceof MagicTarget) {
setTarget((MagicTarget)choiceResult);
@ -58,7 +58,7 @@ public class MagicPayedCost implements MagicCopyable {
setX(((MagicPayManaCostResult)choiceResult).getX());
}
}
public void setKicker(final int aKicker) {
kicker = aKicker;
}
@ -66,7 +66,7 @@ public class MagicPayedCost implements MagicCopyable {
public int getKicker() {
return kicker;
}
public boolean isKicked() {
return kicker > 0;
}

View File

@ -36,22 +36,22 @@ import java.util.Collections;
public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicPermanent> {
public static final int NO_COLOR_FLAGS=-1;
private final long id;
private final MagicCardDefinition cardDefinition;
private final MagicCard card;
private final MagicPlayer firstController;
private MagicPermanent equippedCreature = MagicPermanent.NONE;
private final MagicPermanentSet equipmentPermanents;
private final MagicPermanentSet equipmentPermanents;
private MagicPermanent enchantedCreature = MagicPermanent.NONE;
private final MagicPermanentSet auraPermanents;
private final MagicPermanentSet auraPermanents;
private MagicPermanent blockedCreature = MagicPermanent.NONE;
private final MagicPermanentList blockingCreatures;
private final MagicPermanentList blockingCreatures;
private MagicPermanent pairedCreature = MagicPermanent.NONE;
private final MagicCardList exiledCards;
private MagicTarget chosenTarget = MagicTargetNone.getInstance();
private int[] counters=new int[MagicCounterType.NR_COUNTERS];
private int stateFlags =
private int stateFlags =
MagicPermanentState.Summoned.getMask() |
MagicPermanentState.MustPayEchoCost.getMask();
private int abilityPlayedThisTurn;
@ -78,7 +78,7 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
card = aCard;
cardDefinition = card.getCardDefinition();
firstController = aController;
equipmentPermanents=new MagicPermanentSet();
auraPermanents=new MagicPermanentSet();
blockingCreatures=new MagicPermanentList();
@ -88,9 +88,9 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
private MagicPermanent(final MagicCopyMap copyMap, final MagicPermanent sourcePermanent) {
id = sourcePermanent.id;
cardDefinition = sourcePermanent.cardDefinition;
copyMap.put(sourcePermanent, this);
card = copyMap.copy(sourcePermanent.card);
firstController = copyMap.copy(sourcePermanent.firstController);
stateFlags=sourcePermanent.stateFlags;
@ -110,7 +110,7 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
fixedScore=sourcePermanent.fixedScore;
score=sourcePermanent.score;
stateId=sourcePermanent.stateId;
cachedController = copyMap.copy(sourcePermanent.cachedController);
cachedTypeFlags = sourcePermanent.cachedTypeFlags;
cachedSubTypeFlags = sourcePermanent.cachedSubTypeFlags;
@ -118,18 +118,18 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
cachedAbilityFlags = sourcePermanent.cachedAbilityFlags;
cachedPowerToughness = sourcePermanent.cachedPowerToughness;
}
@Override
public MagicPermanent copy(final MagicCopyMap copyMap) {
return new MagicPermanent(copyMap, this);
}
@Override
public MagicPermanent map(final MagicGame game) {
final MagicPlayer mappedController=getController().map(game);
return mappedController.getPermanents().getPermanent(id);
}
public long getId() {
return id;
}
@ -137,11 +137,11 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
public boolean isValid() {
return true;
}
public boolean isInvalid() {
return !isValid();
}
public long getStateId() {
stateId = stateId != 0 ? stateId : magic.MurmurHash3.hash(new long[] {
cardDefinition.getIndex(),
@ -170,39 +170,39 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
});
return stateId;
}
/** Determines uniqueness of a mana permanent, e.g. for producing mana, all Mountains are equal. */
public int getManaId() {
// Creatures or lands that can be animated are unique by default.
if (cardDefinition.hasExcludeManaOrCombat()) {
return (int)id;
}
}
// Uniqueness is determined by card definition and number of charge counters.
return -((cardDefinition.getIndex()<<16)+getCounters(MagicCounterType.Charge));
}
public MagicCard getCard() {
return card;
}
public boolean isToken() {
return card.isToken();
}
public boolean isNonToken() {
return !card.isToken();
}
@Override
public MagicCardDefinition getCardDefinition() {
return cardDefinition;
}
@Override
public Collection<MagicActivation> getActivations() {
return cardDefinition.getActivations();
}
public Collection<MagicManaActivation> getManaActivations() {
return cardDefinition.getManaActivations();
}
@ -210,11 +210,11 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
public Collection<MagicStatic> getStatics() {
return cardDefinition.getStatics();
}
public Collection<MagicTrigger<?>> getTriggers() {
return cardDefinition.getTriggers();
}
public Collection<MagicWhenComesIntoPlayTrigger> getComeIntoPlayTriggers() {
return cardDefinition.getComeIntoPlayTriggers();
}
@ -226,15 +226,15 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
public boolean producesMana() {
return !cardDefinition.getManaActivations().isEmpty();
}
public int countManaActivations() {
return cardDefinition.getManaActivations().size();
}
public String getName() {
return card.getName();
}
@Override
public String toString() {
return getName();
@ -252,12 +252,12 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
public MagicPlayer getFirstController() {
return firstController;
}
public MagicPlayer getController() {
assert cachedController != null : "cachedController is null in " + this;
return cachedController;
}
public MagicPlayer getOpponent() {
return getController().getOpponent();
}
@ -265,35 +265,35 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
public boolean isFriend(final MagicObject other) {
return getController() == other.getController();
}
public boolean isEnemy(final MagicObject other) {
return getController() != other.getController();
}
public boolean isController(final MagicTarget player) {
return getController() == player;
}
public boolean isOwner(final MagicTarget player) {
return getOwner() == player;
}
public boolean isOpponent(final MagicTarget player) {
return getOpponent() == player;
}
public static void update(final MagicGame game) {
MagicPermanent.updateProperties(game);
MagicPermanent.updateScoreFixController(game);
}
public static void updateScoreFixController(final MagicGame game) {
for (final MagicPlayer player : game.getPlayers()) {
for (final MagicPermanent perm : player.getPermanents()) {
final MagicPlayer curr = perm.getController();
if (!curr.controlsPermanent(perm)) {
game.addDelayedAction(new MagicChangeControlAction(curr, perm, perm.getScore()));
}
}
perm.updateScore();
}}
}
@ -317,7 +317,7 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
}
}
}
private void apply(final MagicLayer layer) {
switch (layer) {
case Card:
@ -369,48 +369,48 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
public void setState(final MagicPermanentState state) {
stateFlags|=state.getMask();
}
public void clearState(final MagicPermanentState state) {
stateFlags&=Integer.MAX_VALUE-state.getMask();
}
public boolean hasState(final MagicPermanentState state) {
return state.hasState(stateFlags);
}
public int getStateFlags() {
return stateFlags;
}
public void setStateFlags(final int flags) {
stateFlags=flags;
}
public boolean isTapped() {
return hasState(MagicPermanentState.Tapped);
}
public boolean isUntapped() {
return !hasState(MagicPermanentState.Tapped);
}
private int getColorFlags() {
return cachedColorFlags;
}
@Override
public boolean hasColor(final MagicColor color) {
return color.hasColor(getColorFlags());
return color.hasColor(getColorFlags());
}
public void changeCounters(final MagicCounterType counterType,final int amount) {
counters[counterType.ordinal()]+=amount;
}
public int getCounters(final MagicCounterType counterType) {
return counters[counterType.ordinal()];
}
public boolean hasCounters() {
for (final int amount : counters) {
if (amount>0) {
@ -419,7 +419,7 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
}
return false;
}
public boolean hasSubType(final MagicSubType subType) {
return cachedSubTypeFlags.contains(subType);
}
@ -431,15 +431,15 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
public MagicPowerToughness getPowerToughness() {
return cachedPowerToughness;
}
public int getPower() {
return getPowerToughness().getPositivePower();
}
public int getToughness() {
return getPowerToughness().getPositiveToughness();
}
public Set<MagicAbility> getAbilityFlags() {
return cachedAbilityFlags;
}
@ -448,33 +448,33 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
public boolean hasAbility(final MagicAbility ability) {
return cachedAbilityFlags.contains(ability);
}
private void updateScore() {
stateId = 0;
fixedScore = ArtificialScoringSystem.getFixedPermanentScore(this);
score = fixedScore + ArtificialScoringSystem.getVariablePermanentScore(this);
}
public int getScore() {
return score;
}
public int getStaticScore() {
return cardDefinition.getStaticType().getScore(this);
}
public int getCardScore() {
return cardDefinition.getScore();
}
public int getDamage() {
return damage;
}
public void setDamage(final int damage) {
this.damage=damage;
}
@Override
public int getPreventDamage() {
return preventDamage;
@ -488,49 +488,49 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
public int getLethalDamage(final int toughness) {
return toughness<=damage?0:toughness-damage;
}
// Tap symbol.
public boolean canTap() {
return !hasState(MagicPermanentState.Tapped) &&
(!hasState(MagicPermanentState.Summoned) ||
!isCreature() ||
return !hasState(MagicPermanentState.Tapped) &&
(!hasState(MagicPermanentState.Summoned) ||
!isCreature() ||
hasAbility(MagicAbility.Haste)
);
}
// Untap symbol.
public boolean canUntap() {
return hasState(MagicPermanentState.Tapped) &&
(!hasState(MagicPermanentState.Summoned) ||
!isCreature() ||
return hasState(MagicPermanentState.Tapped) &&
(!hasState(MagicPermanentState.Summoned) ||
!isCreature() ||
hasAbility(MagicAbility.Haste)
);
);
}
public boolean canRegenerate() {
return !hasState(MagicPermanentState.Regenerated)&&!hasState(MagicPermanentState.CannotBeRegenerated);
}
public boolean isRegenerated() {
return hasState(MagicPermanentState.Regenerated)&&!hasState(MagicPermanentState.CannotBeRegenerated);
}
public boolean isAttacking() {
return hasState(MagicPermanentState.Attacking);
}
public boolean isBlocked() {
return hasState(MagicPermanentState.Blocked);
}
public boolean isBlocking() {
return hasState(MagicPermanentState.Blocking);
}
public MagicPermanent getBlockedCreature() {
return blockedCreature;
}
public void setBlockedCreature(final MagicPermanent creature) {
if (creature.isValid()) {
blockedName = creature.getName() + creature.getId() + (100 + creature.numBlockingCreatures());
@ -545,67 +545,67 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
public MagicPermanentList getBlockingCreatures() {
return blockingCreatures;
}
public int numBlockingCreatures() {
return blockingCreatures.size();
}
public void setBlockingCreatures(final MagicPermanentList creatures) {
blockingCreatures.clear();
blockingCreatures.addAll(creatures);
}
public void addBlockingCreature(final MagicPermanent creature) {
blockingCreatures.add(creature);
}
public void removeBlockingCreature(final MagicPermanent creature) {
blockingCreatures.remove(creature);
}
public void removeBlockingCreatures() {
blockingCreatures.clear();
}
public MagicPermanent getPairedCreature() {
return pairedCreature;
}
public void setPairedCreature(final MagicPermanent creature) {
pairedCreature = creature;
}
public boolean isPaired() {
return pairedCreature != MagicPermanent.NONE;
}
public MagicCardList getExiledCards() {
return exiledCards;
}
public void addExiledCard(final MagicCard card) {
// only non tokens can be added
if (!card.isToken()) {
exiledCards.add(card);
}
}
public void removeExiledCard(final MagicCard card) {
exiledCards.remove(card);
}
public MagicTarget getChosenTarget() {
return chosenTarget;
}
public MagicPlayer getChosenPlayer() {
return (MagicPlayer)chosenTarget;
}
public void setChosenTarget(final MagicTarget target) {
chosenTarget = target;
}
void generateStateBasedActions() {
final MagicGame game = getGame();
if (isCreature()) {
@ -619,26 +619,26 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
} else if (toughness-damage<=0) {
game.addDelayedAction(new MagicDestroyAction(this));
}
// Soulbond
if (pairedCreature.isValid() &&
!pairedCreature.isCreature()) {
game.doAction(new MagicSoulbondAction(this,pairedCreature,false));
}
}
}
if (isAura()) {
final MagicPlayAuraEvent auraEvent = (MagicPlayAuraEvent)cardDefinition.getCardEvent();
//not targeting since Aura is already attached
final MagicTargetChoice tchoice = new MagicTargetChoice(auraEvent.getTargetChoice(), false);
if (!enchantedCreature.isValid() ||
if (!enchantedCreature.isValid() ||
!game.isLegalTarget(getController(),this,tchoice,enchantedCreature) ||
enchantedCreature.hasProtectionFrom(this)) {
game.logAppendMessage(getController(),getName()+" is put into its owner's graveyard.");
game.addDelayedAction(new MagicRemoveFromPlayAction(this,MagicLocationType.Graveyard));
}
}
}
if (isEquipment() && equippedCreature.isValid()) {
if (isCreature() || !equippedCreature.isCreature() || equippedCreature.hasProtectionFrom(this)) {
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.addDelayedAction(new MagicRemoveFromPlayAction(this,MagicLocationType.Graveyard));
}
// +1/+1 and -1/-1 counters cancel each other out.
final int plusCounters=getCounters(MagicCounterType.PlusOne);
if (plusCounters>0) {
@ -662,7 +662,7 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
}
}
}
public boolean hasProtectionFrom(final MagicSource source) {
// From a color.
int numColors = 0;
@ -675,7 +675,7 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
}
}
}
// From monocolored.
if (numColors == 1 &&
hasAbility(MagicAbility.ProtectionFromMonoColored)) {
@ -687,7 +687,7 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
}
final MagicPermanent creature = (MagicPermanent)source;
// From creatures.
if (creature.hasType(MagicType.Creature) &&
hasAbility(MagicAbility.ProtectionFromCreatures)) {
@ -723,48 +723,48 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
hasAbility(MagicAbility.ProtectionFromZombies)) {
return true;
}
return false;
}
public boolean canAttack() {
if (!isCreature() ||
!canTap() ||
if (!isCreature() ||
!canTap() ||
hasState(MagicPermanentState.ExcludeFromCombat) ||
hasState(MagicPermanentState.CannotAttack)) {
return false;
}
return !hasAbility(MagicAbility.CannotAttackOrBlock) &&
return !hasAbility(MagicAbility.CannotAttackOrBlock) &&
!hasAbility(MagicAbility.Defender);
}
public boolean canBlock() {
if (!isCreature() ||
isTapped() ||
if (!isCreature() ||
isTapped() ||
hasState(MagicPermanentState.ExcludeFromCombat)) {
return false;
}
return !hasAbility(MagicAbility.CannotAttackOrBlock) &&
!hasAbility(MagicAbility.CannotBlock);
}
public boolean canBeBlocked(final MagicPlayer defendingPlayer) {
// Unblockable
if (hasAbility(MagicAbility.Unblockable)) {
return false;
}
}
// Landwalk
for (final MagicColor color : MagicColor.values()) {
if (hasAbility(color.getLandwalkAbility()) &&
if (hasAbility(color.getLandwalkAbility()) &&
defendingPlayer.controlsPermanent(color.getLandSubType())) {
return false;
}
}
return true;
}
public boolean canBlock(final MagicPermanent attacker) {
// Fear and Intimidate
if (!isArtifact()) {
@ -777,7 +777,7 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
return false;
}
}
// Shadow
if (attacker.hasAbility(MagicAbility.Shadow)) {
if (!hasAbility(MagicAbility.Shadow) &&
@ -787,18 +787,18 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
} else if (hasAbility(MagicAbility.Shadow)) {
return false;
}
// Flying
if (attacker.hasAbility(MagicAbility.CannotBeBlockedByFlying) &&
hasAbility(MagicAbility.Flying)) {
return false;
}
if (attacker.hasAbility(MagicAbility.CannotBeBlockedExceptWithFlying) &&
!hasAbility(MagicAbility.Flying)) {
return false;
}
if (!attacker.hasAbility(MagicAbility.Flying) &&
hasAbility(MagicAbility.CannotBlockWithoutFlying)) {
return false;
@ -809,20 +809,20 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
!hasAbility(MagicAbility.Flying) &&
!hasAbility(MagicAbility.Reach)) {
return false;
}
}
if (attacker.hasAbility(MagicAbility.CannotBeBlockedExceptWithFlyingOrReach) &&
!hasAbility(MagicAbility.Flying) &&
!hasAbility(MagicAbility.Reach)) {
return false;
}
// Subtype
if (attacker.hasAbility(MagicAbility.CannotBeBlockedByHumans) &&
hasSubType(MagicSubType.Human)) {
return false;
}
if (attacker.hasAbility(MagicAbility.CannotBeBlockedExceptBySliver) &&
!hasSubType(MagicSubType.Sliver)) {
return false;
@ -841,11 +841,11 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
return false;
}
}
// Protection
return !attacker.hasProtectionFrom(this);
}
public MagicPermanent getEquippedCreature() {
return equippedCreature;
}
@ -853,23 +853,23 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
public void setEquippedCreature(final MagicPermanent creature) {
equippedCreature=creature;
}
public MagicPermanentSet getEquipmentPermanents() {
return equipmentPermanents;
}
public void addEquipment(final MagicPermanent equipment) {
equipmentPermanents.add(equipment);
}
public void removeEquipment(final MagicPermanent equipment) {
equipmentPermanents.remove(equipment);
}
public boolean isEquipped() {
return equipmentPermanents.size()>0;
}
public MagicPermanent getEnchantedCreature() {
return enchantedCreature;
}
@ -877,31 +877,31 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
public void setEnchantedCreature(final MagicPermanent creature) {
enchantedCreature=creature;
}
public MagicPermanentSet getAuraPermanents() {
return auraPermanents;
}
public void addAura(final MagicPermanent aura) {
auraPermanents.add(aura);
}
public void removeAura(final MagicPermanent aura) {
auraPermanents.remove(aura);
}
public boolean isEnchanted() {
return auraPermanents.size()>0;
}
public int getAbilityPlayedThisTurn() {
return abilityPlayedThisTurn;
}
public void setAbilityPlayedThisTurn(final int amount) {
abilityPlayedThisTurn=amount;
}
public void incrementAbilityPlayedThisTurn() {
abilityPlayedThisTurn++;
}
@ -909,47 +909,47 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
public void decrementAbilityPlayedThisTurn() {
abilityPlayedThisTurn--;
}
private int getTypeFlags() {
return cachedTypeFlags;
}
public boolean hasType(final MagicType type) {
return type.hasType(getTypeFlags());
}
public boolean isBasic() {
return hasType(MagicType.Basic);
}
public boolean isLand() {
return hasType(MagicType.Land);
}
public boolean isCreature() {
return hasType(MagicType.Creature);
}
public boolean isEquipment() {
return isArtifact() && hasSubType(MagicSubType.Equipment);
}
public boolean isArtifact() {
return hasType(MagicType.Artifact);
}
public boolean isEnchantment() {
return hasType(MagicType.Enchantment);
}
public boolean isAura() {
return isEnchantment() && hasSubType(MagicSubType.Aura);
}
public boolean isPlaneswalker() {
return hasType(MagicType.Planeswalker);
}
@Override
public boolean isSpell() {
return false;
@ -959,12 +959,12 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
public boolean isPlayer() {
return false;
}
@Override
public boolean isPermanent() {
return true;
}
}
@Override
public boolean isValidTarget(final MagicSource source) {
// 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) {
return false;
}
// Can't be the target of spells or abilities player 1 controls.
if (hasAbility(MagicAbility.CannotBeTheTarget1) && source.getController().getIndex() == 1) {
return false;
@ -1023,11 +1023,11 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
}
return false;
}
public ImageIcon getIcon() {
if (isAttacking()) {
return IconImages.ATTACK;
}
}
if (isBlocking()) {
return IconImages.BLOCK;
}
@ -1036,12 +1036,12 @@ public class MagicPermanent implements MagicSource,MagicTarget,Comparable<MagicP
}
return cardDefinition.getIcon();
}
@Override
public boolean isLegalTarget(final MagicPlayer player, final MagicTargetFilter<? extends MagicTarget> targetFilter) {
return getController().controlsPermanent(this);
}
public static final MagicPermanent NONE = new MagicPermanent(-1L, MagicCard.NONE, MagicPlayer.NONE) {
@Override
public boolean isValid() {

View File

@ -7,11 +7,11 @@ public class MagicPermanentList extends ArrayList<MagicPermanent> implements Mag
private static final long serialVersionUID = 1L;
public MagicPermanentList() {}
public MagicPermanentList(final MagicPermanentList list) {
addAll(list);
}
MagicPermanentList(final MagicCopyMap copyMap,final MagicPermanentList list) {
for (final MagicPermanent permanent : list) {
add(copyMap.copy(permanent));

View File

@ -7,13 +7,13 @@ public class MagicPermanentSet extends TreeSet<MagicPermanent> {
private static final long serialVersionUID = 1L;
MagicPermanentSet() {}
MagicPermanentSet(final MagicCopyMap copyMap,final MagicPermanentSet source) {
for (final MagicPermanent permanent : source) {
add(copyMap.copy(permanent));
}
}
MagicPermanent getPermanent(final long id) {
for (final MagicPermanent permanent : this) {
if (permanent.getId() == id) {
@ -21,8 +21,8 @@ public class MagicPermanentSet extends TreeSet<MagicPermanent> {
}
}
return MagicPermanent.NONE;
}
}
long getStateId() {
final long[] keys = new long[size()];
int idx = 0;

View File

@ -1,7 +1,7 @@
package magic.model;
public enum MagicPermanentState {
Tapped("tapped","{T}"),
Summoned("summoned","{n}"),
DoesNotUntapDuringNext("doesn't untap during its controller's next untap step","{s}"),
@ -39,29 +39,29 @@ public enum MagicPermanentState {
ExcludeFromCombat.getMask()|
DestroyAtEndOfCombat.getMask()|
MustPayEchoCost.getMask();
private final String description;
private final String text;
private final int mask;
private MagicPermanentState(final String description,final String text) {
this.description=description;
this.text=text;
this.mask=1<<ordinal();
}
public String getDescription() {
return description;
}
public String getText() {
return text;
}
public int getMask() {
return mask;
}
public boolean hasState(final int flags) {
return (flags&mask)!=0;
}

View File

@ -47,10 +47,10 @@ public class MagicPlayer implements MagicTarget {
private static final int LOSING_POISON=10;
private static final long ID_FACTOR=31;
private final MagicPlayerDefinition playerDefinition;
private final int index;
private int life;
private int stateFlags;
private int poison;
@ -76,7 +76,7 @@ public class MagicPlayer implements MagicTarget {
playerDefinition = aPlayerDefinition;
index = aIndex;
life = aLife;
hand=new MagicCardList();
library=new MagicCardList();
graveyard=new MagicCardList();
@ -87,10 +87,10 @@ public class MagicPlayer implements MagicTarget {
builderCost=new MagicBuilderManaCost();
activationPriority=new MagicActivationPriority();
}
private MagicPlayer(final MagicCopyMap copyMap, final MagicPlayer sourcePlayer) {
copyMap.put(sourcePlayer, this);
playerDefinition = sourcePlayer.playerDefinition;
index = sourcePlayer.index;
life = sourcePlayer.life;
@ -111,12 +111,12 @@ public class MagicPlayer implements MagicTarget {
activationPriority=new MagicActivationPriority(sourcePlayer.activationPriority);
cachedAbilityFlags=sourcePlayer.cachedAbilityFlags;
}
@Override
public MagicPlayer copy(final MagicCopyMap copyMap) {
return new MagicPlayer(copyMap, this);
}
@Override
public MagicPlayer map(final MagicGame game) {
return game.getPlayer(index);
@ -129,7 +129,7 @@ public class MagicPlayer implements MagicTarget {
public MagicGame getGame() {
return currGame;
}
public long getStateId() {
keys = new long[] {
life,
@ -151,7 +151,7 @@ public class MagicPlayer implements MagicTarget {
};
return magic.MurmurHash3.hash(keys);
}
String getIdString() {
final StringBuilder sb = new StringBuilder();
sb.append(keys[0]);
@ -161,7 +161,7 @@ public class MagicPlayer implements MagicTarget {
}
return sb.toString();
}
long getPlayerId(final long id) {
// Exile is not used for id.
long playerId=id;
@ -173,20 +173,20 @@ public class MagicPlayer implements MagicTarget {
playerId=playerId*ID_FACTOR+graveyard.getStateId();
return playerId;
}
@Override
public String toString() {
return playerDefinition.getName();
}
public MagicActivationMap getActivationMap() {
return activationMap;
}
public MagicPlayerDefinition getPlayerDefinition() {
return playerDefinition;
}
public int getIndex() {
return index;
}
@ -194,63 +194,63 @@ public class MagicPlayer implements MagicTarget {
public long getId() {
return 1000000000L + index;
}
public void setState(final MagicPlayerState state) {
stateFlags|=state.getMask();
}
public void clearState(final MagicPlayerState state) {
stateFlags&=Integer.MAX_VALUE-state.getMask();
}
public boolean hasState(final MagicPlayerState state) {
return state.hasState(stateFlags);
}
public int getStateFlags() {
return stateFlags;
}
public void setStateFlags(final int flags) {
stateFlags=flags;
}
public void setLife(final int life) {
this.life=life;
}
public int getLife() {
return life;
}
public void setPoison(final int poison) {
this.poison=poison;
}
public int getPoison() {
return poison;
}
public void changeExtraTurns(final int amount) {
extraTurns+=amount;
}
public int getExtraTurns() {
return extraTurns;
}
public int getHandSize() {
return hand.size();
}
public int getNumExcessCards() {
return Math.max(0, getHandSize() - maxHandSize);
}
public void noMaxHandSize() {
maxHandSize = Integer.MAX_VALUE;
}
public MagicCardList getHand() {
return hand;
}
@ -259,17 +259,17 @@ public class MagicPlayer implements MagicTarget {
hand.addToTop(card);
activationMap.addActivations(card);
}
public void addCardToHand(final MagicCard card,final int aIndex) {
hand.add(aIndex,card);
activationMap.addActivations(card);
}
public int removeCardFromHand(final MagicCard card) {
activationMap.removeActivations(card);
return hand.removeCard(card);
}
void setHandToUnknown() {
activationMap.removeActivations(hand);
hand.setKnown(false);
@ -292,7 +292,7 @@ public class MagicPlayer implements MagicTarget {
addCardToHand(library.removeCardAtTop());
}
}
void createHandAndLibrary(final int handSize) {
for (final MagicCardDefinition cardDefinition : playerDefinition.getDeck()) {
final long id = currGame.getUniqueId();
@ -303,8 +303,8 @@ public class MagicPlayer implements MagicTarget {
final long seed = magic.MurmurHash3.hash(new long[] {
2 * index - 1,
MagicGame.getCount(),
(System.getProperty("rndSeed") != null) ?
Long.parseLong(System.getProperty("rndSeed")) :
(System.getProperty("rndSeed") != null) ?
Long.parseLong(System.getProperty("rndSeed")) :
System.currentTimeMillis()
});
@ -318,15 +318,15 @@ public class MagicPlayer implements MagicTarget {
public MagicCardList getLibrary() {
return library;
}
public MagicCardList getGraveyard() {
return graveyard;
}
public MagicCardList getExile() {
return exile;
}
public MagicPermanentSet getPermanents() {
return permanents;
}
@ -348,15 +348,15 @@ public class MagicPlayer implements MagicTarget {
}
activationMap.removeActivations(permanent);
}
public List<MagicSourceManaActivation> getManaActivations(final MagicGame game) {
final List<MagicSourceManaActivation> activations=new ArrayList<MagicSourceManaActivation>();
for (final MagicPermanent permanent : manaPermanents) {
if (game.isArtificial()&&permanent.hasState(MagicPermanentState.ExcludeManaSource)) {
continue;
}
final MagicSourceManaActivation sourceActivation=new MagicSourceManaActivation(game,permanent);
if (sourceActivation.available) {
activations.add(sourceActivation);
@ -364,7 +364,7 @@ public class MagicPlayer implements MagicTarget {
}
return activations;
}
private int getManaActivationsCount(final MagicGame game) {
int count=0;
for (final MagicPermanent permanent : manaPermanents) {
@ -376,11 +376,11 @@ public class MagicPlayer implements MagicTarget {
}
return count;
}
public void setBuilderCost(final MagicBuilderManaCost builderCost) {
this.builderCost=builderCost;
}
public MagicBuilderManaCost getBuilderCost() {
return builderCost;
}
@ -388,11 +388,11 @@ public class MagicPlayer implements MagicTarget {
public void setActivationPriority(final MagicActivationPriority abilityPriority) {
this.activationPriority=abilityPriority;
}
public MagicActivationPriority getActivationPriority() {
return activationPriority;
}
public int getMaximumX(final MagicGame game,final MagicManaCost cost) {
return (getManaActivationsCount(game) -
builderCost.getMinimumAmount() -
@ -409,7 +409,7 @@ public class MagicPlayer implements MagicTarget {
}
return count;
}
public int getNrOfBlockers() {
int count=0;
for (final MagicPermanent permanent : permanents) {
@ -419,7 +419,7 @@ public class MagicPlayer implements MagicTarget {
}
return count;
}
public int getNrOfPermanentsWithType(final MagicType type) {
int count=0;
for (final MagicPermanent permanent : permanents) {
@ -439,7 +439,7 @@ public class MagicPlayer implements MagicTarget {
}
return count;
}
public int getNrOfPermanents(final MagicTargetFilter<MagicPermanent> filter) {
int count = 0;
for (final MagicPermanent permanent : permanents) {
@ -449,8 +449,8 @@ public class MagicPlayer implements MagicTarget {
}
return count;
}
public boolean controlsPermanent(final MagicTargetFilter<MagicPermanent> filter) {
for (final MagicPermanent permanent : permanents) {
if (filter.accept(currGame, this, permanent)) {
@ -459,11 +459,11 @@ public class MagicPlayer implements MagicTarget {
}
return false;
}
public boolean controlsPermanent(final MagicPermanent permanent) {
return permanents.contains(permanent);
}
public boolean controlsPermanent(final MagicColor color) {
for (final MagicPermanent permanent : permanents) {
if (permanent.hasColor(color)) {
@ -472,7 +472,7 @@ public class MagicPlayer implements MagicTarget {
}
return false;
}
public boolean controlsPermanent(final MagicType type) {
for (final MagicPermanent permanent : permanents) {
if (permanent.hasType(type)) {
@ -481,40 +481,40 @@ public class MagicPlayer implements MagicTarget {
}
return false;
}
public boolean controlsPermanent(final MagicSubType subType) {
for (final MagicPermanent permanent : permanents) {
if (permanent.hasSubType(subType)) {
return true;
}
}
return false;
return false;
}
public boolean controlsPermanent(final MagicAbility ability) {
for (final MagicPermanent permanent : permanents) {
if (permanent.hasAbility(ability)) {
return true;
}
}
return false;
return false;
}
@Override
public MagicCardDefinition getCardDefinition() {
throw new RuntimeException("player has no card definition");
throw new RuntimeException("player has no card definition");
}
@Override
public String getName() {
return playerDefinition.getName();
}
@Override
public boolean isPermanent() {
return false;
}
@Override
public boolean isCreature() {
return false;
@ -524,7 +524,7 @@ public class MagicPlayer implements MagicTarget {
public boolean isPlayer() {
return true;
}
@Override
public boolean isPlaneswalker() {
return false;
@ -566,22 +566,22 @@ public class MagicPlayer implements MagicTarget {
public boolean hasAbility(final MagicAbility ability) {
return cachedAbilityFlags.contains(ability);
}
@Override
public boolean hasType(final MagicType type) {
return false;
}
@Override
public boolean hasSubType(final MagicSubType subType) {
return false;
}
@Override
public boolean hasColor(final MagicColor color) {
return false;
}
@Override
public boolean isValidTarget(final MagicSource source) {
// Can't be the target of spells or abilities your opponents controls.
@ -590,7 +590,7 @@ public class MagicPlayer implements MagicTarget {
}
return true;
}
@Override
public boolean isLegalTarget(final MagicPlayer player, final MagicTargetFilter<? extends MagicTarget> targetFilter) {
return true;
@ -599,7 +599,7 @@ public class MagicPlayer implements MagicTarget {
public void incDrawnCards() {
drawnCards++;
}
public void decDrawnCards() {
drawnCards--;
}
@ -620,7 +620,7 @@ public class MagicPlayer implements MagicTarget {
currGame.addDelayedAction(new MagicLoseGameAction(this,MagicLoseGameAction.POISON_REASON));
}
}
public void apply(final MagicLayer layer) {
switch (layer) {
case Player:
@ -632,7 +632,7 @@ public class MagicPlayer implements MagicTarget {
throw new RuntimeException("No case for " + layer + " in MagicPlayer.apply");
}
}
private void apply(final MagicPermanent source, final MagicStatic mstatic) {
final MagicLayer layer = mstatic.getLayer();
switch (layer) {

View File

@ -10,12 +10,12 @@ public class MagicPlayerDefinition {
private static final int DECK_SIZE=40;
private static final int MIN_SOURCE=16;
private static final String NAME="name";
private static final String ARTIFICIAL="artificial";
private static final String COLORS="colors";
private static final String FACE="face";
private String name;
private boolean artificial;
private MagicPlayerProfile profile;
@ -23,14 +23,14 @@ public class MagicPlayerDefinition {
private final MagicDeck deck = new MagicDeck();
MagicPlayerDefinition() {}
public MagicPlayerDefinition(final String name,final boolean artificial,final MagicPlayerProfile profile,final int face) {
this.name=name;
this.artificial=artificial;
this.profile=profile;
this.face=face;
}
public String getName() {
return name;
}
@ -38,23 +38,23 @@ public class MagicPlayerDefinition {
public void setArtificial(final boolean art) {
this.artificial=art;
}
public boolean isArtificial() {
return artificial;
}
public void setProfile(final MagicPlayerProfile profile) {
this.profile=profile;
}
public MagicPlayerProfile getProfile() {
return profile;
}
public int getFace() {
return face;
}
private void addBasicLandsToDeck() {
// Calculate statistics per color.
final int[] colorCount=new int[MagicColor.NR_COLORS];
@ -70,10 +70,10 @@ public class MagicPlayerDefinition {
if (color.hasColor(colorFlags)) {
colorCount[color.ordinal()]++;
}
}
}
}
}
// Add optimal basic lands to deck.
while (deck.size()<DECK_SIZE) {
MagicColor bestColor=null;
@ -100,41 +100,41 @@ public class MagicPlayerDefinition {
deck.add(landCard);
}
}
public MagicDeck getDeck() {
return deck;
}
}
public void setDeck(final MagicDeck aDeck) {
deck.setContent(aDeck);
}
}
public DefaultDeckGenerator getDeckGenerator() {
final String name = getProfile().getDeckGeneratorName();
if (name == null) {
return null;
}
return DeckGenerators.getInstance().getDeckGenerator(name);
}
void generateDeck(final DefaultDeckGenerator defaultGenerator) {
final DefaultDeckGenerator customGenerator = getDeckGenerator();
if(customGenerator == null) {
defaultGenerator.generateDeck(DECK_SIZE, profile, deck);
} else {
customGenerator.generateDeck(DECK_SIZE, profile, deck);
}
addBasicLandsToDeck();
}
private static String getDeckPrefix(final String prefix,final int index) {
return prefix+"deck"+index;
}
void load(final Properties properties,final String prefix) {
name=properties.getProperty(prefix+NAME,"");
artificial=Boolean.parseBoolean(properties.getProperty(prefix+ARTIFICIAL,"true"));
@ -159,13 +159,13 @@ public class MagicPlayerDefinition {
magic.data.DeckUtils.showUnsupportedCards(unsupported);
}
void save(final Properties properties,final String prefix) {
properties.setProperty(prefix+NAME,name);
properties.setProperty(prefix+ARTIFICIAL,Boolean.toString(artificial));
properties.setProperty(prefix+COLORS,getProfile().getColorText());
properties.setProperty(prefix+FACE,Integer.toString(face));
int index=1;
for (final MagicCardDefinition cardDefinition : deck) {
properties.setProperty(getDeckPrefix(prefix,index++),cardDefinition.getFullName());

View File

@ -1,78 +1,78 @@
package magic.model;
public class MagicPlayerProfile {
private String deckGeneratorName;
private String deckGeneratorName;
private String colorText;
private MagicColor[] colors;
private boolean isPreConstructed;
public MagicPlayerProfile(final String colorText) {
this(colorText, null);
}
public MagicPlayerProfile(final String colorText, final String deckGeneratorName) {
setColors(colorText);
setDeckGeneratorName(deckGeneratorName);
}
public void setColors(final String colorText) {
this.colorText=colorText;
colors=new MagicColor[colorText.length()];
for (int i=0;i<colorText.length();i++) {
colors[i]=MagicColor.getColor(colorText.charAt(i));
}
}
public void setDeckGeneratorName(final String name) {
this.deckGeneratorName = name;
}
public String getDeckGeneratorName() {
return deckGeneratorName;
}
String getColorText() {
return colorText;
}
public MagicColor[] getColors() {
return colors;
}
int getNrOfColors() {
return colors.length;
}
public int getNrOfNonBasicLands(final int amount) {
switch (colors.length) {
case 3: return amount/2;
case 2: return amount/4;
default: return 0;
}
}
boolean allowsManaType(final MagicManaType manaType) {
for (final MagicColor color : colors) {
if (color.getManaType()==manaType) {
return true;
}
}
return false;
}
public void setPreConstructed() {
isPreConstructed = true;
}
public boolean isPreConstructed() {
return isPreConstructed;
}

View File

@ -9,23 +9,23 @@ public enum MagicPlayerState {
CantCastSpells("can't cast spells this turn"),
CantActivateAbilities("can't activate abilities this turn"),
;
private final String description;
private final int mask;
private MagicPlayerState(final String description) {
this.description=description;
this.mask=1<<ordinal();
}
public String getDescription() {
return description;
}
public int getMask() {
return mask;
}
public boolean hasState(final int flags) {
return (flags&mask)!=0;
}

View File

@ -4,12 +4,12 @@ public class MagicPowerToughness {
private int power;
private int toughness;
public MagicPowerToughness(final int aPower,final int aToughness) {
power = aPower;
toughness = aToughness;
}
public int power() {
return power;
}
@ -17,34 +17,34 @@ public class MagicPowerToughness {
public int toughness() {
return toughness;
}
public int getPositivePower() {
return power>0?power:0;
}
public int getPositiveToughness() {
return toughness>0?toughness:0;
}
public void add(final MagicPowerToughness pt) {
power += pt.power;
toughness += pt.toughness;
}
public void add(final int pAmount, final int tAmount) {
power += pAmount;
toughness += tAmount;
}
public void set(final int pAmount, final int tAmount) {
power = pAmount;
toughness = tAmount;
}
public void setPower(final int tAmount) {
power = tAmount;
}
public void setToughness(final int tAmount) {
toughness = tAmount;
}

View File

@ -5,7 +5,7 @@ import magic.MersenneTwisterFast;
public class MagicRandom {
private static final MersenneTwisterFast RNG;
static {
final String seedStr = System.getProperty("rndSeed");
if (seedStr != null) {
@ -17,7 +17,7 @@ public class MagicRandom {
}
private MagicRandom() {}
public static int nextInt(final int n) {
return RNG.nextInt(n);
}

View File

@ -8,7 +8,7 @@ public enum MagicRarity {
Mythic_Rare('M');
public static final int length = values().length;
private final char c;
private MagicRarity(final char c) {
@ -22,7 +22,7 @@ public enum MagicRarity {
public String getName() {
return toString().replace('_',' ');
}
public static MagicRarity getRarity(final char c) {
for (final MagicRarity type : values()) {
if (type.c == c) {

View File

@ -7,17 +7,17 @@ public enum MagicStaticType {
Player("player"),
Opponent("opponent")
;
private final String name;
private MagicStaticType(final String name) {
this.name=name;
}
private String getName() {
return name;
}
public int getScore(final MagicPermanent scorePermanent) {
if (this==None) {
return 0;
@ -41,7 +41,7 @@ public enum MagicStaticType {
}
return score;
}
public static MagicStaticType getStaticTypeFor(final String name) {
for (final MagicStaticType type : values()) {
if (type.getName().equalsIgnoreCase(name)) {

Some files were not shown because too many files have changed in this diff Show More