/* CVS: $Id: ActionKnowledgeCatalog.java,v 1.43 2001/03/18 19:16:33 gvijf Exp $ */ package evolution.actions; import java.util.*; import java.io.*; import evolution.*; import evolution.lands.*; import evolution.constructions.*; /** * The KnowledgeCatalog for evolution.actions. * @stereotype singleton */ public class ActionKnowledgeCatalog extends KnowledgeCatalog { /** * Create a new KnowledgeCatalog from the given file. */ protected ActionKnowledgeCatalog(String fileName) throws FileNotFoundException, IOException { super(fileName); parseActionTypes(getProperty("Actions")); parseDefaultActionType(getProperty("DefaultAction")); parseEnergyBufferActionTypes(getProperty("EnergyBufferActions")); } /** * Return the instance of this singleton. */ public static ActionKnowledgeCatalog getInst() { if(instance == null) throw new RuntimeException("ActionKnowledgeCatalog was not initialized"); return instance; } /** * Initialize this singleton from the given file. */ public static void initialize(String fileName) throws FileNotFoundException, IOException { instance = new ActionKnowledgeCatalog(fileName); } /** * The normal priority for this action. */ public double getPriority(Action action) { return (new Double(getProperty(action.getName() + ".priority", "1"))).doubleValue(); } /** * A map with as keys the resource and as value the amount the action uses. */ public Map usesResources(String actionName) { return makeStringDoubleMap(actionName + ".usesResources", ""); } /** * A map with as keys the landresource and as value the amount the * action uses. */ public Map usesLandResources(String actionName) { return makeStringDoubleMap(actionName + ".usesLandResources", ""); } /** * Which resource is transformed into which resource by a given action. * Returns a map with as key the name of the resource it transforms into and as * value an array with als first element the name of the resource * which is transformed and as second element a Double transformationvalue. */ //public Map transformsResources(String actionType) { // Map m = new HashMap(); // List lt = split(" ", getProperty(actionType + ".transformsResources", "")); // Iterator it = lt.iterator(); // while(it.hasNext()) { // String e = (String) it.next(); // List fromTo = split("-", extractName(e)); // Double value = extractValue(e); // if (! m.containsKey(fromTo.get(1))) { // Map n = new HashMap(); // //een hashmap met als sleutel de producerende resource en als waarde // //in welke verhouding er geproduceerd wordt // n.put(fromTo.get(0), value); // //een hasmap met als sleutel de geproduceerde resource (bvb energy) // //en als waarde een nieuw hashtabel die hierboven gedefinieerd is // m.put(fromTo.get(1), n); // } // else { // ((HashMap)m.get(fromTo.get(1))).put(fromTo.get(0), value); // } // } // return m; //} /** * A map with as keys the resource and as value the amount the action uses. */ public Map producesResources(String actionName) { return makeStringDoubleMap(actionName + ".producesResources", ""); } /** * A map with as keys the landresource and as value the amount the * action uses. */ public Map producesLandResources(String actionName) { return makeStringDoubleMap(actionName + ".producesLandResources", ""); } /** * Which resources are transformed into a given resource by a given construction? */ //public Object[] areTransformedInto(String resource, String actionType){ // Map map = this.getInst().transformsResources(actionType); // return (Object[]) map.get(resource); //} /** * Which resources are transformed into a given resource. */ //public List areTransformedInto(String resource) { // Iterator it = this.getInst().getActionTypes().iterator(); // List list = new ArrayList(); // while(it.hasNext()) { // String actionName = (String) it.next(); // list.add(areTransformedInto(resource, actionName)); // } // return list; //} /** * A list of resources by which this action is influenced. */ public List influencedBy(String actionName) { String property = getProperty(actionName + ".influencedBy", ""); if (property == null) return new ArrayList(); return split(" ", property); } /** * Check whether the given action must be explored or not. */ public boolean mustBeExplored(String actionName) { return (new Boolean(getProperty(actionName + ".explored", "true"))).booleanValue(); } /** * See if this action can be performed on the given square. * @param actionName Something like Resting, Fishing, ... */ public boolean canBePerformedOn(String actionName, SquareOfLand sq) { List landTypes = split(" ", getProperty(actionName + ".lands", "")); if(sq.isExplored()) { // check if there is a construction if(sq.getConstruction() != null) { // check if the action would transform the land // and ifso if the construction can stand on that land Object[] r = transformsLand(sq, actionName); if(((Boolean) r[0]).booleanValue()) { return landTypes.contains(sq.getLandType()) && ConstructionKnowledgeCatalog.getInst().canStandOnLandType( sq.getConstruction().getName(), (String) r[1]); } } return landTypes.contains(sq.getLandType()); } return !mustBeExplored(actionName) && landTypes.contains(sq.getLandType()); } /** * See if this action can perform better when the needed landresources * are high. */ public boolean isMaximizing(String actionName) { return (new Boolean(getProperty(actionName + ".maximizing", "true"))).booleanValue(); } /** * Does the given action transform the landtype of the given square? *
* Returns Object[] {
* Boolean transforms : does the action transform yes or no
* String toLand : the land type we transform to
* String detLandResource : the determening land resource
* Double limit : the limit the land resource should have
* to transform the land type
* Boolean lte : must the current value be less then equal
* than the limit
* Boolean gte : must the current value be greater then equal
* than the limit
*
*/
public Object[] transformsLand(SquareOfLand sq, String actionName) {
// FIXME: should be cashed!!!!
Boolean lte = new Boolean(false);
Boolean gte = new Boolean(false);
String toLand = null;
String detLandResource = null;
Double limit = new Double(0);
List l = split(" ", getProperty(actionName + ".transformsLand", ""));
Iterator it = l.iterator();
while(it.hasNext()) {
String e = (String) it.next();
String lands = extractName(e);
String fromLand = (String) split("-", lands).get(0);
if(fromLand.equals(sq.getLandType())) {
toLand = (String) split("-", lands).get(1);
detLandResource = (String) split("=", extractArgument(e)).get(0);
limit = new Double((String) split("=", extractArgument(e)).get(1));
if(producesLandResource(actionName, detLandResource) != null)
gte = new Boolean(true);
if(usesLandResource(actionName, detLandResource) != null)
lte = new Boolean(true);
return new Object[] {new Boolean(true), toLand, detLandResource, limit, lte, gte};
}
}
return new Object[] {new Boolean(false)};
}
/**
* Returns the amount produced by the given action of the given
* land resource.
* Returns null if the land resource is not produced by this action.
*/
public Double producesLandResource(String actionName, String resName) {
List lt = split(" ", getProperty(actionName + ".producesLandResources", ""));
Iterator it = lt.iterator();
while(it.hasNext()) {
String e = (String) it.next();
String res = extractName(e);
if(res.equals(resName))
return extractValue(e);
}
return null;
}
/**
* Returns the amount used by the given action of the given
* land resource.
* Returns null if the land resource is not used by this action.
*/
public Double usesLandResource(String actionName, String resName) {
List lt = split(" ", getProperty(actionName + ".usesLandResources", ""));
Iterator it = lt.iterator();
while(it.hasNext()) {
String e = (String) it.next();
String res = extractName(e);
if(res.equals(resName))
return extractValue(e);
}
return null;
}
/**
* A hash of resources/speeds for the given action.
*/
public Map reveals(Action action) {
return new HashMap();
}
/**
* Does the action with this name exist?
*/
public boolean actionExists(String actionName) {
return actionTypes.contains(actionName);
}
/**
* Instantiate the action with the given name on the given square.
* precondition: the actionName must be valid
*/
public Action instantiate(String actionName) {
if(!actionExists(actionName))
throw new RuntimeException(actionName + " is not a valid action name");
try {
// first try to dynamically load
Class c = dlClassForName("actions", actionName);
try {
return (Action) c.newInstance();
} catch(Exception e) {
throw new RuntimeException(actionName +
" does not have a proper default constructor");
}
} catch(ClassNotFoundException e) {
// if not dynamically loadable the action is completely defined
// by the config file
return new SimpleAction(actionName);
}
}
/**
* An info list with all possible actions in the game.
*/
public InfoList getActionsInfo() {
InfoList list = new InfoList();
List actionTypes = getActionTypes();
Iterator it = actionTypes.iterator();
while(it.hasNext()) {
String name = (String) it.next();
//if(!name.equals("Constructing"))
list.add(name, InfoList.STRING, name);
}
return list;
}
/**
* Return a list of all possible actions.
* This is a list of Strings.
*/
public List getActionTypes() {
return actionTypes;
}
/**
* Return a list of all possible actions while using the energy buffer.
* This is a list of Strings.
*/
public List getEnergyBufferActionTypes() {
return energyBufferActionTypes;
}
/**
* Return the the name for the default action.
*/
public String getDefaultActionType() {
return defaultActionType;
}
/**
* Return an instance of the default action type.
* This is cached version.
*/
public Action getDefaultAction() {
if(defaultAction == null)
defaultAction = instantiate(getDefaultActionType());
return defaultAction;
}
/**
* Parse a actiontypes string.
*/
protected void parseActionTypes(String actionTypesString) {
actionTypes = parseActionTypesInto(actionTypesString, null);
SystemMessage.message(actionTypes.size() + " actiontypes loaded");
}
/**
* Parse a energy buffer actiontypes string.
*/
protected void parseEnergyBufferActionTypes(String actionTypesString) {
energyBufferActionTypes = parseActionTypesInto(actionTypesString, actionTypes);
}
/**
* Parse the default actiontype string.
*/
protected void parseDefaultActionType(String actionTypeString) {
defaultActionType = actionTypeString;
if(defaultActionType == null)
throw new RuntimeException("No default actiontype found");
if(!actionTypes.contains(defaultActionType))
throw new RuntimeException("Default action type is not in the Actions property");
}
/**
* Parse a actiontypes string.
* @param retain A List of action names. If this is not null, only
* the specified actions will be extracted.
*/
protected List parseActionTypesInto(String actionTypesString, List retain) {
List lt = split(" ", actionTypesString);
Iterator it = lt.iterator();
List result = new ArrayList();
while(it.hasNext()) {
String type = (String) it.next();
if((retain == null) || retain.contains(type)) {
result.add(type);
}
}
return result;
}
/**
* An array of all the loaded actions.
* These are extracted from the properties list at construction.
* This is a list of Strings.
*/
private List actionTypes = new ArrayList();
/**
* The default actiontype.
* This is extracted from the properties list at construction.
*/
private String defaultActionType;
/**
* A cached version of an instantiated default action.
*/
private Action defaultAction;
/**
* The actiontypes that can be performed when using the EnergyBuffer.
* These are extracted from the properties list at construction.
* This is a list of Strings.
*/
private List energyBufferActionTypes = new ArrayList();
/**
* Instance of the singleton.
*/
protected static ActionKnowledgeCatalog instance = null;
}