package stoppers; import java.lang.*; import java.io.*; import main.BetterTokenizer; import java.util.*; import main.Cell; import main.GeneralInput; import main.Model; /** Use this Stopper to combine together several simple Stoppers to look for more complicated patterns. MetaStop can return either the maximum value of any of its subsidiary stoppers or the average value, set using the tag &ValueMode (either "Max" or "Average"). You can have MetaStop stop a run when any one of the subsidiary Stoppers wants to stop, or only when all of them want to stop. Use the tag &StopMode (either "And" or "Or"). As with other Stoppers you can also set a &StopTime and a &Cutoff score. */ public class MetaStop extends SimpleStop { final static int AND_MODE = 1; final static int OR_MODE = 2; final static int MAX_MODE = 1; final static int ADD_MODE = 2; int stopMode = AND_MODE; int valueMode = MAX_MODE; float stopTime = 1; Vector itsStoppers = new Vector(); float Cutoff = 1f; // No arg constructor for instantiating by name public MetaStop() { stopTime = 1; } public boolean stop(float time) { boolean done; if(stopMode == AND_MODE) done = true; else done = false; for(Enumeration enum = itsStoppers.elements(); enum.hasMoreElements();) { SimpleStop a_stop = (SimpleStop)enum.nextElement(); try { boolean ret = a_stop.stop(time); if(stopMode == AND_MODE && !ret) done = false; else if(stopMode == OR_MODE && ret) done = true; } catch(Exception e) { System.out.println("Problem with stopping condition: " + e.toString()); } } return done; } public void setCutoff(float c) { Cutoff = c; for(Enumeration enum = itsStoppers.elements(); enum.hasMoreElements();) ((SimpleStop)enum.nextElement()).setCutoff(c); } public float getScore() { score = 0; if(valueMode == ADD_MODE) { for(Enumeration enum = itsStoppers.elements(); enum.hasMoreElements();) { score += ((SimpleStop)enum.nextElement()).getScore(); } } else { for(Enumeration enum = itsStoppers.elements(); enum.hasMoreElements();) { float next_val = ((SimpleStop)enum.nextElement()).getScore(); if(next_val > score) score = next_val; } } return score; } public boolean didPass() { score = getScore(); if(score <= Cutoff) return true; else return false; } public boolean didPass(float s) { if(s <= Cutoff) return true; else return false; } public void reset() { for(Enumeration enum = itsStoppers.elements(); enum.hasMoreElements();) ((SimpleStop)enum.nextElement()).reset(); } public void loadParameters(BetterTokenizer tokenizer) throws Exception { super.loadParameters(tokenizer); setCutoff(Cutoff); } protected void loadParameter(String info, BetterTokenizer tokenizer) throws Exception { if(info.equals("StopTime")) { GeneralInput.nextToken(tokenizer); stopTime = (float)tokenizer.nval; } else if(info.equals("StopMode")) { GeneralInput.nextToken(tokenizer); if(tokenizer.sval.equals("And")) stopMode = AND_MODE; else stopMode = OR_MODE; } else if(info.equals("ValueMode")) { GeneralInput.nextToken(tokenizer); if(tokenizer.sval.equals("Max")) valueMode = MAX_MODE; else valueMode = ADD_MODE; } else if(info.equals("Stopper")) { GeneralInput.nextToken(tokenizer); String stopper_name = tokenizer.sval; Class c = Class.forName("stoppers." + stopper_name); SimpleStop stopper = (SimpleStop)c.newInstance(); stopper.init(model); itsStoppers.addElement(stopper); stopper.loadParameters(tokenizer); } else if(info.equals("Cutoff")) { GeneralInput.nextToken(tokenizer); Cutoff = (float)tokenizer.nval; if(Cutoff < 0.0f || Cutoff > 1.0f) throw new Exception("Stopper: bad Cutoff"); } } public float getStopTime() { return stopTime; } public void setStopTime(float newtime) { stopTime = newtime; } }