package forge;
import forge.card.mana.ManaCost;
import forge.card.spellability.SpellAbility;
import forge.card.spellability.SpellAbilityList;
import forge.properties.ForgeProps;
import forge.properties.NewConstants;
import java.io.File;
import java.util.*;
/**
* <p>CardUtil class.</p>
*
* @author Forge
* @version $Id: $
*/
public class CardUtil {
/** Constant <code>r</code> */
public final static Random r = MyRandom.random;
/**
* <p>getRandomIndex.</p>
*
* @param o an array of {@link java.lang.Object} objects.
* @return a int.
*/
public static int getRandomIndex(Object[] o) {
if (o == null || o.length == 0) throw new RuntimeException(
"CardUtil : getRandomIndex() argument is null or length is 0");
return r.nextInt(o.length);
}
/**
* <p>getRandom.</p>
*
* @param o an array of {@link forge.Card} objects.
* @return a {@link forge.Card} object.
*/
public static Card getRandom(Card[] o) {
return o[getRandomIndex(o)];
}
/**
* <p>getRandomIndex.</p>
*
* @param list a {@link forge.card.spellability.SpellAbilityList} object.
* @return a int.
*/
public static int getRandomIndex(SpellAbilityList list) {
if (list == null || list.size() == 0) throw new RuntimeException(
"CardUtil : getRandomIndex(SpellAbilityList) argument is null or length is 0");
return r.nextInt(list.size());
}
/**
* <p>getRandomIndex.</p>
*
* @param c a {@link forge.CardList} object.
* @return a int.
*/
public static int getRandomIndex(CardList c) {
return r.nextInt(c.size());
}
//returns Card Name (unique number) attack/defense
//example: Big Elf (12) 2/3
/**
* <p>toText.</p>
*
* @param c a {@link forge.Card} object.
* @return a {@link java.lang.String} object.
*/
public static String toText(Card c) {
return c.getName() + " (" + c.getUniqueNumber() + ") " + c.getNetAttack() + "/" + c.getNetDefense();
}
/**
* <p>toCard.</p>
*
* @param col a {@link java.util.Collection} object.
* @return an array of {@link forge.Card} objects.
*/
public static Card[] toCard(Collection<Card> col) {
Object o[] = col.toArray();
Card c[] = new Card[o.length];
for (int i = 0; i < c.length; i++) {
Object swap = o[i];
if (swap instanceof Card) c[i] = (Card) o[i];
else throw new RuntimeException("CardUtil : toCard() invalid class, should be Card - "
+ o[i].getClass() + " - toString() - " + o[i].toString());
}
return c;
}
/**
* <p>toCard.</p>
*
* @param list a {@link java.util.ArrayList} object.
* @return an array of {@link forge.Card} objects.
*/
public static Card[] toCard(ArrayList<Card> list) {
Card[] c = new Card[list.size()];
list.toArray(c);
return c;
}
/**
* <p>toList.</p>
*
* @param c an array of {@link forge.Card} objects.
* @return a {@link java.util.ArrayList} object.
*/
public static ArrayList<Card> toList(Card c[]) {
ArrayList<Card> a = new ArrayList<Card>();
for (int i = 0; i < c.length; i++)
a.add(c[i]);
return a;
}
//returns "G", longColor is Constant.Color.Green and the like
/**
* <p>getShortColor.</p>
*
* @param longColor a {@link java.lang.String} object.
* @return a {@link java.lang.String} object.
*/
public static String getShortColor(String longColor) {
Map<String, String> map = new HashMap<String, String>();
map.put(Constant.Color.Black, "B");
map.put(Constant.Color.Blue, "U");
map.put(Constant.Color.Green, "G");
map.put(Constant.Color.Red, "R");
map.put(Constant.Color.White, "W");
Object o = map.get(longColor);
if (o == null) throw new RuntimeException("CardUtil : getShortColor() invalid argument - " + longColor);
return (String) o;
}
/**
* <p>isColor.</p>
*
* @param c a {@link forge.Card} object.
* @param col a {@link java.lang.String} object.
* @return a boolean.
*/
public static boolean isColor(Card c, String col) {
ArrayList<String> list = getColors(c);
return list.contains(col);
}
/**
* <p>getColors.</p>
*
* @param c a {@link forge.Card} object.
* @return a {@link java.util.ArrayList} object.
*/
public static ArrayList<String> getColors(Card c) {
return c.determineColor().toStringArray();
}
/**
* <p>getOnlyColors.</p>
*
* @param c a {@link forge.Card} object.
* @return a {@link java.util.ArrayList} object.
*/
public static ArrayList<String> getOnlyColors(Card c) {
String m = c.getManaCost();
Set<String> colors = new HashSet<String>();
for (int i = 0; i < m.length(); i++) {
switch (m.charAt(i)) {
case ' ':
break;
case 'G':
colors.add(Constant.Color.Green);
break;
case 'W':
colors.add(Constant.Color.White);
break;
case 'B':
colors.add(Constant.Color.Black);
break;
case 'U':
colors.add(Constant.Color.Blue);
break;
case 'R':
colors.add(Constant.Color.Red);
break;
}
}
for (String kw : c.getKeyword())
if (kw.startsWith(c.getName() + " is ") || kw.startsWith("CARDNAME is "))
for (String color : Constant.Color.Colors)
if (kw.endsWith(color + "."))
colors.add(color);
return new ArrayList<String>(colors);
}
/**
* <p>hasCardName.</p>
*
* @param cardName a {@link java.lang.String} object.
* @param list a {@link java.util.ArrayList} object.
* @return a boolean.
*/
public static boolean hasCardName(String cardName, ArrayList<Card> list) {
Card c;
boolean b = false;
for (int i = 0; i < list.size(); i++) {
c = list.get(i);
if (c.getName().equals(cardName)) {
b = true;
break;
}
}
return b;
}//hasCardName()
//probably should put this somewhere else, but not sure where
/**
* <p>getConvertedManaCost.</p>
*
* @param sa a {@link forge.card.spellability.SpellAbility} object.
* @return a int.
*/
static public int getConvertedManaCost(SpellAbility sa) {
return getConvertedManaCost(sa.getManaCost());
}
/**
* <p>getConvertedManaCost.</p>
*
* @param c a {@link forge.Card} object.
* @return a int.
*/
static public int getConvertedManaCost(Card c) {
if (c.isToken() && !c.isCopiedToken())
return 0;
return getConvertedManaCost(c.getManaCost());
}
/**
* <p>getConvertedManaCost.</p>
*
* @param manaCost a {@link java.lang.String} object.
* @return a int.
*/
static public int getConvertedManaCost(String manaCost) {
if (manaCost.equals("")) return 0;
ManaCost cost = new ManaCost(manaCost);
return cost.getConvertedManaCost();
}
/**
* <p>addManaCosts.</p>
*
* @param mc1 a {@link java.lang.String} object.
* @param mc2 a {@link java.lang.String} object.
* @return a {@link java.lang.String} object.
*/
static public String addManaCosts(String mc1, String mc2) {
String tMC = "";
Integer cl1, cl2, tCL;
String c1, c2, cc1, cc2;
c1 = mc1.replaceAll("[WUBRGSX]", "").trim();
c2 = mc2.replaceAll("[WUBRGSX]", "").trim();
if (c1.length() > 0)
cl1 = Integer.valueOf(c1);
else
cl1 = 0;
if (c2.length() > 0)
cl2 = Integer.valueOf(c2);
else
cl2 = 0;
tCL = cl1 + cl2;
cc1 = mc1.replaceAll("[0-9]", "").trim();
cc2 = mc2.replaceAll("[0-9]", "").trim();
tMC = tCL.toString() + " " + cc1 + " " + cc2;
//System.out.println("TMC:" + tMC);
return tMC.trim();
}
/**
* <p>getRelative.</p>
*
* @param c a {@link forge.Card} object.
* @param relation a {@link java.lang.String} object.
* @return a {@link forge.Card} object.
*/
static public Card getRelative(Card c, String relation) {
if (relation.equals("CARDNAME")) return c;
else if (relation.startsWith("enchanted ")) return c.getEnchanting().get(0);
else if (relation.startsWith("equipped ")) return c.getEquipping().get(0);
//else if(relation.startsWith("target ")) return c.getTargetCard();
else
throw new IllegalArgumentException("Error at CardUtil.getRelative: " + relation + "is not a valid relation");
}
/**
* <p>isACardType.</p>
*
* @param cardType a {@link java.lang.String} object.
* @return a boolean.
*/
public static boolean isACardType(String cardType) {
return getAllCardTypes().contains(cardType);
}
/**
* <p>getAllCardTypes.</p>
*
* @return a {@link java.util.ArrayList} object.
*/
public static ArrayList<String> getAllCardTypes() {
ArrayList<String> types = new ArrayList<String>();
//types.addAll(getCardTypes());
types.addAll(Constant.CardTypes.cardTypes[0].list);
//not currently used by Forge
types.add("Plane");
types.add("Scheme");
types.add("Vanguard");
return types;
}
/**
* <p>getCardTypes.</p>
*
* @return a {@link java.util.ArrayList} object.
*/
public static ArrayList<String> getCardTypes() {
ArrayList<String> types = new ArrayList<String>();
// types.add("Artifact");
// types.add("Creature");
// types.add("Enchantment");
// types.add("Instant");
// types.add("Land");
// types.add("Planeswalker");
// types.add("Sorcery");
// types.add("Tribal");
types.addAll(Constant.CardTypes.cardTypes[0].list);
return types;
}
/**
* <p>isASuperType.</p>
*
* @param cardType a {@link java.lang.String} object.
* @return a boolean.
*/
public static boolean isASuperType(String cardType) {
// return ( cardType.equals("Basic") || cardType.equals("Legendary")
// || cardType.equals("Snow") || cardType.equals("World"));
return (Constant.CardTypes.superTypes[0].list.contains(cardType));
}
/**
* <p>isASubType.</p>
*
* @param cardType a {@link java.lang.String} object.
* @return a boolean.
*/
public static boolean isASubType(String cardType) {
return (!isASuperType(cardType) && !isACardType(cardType));
}
// Check if a Type is a Creature Type (by excluding all other types)
/**
* <p>isACreatureType.</p>
*
* @param cardType a {@link java.lang.String} object.
* @return a boolean.
*/
public static boolean isACreatureType(String cardType) {
// return (!isACardType(cardType) && !isASuperType(cardType) && !isALandType(cardType)
// && !cardType.equals("Arcane") && !cardType.equals("Trap")
// && !cardType.equals("Aura") && !cardType.equals("Shrine")
// && !cardType.equals("Equipment") && !cardType.equals("Fortification"));
return (Constant.CardTypes.creatureTypes[0].list.contains(cardType));
}
/**
* <p>isALandType.</p>
*
* @param cardType a {@link java.lang.String} object.
* @return a boolean.
*/
public static boolean isALandType(String cardType) {
// return (isABasicLandType(cardType)
// || cardType.equals("Locus") || cardType.equals("Lair")
// || cardType.equals("Mine") || cardType.equals("Power-Plant")
// || cardType.equals("Tower") || cardType.equals("Urza's")
// || cardType.equals("Desert"));
return (Constant.CardTypes.landTypes[0].list.contains(cardType));
}
/**
* <p>isABasicLandType.</p>
*
* @param cardType a {@link java.lang.String} object.
* @return a boolean.
*/
public static boolean isABasicLandType(String cardType) {
// return (cardType.equals("Plains")
// || cardType.equals("Island") || cardType.equals("Swamp")
// || cardType.equals("Mountain") || cardType.equals("Forest"));
return (Constant.CardTypes.basicTypes[0].list.contains(cardType));
}
//this function checks, if duplicates of a keyword are not necessary (like flying, trample, etc.)
/**
* <p>isNonStackingKeyword.</p>
*
* @param keyword a {@link java.lang.String} object.
* @return a boolean.
*/
public static boolean isNonStackingKeyword(String keyword) {
/* return (
keyword.equals("Deathtouch") || keyword.equals("Defender")
|| keyword.equals("Double Strike") || keyword.equals("First Strike")
|| keyword.equals("Flash") || keyword.equals("Flying")
|| keyword.equals("Haste") || keyword.equals("Intimidate")
|| keyword.equals("Lifelink") || keyword.equals("Reach")
|| keyword.equals("Shroud") || keyword.equals("Trample")
|| keyword.equals("Vigilance") || keyword.equals("Horsemanship")
|| keyword.equals("Fear") || keyword.equals("Changeling")
|| keyword.equals("Wither") || keyword.equals("Infect"));*/
return Constant.Keywords.NonStackingList[0].list.contains(keyword);
}
/**
* <p>isStackingKeyword.</p>
*
* @param keyword a {@link java.lang.String} object.
* @return a boolean.
*/
public static boolean isStackingKeyword(String keyword) {
return !isNonStackingKeyword(keyword);
}
/**
* <p>buildFilename.</p>
*
* @param card a {@link forge.Card} object.
* @return a {@link java.lang.String} object.
*/
public static String buildFilename(Card card) {
File path = null;
if (card.isToken() && !card.isCopiedToken())
path = ForgeProps.getFile(NewConstants.IMAGE_TOKEN);
else
path = ForgeProps.getFile(NewConstants.IMAGE_BASE);
StringBuilder sbKey = new StringBuilder();
File f = null;
if (!card.getCurSetCode().equals("")) {
String nn = "";
if (card.getRandomPicture() > 0)
nn = Integer.toString(card.getRandomPicture());
//First try 3 letter set code with MWS filename format
sbKey.append(card.getCurSetCode() + "/");
sbKey.append(GuiDisplayUtil.cleanStringMWS(card.getName()) + nn + ".full");
f = new File(path, sbKey.toString() + ".jpg");
if (f.exists())
return sbKey.toString();
sbKey = new StringBuilder();
//Second, try 2 letter set code with MWS filename format
sbKey.append(SetInfoUtil.getSetCode2_SetCode3(card.getCurSetCode()) + "/");
sbKey.append(GuiDisplayUtil.cleanStringMWS(card.getName()) + nn + ".full");
f = new File(path, sbKey.toString() + ".jpg");
if (f.exists())
return sbKey.toString();
sbKey = new StringBuilder();
//Third, try 3 letter set code with Forge filename format
sbKey.append(card.getCurSetCode() + "/");
sbKey.append(GuiDisplayUtil.cleanString(card.getName()) + nn);
f = new File(path, sbKey.toString() + ".jpg");
if (f.exists())
return sbKey.toString();
sbKey = new StringBuilder();
}
//Last, give up with set images, go with the old picture type
sbKey.append(GuiDisplayUtil.cleanString(card.getImageName()));
if (card.getRandomPicture() > 1)
sbKey.append(card.getRandomPicture());
f = new File(path, sbKey.toString() + ".jpg");
if (f.exists())
return sbKey.toString();
sbKey = new StringBuilder();
//Really last-ditch effort, forget the picture number
sbKey.append(GuiDisplayUtil.cleanString(card.getImageName()));
f = new File(path, sbKey.toString() + ".jpg");
if (f.exists())
return sbKey.toString();
//if still no file, download if option enabled?
return "none";
}
/**
* <p>getWeightedManaCost.</p>
*
* @param manaCost a {@link java.lang.String} object.
* @return a double.
*/
public static double getWeightedManaCost(String manaCost) {
if (manaCost.equals("")) return 0;
ManaCost cost = new ManaCost(manaCost);
return cost.getWeightedManaCost();
}
/**
* <p>getShortColorsString.</p>
*
* @param colors a {@link java.util.ArrayList} object.
* @return a {@link java.lang.String} object.
*/
public static String getShortColorsString(ArrayList<String> colors) {
String colorDesc = "";
for (String col : colors) {
if (col.equalsIgnoreCase("White")) {
colorDesc += "W";
} else if (col.equalsIgnoreCase("Blue")) {
colorDesc += "U";
} else if (col.equalsIgnoreCase("Black")) {
colorDesc += "B";
} else if (col.equalsIgnoreCase("Red")) {
colorDesc += "R";
} else if (col.equalsIgnoreCase("Green")) {
colorDesc += "G";
} else if (col.equalsIgnoreCase("Colorless")) {
colorDesc = "C";
}
}
return colorDesc;
}
}