/* CVS: $Id: ResourceKnowledgeCatalog.java,v 1.30 2001/03/18 20:54:12 gvijf Exp $ */ package evolution.resources; import java.util.*; import java.io.*; import evolution.KnowledgeCatalog; import evolution.SystemMessage; import evolution.InfoList; import evolution.actions.ActionKnowledgeCatalog; import evolution.constructions.ConstructionKnowledgeCatalog; /** * The Resource KnowledgeCatalog. * @stereotype singleton */ public class ResourceKnowledgeCatalog extends KnowledgeCatalog { /** * Create a new KnowledgeCatalog from the given file. */ protected ResourceKnowledgeCatalog(String fileName) throws IOException, FileNotFoundException { super(fileName); parseResources(getProperty("Resources")); } /** * Return the instance of this singleton. */ public static ResourceKnowledgeCatalog getInst() { if(instance == null) throw new RuntimeException("ResourceKnowledgeCatalog was not initialized"); return instance; } /** * Initialize this singleton from the given file. */ public static void initialize(String fileName) throws FileNotFoundException, IOException { instance = new ResourceKnowledgeCatalog(fileName); } /** * Generate an info list of all available resources. */ public InfoList getResourcesInfo() { InfoList l = new InfoList(); Iterator it = getResourcesNames().iterator(); while(it.hasNext()) { String resName = (String) it.next(); Resource res = (Resource) getResource(resName); l.add(resName, InfoList.VALUE, res.getValue()); } return l; } /** * An map of all resources which are connected to the current world. * @return A Map of (String, Resource). */ public Map getResourceInstances() { return resourcesMap; } /** * Return the resource with the given name. */ public Resource getResource(String resName) { return (Resource) resourcesMap.get(resName); } /** * Parse the resources string. */ protected void parseResources(String resourcesString) { List r = split(" ", resourcesString); resourcesMap = new HashMap(); Resource energy = new Energy(); resourcesMap.put("Energy", energy); resources.add("Energy"); resourcesMap.put("Max Energy", new SimpleResource("Max Energy", 0, 0, Double.MAX_VALUE, Resource.LINEAR)); resources.add("Max Energy"); Iterator it = r.iterator(); while(it.hasNext()) { String part = (String) it.next(); String resourceName = extractName(part); if(resourcesMap.containsKey(resourceName)) throw new RuntimeException(resourceName + " is a reserved resource name or already in use, sorry dude"); Double value = new Double(getProperty(resourceName + ".init", "0")); Double min = new Double(getProperty(resourceName + ".min", "0")); Double max = new Double(getProperty(resourceName + ".max", Double.MAX_VALUE + "")); String curve = getProperty(resourceName + ".curve", "LINEAR"); Integer function = new Integer(Resource.LINEAR); if(curve.equals("SLOPE")) function = new Integer(Resource.SLOPE); else if(!curve.equals("LINEAR")) throw new RuntimeException("Unknow resource curve " + curve); try { // A resource with a real class underneath Class cl = dlClassForName("resources", resourceName); Resource res = (Resource) cl. getConstructor(new Class[] { double.class, double.class, double.class, int.class}). newInstance(new Object[] { value, min, max, function}); resourcesMap.put(resourceName, res); resources.add(resourceName); } catch(ClassNotFoundException e) { // a SimpleResource case Resource res = new SimpleResource(resourceName, value.doubleValue(), min.doubleValue(), max.doubleValue(), function.intValue()); resourcesMap.put(resourceName, res); resources.add(resourceName); } catch(Exception e) { throw new RuntimeException("No proper constructor for " + resourceName); } } } /** * Increase or decrease the named resource with the given value. */ public void modResource(String resourceName, double v) throws NotEnoughResourcesException { Resource res = (Resource) resourcesMap.get(resourceName); if(res == null) { System.err.println("Trying to modify unknown resource " + resourceName); return; } res.modValue(v); } /** * Increase or decrease the named resource with the given value. The amount of * increase or decrease will also depend on the resources that influence the * named action. */ public void modResource(String resourceName, String actionName, double v) throws NotEnoughResourcesException { double influencedValue = influencedByResources(actionName, v); Resource res = (Resource) resourcesMap.get(resourceName); if(res == null) { System.err.println("Trying to modify unknown resource " + resourceName); return; } res.modValue(influencedValue); } /** * Influence a value by all resources that influence the given action. */ public double influencedByResources(String actionName, double v) { List influencedBy = ActionKnowledgeCatalog.getInst().influencedBy(actionName); Iterator it = influencedBy.iterator(); double influencedValue = v; while (it.hasNext()) { String influenceName = (String) it.next(); Resource influenceRes = (Resource) resourcesMap.get(influenceName); if (influenceRes == null) System.err.println("Action " + actionName + "is influenced by an unknown resource " + influenceName); else influencedValue = influenceRes.influence(influencedValue); } return influencedValue; } /** * See from which resources we can fullfill the need for this one. * Returns a List of Object[]{Resource, Double}. */ public List transformsFrom(String resourceName) { List result = new ArrayList(); List l = split(" ", getProperty(resourceName + ".from", "")); Iterator it = l.iterator(); while(it.hasNext()) { String e = (String) it.next(); String resName = extractName(e); Resource res = (Resource) resourcesMap.get(resName); Double ratio = extractValue(e); Object[] o = new Object[]{res, ratio}; result.add(o); } return result; } /** * Is the named resource a temporary one? */ public boolean isTemporary(String resourceName) { return (new Boolean(getProperty(resourceName + ".temporary", "false"))).booleanValue(); } /** * Reset all temporary resources to their minimum. */ public void resetTemporaries() { Iterator it = getResourcesNames().iterator(); while(it.hasNext()) { String resName = (String) it.next(); if(isTemporary(resName)) { Resource r = getResource(resName); try { r.setValue(r.getMin()); } catch(NotEnoughResourcesException e) { } } } } /** * Set all the temporary resources. * @param max A (String, Double) Map, where the String is the name * of the resource and the Double is the maximum producable. * @param percentage The percentage we have to set of the maximum * for each temporary resource. */ public void setTemporaries(Map max, double percentage) { Iterator it = getResourcesNames().iterator(); while(it.hasNext()) { String resName = (String) it.next(); if(isTemporary(resName)) { Resource r = getResource(resName); try { r.setValue(((Double) max.get(resName)).doubleValue() * percentage); } catch(NotEnoughResourcesException e) { } } } } /** * Get the current world resources as a (String, Double) Map. */ public Map getResourcesStringDoubleMap() { Map result = new HashMap(); Iterator it = getResourcesNames().iterator(); while(it.hasNext()) { String resName = (String) it.next(); result.put(resName, new Double(getResource(resName).getValue())); } return result; } /** * Set the worldresources. * @param resMap A Map of (String, Double). */ public void setResources(Map resMap) { Iterator it = resMap.keySet().iterator(); while(it.hasNext()) { String name = (String) it.next(); Double value = (Double) resMap.get(name); try { getResource(name).setValue(value.doubleValue()); } catch(NotEnoughResourcesException e) { } } } /** * Add a percentage of a maximum to the world resources. * @param resMap A Map of (String, Double). * @param percentage The percentage to add. */ public void addResources(Map resMap, double percentage) { Iterator it = resMap.keySet().iterator(); while(it.hasNext()) { String name = (String) it.next(); Double value = (Double) resMap.get(name); Resource r = getResource(name); try { r.setValue(r.getValue() + value.doubleValue()*percentage); } catch(NotEnoughResourcesException e) { } } } /** * The names of the worldresources. * A List of Strings. */ public List getResourcesNames() { return resources; } /** * The names of the worldresources. * This is kept separate to keep the order of the worldresources. * A List of Strings. */ private List resources = new ArrayList(); /** * The worldresources. * A Map of (String, Resource). */ private Map resourcesMap; /** * Instance of the singleton. */ protected static ResourceKnowledgeCatalog instance = null; }