From 5fdfe987aedad16fcad02db6be3d922dbd798555 Mon Sep 17 00:00:00 2001 From: jendave Date: Sat, 6 Aug 2011 05:37:35 +0000 Subject: [PATCH] - Improved the AI of Wrath of God and Damnation by considering indestructible. - Added getNotKeyword (to filter out cards with certain keywords) to Cardlist.java. - More elegant implementation of Mirror Gallery. --- .gitattributes | 2 +- src/forge/CardFactory.java | 2 + src/forge/CardList.java | 543 +++++++++++++++++++------------------ src/forge/GameAction.java | 13 +- 4 files changed, 282 insertions(+), 278 deletions(-) diff --git a/.gitattributes b/.gitattributes index 4db677732c9..042e73a93c6 100644 --- a/.gitattributes +++ b/.gitattributes @@ -380,7 +380,7 @@ src/forge/CardFactory_Equipment.java -text svneol=native#text/plain src/forge/CardFactory_Lands.java -text svneol=native#text/plain src/forge/CardFactory_Planeswalkers.java -text svneol=native#text/plain src/forge/CardFilter.java -text svneol=native#text/plain -src/forge/CardList.java svneol=native#text/plain +src/forge/CardList.java -text svneol=native#text/plain src/forge/CardListFilter.java svneol=native#text/plain src/forge/CardListUtil.java svneol=native#text/plain src/forge/CardShopTableModel.java -text svneol=native#text/plain diff --git a/src/forge/CardFactory.java b/src/forge/CardFactory.java index 302c9045cbd..8e2bab6616a 100644 --- a/src/forge/CardFactory.java +++ b/src/forge/CardFactory.java @@ -9896,7 +9896,9 @@ public class CardFactory implements NewConstants { CardList computer = new CardList(AllZone.Computer_Play.getCards()); human = human.getType("Creature"); + human = human.getNotKeyword("Indestructible"); computer = computer.getType("Creature"); + computer = computer.getNotKeyword("Indestructible"); // the computer will at least destroy 2 more human creatures return AllZone.Phase.getPhase().equals(Constant.Phase.Main2) && diff --git a/src/forge/CardList.java b/src/forge/CardList.java index c85c08462c6..6e8e0a607b4 100644 --- a/src/forge/CardList.java +++ b/src/forge/CardList.java @@ -1,267 +1,276 @@ - -package forge; - - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; - - -public class CardList implements Iterable { - - public Iterator iterator() { - return list.iterator(); - } - - private ArrayList list = new ArrayList(); - - //private LinkedList list = new LinkedList(); - - public CardList() {} - - public CardList(Card... c) { - addAll(c); - } - - public CardList(Object[] c) { - addAll(c); - } - -// cardColor is like "R" or "G", returns a new CardList that is a subset of current CardList - public CardList getColor(String cardColor) { - CardList c = new CardList(); - Card card; - for(int i = 0; i < size(); i++) { - card = getCard(i); - - if(-1 < card.getManaCost().indexOf(cardColor)) //hopefully this line works - c.add(getCard(i)); - } - return c; - }//getColor() - - public void reverse() { - Collections.reverse(list); - } - - public boolean equals(Object a) { - if(a instanceof CardList){ - CardList b = (CardList)a; - if(list.size() != b.size()) return false; - - for(int i = 0; i < list.size(); i++) - if(!list.get(i).equals(b.get(i))) return false; - - return true; - } else return false; - } - - //removes one copy of that card - public void remove(final String cardName) { - CardList find = this.filter(new CardListFilter() { - public boolean addCard(Card c) { - return c.getName().equals(cardName); - } - }); - - if(0 < find.size()) this.remove(find.get(0)); - else throw new RuntimeException("CardList : remove(String cardname), error - card name not found: " - + cardName + " - contents of Arraylist:" + list); - - }//remove(String cardName) - - public int size() { - return list.size(); - } - - public void add(Card c) { - list.add(c); - } - - public void add(int n, Card c) { - list.add(n, c); - } - - /** - * add(CardList) - lets you add one CardList to another directly - * @param in - CardList to add to the current CardList - */ - public void add(CardList in) { - addAll(in.toArray()); - } - - public boolean contains(Card c) { - return list.contains(c); - } - - //probably remove getCard() in the future - public Card getCard(int index) { - return list.get(index); - } - - public Card get(int i) { - return getCard(i); - } - - public void addAll(Object c[]) { - for(int i = 0; i < c.length; i++) - list.add((Card) c[i]); - } - - public boolean containsName(Card c) { - return containsName(c.getName()); - } - - public boolean containsName(String name) { - for(int i = 0; i < size(); i++) - if(getCard(i).getName().equals(name)) return true; - - return false; - } - - //returns new subset of all the cards with the same name - public CardList getName(String name) { - CardList c = new CardList(); - - for(int i = 0; i < size(); i++) - if(getCard(i).getName().equals(name)) c.add(getCard(i)); - - return c; - } - - public CardList getImageName(String name) { - CardList c = new CardList(); - - for(int i = 0; i < size(); i++) - if(getCard(i).getImageName().equals(name)) c.add(getCard(i)); - - return c; - } - - //cardType is like "Land" or "Goblin", returns a new CardList that is a subset of current CardList - public CardList getType(String cardType) { - CardList c = new CardList(); - Card card; - for(int i = 0; i < size(); i++) { - card = getCard(i); - if(card.getType().contains(cardType) - || ((card.isCreature() || (card.isTribal() && !cardType.equals("Creature"))) - && !cardType.equals("Legendary") && !cardType.equals("Planeswalker") - && !cardType.equals("Basic") && !cardType.equals("Enchantment") - && !cardType.equals("Land") && !cardType.equals("Sorcery") - && !cardType.equals("Instant") && !cardType.equals("Artifact") - && !cardType.equals("Plains") && !cardType.equals("Mountain") - && !cardType.equals("Island") && !cardType.equals("Forest") - && !cardType.equals("Swamp") && card.getKeyword().contains("Changeling"))) //changelings, see Lorwyn FAQ - c.add(getCard(i)); - } - return c; - }//getType() - - public CardList getKeyword(final String keyword) { - return this.filter(new CardListFilter() { - public boolean addCard(Card c) { - return c.getKeyword().contains(keyword); - } - }); - } - - public CardList filter(CardListFilter f) { - CardList c = new CardList(); - for(int i = 0; i < size(); i++) - if(f.addCard(getCard(i))) c.add(getCard(i)); - - return c; - } - - public final Card[] toArray() { - Card[] c = new Card[list.size()]; - list.toArray(c); - return c; - } - - @Override - public String toString() { - return list.toString(); - } - - public boolean isEmpty() { - return list.isEmpty(); - } - - public Card remove(int i) { - return list.remove(i); - } - - public void remove(Card c) { - list.remove(c); - } - - public void clear() { - list.clear(); - } - - public void shuffle() { - Collections.shuffle(list, MyRandom.random); - Collections.shuffle(list, MyRandom.random); - Collections.shuffle(list, MyRandom.random); - } - - public void sort(Comparator c) { - Collections.sort(list, c); - } - - public CardList getValidCards(String Restrictions[]) { - CardList tmpList = new CardList(toArray()); - CardList retList = new CardList(); - - for(int i = 0; i < Restrictions.length; i++) { - String incR[] = Restrictions[i].split("\\."); // Inclusive restrictions are Card types - - if(!incR[0].equals("Permanent")) // Since the cards don't actually say "Permanent" - tmpList = getType(incR[0]); - - if(incR.length > 1) { - final String excR = incR[1]; - tmpList = tmpList.filter(new CardListFilter() { - public boolean addCard(Card c) { - boolean r = true; - String exR[] = excR.split("\\+"); // Exclusive Restrictions are ... - for(int j = 0; j < exR.length; j++) { - if(exR[j].contains("White") - || // ... Card colors - exR[j].contains("Blue") || exR[j].contains("Black") || exR[j].contains("Red") - || exR[j].contains("Green") || exR[j].contains("Colorless")) if(exR[j].startsWith("non")) r = r - && (!CardUtil.getColors(c).contains(exR[j].substring(3).toLowerCase())); - else r = r && (CardUtil.getColors(c).contains(exR[j].toLowerCase())); - else if(exR[j].contains("MultiColor")) // ... Card is multicolored - if(exR[j].startsWith("non")) r = r && (CardUtil.getColors(c).size() == 1); - else r = r && (CardUtil.getColors(c).size() > 1); - else if(exR[j].contains("with")) // ... Card keywords - if(exR[j].startsWith("without")) r = r - && (!c.getKeyword().contains(exR[j].substring(7))); - else r = r && (c.getKeyword().contains(exR[j].substring(4))); - //TODO: converted mana cost - //TODO: tapped - //TODO: enchanted - //TODO: enchanting - //TODO: token - //TODO: counters - else if(exR[j].startsWith("named")) //by name - r = r && (c.getName().equals(exR[j].substring(6))); - else if(exR[j].startsWith("non")) // ... Other Card types - r = r && (!c.getType().contains(exR[j].substring(3))); - else r = r && (c.getType().contains(exR[j])); - } - return r; - } - }); - } - retList.addAll(tmpList.toArray()); - } - return retList; - }//getValidCards - - -} + +package forge; + + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; + + +public class CardList implements Iterable { + + public Iterator iterator() { + return list.iterator(); + } + + private ArrayList list = new ArrayList(); + + //private LinkedList list = new LinkedList(); + + public CardList() {} + + public CardList(Card... c) { + addAll(c); + } + + public CardList(Object[] c) { + addAll(c); + } + +// cardColor is like "R" or "G", returns a new CardList that is a subset of current CardList + public CardList getColor(String cardColor) { + CardList c = new CardList(); + Card card; + for(int i = 0; i < size(); i++) { + card = getCard(i); + + if(-1 < card.getManaCost().indexOf(cardColor)) //hopefully this line works + c.add(getCard(i)); + } + return c; + }//getColor() + + public void reverse() { + Collections.reverse(list); + } + + public boolean equals(Object a) { + if(a instanceof CardList){ + CardList b = (CardList)a; + if(list.size() != b.size()) return false; + + for(int i = 0; i < list.size(); i++) + if(!list.get(i).equals(b.get(i))) return false; + + return true; + } else return false; + } + + //removes one copy of that card + public void remove(final String cardName) { + CardList find = this.filter(new CardListFilter() { + public boolean addCard(Card c) { + return c.getName().equals(cardName); + } + }); + + if(0 < find.size()) this.remove(find.get(0)); + else throw new RuntimeException("CardList : remove(String cardname), error - card name not found: " + + cardName + " - contents of Arraylist:" + list); + + }//remove(String cardName) + + public int size() { + return list.size(); + } + + public void add(Card c) { + list.add(c); + } + + public void add(int n, Card c) { + list.add(n, c); + } + + /** + * add(CardList) - lets you add one CardList to another directly + * @param in - CardList to add to the current CardList + */ + public void add(CardList in) { + addAll(in.toArray()); + } + + public boolean contains(Card c) { + return list.contains(c); + } + + //probably remove getCard() in the future + public Card getCard(int index) { + return list.get(index); + } + + public Card get(int i) { + return getCard(i); + } + + public void addAll(Object c[]) { + for(int i = 0; i < c.length; i++) + list.add((Card) c[i]); + } + + public boolean containsName(Card c) { + return containsName(c.getName()); + } + + public boolean containsName(String name) { + for(int i = 0; i < size(); i++) + if(getCard(i).getName().equals(name)) return true; + + return false; + } + + //returns new subset of all the cards with the same name + public CardList getName(String name) { + CardList c = new CardList(); + + for(int i = 0; i < size(); i++) + if(getCard(i).getName().equals(name)) c.add(getCard(i)); + + return c; + } + + public CardList getImageName(String name) { + CardList c = new CardList(); + + for(int i = 0; i < size(); i++) + if(getCard(i).getImageName().equals(name)) c.add(getCard(i)); + + return c; + } + + //cardType is like "Land" or "Goblin", returns a new CardList that is a subset of current CardList + public CardList getType(String cardType) { + CardList c = new CardList(); + Card card; + for(int i = 0; i < size(); i++) { + card = getCard(i); + if(card.getType().contains(cardType) + || ((card.isCreature() || (card.isTribal() && !cardType.equals("Creature"))) + && !cardType.equals("Legendary") && !cardType.equals("Planeswalker") + && !cardType.equals("Basic") && !cardType.equals("Enchantment") + && !cardType.equals("Land") && !cardType.equals("Sorcery") + && !cardType.equals("Instant") && !cardType.equals("Artifact") + && !cardType.equals("Plains") && !cardType.equals("Mountain") + && !cardType.equals("Island") && !cardType.equals("Forest") + && !cardType.equals("Swamp") && card.getKeyword().contains("Changeling"))) //changelings, see Lorwyn FAQ + c.add(getCard(i)); + } + return c; + }//getType() + + public CardList getKeyword(final String keyword) { + return this.filter(new CardListFilter() { + public boolean addCard(Card c) { + return c.getKeyword().contains(keyword); + } + }); + } + + public CardList getNotKeyword(final String keyword) { + return this.filter(new CardListFilter() { + public boolean addCard(Card c) { + return !c.getKeyword().contains(keyword); + } + }); + } + + + public CardList filter(CardListFilter f) { + CardList c = new CardList(); + for(int i = 0; i < size(); i++) + if(f.addCard(getCard(i))) c.add(getCard(i)); + + return c; + } + + public final Card[] toArray() { + Card[] c = new Card[list.size()]; + list.toArray(c); + return c; + } + + @Override + public String toString() { + return list.toString(); + } + + public boolean isEmpty() { + return list.isEmpty(); + } + + public Card remove(int i) { + return list.remove(i); + } + + public void remove(Card c) { + list.remove(c); + } + + public void clear() { + list.clear(); + } + + public void shuffle() { + Collections.shuffle(list, MyRandom.random); + Collections.shuffle(list, MyRandom.random); + Collections.shuffle(list, MyRandom.random); + } + + public void sort(Comparator c) { + Collections.sort(list, c); + } + + public CardList getValidCards(String Restrictions[]) { + CardList tmpList = new CardList(toArray()); + CardList retList = new CardList(); + + for(int i = 0; i < Restrictions.length; i++) { + String incR[] = Restrictions[i].split("\\."); // Inclusive restrictions are Card types + + if(!incR[0].equals("Permanent")) // Since the cards don't actually say "Permanent" + tmpList = getType(incR[0]); + + if(incR.length > 1) { + final String excR = incR[1]; + tmpList = tmpList.filter(new CardListFilter() { + public boolean addCard(Card c) { + boolean r = true; + String exR[] = excR.split("\\+"); // Exclusive Restrictions are ... + for(int j = 0; j < exR.length; j++) { + if(exR[j].contains("White") + || // ... Card colors + exR[j].contains("Blue") || exR[j].contains("Black") || exR[j].contains("Red") + || exR[j].contains("Green") || exR[j].contains("Colorless")) if(exR[j].startsWith("non")) r = r + && (!CardUtil.getColors(c).contains(exR[j].substring(3).toLowerCase())); + else r = r && (CardUtil.getColors(c).contains(exR[j].toLowerCase())); + else if(exR[j].contains("MultiColor")) // ... Card is multicolored + if(exR[j].startsWith("non")) r = r && (CardUtil.getColors(c).size() == 1); + else r = r && (CardUtil.getColors(c).size() > 1); + else if(exR[j].contains("with")) // ... Card keywords + if(exR[j].startsWith("without")) r = r + && (!c.getKeyword().contains(exR[j].substring(7))); + else r = r && (c.getKeyword().contains(exR[j].substring(4))); + //TODO: converted mana cost + //TODO: tapped + //TODO: enchanted + //TODO: enchanting + //TODO: token + //TODO: counters + else if(exR[j].startsWith("named")) //by name + r = r && (c.getName().equals(exR[j].substring(6))); + else if(exR[j].startsWith("non")) // ... Other Card types + r = r && (!c.getType().contains(exR[j].substring(3))); + else r = r && (c.getType().contains(exR[j])); + } + return r; + } + }); + } + retList.addAll(tmpList.toArray()); + } + return retList; + }//getValidCards + + +} diff --git a/src/forge/GameAction.java b/src/forge/GameAction.java index 5b171935c30..88396ac555d 100644 --- a/src/forge/GameAction.java +++ b/src/forge/GameAction.java @@ -638,22 +638,15 @@ public class GameAction { private void destroyLegendaryCreatures() { ArrayList a = PlayerZoneUtil.getCardType(AllZone.Human_Play, "Legendary"); - a.addAll(PlayerZoneUtil.getCardType(AllZone.Computer_Play, "Legendary")); - - CardList Mirror_Gallery = new CardList(); // Mirror Gallery suppresses the Legend rule - Mirror_Gallery.addAll(AllZone.Human_Play.getCards()); - Mirror_Gallery.addAll(AllZone.Computer_Play.getCards()); - Mirror_Gallery = Mirror_Gallery.getName("Mirror Gallery"); + a.addAll(PlayerZoneUtil.getCardType(AllZone.Computer_Play, "Legendary")); - while(!a.isEmpty() && Mirror_Gallery.isEmpty()) { + while(!a.isEmpty() && !isCardInPlay("Mirror Gallery")) { // Mirror Gallery suppresses the Legend rule ArrayList b = getCardsNamed(a, (a.get(0)).getName()); a.remove(0); if(1 < b.size()) { for(int i = 0; i < b.size(); i++) - AllZone.GameAction.sacrificeDestroy(b.get(i)); - - + AllZone.GameAction.sacrificeDestroy(b.get(i)); } } }//destroyLegendaryCreatures()