From 879f1ddb97bc4e933bac10f43b1058f41150595d Mon Sep 17 00:00:00 2001 From: jendave Date: Sat, 6 Aug 2011 02:39:04 +0000 Subject: [PATCH] Card parsing class I'm working on --- .gitattributes | 1 + src/CardParser.java | 195 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 196 insertions(+) create mode 100644 src/CardParser.java diff --git a/.gitattributes b/.gitattributes index ef6588e982b..9ed8aef3a70 100644 --- a/.gitattributes +++ b/.gitattributes @@ -51,6 +51,7 @@ src/CardList.java svneol=native#text/plain src/CardListFilter.java svneol=native#text/plain src/CardListUtil.java svneol=native#text/plain src/CardPanel.java svneol=native#text/plain +src/CardParser.java svneol=native#text/plain src/CardUtil.java svneol=native#text/plain src/Combat.java svneol=native#text/plain src/CombatPlaneswalker.java svneol=native#text/plain diff --git a/src/CardParser.java b/src/CardParser.java new file mode 100644 index 00000000000..91c4b46e3e6 --- /dev/null +++ b/src/CardParser.java @@ -0,0 +1,195 @@ +import java.io.*; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.*; +public class CardParser { + enum name + { + EXIT, MAKE, SET, GET, INPUT, ADD, PUT, IF, PAROPEN; + public String toString(){return name().charAt(0) + name().toLowerCase().substring(1);} + } + HashMap parseCommand = new HashMap(); + public void init()//call where appropriate + { + parseCommand.put("{", name.PAROPEN); + for (name n : name.values()) + if(!n.toString().equals("Paropen")) + parseCommand.put(n.toString(), n); + } + static HashMap> parseClass; + static HashMap, String> unParseClass; + static HashMap parseSet; + static HashMap parseGet; + static HashMap parseIf; + static HashMap parseZone; + ArrayList all; + HashMap labels; + public Card getNextCard(BufferedReader reader) throws IOException + { + labels.clear(); + final Card res = new Card(); + res.setName(reader.readLine()); + all.add(res); + labels.put("maincard", 0); + parseCommand(reader, true).execute(); + return res; + } + + @SuppressWarnings({ "serial", "unchecked" }) + Command parseCommand(BufferedReader reader, boolean linesleft) throws IOException + { + final String command = reader.readLine().trim(); + if(command.isEmpty() || command.equals ("}")) + { + linesleft = false; + return Command.Blank; + } + final String[] pieces = command.split(" "); + switch(parseCommand.get(pieces[0])){ + case EXIT: return null; + case PAROPEN: + boolean cont = true; + final CommandList todo = new CommandList(); + while(cont) todo.add(parseCommand(reader, cont)); + return new Command(){ public void execute() + { + for(Command c : todo) + { + if(c != null) + c.execute(); + else + break; + } + }}; + + case MAKE: + String varname = command.split(" named ")[1]; + final int where = all.size() - 1; + labels.put(varname, where); + return new Command(){ public void execute() + { + try { + all.set(where, parseClass.get(command.substring(5).split(" named ")[0]).newInstance()); + } catch (InstantiationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + //where parseClass is a Map containing values like <"activated ability", Ability.Class> + } + }; + + //where unParseClass is a Map containing values like + case SET: + final Object destObject = fetchValue(pieces[1]); + final String setMethod = unParseClass.get(destObject.getClass()) + command.split(" to ")[0].substring(command.indexOf(" ", 4)); + final Object sourceValue = fetchValue(command.split(" to ")[1]); + return new Command(){ public void execute(){ try { + parseSet.get(setMethod).invoke(destObject, sourceValue); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvocationTargetException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + }}}; + //where parseSet is a Map containing values like <"card name", Card.setName> + + case GET: + final Object whose_2 = fetchValue(pieces[1]); + final String how_2 = unParseClass.get(whose_2.getClass()) + command.split(" to ")[0].substring(command.indexOf(" ", 4)); + String label2 = command.split(" named ")[1]; + final int where_2 = all.size() - 1; + labels.put(label2, where_2); + final Object what_2 = fetchValue(command.split(" to ")[1]); + return new Command(){ public void execute(){ try { + all.set(where_2, parseGet.get(how_2).invoke(whose_2, what_2)); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvocationTargetException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + }}}; + //where parseGet is a Map containing values like <"spell or ability mana cost", SpellAbility.setManaCost> + + case INPUT: + final Object in = fetchValue(pieces[1]); + if(!(in instanceof Input)) throw new IllegalArgumentException("Error : " + command.split(" named ")[1] + " is not an Input"); + return new Command(){ public void execute(){ AllZone.InputControl.setInput((Input)in);}}; + + case ADD: + final SpellAbility sa = (SpellAbility)fetchValue(pieces[1]); + final Card card = (Card)fetchValue(command.split(" to ")[1]); + return new Command(){ public void execute(){ card.addSpellAbility(sa);}};//TODO: Counters? + + case PUT: + final Card card_2 = (Card)fetchValue(pieces[1]); + final PlayerZone zone = parseZone.get(command.split(" in ")[1]); + //where parseZone is a Map ... i.e. <"battlefield", AllZone.Play> + return new Command(){ public void execute(){AllZone.GameAction.moveTo(zone, card_2);}}; + + case IF: + final Object whose_3 = fetchValue(pieces[1]); + final Object arg1 = fetchValue(pieces[1]); + final boolean not = pieces[2].equals("not"); + final Command res = parseCommand(reader, linesleft); + final Method todo_2 = parseIf.get(unParseClass.get(whose_3.getClass()) + command.substring(command.indexOf(" ", 3) + (not ? 0 : 4))); + //where parseIf is a Map... <"input equals", Input.equals>, <"card in play", Card.inPlay> + Class[] need = todo_2.getParameterTypes(); + final Object[] args = new Object[need.length]; + if(need.length == 1) args[1] = fetchValue(pieces[pieces.length-1]); + return new Command(){ public void execute(){ + try { + if(todo_2.invoke(arg1, args).equals(false) ^ not) res.execute(); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InvocationTargetException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + }}}; + default: + throw new IllegalArgumentException("Command not supported: " + command); + } + } + + Object fetchValue(String label){return fetchValue(label, Object.class);} + @SuppressWarnings("serial") + Object fetchValue(final String label, Class type) + { + if(labels.containsKey(label)) + return all.get(labels.get(label)); + if(label.contains("\"")) + { + if(String.class.isInstance(type)) + return label.substring(1, label.length() - 1); + if(CommandArgs.class.isInstance(type)); + return new CommandArgs(){public void execute(Object o) + { + if(o instanceof ArrayList && ((ArrayList)o).size() == 2 && ((ArrayList)o).get(0) instanceof SpellAbility && ((ArrayList)o).get(1) instanceof Card) + { + SpellAbility sa = ((SpellAbility)((ArrayList)o).get(0)); + Card c= ((Card)((ArrayList)o).get(1)); + CardList cl = new CardList(); + cl.add(c); + String[] s = {label}; + if(!cl.getValidCards(s).isEmpty())//TODO: Bettter way? + sa.setTargetCard(c); + } + }}; + } + return all.get(labels.get(label)); //i.e. throw exception + } +}