|
From: <ev...@us...> - 2011-06-21 21:25:57
|
Revision: 1581
http://rails.svn.sourceforge.net/rails/?rev=1581&view=rev
Author: evos
Date: 2011-06-21 21:25:49 +0000 (Tue, 21 Jun 2011)
Log Message:
-----------
Train management refactoring II - game
Major overhaul of train management.
TrainCertificateType describes buyable trains, single or dual
TrainType describes a singe train type
Train describes separate train certificate objects. It contains a reference to the current TrainType, which is null as long as it is owned by the Bank.
Modified Paths:
--------------
trunk/18xx/LocalisedText.properties
trunk/18xx/rails/algorithms/NetworkTrain.java
trunk/18xx/rails/algorithms/RevenueAdapter.java
trunk/18xx/rails/algorithms/RevenueBonus.java
trunk/18xx/rails/algorithms/RevenueBonusTemplate.java
trunk/18xx/rails/game/OperatingRound.java
trunk/18xx/rails/game/Portfolio.java
trunk/18xx/rails/game/PublicCompany.java
trunk/18xx/rails/game/Train.java
trunk/18xx/rails/game/TrainI.java
trunk/18xx/rails/game/TrainManager.java
trunk/18xx/rails/game/TrainType.java
trunk/18xx/rails/game/action/BuyTrain.java
trunk/18xx/rails/game/model/TrainsModel.java
trunk/18xx/rails/game/specific/_1856/CGRFormationRound.java
trunk/18xx/rails/game/specific/_1856/PublicCompany_1856.java
trunk/18xx/rails/game/specific/_1856/PublicCompany_CGR.java
trunk/18xx/rails/game/specific/_18AL/NameableTrain.java
trunk/18xx/rails/game/specific/_18EU/OperatingRound_18EU.java
trunk/18xx/rails/game/state/GenericState.java
trunk/18xx/rails/ui/swing/ORPanel.java
trunk/18xx/rails/ui/swing/ORUIManager.java
Added Paths:
-----------
trunk/18xx/rails/game/TrainCertificateType.java
Removed Paths:
-------------
trunk/18xx/rails/game/TrainTypeI.java
Modified: trunk/18xx/LocalisedText.properties
===================================================================
--- trunk/18xx/LocalisedText.properties 2011-06-21 21:21:43 UTC (rev 1580)
+++ trunk/18xx/LocalisedText.properties 2011-06-21 21:25:49 UTC (rev 1581)
@@ -322,13 +322,10 @@
InvalidAction=Invalid action in this game
InvalidAllocationTypeIndex=Invalid allocation type index: {0}
InvalidBid=Invalid bid by {0} on {1}: {2}
-InvalidCost=Invalid or zero cost specified
InvalidDoneAction=Invalid Done action
InvalidParPriceSetting=Invalid par price {0} set by {1} for {2}: {3}
InvalidPass=Invalid pass by {0}: {1}
-InvalidQuantity=Invalid quantity specified: {0}
InvalidStartPrice=Invalid start price {0} for {1}
-InvalidStops=Invalid or zero major stops specified
InvalidTileColourName=Invalid colour name {1} for tile {0}
InvalidTileLay=Invalid tile lay
InvalidTrackEnd=Invalid track end
@@ -401,7 +398,6 @@
NoIncomeForPreviousOperation={0} gets no income for {1}% {2} shares as precursors have operated
NoMapMode=No map mode (for ftf play)
NoMoney=Not enough money
-NoNameSpecified=No name specified
None=None
NoPriceToSet=No price to be set
# Texts with lowercase keys are intended to be inserted into other messages
Modified: trunk/18xx/rails/algorithms/NetworkTrain.java
===================================================================
--- trunk/18xx/rails/algorithms/NetworkTrain.java 2011-06-21 21:21:43 UTC (rev 1580)
+++ trunk/18xx/rails/algorithms/NetworkTrain.java 2011-06-21 21:25:49 UTC (rev 1581)
@@ -3,7 +3,7 @@
import org.apache.log4j.Logger;
import rails.game.TrainI;
-import rails.game.TrainTypeI;
+import rails.game.TrainType;
public final class NetworkTrain {
@@ -118,7 +118,7 @@
return railsTrain;
}
- public TrainTypeI getRailsTrainType() {
+ public TrainType getRailsTrainType() {
if (railsTrain == null) return null;
return railsTrain.getType();
Modified: trunk/18xx/rails/algorithms/RevenueAdapter.java
===================================================================
--- trunk/18xx/rails/algorithms/RevenueAdapter.java 2011-06-21 21:21:43 UTC (rev 1580)
+++ trunk/18xx/rails/algorithms/RevenueAdapter.java 2011-06-21 21:25:49 UTC (rev 1581)
@@ -22,7 +22,7 @@
import rails.game.PhaseI;
import rails.game.PublicCompanyI;
import rails.game.TrainI;
-import rails.game.TrainTypeI;
+import rails.game.TrainType;
import rails.ui.swing.hexmap.HexMap;
import rails.util.LocalText;
@@ -172,10 +172,10 @@
}
public boolean addTrainByString(String trainString) {
- TrainTypeI trainType = gameManager.getTrainManager().getTypeByName(trainString.trim());
+ TrainType trainType = gameManager.getTrainManager().getTypeByName(trainString.trim());
if (trainType != null) { // string defines available trainType
log.info("RA: found trainType" + trainType);
- TrainI railsTrain = gameManager.getTrainManager().cloneTrain(trainType);
+ TrainI railsTrain = gameManager.getTrainManager().cloneTrain(trainType.getCertificateType());
return addTrain(railsTrain);
} else { // otherwise interpret the train
NetworkTrain train = NetworkTrain.createFromString(trainString);
Modified: trunk/18xx/rails/algorithms/RevenueBonus.java
===================================================================
--- trunk/18xx/rails/algorithms/RevenueBonus.java 2011-06-21 21:21:43 UTC (rev 1580)
+++ trunk/18xx/rails/algorithms/RevenueBonus.java 2011-06-21 21:25:49 UTC (rev 1581)
@@ -10,7 +10,7 @@
import rails.game.PhaseI;
import rails.game.TrainI;
-import rails.game.TrainTypeI;
+import rails.game.TrainType;
public final class RevenueBonus {
@@ -25,7 +25,7 @@
// internal attributes
private List<NetworkVertex> vertices;
- private List<TrainTypeI> trainTypes;
+ private List<TrainType> trainTypes;
private List<TrainI> trains;
private List<PhaseI> phases;
@@ -34,7 +34,7 @@
this.name = name;
vertices = new ArrayList<NetworkVertex>();
- trainTypes = new ArrayList<TrainTypeI>();
+ trainTypes = new ArrayList<TrainType>();
trains = new ArrayList<TrainI>();
phases = new ArrayList<PhaseI>();
}
@@ -47,7 +47,7 @@
this.vertices.addAll(vertices);
}
- public void addTrainType(TrainTypeI trainType) {
+ public void addTrainType(TrainType trainType) {
trainTypes.add(trainType);
}
@@ -71,7 +71,7 @@
return vertices;
}
- public List<TrainTypeI> getTrainTypes() {
+ public List<TrainType> getTrainTypes() {
return trainTypes;
}
Modified: trunk/18xx/rails/algorithms/RevenueBonusTemplate.java
===================================================================
--- trunk/18xx/rails/algorithms/RevenueBonusTemplate.java 2011-06-21 21:21:43 UTC (rev 1580)
+++ trunk/18xx/rails/algorithms/RevenueBonusTemplate.java 2011-06-21 21:25:49 UTC (rev 1581)
@@ -12,7 +12,7 @@
import rails.game.PhaseI;
import rails.game.PhaseManager;
import rails.game.TrainManager;
-import rails.game.TrainTypeI;
+import rails.game.TrainType;
import rails.util.Tag;
/**
@@ -117,7 +117,7 @@
private void convertTrainTypes(RevenueBonus bonus, TrainManager tm) {
for (String identTrainType:identTrainTypes) {
- TrainTypeI trainType = tm.getTypeByName(identTrainType);
+ TrainType trainType = tm.getTypeByName(identTrainType);
if (trainType != null) {
bonus.addTrainType(trainType);
}
Modified: trunk/18xx/rails/game/OperatingRound.java
===================================================================
--- trunk/18xx/rails/game/OperatingRound.java 2011-06-21 21:21:43 UTC (rev 1580)
+++ trunk/18xx/rails/game/OperatingRound.java 2011-06-21 21:25:49 UTC (rev 1581)
@@ -58,8 +58,8 @@
/** A List per player with owned companies that have excess trains */
protected Map<Player, List<PublicCompanyI>> excessTrainCompanies = null;
- protected List<TrainTypeI> trainsBoughtThisTurn =
- new ArrayList<TrainTypeI>(4);
+ protected List<TrainCertificateType> trainsBoughtThisTurn =
+ new ArrayList<TrainCertificateType>(4);
protected Map<PublicCompanyI, Integer> loansThisRound = null;
@@ -1763,7 +1763,7 @@
//exchangedTrain = operatingCompany.getObject().getPortfolio().getTrainList().get(0);
//action.setExchangedTrain(exchangedTrain);
break;
- } else if (operatingCompany.get().getPortfolio().getTrainOfType(exchangedTrain.getType()) == null) {
+ } else if (operatingCompany.get().getPortfolio().getTrainOfType(exchangedTrain.getCertType()) == null) {
errMsg = LocalText.getText("CompanyDoesNotOwnTrain",
operatingCompany.get().getName(),
exchangedTrain.getName());
@@ -1812,7 +1812,7 @@
if (exchangedTrain != null) {
TrainI oldTrain =
operatingCompany.get().getPortfolio().getTrainOfType(
- exchangedTrain.getType());
+ exchangedTrain.getCertType());
oldTrain.moveTo(train.isObsolete() ? scrapHeap : pool);
ReportBuffer.add(LocalText.getText("ExchangesTrain",
companyName,
@@ -1835,18 +1835,20 @@
stb.getOriginalCompany().getName() ));
}
+ train.setType(action.getType()); // Needed for dual trains bought from the Bank
+
operatingCompany.get().buyTrain(train, price);
if (oldHolder == ipo) {
- train.getType().addToBoughtFromIPO();
+ train.getCertType().addToBoughtFromIPO();
trainManager.setAnyTrainBought(true);
// Clone the train if infinitely available
- if (train.getType().hasInfiniteQuantity()) {
- ipo.addTrain(trainManager.cloneTrain(train.getType()));
+ if (train.getCertType().hasInfiniteQuantity()) {
+ ipo.addTrain(trainManager.cloneTrain(train.getCertType()));
}
}
if (oldHolder.getOwner() instanceof Bank) {
- trainsBoughtThisTurn.add(train.getType());
+ trainsBoughtThisTurn.add(train.getCertType());
}
if (stb != null) {
@@ -1957,6 +1959,11 @@
//
if (action.isForced()) moveStack.linkToPreviousMoveSet();
+ // Reset type of dual trains
+ if (train.getCertType().getPotentialTrainTypes().size() > 1) {
+ train.setType(null);
+ }
+
train.moveTo(train.isObsolete() ? scrapHeap : pool);
ReportBuffer.add(LocalText.getText("CompanyDiscardsTrain",
companyName,
@@ -2623,7 +2630,7 @@
int cash = operatingCompany.get().getCash();
- int cost;
+ int cost = 0;
List<TrainI> trains;
boolean hasTrains =
@@ -2650,24 +2657,30 @@
for (TrainI train : trains) {
if (!operatingCompany.get().mayBuyTrainType(train)) continue;
if (!mayBuyMoreOfEachType
- && trainsBoughtThisTurn.contains(train.getType())) {
+ && trainsBoughtThisTurn.contains(train.getCertType())) {
continue;
}
- cost = train.getCost();
- if (cost <= cash) {
- if (canBuyTrainNow) {
- BuyTrain action = new BuyTrain(train, ipo, cost);
- action.setForcedBuyIfNoRoute(presidentMayHelp); // TEMPORARY
- possibleActions.add(action);
+
+ // Allow dual trains (since jun 2011)
+ List<TrainType> types = train.getCertType().getPotentialTrainTypes();
+ for (TrainType type : types) {
+ cost = type.getCost();
+ if (cost <= cash) {
+ if (canBuyTrainNow) {
+ BuyTrain action = new BuyTrain(train, type, ipo, cost);
+ action.setForcedBuyIfNoRoute(presidentMayHelp); // TEMPORARY
+ possibleActions.add(action);
+ }
+ } else if (costOfCheapestTrain == 0
+ || cost < costOfCheapestTrain) {
+ cheapestTrain = train;
+ costOfCheapestTrain = cost;
}
- } else if (costOfCheapestTrain == 0
- || cost < costOfCheapestTrain) {
- cheapestTrain = train;
- costOfCheapestTrain = cost;
}
+
// Even at train limit, exchange is allowed (per 1856)
if (train.canBeExchanged() && hasTrains) {
- cost = train.getType().getExchangeCost();
+ cost = train.getCertType().getExchangeCost();
if (cost <= cash) {
List<TrainI> exchangeableTrains =
operatingCompany.get().getPortfolio().getUniqueTrains();
@@ -2683,8 +2696,8 @@
// Can a special property be used?
// N.B. Assume that this never occurs in combination with
- // a train exchange, otherwise the below code must be duplicated
- // above.
+ // dual trains or train exchanges,
+ // otherwise the below code must be duplicated above.
for (SpecialTrainBuy stb : getSpecialProperties(SpecialTrainBuy.class)) {
int reducedPrice = stb.getPrice(cost);
if (reducedPrice > cash) continue;
@@ -2701,7 +2714,7 @@
trains = pool.getUniqueTrains();
for (TrainI train : trains) {
if (!mayBuyMoreOfEachType
- && trainsBoughtThisTurn.contains(train.getType())) {
+ && trainsBoughtThisTurn.contains(train.getCertType())) {
continue;
}
cost = train.getCost();
@@ -2895,7 +2908,7 @@
if (getGameParameterAsBoolean(GameDef.Parm.REMOVE_TRAIN_BEFORE_SR)
&& trainManager.isAnyTrainBought()) {
TrainI train = trainManager.getAvailableNewTrains().get(0);
- if (train.getType().hasInfiniteQuantity()) return;
+ if (train.getCertType().hasInfiniteQuantity()) return;
new ObjectMove (train, ipo, scrapHeap);
ReportBuffer.add(LocalText.getText("RemoveTrain", train.getName()));
}
Modified: trunk/18xx/rails/game/Portfolio.java
===================================================================
--- trunk/18xx/rails/game/Portfolio.java 2011-06-21 21:21:43 UTC (rev 1580)
+++ trunk/18xx/rails/game/Portfolio.java 2011-06-21 21:25:49 UTC (rev 1581)
@@ -51,8 +51,10 @@
/** Owned trains */
protected List<TrainI> trains = new ArrayList<TrainI>();
- protected Map<TrainTypeI, List<TrainI>> trainsPerType =
- new HashMap<TrainTypeI, List<TrainI>>();
+ protected Map<TrainType, List<TrainI>> trainsPerType =
+ new HashMap<TrainType, List<TrainI>>();
+ protected Map<TrainCertificateType, List<TrainI>> trainsPerCertType =
+ new HashMap<TrainCertificateType, List<TrainI>>();
protected TrainsModel trainsModel = new TrainsModel(this);
/** Owned tokens */
@@ -73,6 +75,8 @@
protected String name;
/** Unique name (including owner class name) */
protected String uniqueName;
+
+ GameManagerI gameManager;
/** Specific portfolio names */
public static final String IPO_NAME = "IPO";
@@ -88,7 +92,8 @@
this.owner = holder;
this.uniqueName = holder.getClass().getSimpleName() + "_" + name;
- GameManager.getInstance().addPortfolio(this);
+ gameManager = GameManager.getInstance();
+ gameManager.addPortfolio(this);
if (owner instanceof PublicCompanyI) {
trainsModel.setOption(TrainsModel.FULL_LIST);
@@ -390,24 +395,33 @@
}
public void addTrain (TrainI train) {
- addTrain (train, new int[] {-1,-1});
+ addTrain (train, new int[] {-1,-1,-1});
}
public void addTrain(TrainI train, int[] position) {
Util.addToList(trains, train, position[0]);
- TrainTypeI type = train.getType();
+
+ TrainType type = train.getType();
if (!trainsPerType.containsKey(type)) {
trainsPerType.put(type, new ArrayList<TrainI>());
}
- Util.addToList(trainsPerType.get(train.getType()), train, position[1]);
+ Util.addToList(trainsPerType.get(type), train, position[1]);
+
+ TrainCertificateType certType = train.getCertType();
+ if (!trainsPerCertType.containsKey(certType)) {
+ trainsPerCertType.put(certType, new ArrayList<TrainI>());
+ }
+ Util.addToList(trainsPerCertType.get(certType), train, position[2]);
+
train.setHolder(this);
trainsModel.update();
}
public void removeTrain(TrainI train) {
trains.remove(train);
- trainsPerType.get(train.getType()).remove(train);
+ trainsPerType.get(train.getPreviousType()).remove(train);
+ trainsPerCertType.get(train.getCertType()).remove(train);
train.setHolder(null);
trainsModel.update();
}
@@ -436,7 +450,7 @@
return trains;
}
- public TrainI[] getTrainsPerType(TrainTypeI type) {
+ public TrainI[] getTrainsPerType(TrainType type) {
List<TrainI> trainsFound = new ArrayList<TrainI>();
for (TrainI train : trains) {
@@ -454,8 +468,8 @@
public List<TrainI> getUniqueTrains() {
List<TrainI> trainsFound = new ArrayList<TrainI>();
- Map<TrainTypeI, Object> trainTypesFound =
- new HashMap<TrainTypeI, Object>();
+ Map<TrainType, Object> trainTypesFound =
+ new HashMap<TrainType, Object>();
for (TrainI train : trains) {
if (!trainTypesFound.containsKey(train.getType())) {
trainsFound.add(train);
@@ -466,9 +480,9 @@
}
- public TrainI getTrainOfType(TrainTypeI type) {
+ public TrainI getTrainOfType(TrainCertificateType type) {
for (TrainI train : trains) {
- if (train.getType() == type) return train;
+ if (train.getCertType() == type) return train;
}
return null;
}
@@ -478,19 +492,19 @@
* IPO.
*/
- public String makeAbbreviatedListOfTrains() {
+ public String makeListOfTrainCertificates() {
if (trains == null || trains.isEmpty()) return "";
- StringBuffer b = new StringBuffer();
+ StringBuilder b = new StringBuilder();
List<TrainI> trainsOfType;
- for (TrainTypeI type : GameManager.getInstance().getTrainManager().getTrainTypes()) {
- trainsOfType = trainsPerType.get(type);
+ for (TrainCertificateType certType : gameManager.getTrainManager().getTrainCertTypes()) {
+ trainsOfType = trainsPerCertType.get(certType);
if (trainsOfType != null && !trainsOfType.isEmpty()) {
if (b.length() > 0) b.append(" ");
- b.append(type.getName()).append("(");
- if (type.hasInfiniteQuantity()) {
+ b.append(certType.getName()).append("(");
+ if (certType.hasInfiniteQuantity()) {
b.append("+");
} else {
b.append(trainsOfType.size());
@@ -506,14 +520,14 @@
* Make a full list of trains, like "2 2 3 3", to show in any field
* describing train possessions, except the IPO.
*/
- public String makeFullListOfTrains() {
+ public String makeListOfTrains() {
if (trains == null || trains.isEmpty()) return "";
List<TrainI> trainsOfType;
- StringBuffer b = new StringBuffer();
+ StringBuilder b = new StringBuilder();
- for (TrainTypeI type : GameManager.getInstance().getTrainManager().getTrainTypes()) {
+ for (TrainType type : gameManager.getTrainManager().getTrainTypes()) {
trainsOfType = trainsPerType.get(type);
if (trainsOfType != null && !trainsOfType.isEmpty()) {
for (TrainI train : trainsOfType) {
@@ -603,7 +617,7 @@
addPrivate((PrivateCompanyI) object, position == null ? -1 : position[0]);
return true;
} else if (object instanceof TrainI) {
- if (position == null) position = new int[] {-1, -1};
+ if (position == null) position = new int[] {-1, -1, -1};
addTrain((TrainI) object, position);
return true;
} else if (object instanceof SpecialPropertyI) {
@@ -654,7 +668,8 @@
TrainI train = (TrainI) object;
return new int[] {
trains.indexOf(train),
- trainsPerType.get(train.getType()).indexOf(train)
+ train.getPreviousType() != null ? trainsPerType.get(train.getPreviousType()).indexOf(train) : -1,
+ trainsPerCertType.get(train.getCertType()).indexOf(train)
};
} else if (object instanceof SpecialPropertyI) {
return new int[] {specialProperties.indexOf(object)};
Modified: trunk/18xx/rails/game/PublicCompany.java
===================================================================
--- trunk/18xx/rails/game/PublicCompany.java 2011-06-21 21:21:43 UTC (rev 1580)
+++ trunk/18xx/rails/game/PublicCompany.java 2011-06-21 21:25:49 UTC (rev 1581)
@@ -973,7 +973,7 @@
if (initialTrainType != null) {
TrainManager trainManager = gameManager.getTrainManager();
- TrainTypeI type = trainManager.getTypeByName(initialTrainType);
+ TrainCertificateType type = trainManager.getCertTypeByName(initialTrainType);
TrainI train = bank.getIpo().getTrainOfType(type);
buyTrain(train, initialTrainCost);
train.setTradeable(initialTrainTradeable);
Modified: trunk/18xx/rails/game/Train.java
===================================================================
--- trunk/18xx/rails/game/Train.java 2011-06-21 21:21:43 UTC (rev 1580)
+++ trunk/18xx/rails/game/Train.java 2011-06-21 21:25:49 UTC (rev 1581)
@@ -6,10 +6,16 @@
import rails.game.move.MoveableHolder;
import rails.game.move.ObjectMove;
import rails.game.state.BooleanState;
+import rails.game.state.GenericState;
public class Train implements TrainI {
- protected TrainTypeI type;
+ protected TrainCertificateType certificateType;
+
+ protected GenericState<TrainType> type;
+
+ /** Temporary variable, only used during moves. */
+ protected TrainType previousType = null;
/** Some specific trains cannot be traded between companies */
protected boolean tradeable = true;
@@ -24,14 +30,36 @@
public Train() {}
- public void init(TrainTypeI type, String uniqueId) {
+ public void init(TrainCertificateType certType, TrainType type, String uniqueId) {
- this.type = type;
+ this.certificateType = certType;
this.uniqueId = uniqueId;
+ this.type = new GenericState<TrainType>(certType.getName()+"_CurrentType", type);
+ this.previousType = type;
obsolete = new BooleanState(uniqueId, false);
}
+
+ public void setType (TrainType type) {
+ previousType = this.type.get();
+ this.type.set(type);
+ }
+ /**
+ * @return Returns the type.
+ */
+ public TrainCertificateType getCertType() {
+ return certificateType;
+ }
+
+ public TrainType getType() {
+ return isAssigned() ? type.get() : null;
+ }
+
+ public TrainType getPreviousType() {
+ return previousType;
+ }
+
public String getUniqueId() {
return uniqueId;
}
@@ -40,53 +68,54 @@
* @return Returns the cityScoreFactor.
*/
public int getCityScoreFactor() {
- return type.getCityScoreFactor();
+ return getType().getCityScoreFactor();
}
/**
* @return Returns the cost.
*/
public int getCost() {
- return type.getCost();
+ return getType().getCost();
}
/**
* @return Returns the majorStops.
*/
public int getMajorStops() {
- return type.getMajorStops();
+ return getType().getMajorStops();
}
/**
* @return Returns the minorStops.
*/
public int getMinorStops() {
- return type.getMinorStops();
+ return getType().getMinorStops();
}
/**
* @return Returns the townCountIndicator.
*/
public int getTownCountIndicator() {
- return type.getTownCountIndicator();
+ return getType().getTownCountIndicator();
}
/**
* @return Returns the townScoreFactor.
*/
public int getTownScoreFactor() {
- return type.getTownScoreFactor();
+ return getType().getTownScoreFactor();
}
- /**
- * @return Returns the type.
- */
- public TrainTypeI getType() {
- return type;
+ public boolean isAssigned() {
+ return type.get() != null;
}
-
+
+ public boolean isPermanent() {
+ return certificateType.isPermanent();
+ }
+
public String getName() {
- return type.getName();
+ return isAssigned() ? type.get().getName() : certificateType.getName();
}
public Portfolio getHolder() {
@@ -123,7 +152,7 @@
}
public boolean canBeExchanged() {
- return type.nextCanBeExchanged();
+ return certificateType.nextCanBeExchanged();
}
public String toDisplay() {
@@ -138,4 +167,11 @@
this.tradeable = tradeable;
}
+ public String toString() {
+ StringBuilder b = new StringBuilder(uniqueId);
+ b.append(" certType=").append(getCertType());
+ b.append(" type=").append(getType());
+ b.append(" holder=").append(holder.getName());
+ return b.toString();
+ }
}
Added: trunk/18xx/rails/game/TrainCertificateType.java
===================================================================
--- trunk/18xx/rails/game/TrainCertificateType.java (rev 0)
+++ trunk/18xx/rails/game/TrainCertificateType.java 2011-06-21 21:25:49 UTC (rev 1581)
@@ -0,0 +1,316 @@
+package rails.game;
+
+import java.util.*;
+
+import org.apache.log4j.Logger;
+
+import rails.game.state.BooleanState;
+import rails.game.state.IntegerState;
+import rails.util.*;
+
+public class TrainCertificateType {
+
+ protected String name;
+ protected int quantity = 0;
+ protected boolean infiniteQuantity = false;
+
+ protected String startedPhaseName = null;
+ // Phase startedPhase;
+
+ protected List<TrainType> potentialTrainTypes = new ArrayList<TrainType>(2);
+
+ protected Map<Integer, String> rustedTrainTypeNames = null;
+ protected Map<Integer, TrainCertificateType> rustedTrainType = null;
+
+ protected boolean permanent = true;
+ protected boolean obsoleting = false;
+
+ protected String releasedTrainTypeNames = null;
+ protected List<TrainCertificateType> releasedTrainTypes = null;
+
+ protected boolean canBeExchanged = false;
+ protected int cost;
+ protected int exchangeCost;
+
+ protected String trainClassName = "rails.game.Train";
+ protected Class<? extends Train> trainClass;
+
+
+ protected int lastIndex = 0;
+
+ // State variables
+ protected IntegerState numberBoughtFromIPO;
+ protected BooleanState available;
+ protected BooleanState rusted;
+
+ // References
+ protected TrainManager trainManager;
+
+ /** In some cases, trains start their life in the Pool */
+ protected String initialPortfolio = "IPO";
+
+ protected static Logger log =
+ Logger.getLogger(TrainCertificateType.class.getPackage().getName());
+
+ public TrainCertificateType () {
+ }
+
+ public void configureFromXML(Tag tag) throws ConfigurationException {
+
+ trainClassName = tag.getAttributeAsString("class", trainClassName);
+ try {
+ trainClass = Class.forName(trainClassName).asSubclass(Train.class);
+ } catch (ClassNotFoundException e) {
+ throw new ConfigurationException("Class " + trainClassName
+ + "not found", e);
+ }
+
+ // Name
+ name = tag.getAttributeAsString("name");
+
+ // Quantity
+ quantity = tag.getAttributeAsInteger("quantity", quantity);
+ quantity += tag.getAttributeAsInteger("quantityIncrement", 0);
+
+ // Phase started
+ startedPhaseName = tag.getAttributeAsString("startPhase", "");
+
+ // Train type rusted
+ String rustedTrainTypeName1 = tag.getAttributeAsString("rustedTrain");
+ if (Util.hasValue(rustedTrainTypeName1)) {
+ rustedTrainTypeNames = new HashMap<Integer, String>();
+ rustedTrainTypeNames.put(1, rustedTrainTypeName1);
+ }
+
+ // Other train type released for buying
+ releasedTrainTypeNames = tag.getAttributeAsString("releasedTrain");
+
+ // From where is this type initially available
+ initialPortfolio =
+ tag.getAttributeAsString("initialPortfolio",
+ initialPortfolio);
+
+ // Configure any actions on other than the first train of a type
+ List<Tag> subs = tag.getChildren("Sub");
+ if (subs != null) {
+ for (Tag sub : tag.getChildren("Sub")) {
+ int index = sub.getAttributeAsInteger("index");
+ rustedTrainTypeName1 = sub.getAttributeAsString("rustedTrain");
+ if (rustedTrainTypeNames == null) {
+ rustedTrainTypeNames = new HashMap<Integer, String>();
+ }
+ rustedTrainTypeNames.put(index, rustedTrainTypeName1);
+ }
+ }
+
+ // Exchangeable
+ Tag swapTag = tag.getChild("Exchange");
+ if (swapTag != null) {
+ exchangeCost = swapTag.getAttributeAsInteger("cost", 0);
+ canBeExchanged = (exchangeCost > 0);
+ }
+
+ // Can run as obsolete train
+ obsoleting = tag.getAttributeAsBoolean("obsoleting");
+
+ // Final initialisations
+ numberBoughtFromIPO = new IntegerState(name + "-trains_Bought", 0);
+ available = new BooleanState(name + "-trains_Available", false);
+ rusted = new BooleanState(name + "-trains_Rusted", false);
+
+ }
+
+ public void finishConfiguration (GameManagerI gameManager)
+ throws ConfigurationException {
+
+ trainManager = gameManager.getTrainManager();
+
+ if (name == null) {
+ throw new ConfigurationException("No name specified for TrainType");
+ }
+
+ if (quantity == -1) {
+ infiniteQuantity = true;
+ } else if (quantity <= 0) {
+ throw new ConfigurationException("Invalid quantity "+quantity+" for train cert type "+name);
+ }
+ }
+
+ public TrainI createTrain () throws ConfigurationException {
+
+ TrainI train;
+ try {
+ train = trainClass.newInstance();
+ } catch (InstantiationException e) {
+ throw new ConfigurationException(
+ "Cannot instantiate class " + trainClassName, e);
+ } catch (IllegalAccessException e) {
+ throw new ConfigurationException("Cannot access class "
+ + trainClassName
+ + "constructor", e);
+ }
+ return train;
+ }
+
+ public List<TrainType> getPotentialTrainTypes() {
+ return potentialTrainTypes;
+ }
+
+ protected void addPotentialTrainType (TrainType type) {
+ potentialTrainTypes.add(type);
+ }
+
+ /**
+ * @return Returns the available.
+ */
+ public boolean isAvailable() {
+ return available.booleanValue();
+ }
+
+ /**
+ * Make a train type available for buying by public companies.
+ */
+ public void setAvailable() {
+ available.set(true);
+ }
+
+ public void setRusted() {
+ rusted.set(true);
+ }
+
+ public boolean hasRusted() {
+ return rusted.booleanValue();
+ }
+
+ /**
+ * @return Returns the name.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @return Returns the releasedTrainTypeName.
+ */
+ public String getReleasedTrainTypeNames() {
+ return releasedTrainTypeNames;
+ }
+
+ /**
+ * @return Returns the rustedTrainTypeName.
+ */
+ public Map<Integer,String> getRustedTrainTypeNames() {
+ return rustedTrainTypeNames;
+ }
+
+ /**
+ * @param releasedTrainType The releasedTrainType to set.
+ */
+ public void setReleasedTrainTypes(List<TrainCertificateType> releasedTrainTypes) {
+ this.releasedTrainTypes = releasedTrainTypes;
+ }
+
+ /**
+ * @param rustedTrainType The rustedTrainType to set.
+ */
+ public void setRustedTrainType(int index, TrainCertificateType rustedTrainType) {
+ if (this.rustedTrainType == null) {
+ this.rustedTrainType = new HashMap<Integer, TrainCertificateType>();
+ }
+ this.rustedTrainType.put(index, rustedTrainType);
+ }
+
+ public boolean isPermanent() {
+ return permanent;
+ }
+
+ public boolean isObsoleting() {
+ return obsoleting;
+ }
+
+ public void setPermanent(boolean permanent) {
+ this.permanent = permanent;
+ }
+
+ /**
+ * @return Returns the releasedTrainTypes.
+ */
+ public List<TrainCertificateType> getReleasedTrainTypes() {
+ return releasedTrainTypes;
+ }
+
+ /**
+ * @return Returns the rustedTrainType.
+ */
+ public TrainCertificateType getRustedTrainType(int index) {
+ if (rustedTrainType == null) return null;
+ return rustedTrainType.get(index);
+ }
+
+ /**
+ * @return Returns the startedPhaseName.
+ */
+ public String getStartedPhaseName() {
+ return startedPhaseName;
+ }
+
+ public int getQuantity() {
+ return quantity;
+ }
+
+ public boolean hasInfiniteQuantity() {
+ return infiniteQuantity;
+ }
+
+ public boolean nextCanBeExchanged() {
+ return canBeExchanged;
+ }
+
+ public void addToBoughtFromIPO() {
+ numberBoughtFromIPO.add(1);
+ }
+
+ public int getNumberBoughtFromIPO() {
+ return numberBoughtFromIPO.intValue();
+ }
+
+ public int getCost() {
+ return cost;
+ }
+
+ public int getExchangeCost() {
+ return exchangeCost;
+ }
+
+ public String getInitialPortfolio() {
+ return initialPortfolio;
+ }
+
+ public String getInfo() {
+ StringBuilder b = new StringBuilder ("<html>");
+ b.append(LocalText.getText("TrainInfo", name, Bank.format(cost), quantity));
+ if (Util.hasValue(startedPhaseName)) {
+ appendInfoText(b, LocalText.getText("StartsPhase", startedPhaseName));
+ }
+ if (rustedTrainTypeNames != null) {
+ appendInfoText(b, LocalText.getText("RustsTrains", rustedTrainTypeNames.get(1)));
+ // Ignore any 'Sub' cases for now
+ }
+ if (releasedTrainTypeNames != null) {
+ appendInfoText(b, LocalText.getText("ReleasesTrains", releasedTrainTypeNames));
+ }
+ if (b.length() == 6) b.append(LocalText.getText("None"));
+
+ return b.toString();
+ }
+
+ private void appendInfoText (StringBuilder b, String text) {
+ if (text == null || text.length() == 0) return;
+ if (b.length() > 6) b.append("<br>");
+ b.append(text);
+ }
+
+ public String toString() {
+ return name;
+ }
+}
Property changes on: trunk/18xx/rails/game/TrainCertificateType.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/18xx/rails/game/TrainI.java
===================================================================
--- trunk/18xx/rails/game/TrainI.java 2011-06-21 21:21:43 UTC (rev 1580)
+++ trunk/18xx/rails/game/TrainI.java 2011-06-21 21:25:49 UTC (rev 1581)
@@ -5,7 +5,7 @@
public interface TrainI extends Moveable {
- public void init(TrainTypeI type, String uniqueId);
+ public void init(TrainCertificateType certType, TrainType type, String uniqueId);
/**
* @return Returns the cost.
@@ -38,10 +38,13 @@
*/
public int getTownScoreFactor();
+ public void setType (TrainType type);
/**
* @return Returns the train type.
*/
- public TrainTypeI getType();
+ public TrainType getType();
+ public TrainCertificateType getCertType();
+ public TrainType getPreviousType();
public String getName();
@@ -52,6 +55,7 @@
public CashHolder getOwner();
public boolean isObsolete();
+ public boolean isPermanent();
public void setHolder(Portfolio newHolder);
Modified: trunk/18xx/rails/game/TrainManager.java
===================================================================
--- trunk/18xx/rails/game/TrainManager.java 2011-06-21 21:21:43 UTC (rev 1580)
+++ trunk/18xx/rails/game/TrainManager.java 2011-06-21 21:25:49 UTC (rev 1581)
@@ -5,6 +5,7 @@
import org.apache.log4j.Logger;
+import rails.game.move.ObjectMove;
import rails.game.state.BooleanState;
import rails.game.state.IntegerState;
import rails.util.LocalText;
@@ -12,25 +13,32 @@
public class TrainManager implements ConfigurableComponentI {
// Static attributes
- protected List<TrainTypeI> lTrainTypes = new ArrayList<TrainTypeI>();
+ protected List<TrainType> lTrainTypes = new ArrayList<TrainType>();
- protected Map<String, TrainTypeI> mTrainTypes =
- new HashMap<String, TrainTypeI>();
+ protected Map<String, TrainType> mTrainTypes
+ = new HashMap<String, TrainType>();
- protected Map<String, TrainI> trainMap =
- new HashMap<String, TrainI>();
+ protected List<TrainCertificateType> trainCertTypes
+ = new ArrayList<TrainCertificateType>();
+
+ protected Map<String, TrainCertificateType> trainCertTypeMap
+ = new HashMap<String, TrainCertificateType>();
+
+ protected Map<String, TrainI> trainMap
+ = new HashMap<String, TrainI>();
- protected Map<TrainTypeI, List<TrainI>> trainsPerType = new HashMap<TrainTypeI, List<TrainI>>();
+ protected Map<TrainCertificateType, List<TrainI>> trainsPerCertType
+ = new HashMap<TrainCertificateType, List<TrainI>>();
+ protected TrainType defaultType = null; // Only required locally and in ChoiceType
+
private boolean removeTrain = false;
// Dynamic attributes
- protected Portfolio unavailable = null;
-
protected IntegerState newTypeIndex;
- protected Map<TrainTypeI, Integer> lastIndexPerType = new HashMap<TrainTypeI, Integer>();
+ protected Map<String, Integer> lastIndexPerType = new HashMap<String, Integer>();
protected boolean trainsHaveRusted = false;
protected boolean phaseHasChanged = false;
@@ -46,7 +54,7 @@
protected BooleanState anyTrainBought = new BooleanState ("AnyTrainBought", false);
// Non-game attributes
- protected Portfolio ipo = null;
+ protected Portfolio ipo, pool, unavailable;
// For initialisation only
boolean trainPriceAtFaceValueIfDifferentPresidents = false;
@@ -66,31 +74,43 @@
* @see rails.game.ConfigurableComponentI#configureFromXML(org.w3c.dom.Element)
*/
public void configureFromXML(Tag tag) throws ConfigurationException {
- TrainType defaultType = null;
+
TrainType newType;
Tag defaultsTag = tag.getChild("Defaults");
- if (defaultsTag != null) {
- defaultType = new TrainType(false);
- defaultType.configureFromXML(defaultsTag);
- }
+ // We will use this tag later, to preconfigure TrainCertType and TrainType.
- List<Tag> typeTags = tag.getChildren("Train");
+ List<Tag> typeTags;
- for (Tag typeTag : typeTags) {
- if (defaultType != null) {
- newType = (TrainType) defaultType.clone();
- if (newType == null) {
- throw new ConfigurationException("Cannot clone traintype "
- + defaultType.getName());
+ // Choice train types (new style)
+ List<Tag> trainTypeTags = tag.getChildren("TrainType");
+
+ if (trainTypeTags != null) {
+ for (Tag trainTypeTag : trainTypeTags) {
+ TrainCertificateType certType = new TrainCertificateType();
+ if (defaultsTag != null) certType.configureFromXML(defaultsTag);
+ certType.configureFromXML(trainTypeTag);
+ trainCertTypes.add(certType);
+ trainCertTypeMap.put(certType.getName(), certType);
+
+ // The potential train types
+ typeTags = trainTypeTag.getChildren("Train");
+ if (typeTags == null) {
+ // That's OK, all properties are in TrainType, to let's reuse that tag
+ typeTags = Arrays.asList(trainTypeTag);
}
- } else {
- newType = new TrainType(true);
+ for (Tag typeTag : typeTags) {
+ newType = new TrainType();
+ if (defaultsTag != null) newType.configureFromXML(defaultsTag);
+ newType.configureFromXML(trainTypeTag);
+ newType.configureFromXML(typeTag);
+ lTrainTypes.add(newType);
+ mTrainTypes.put(newType.getName(), newType);
+ certType.addPotentialTrainType(newType);
+ }
}
- lTrainTypes.add(newType);
- newType.configureFromXML(typeTag);
- mTrainTypes.put(newType.getName(), newType);
}
+
// Special train buying rules
Tag rulesTag = tag.getChild("TrainBuyingRules");
@@ -99,54 +119,63 @@
trainPriceAtFaceValueIfDifferentPresidents = rulesTag.getChild("FaceValueIfDifferentPresidents") != null;
}
+ // Are trains sold to foreigners?
+ Tag removeTrainTag = tag.getChild("RemoveTrainBeforeSR");
+ if (removeTrainTag != null) {
+ // Trains "bought by foreigners" (1844, 1824)
+ removeTrain = true; // completed in finishConfiguration()
+ }
+
+ }
+
+ public void finishConfiguration (GameManagerI gameManager)
+ throws ConfigurationException {
+ this.gameManager = gameManager;
+ bank = gameManager.getBank();
+ ipo = bank.getIpo();
+ pool = bank.getPool();
+ unavailable = bank.getUnavailable();
+
// Finish initialisation of the train types
Map<Integer, String> rustedTrainTypeNames;
- TrainTypeI rustedType;
- for (TrainTypeI type : lTrainTypes) {
+ TrainCertificateType rustedType;
+ for (TrainCertificateType type : trainCertTypes) {
if (type.getReleasedTrainTypeNames() != null) {
- List<TrainTypeI> rtts = new ArrayList<TrainTypeI>(2);
+ List<TrainCertificateType> rtts = new ArrayList<TrainCertificateType>(2);
for (String ttName : type.getReleasedTrainTypeNames().split(",")) {
- rtts.add (mTrainTypes.get(ttName));
+ rtts.add (trainCertTypeMap.get(ttName));
}
type.setReleasedTrainTypes(rtts);
}
rustedTrainTypeNames = type.getRustedTrainTypeNames();
if (rustedTrainTypeNames != null) {
for (int index : rustedTrainTypeNames.keySet()) {
- rustedType = mTrainTypes.get(rustedTrainTypeNames.get(index));
+ rustedType = trainCertTypeMap.get(rustedTrainTypeNames.get(index));
type.setRustedTrainType(index, rustedType);
rustedType.setPermanent(false);
}
}
}
- // Are trains sold to foreigners?
- Tag removeTrainTag = tag.getChild("RemoveTrainBeforeSR");
- if (removeTrainTag != null) {
- // Trains "bought by foreigners" (1844, 1824)
- removeTrain = true; // completed in finishConfiguration()
- }
-
- }
-
- public void finishConfiguration (GameManagerI gameManager)
- throws ConfigurationException {
- this.gameManager = gameManager;
- bank = gameManager.getBank();
- ipo = bank.getIpo();
- unavailable = bank.getUnavailable();
-
- for (TrainTypeI type : lTrainTypes) {
- type.finishConfiguration(gameManager);
+ for (TrainCertificateType certType : trainCertTypes) {
+ certType.finishConfiguration(gameManager);
+ List<TrainType> types = certType.getPotentialTrainTypes();
+ for (TrainType type : types) {
+ type.finishConfiguration(gameManager, certType);
+ }
+
// Now create the trains of this type
TrainI train;
- /* If the amount is infinite, only one trains is created.
+ // Multi-train certificates cannot yet be assigned a type
+ TrainType initialType = types.size() == 1 ? types.get(0) : null;
+
+ /* If the amount is infinite, only one train is created.
* Each time this train is bought, another one is created.
*/
- for (int i = 0; i < (type.hasInfiniteQuantity() ? 1 : type.getQuantity()); i++) {
- train = type.createTrain ();
- train.init(type, getNewUniqueId(type));
+ for (int i = 0; i < (certType.hasInfiniteQuantity() ? 1 : certType.getQuantity()); i++) {
+ train = certType.createTrain ();
+ train.init(certType, initialType, getNewUniqueId(certType.getName()));
addTrain(train);
unavailable.addTrain(train);
}
@@ -155,7 +184,7 @@
// By default, set the first train type to "available".
newTypeIndex.set(0);
- lTrainTypes.get(newTypeIndex.intValue()).setAvailable(bank);
+ makeTrainAvailable(trainCertTypes.get(newTypeIndex.intValue()));
// Trains "bought by foreigners" (1844, 1824)
if (removeTrain) {
@@ -172,14 +201,16 @@
* i.e. in cloning infinitely available trains.
*/
- public TrainI cloneTrain (TrainTypeI type) {
+ public TrainI cloneTrain (TrainCertificateType certType) {
TrainI train = null;
+ List<TrainType> types = certType.getPotentialTrainTypes();
+ TrainType initialType = types.size() == 1 ? types.get(0) : null;
try {
- train = type.createTrain();
+ train = certType.createTrain();
} catch (ConfigurationException e) {
log.warn("Unexpected exception", e);
}
- train.init(type, getNewUniqueId(type));
+ train.init(certType, initialType, getNewUniqueId(certType.getName()));
addTrain(train);
return train;
}
@@ -187,27 +218,23 @@
public void addTrain (TrainI train) {
trainMap.put(train.getUniqueId(), train);
- TrainTypeI type = train.getType();
- if (!trainsPerType.containsKey(type)) {
- trainsPerType.put (type, new ArrayList<TrainI>());
+ TrainCertificateType type = train.getCertType();
+ if (!trainsPerCertType.containsKey(type)) {
+ trainsPerCertType.put (type, new ArrayList<TrainI>());
}
- trainsPerType.get(type).add(train);
+ trainsPerCertType.get(type).add(train);
}
public TrainI getTrainByUniqueId(String id) {
return trainMap.get(id);
}
- public String getNewUniqueId (TrainTypeI type) {
- int newIndex = lastIndexPerType.containsKey(type) ? lastIndexPerType.get(type) + 1 : 0;
- lastIndexPerType.put (type, newIndex);
- return type.getName() + "_"+ newIndex;
+ public String getNewUniqueId (String typeName) {
+ int newIndex = lastIndexPerType.containsKey(typeName) ? lastIndexPerType.get(typeName) + 1 : 0;
+ lastIndexPerType.put (typeName, newIndex);
+ return typeName + "_"+ newIndex;
}
- public List<TrainI> getTrainsOfType (TrainTypeI type) {
- return trainsPerType.get(type);
- }
-
/**
* This method handles any consequences of new train buying (from the IPO),
* such as rusting and phase changes. It must be called <b>after</b> the
@@ -220,17 +247,17 @@
phaseHasChanged = false;
if (from != ipo) return;
- TrainTypeI boughtType, nextType;
- boughtType = train.getType();
- if (boughtType == (lTrainTypes.get(newTypeIndex.intValue()))
+ TrainCertificateType boughtType, nextType;
+ boughtType = train.getCertType();
+ if (boughtType == (trainCertTypes.get(newTypeIndex.intValue()))
&& ipo.getTrainOfType(boughtType) == null) {
// Last train bought, make a new type available.
newTypeIndex.add(1);
if (newTypeIndex.intValue() < lTrainTypes.size()) {
- nextType = (lTrainTypes.get(newTypeIndex.intValue()));
+ nextType = (trainCertTypes.get(newTypeIndex.intValue()));
if (nextType != null) {
if (!nextType.isAvailable()) {
- nextType.setAvailable(bank);
+ makeTrainAvailable(nextType);
trainAvailabilityChanged = true;
ReportBuffer.add("All " + boughtType.getName()
+ "-trains are sold out, "
@@ -252,11 +279,11 @@
phaseHasChanged = true;
}
- List<TrainTypeI> releasedTypes = boughtType.getReleasedTrainTypes();
+ List<TrainCertificateType> releasedTypes = boughtType.getReleasedTrainTypes();
if (releasedTypes != null) {
- for (TrainTypeI releasedType : releasedTypes) {
+ for (TrainCertificateType releasedType : releasedTypes) {
if (!releasedType.isAvailable()) {
- releasedType.setAvailable(bank);
+ makeTrainAvailable(releasedType);
ReportBuffer.add(LocalText.getText("TrainsAvailable",
releasedType.getName()));
}
@@ -265,10 +292,9 @@
}
}
- TrainTypeI rustedType = boughtType.getRustedTrainType(trainIndex);
+ TrainCertificateType rustedType = boughtType.getRustedTrainType(trainIndex);
if (rustedType != null && !rustedType.hasRusted()) {
- rustedType.setRusted(train.getHolder()); // Or obsolete,
- // where applicable
+ rustTrainType (rustedType, train.getHolder());
if (rustedType.isObsoleting()) {
ReportBuffer.add(LocalText.getText("TrainsObsolete",
rustedType.getName()));
@@ -280,14 +306,46 @@
trainAvailabilityChanged = true;
}
-}
+ }
+
+ protected void makeTrainAvailable (TrainCertificateType type) {
+ type.setAvailable();
+
+ Portfolio to =
+ (type.getInitialPortfolio().equalsIgnoreCase("Pool") ? bank.getPool()
+ : bank.getIpo());
+
+ for (TrainI train : trainsPerCertType.get(type)) {
+ new ObjectMove(train, unavailable, to);
+ }
+ }
+
+ protected void rustTrainType (TrainCertificateType type, Portfolio lastBuyingCompany) {
+ type.setRusted();
+ for (TrainI train : trainsPerCertType.get(type)) {
+ Portfolio holder = train.getHolder();
+ if (type.isObsoleting() && holder.getOwner() instanceof PublicCompanyI
+ && holder != lastBuyingCompany) {
+ log.debug("Train " + train.getUniqueId() + " (owned by "
+ + holder.getName() + ") obsoleted");
+ train.setObsolete();
+ holder.getTrainsModel().update();
+ } else {
+ log.debug("Train " + train.getUniqueId() + " (owned by "
+ + holder.getName() + ") rusted");
+ train.setRusted();
+ }
+ }
+
+ }
+
public List<TrainI> getAvailableNewTrains() {
List<TrainI> availableTrains = new ArrayList<TrainI>();
TrainI train;
- for (TrainTypeI type : lTrainTypes) {
+ for (TrainCertificateType type : trainCertTypes) {
if (type.isAvailable()) {
train = ipo.getTrainOfType(type);
if (train != null) {
@@ -299,25 +357,40 @@
}
public String getTrainCostOverview() {
- StringBuffer b = new StringBuffer();
- for (TrainTypeI type : lTrainTypes) {
- if (b.length() > 1) b.append(" ");
- b.append(type.getName()).append(":").append(Bank.format(type.getCost()));
- if (type.getExchangeCost() > 0) {
- b.append("(").append(Bank.format(type.getExchangeCost())).append(")");
+ StringBuilder b = new StringBuilder();
+ for (TrainCertificateType certType : trainCertTypes) {
+ if (certType.getCost() > 0) {
+ if (b.length() > 1) b.append(" ");
+ b.append(certType.getName()).append(":").append(Bank.format(certType.getCost()));
+ if (certType.getExchangeCost() > 0) {
+ b.append("(").append(Bank.format(certType.getExchangeCost())).append(")");
+ }
+ } else {
+ for (TrainType type : certType.getPotentialTrainTypes()) {
+ if (b.length() > 1) b.append(" ");
+ b.append(type.getName()).append(":").append(Bank.format(type.getCost()));
+ }
}
}
return b.toString();
}
- public TrainTypeI getTypeByName(String name) {
+ public TrainType getTypeByName(String name) {
return mTrainTypes.get(name);
}
- public List<TrainTypeI> getTrainTypes() {
+ public List<TrainType> getTrainTypes() {
return lTrainTypes;
}
+ public List<TrainCertificateType> getTrainCertTypes() {
+ return trainCertTypes;
+ }
+
+ public TrainCertificateType getCertTypeByName (String name) {
+ return trainCertTypeMap.get(name);
+ }
+
public boolean hasAvailabilityChanged() {
return trainAvailabilityChanged;
}
Modified: trunk/18xx/rails/game/TrainType.java
===================================================================
--- trunk/18xx/rails/game/TrainType.java 2011-06-21 21:21:43 UTC (rev 1580)
+++ trunk/18xx/rails/game/TrainType.java 2011-06-21 21:25:49 UTC (rev 1581)
@@ -1,67 +1,38 @@
/* $Header: /Users/blentz/rails_rcs/cvs/18xx/rails/game/TrainType.java,v 1.32 2010/05/11 21:47:21 stefanfrey Exp $ */
package rails.game;
-import java.util.*;
-
import org.apache.log4j.Logger;
-import rails.game.move.ObjectMove;
import rails.game.state.BooleanState;
-import rails.game.state.IntegerState;
import rails.util.*;
-public class TrainType implements TrainTypeI {
+public class TrainType implements Cloneable {
public final static int TOWN_COUNT_MAJOR = 2;
public final static int TOWN_COUNT_MINOR = 1;
public final static int NO_TOWN_COUNT = 0;
- protected String trainClassName = "rails.game.Train";
- protected Class<? extends Train> trainClass;
-
protected String name;
- protected int quantity;
- protected boolean infiniteQuantity = false;
+ protected TrainCertificateType certificateType;
- private String reachBasis = "stops";
+ protected String reachBasis = "stops";
protected boolean countHexes = false;
- private String countTowns = "major";
+ protected String countTowns = "major";
protected int townCountIndicator = TOWN_COUNT_MAJOR;
- private String scoreTowns = "yes";
+ protected String scoreTowns = "yes";
protected int townScoreFactor = 1;
- private String scoreCities = "single";
+ protected String scoreCities = "single";
protected int cityScoreFactor = 1;
- protected boolean canBeExchanged = false;
- protected IntegerState numberBoughtFromIPO;
-
- protected boolean obsoleting = false;
-
- protected boolean permanent = true;
-
- private boolean real; // Only to determine if top-level attributes must be
- // read.
-
protected int cost;
protected int majorStops;
protected int minorStops;
- protected int exchangeCost;
- protected String startedPhaseName = null;
- // Phase startedPhase;
-
- private Map<Integer, String> rustedTrainTypeNames = null;
- protected Map<Integer, TrainTypeI> rustedTrainType = null;
-
- private String releasedTrainTypeNames = null;
- protected List<TrainTypeI> releasedTrainTypes = null;
-
protected int lastIndex = 0;
- protected BooleanState available;
protected BooleanState rusted;
protected TrainManager trainManager;
@@ -76,96 +47,26 @@
* @param real False for the default type, else real. The default type does
* not have top-level attributes.
*/
- public TrainType(boolean real) {
- this.real = real;
+ public TrainType() {
}
/**
* @see rails.game.ConfigurableComponentI#configureFromXML(org.w3c.dom.Element)
*/
public void configureFromXML(Tag tag) throws ConfigurationException {
- trainClassName = tag.getAttributeAsString("class", trainClassName);
- try {
- trainClass = Class.forName(trainClassName).asSubclass(Train.class);
- } catch (ClassNotFoundException e) {
- throw new ConfigurationException("Class " + trainClassName
- + "not found", e);
- }
- if (real) {
- // Name
- name = tag.getAttributeAsString("name");
- if (name == null) {
- throw new ConfigurationException(
- LocalText.getText("NoNameSpecified"));
- }
+ // Name
+ name = tag.getAttributeAsString("name");
- // Cost
- cost = tag.getAttributeAsInteger("cost");
- if (cost == 0) {
- throw new ConfigurationException(
- LocalText.getText("InvalidCost"));
- }
+ // Cost
+ cost = tag.getAttributeAsInteger("cost");
- // Amount
- quantity = tag.getAttributeAsInteger("quantity");
- if (quantity == -1) {
- infiniteQuantity = true;
- } else if (quantity <= 0) {
- throw new ConfigurationException(
- LocalText.getText("InvalidQuantity", String.valueOf(quantity)));
- } else {
- quantity += tag.getAttributeAsInteger("quantityIncrement", 0);
- }
+ // Major stops
+ majorStops = tag.getAttributeAsInteger("majorStops");
- // Major stops
- majorStops = tag.getAttributeAsInteger("majorStops");
- if (majorStops == 0) {
- throw new ConfigurationException(
- LocalText.getText("InvalidStops"));
- }
+ // Minor stops
+ minorStops = tag.getAttributeAsInteger("minorStops");
- // Minor stops
- minorStops = tag.getAttributeAsInteger("minorStops");
-
- // Phase started
- startedPhaseName = tag.getAttributeAsString("startPhase", "");
-
- // Train type rusted
- String rustedTrainTypeName1 = tag.getAttributeAsString("rustedTrain");
- if (Util.hasValue(rustedTrainTypeName1)) {
- rustedTrainTypeNames = new HashMap<Integer, String>();
- rustedTrainTypeNames.put(1, rustedTrainTypeName1);
- }
-
- // Other train type released for buying
- releasedTrainTypeNames = tag.get...
[truncated message content] |