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; } }