// // @(#)Variant.java 1.00 7/2002 // // Copyright 2002 Zachary DelProposto. All rights reserved. // Use is subject to license terms. // // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Or from http://www.gnu.org/ // package dip.world.variant.data; import dip.world.Power; import dip.world.Phase; import dip.misc.Utils; import java.util.List; /** A Variant. */ public class Variant implements Cloneable, Comparable { @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + Float.floatToIntBits(version); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (!(obj instanceof Variant)) return false; Variant other = (Variant) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; if (Float.floatToIntBits(version) != Float .floatToIntBits(other.version)) return false; return true; } // the arrays in general should not be null. They are defined as null initially // to make it more apparent should a field not be initialized properly. // private String name = null; private boolean isDefault = false; private String description = null; private Power[] powers = null; private Phase phase = null; private InitialState[] istate = null; private SupplyCenter[] supplyCenters = null; private ProvinceData[] provinceData = null; private int vcNumSCForVictory = 0; private int vcMaxYearsNoSCChange = 0; private int vcMaxGameTimeYears = 0; private MapGraphic[] mapGraphics = null; private float version = 0.0f; private NameValuePair[] roNVPs = null; private BorderData[] borderData = null; private boolean allowBCYears = false; private String[] aliases = new String[0]; private String[][] paths; /** Class of Rule Option name/value pairs */ public static class NameValuePair { private final String name; private final String value; /** Create a NameValuePair. Neither name or value may be null. */ public NameValuePair(String name, String value) { if(name == null || value == null) { throw new IllegalArgumentException(); } this.name = name; this.value = value; }// NameValuePair() /** Return the Name */ public String getName() { return name; } /** Return the Value */ public String getValue() { return value; } }// nested class NameValuePair /** Construct a new Variant object */ public Variant() {} /** The name of the variant. */ public String getName() { return name; } /** The aliases (alternate names) of the variant. Never null. */ public String[] getAliases() { return aliases; } /** Version of this variant */ public float getVersion() { return version; } /** Whether this is the default variant. */ public boolean isDefault() { return isDefault; } /** Description for variant; this is typically HTML encoded. */ public String getDescription() { return description; } /** The starting time. */ public Phase getStartingPhase() { return phase; } /** The starting InitialStates. */ public InitialState[] getInitialStates(){ return istate; } /** Returns Powers associated with this Variant. */ public Power[] getPowers() { return powers; } /** Returns SupplyCenter objects */ public SupplyCenter[] getSupplyCenters(){ return supplyCenters; } /** Returns paths for province shapes */ public String[][] getPaths() { return paths; } /** Victory Conditions: Number of Supply Centers required for victory. */ public int getNumSCForVictory() { return vcNumSCForVictory; } /** Victory Conditions: Maximum years without a supply-center ownership change before game ends. */ public int getMaxYearsNoSCChange() { return vcMaxYearsNoSCChange; } /** Victory Conditions: Maximum game duration, in years. */ public int getMaxGameTimeYears() { return vcMaxGameTimeYears; } /** The mapGraphics associated with this Variant. */ public MapGraphic[] getMapGraphics() { return mapGraphics; } /** The ProvinceData associated with this Variant */ public ProvinceData[] getProvinceData() { return provinceData; } /** The RuleOptions (as name-value pairs) associated with this Variant */ public NameValuePair[] getRuleOptionNVPs() { return roNVPs; } /** Gets the BorderData associated with this Variant */ public BorderData[] getBorderData() { return borderData; } /** Gets if BC Years are allowed with this Variant */ public boolean getBCYearsAllowed() { return allowBCYears; } /** Set the variant name. */ public void setName(String value) { name = value; } /** Set the alises. Null is not allowed. */ public void setAliases(String[] aliases) { if(aliases == null) { throw new IllegalArgumentException(); } this.aliases = aliases; } /** Set the version of this variant */ public void setVersion(float value) { version = value; } /** Set if this variant is the default variant. */ public void setDefault(boolean value) { isDefault = value; } /** Set the description for this variant. */ public void setDescription(String value) { description = value; } /** Set the starting phase for this variant. */ public void setStartingPhase(Phase value) { phase = value; } /** Victory Conditions: Number of Supply Centers required for victory. */ public void setNumSCForVictory(int value) { vcNumSCForVictory = value; } /** Victory Conditions: Maximum years without a supply-center ownership change before game ends. */ public void setMaxYearsNoSCChange(int value) { vcMaxYearsNoSCChange = value; } /** Victory Conditions: Maximum game duration, in years. */ public void setMaxGameTimeYears(int value) { vcMaxGameTimeYears = value; } /** Sets the ProvinceData associated with this Variant */ public void setProvinceData(ProvinceData[] value) { provinceData = value; } /** Sets the BorderData associated with this Variant */ public void setBorderData(BorderData[] value) { borderData = value; } /** Sets whether BC years (negative years) are allowed */ public void setBCYearsAllowed(boolean value) { allowBCYears = value; } /** Sets the MapGraphics, from a List */ public void setMapGraphics(List mgList) { mapGraphics = (MapGraphic[]) mgList.toArray(new MapGraphic[mgList.size()]); }// setPowers() /** Sets the Powers, from a List */ public void setPowers(List powerList) { powers = (Power[]) powerList.toArray(new Power[powerList.size()]); }// setPowers() /** Sets the InitialStates, from a List */ public void setInitialStates(List stateList) { istate = (InitialState[]) stateList.toArray(new InitialState[stateList.size()]); }// setInitialStates() /** Sets the supply centers, from a List */ public void setSupplyCenters(List supplyCenterList) { supplyCenters = (SupplyCenter[]) supplyCenterList.toArray(new SupplyCenter[supplyCenterList.size()]); }// setSupplyCenters() public void setPaths(List<String[]> pathsList){ paths = (String[][]) pathsList.toArray(new String[pathsList.size()][]); } /** Sets the RuleOptions (as a List of name-value pairs) associated with this Variant */ public void setRuleOptionNVPs(List nvpList) { roNVPs = (NameValuePair[]) nvpList.toArray(new NameValuePair[nvpList.size()]); }// setRuleOptionNVPs() /** Changes the active/inactive state of a power. The number of values <b>must</b> equal the number of powers. */ public void setActiveState(boolean[] values) { if(values.length != powers.length) { throw new IllegalArgumentException(); } for(int i=0; i<powers.length; i++) { if(powers[i].isActive() != values[i]) { // Powers are constant; we must create a new one. Power old = powers[i]; powers[i] = new Power( old.getNames(), old.getAdjective(), values[i] ); } } }// setActiveState() /** Compares based on Name */ public int compareTo(Object o) { return this.getName().compareTo( ((Variant) o).getName() ); }// compareTo() /** Finds the MapGraphic by name; case insensitive. */ public MapGraphic getMapGrapic(String mgName) { if(mapGraphics != null) { for(int i=0; i<mapGraphics.length; i++) { if(mapGraphics[i].getName().equalsIgnoreCase(mgName)) { return mapGraphics[i]; } } } return null; }// getVariant() /** Gets the default MapGraphic; if there is no default, returns the first one. */ public MapGraphic getDefaultMapGraphic() { MapGraphic mg = null; if(mapGraphics != null && mapGraphics.length > 0) { mg = mapGraphics[0]; for(int i=0; i<mapGraphics.length; i++) { if(mapGraphics[i].isDefault()) { mg = mapGraphics[i]; break; } } } return mg; }// getDefaultMapGraphic() /** * Gets the arguments for an HTML description, suitable for insertion * inside an appropriately-marked HTML template (arguments are * surrounded by curly braces). * <p> * Arguments for the HTML template are: * <ol> * <li>Variant name</li> * <li>variant-description (note: may be in html)</li> * <li>Supply centers for victory</li> * <li>Starting season</li> * <li>Starting year</li> * <li>Starting phase</li> * <li>Powers (comma-separated list)</li> * <li>Number of Powers</li> * </ol> * 8 arguments are given in total. */ public Object[] getHTMLSummaryArguments() { Object args[] = new Object[8]; args[0] = getName(); args[1] = getDescription(); args[2] = String.valueOf(getNumSCForVictory()); if(getStartingPhase() == null) { args[3] = "{bad phase}"; args[4] = "{bad phase}"; args[5] = "{bad phase}"; } else { args[3] = getStartingPhase().getSeasonType(); args[4] = getStartingPhase().getYearType(); args[5] = getStartingPhase().getPhaseType(); } // create list of powers StringBuffer sb = new StringBuffer(512); for(int i=0; i<powers.length; i++) { if(powers[i].isActive()) { sb.append(powers[i].getName()); } else { sb.append('('); sb.append(powers[i].getName()); sb.append(')'); } if(i < (powers.length -1)) { sb.append(", "); } } args[6] = sb.toString(); args[7] = String.valueOf(powers.length); return args; }// getHTMLSummaryArguments() /** Creates a deep clone of all data EXCEPT InitialState / SupplyCenter data / Name / Description */ public Object clone() throws CloneNotSupportedException { // shallow clone Variant variant = (Variant) super.clone(); // deep clone // // phase if(this.phase != null) { // cheap... variant.phase = Phase.parse(this.phase.toString()); } // powers if(this.powers != null) { variant.powers = new Power[powers.length]; for(int i=0; i<powers.length; i++) { Power thisPower = powers[i]; variant.powers[i] = new Power( thisPower.getNames(), thisPower.getAdjective(), thisPower.isActive() ); } } return variant; }// clone() /** For debugging only! */ public String toString() { return Integer.toString(hashCode()); // StringBuffer sb = new StringBuffer(256); // sb.append(this.getClass().getName()); // sb.append('['); // sb.append("name="); // sb.append(name); // sb.append(",isDefault="); // sb.append(isDefault); // sb.append("powers="); // for(int i=0; i<powers.length; i++) // { // sb.append(powers[i]); // sb.append(','); // } // sb.append(",phase="); // sb.append(phase); // sb.append(",istate="); // for(int i=0; i<istate.length; i++) // { // System.out.println(istate[i]); // } // sb.append(",supplyCenters="); // for(int i=0; i<supplyCenters.length; i++) // { // System.out.println(supplyCenters[i]); // } // sb.append(",provinceData="); // for(int i=0; i<provinceData.length; i++) // { // System.out.println(provinceData[i]); // } // sb.append("mapGraphics="); // for(int i=0; i<mapGraphics.length; i++) // { // System.out.println(mapGraphics[i]); // } // sb.append(",vcNumSCForVictory="); // sb.append(vcNumSCForVictory); // sb.append(",vcMaxGameTimeYears="); // sb.append(vcMaxGameTimeYears); // sb.append(",vcMaxYearsNoSCChange="); // sb.append(vcMaxYearsNoSCChange); // sb.append(",version="); // sb.append(version); // sb.append(']'); // return sb.toString(); }// toString() }// class Variant