You can subscribe to this list here.
2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(3) |
Nov
(46) |
Dec
(57) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2009 |
Jan
(51) |
Feb
(10) |
Mar
|
Apr
|
May
(14) |
Jun
|
Jul
(13) |
Aug
(30) |
Sep
(83) |
Oct
(56) |
Nov
(148) |
Dec
(107) |
2010 |
Jan
(260) |
Feb
(164) |
Mar
(183) |
Apr
(99) |
May
(160) |
Jun
(40) |
Jul
(33) |
Aug
(48) |
Sep
(22) |
Oct
(24) |
Nov
(1) |
Dec
(12) |
2011 |
Jan
(6) |
Feb
(15) |
Mar
(13) |
Apr
(37) |
May
(27) |
Jun
(29) |
Jul
(33) |
Aug
(20) |
Sep
(17) |
Oct
(20) |
Nov
(33) |
Dec
(17) |
2012 |
Jan
(39) |
Feb
(38) |
Mar
(20) |
Apr
(21) |
May
(17) |
Jun
(22) |
Jul
(16) |
Aug
(3) |
Sep
(9) |
Oct
(10) |
Nov
|
Dec
|
From: Erik V. <ev...@us...> - 2010-04-15 19:49:10
|
Update of /cvsroot/rails/18xx/rails/game In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv18933/rails/game Modified Files: MapHex.java Log Message: Fixed reserved token spot detection Index: MapHex.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/MapHex.java,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** MapHex.java 11 Apr 2010 15:49:47 -0000 1.42 --- MapHex.java 15 Apr 2010 19:49:02 -0000 1.43 *************** *** 975,978 **** --- 975,979 ---- */ public boolean isBlockedForTokenLays(PublicCompanyI company, int cityNumber) { + if (isHomeFor(company)) // Company can always lay a home base *************** *** 984,989 **** return isBlockedForTokenLays.booleanValue(); } else if (homes != null && !homes.isEmpty()) { // Check if this token lay does not block an unlaid home base ! for (City city : homes.values()) { if (cityNumber == city.getNumber() // Assume that a city is never home to more than one company --- 985,993 ---- return isBlockedForTokenLays.booleanValue(); } else if (homes != null && !homes.isEmpty()) { + City city; // Check if this token lay does not block an unlaid home base ! for (PublicCompanyI comp : homes.keySet()) { ! if (comp.hasLaidHomeBaseTokens() || comp.isClosed()) continue; ! city = homes.get(comp); if (cityNumber == city.getNumber() // Assume that a city is never home to more than one company |
From: Stefan F. <ste...@us...> - 2010-04-14 16:49:24
|
Update of /cvsroot/rails/18xx/test/data/1889/pbem In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv21721/test/data/1889/pbem Added Files: 1889_A_OR6.rails 1889_A_OR6.txt 1889_A_OR6.report Log Message: Added 1889 test game from Phil Davies --- NEW FILE: 1889_A_OR6.txt --- Author: Phil Davies 3 players State: in progress Date: 2010-04-10 Rails 1.2 --- NEW FILE: 1889_A_OR6.rails --- (This appears to be a binary file; contents omitted.) --- NEW FILE: 1889_A_OR6.report --- (This appears to be a binary file; contents omitted.) |
Update of /cvsroot/rails/18xx/rails/algorithms In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv19400/rails/algorithms Modified Files: NetworkTrain.java RevenueCalculator.java RevenueAdapter.java NetworkEdge.java NetworkVertex.java NetworkGraphBuilder.java Log Message: Updated revenue calculation: Added revenue prediction and several bug fixes. Index: RevenueCalculator.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/algorithms/RevenueCalculator.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** RevenueCalculator.java 12 Apr 2010 17:37:32 -0000 1.1 --- RevenueCalculator.java 13 Apr 2010 23:21:12 -0000 1.2 *************** *** 29,33 **** // static train data private final int[] trainMaxCities; ! private final int[] trainMaxCombined; private final boolean[] trainTownsCostNothing; private final int[] trainMultiplyCities; --- 29,33 ---- // static train data private final int[] trainMaxCities; ! private final int[] trainMaxTowns; private final boolean[] trainTownsCostNothing; private final int[] trainMultiplyCities; *************** *** 35,40 **** // dynamic train data ! private final int[] trainCityValue; ! private final int[] trainTownValue; private final int[] trainCities; private final int[] trainTowns; --- 35,39 ---- // dynamic train data ! private final int[] trainCurrentValue; private final int[] trainCities; private final int[] trainTowns; *************** *** 52,55 **** --- 51,59 ---- private int countEdges; + // prediction data + private int[] maxCityRevenues; + private int[] maxTownRevenues; + private int[] maxTrainRevenues; + protected static Logger log = *************** *** 81,88 **** trainMultiplyTowns = new int[nbTrains]; ! trainCityValue = new int[nbTrains]; ! trainTownValue = new int[nbTrains]; trainMaxCities = new int[nbTrains]; ! trainMaxCombined = new int[nbTrains]; trainVisited = new boolean[nbTrains][nbVertexes]; trainVertexStack = new int[nbTrains][nbVertexes]; --- 85,91 ---- trainMultiplyTowns = new int[nbTrains]; ! trainCurrentValue = new int[nbTrains]; trainMaxCities = new int[nbTrains]; ! trainMaxTowns = new int[nbTrains]; trainVisited = new boolean[nbTrains][nbVertexes]; trainVertexStack = new int[nbTrains][nbVertexes]; *************** *** 112,116 **** void setTrain(int id, int cities, int towns, boolean townsCostNothing, int multiplyCities, int multiplyTowns) { trainMaxCities[id] = cities; ! trainMaxCombined[id] = cities + towns; trainTownsCostNothing[id] = townsCostNothing; trainMultiplyCities[id] = multiplyCities; --- 115,119 ---- void setTrain(int id, int cities, int towns, boolean townsCostNothing, int multiplyCities, int multiplyTowns) { trainMaxCities[id] = cities; ! trainMaxTowns[id] = towns; trainTownsCostNothing[id] = townsCostNothing; trainMultiplyCities[id] = multiplyCities; *************** *** 118,121 **** --- 121,129 ---- } + void setPredictionData(int[] maxCityRevenues, int[] maxTownRevenues) { + this.maxCityRevenues = maxCityRevenues; + this.maxTownRevenues = maxTownRevenues; + } + int[][] getOptimalRun() { return currentBestRun; *************** *** 123,127 **** int calculateRevenue(int startTrain, int finalTrain) { ! log.debug("RC: calculateRevenue trains from " + startTrain + " to " + finalTrain); this.finalTrain = finalTrain; --- 131,142 ---- int calculateRevenue(int startTrain, int finalTrain) { ! log.info("RC: calculateRevenue trains from " + startTrain + " to " + finalTrain); ! ! // initialize maximum train revenues ! maxTrainRevenues = new int[nbTrains]; ! for (int j=0; j < nbTrains; j++) { ! maxTrainRevenues[j] = maxCityRevenues[trainMaxCities[j]] * trainMultiplyCities[j] + ! maxTownRevenues[trainMaxTowns[j]] * trainMultiplyTowns[j]; ! } this.finalTrain = finalTrain; *************** *** 131,135 **** private void runTrain(int trainId) { ! log.debug("RC: startTrain " + trainId); // initialize the positions --- 146,150 ---- private void runTrain(int trainId) { ! log.debug("RC: runTrain " + trainId); // initialize the positions *************** *** 141,159 **** int vertexId = startVertexes[i]; log.debug("RC: Using startVertex nr. " + i + " for train " + trainId); ! encounterVertex(trainId, startVertexes[i], true); // and all edges of it boolean evaluateResult = true; ! for (int j = 0; j < maxNeighbors; j++) { ! int neighborId = vertexNeighbors[vertexId][j]; ! log.debug("RC: Testing Neighbor Nr. " + j + " of startVertex is " + neighborId); ! if (neighborId == -1) break; // no more neighbors ! if (travelEdge(vertexId, neighborId, true)) { ! evaluateResult = false; ! trainStartEdge[trainId] = j; // store edge ! nextVertex(trainId, neighborId, vertexId); } } // no more edges to find ! finalizeVertex(trainId, evaluateResult); encounterVertex(trainId, startVertexes[i], false); log.debug("RC: finished startVertex " + vertexId + " for train " +trainId); --- 156,185 ---- int vertexId = startVertexes[i]; log.debug("RC: Using startVertex nr. " + i + " for train " + trainId); ! ! // check train termination and revenue prediction after visit ! boolean trainTerminated; ! if (encounterVertex(trainId, startVertexes[i], true)) { ! trainTerminated = trainTerminated(trainId) || (predictRevenues(trainId)); ! } else { ! trainTerminated = false; ! } ! // and all edges of it boolean evaluateResult = true; ! if (!trainTerminated) { ! for (int j = 0; j < maxNeighbors; j++) { ! int neighborId = vertexNeighbors[vertexId][j]; ! log.debug("RC: Testing Neighbor Nr. " + j + " of startVertex is " + neighborId); ! if (neighborId == -1) break; // no more neighbors ! if (travelEdge(vertexId, neighborId, true)) { ! evaluateResult = false; ! trainStartEdge[trainId] = j; // store edge ! nextVertex(trainId, neighborId, vertexId); ! } } } + // no more edges to find ! finalizeVertex(trainId, startVertexes[i], evaluateResult); encounterVertex(trainId, startVertexes[i], false); log.debug("RC: finished startVertex " + vertexId + " for train " +trainId); *************** *** 162,167 **** } ! private void startBottom(int trainId) { ! log.debug("RC: startBottom " +trainId); trainBottomPos[trainId] = trainStackPos[trainId]; // store the stack position where bottom starts --- 188,193 ---- } ! private void runBottom(int trainId) { ! log.debug("RC: runBottom " +trainId); trainBottomPos[trainId] = trainStackPos[trainId]; // store the stack position where bottom starts *************** *** 198,203 **** // 1. add vertex to path and returns true if train terminated (if start = 0, otherwise it is a revisit of the start) ! encounterVertex(trainId, vertexId, true); ! boolean trainTerminated = trainTerminated(trainId); // 2a. visit neighbors, if train has not terminated --- 224,233 ---- // 1. add vertex to path and returns true if train terminated (if start = 0, otherwise it is a revisit of the start) ! boolean trainTerminated; ! if (encounterVertex(trainId, vertexId, true)) { ! trainTerminated = trainTerminated(trainId) || (predictRevenues(trainId)); ! } else { ! trainTerminated = false; ! } // 2a. visit neighbors, if train has not terminated *************** *** 219,228 **** // 2b. restart at startVertex for bottom part if (trainBottomPos[trainId] == 0 && (vertexCity[vertexId] || vertexTown[vertexId])){ ! startBottom(trainId); } } // 3. no more edges to visit from here => evaluate or start new train ! finalizeVertex(trainId, evaluateResult); // 4. then leave that vertex --- 249,258 ---- // 2b. restart at startVertex for bottom part if (trainBottomPos[trainId] == 0 && (vertexCity[vertexId] || vertexTown[vertexId])){ ! runBottom(trainId); } } // 3. no more edges to visit from here => evaluate or start new train ! finalizeVertex(trainId, vertexId, evaluateResult); // 4. then leave that vertex *************** *** 231,235 **** } ! private void encounterVertex(int trainId, int vertexId, boolean arrive) { log.debug("RC: EncounterVertex, trainId = " + trainId + " vertexId = " + vertexId + " arrive = " + arrive); --- 261,265 ---- } ! private boolean encounterVertex(int trainId, int vertexId, boolean arrive) { log.debug("RC: EncounterVertex, trainId = " + trainId + " vertexId = " + vertexId + " arrive = " + arrive); *************** *** 238,248 **** trainVisited[trainId][vertexId] = arrive; if (arrive) { if (vertexCity[vertexId]) { trainCities[trainId]++; ! trainCityValue[trainId] += vertexValue[vertexId]; } else if (vertexTown[vertexId]) { trainTowns[trainId]++; ! trainTownValue[trainId] += vertexValue[vertexId]; } trainVertexStack[trainId][trainStackPos[trainId]++] = vertexId; // push to stack --- 268,281 ---- trainVisited[trainId][vertexId] = arrive; + boolean valueVertex = false; if (arrive) { if (vertexCity[vertexId]) { trainCities[trainId]++; ! trainCurrentValue[trainId] += vertexValue[vertexId] * trainMultiplyCities[trainId]; ! valueVertex = true; } else if (vertexTown[vertexId]) { trainTowns[trainId]++; ! trainCurrentValue[trainId] += vertexValue[vertexId] * trainMultiplyTowns[trainId]; ! valueVertex = true; } trainVertexStack[trainId][trainStackPos[trainId]++] = vertexId; // push to stack *************** *** 251,258 **** if (vertexCity[vertexId]) { trainCities[trainId]--; ! trainCityValue[trainId] -= vertexValue[vertexId]; } else if (vertexTown[vertexId]) { trainTowns[trainId]--; ! trainTownValue[trainId] -= vertexValue[vertexId]; } trainStackPos[trainId]--; // pull from stack --- 284,293 ---- if (vertexCity[vertexId]) { trainCities[trainId]--; ! trainCurrentValue[trainId] -= vertexValue[vertexId] * trainMultiplyCities[trainId]; ! valueVertex = true; } else if (vertexTown[vertexId]) { trainTowns[trainId]--; ! trainCurrentValue[trainId] -= vertexValue[vertexId] * trainMultiplyTowns[trainId]; ! valueVertex = true; } trainStackPos[trainId]--; // pull from stack *************** *** 260,263 **** --- 295,299 ---- } log.debug("RC: Count Visits = " + countVisits); + return valueVertex; } *************** *** 310,327 **** if (trainTownsCostNothing[trainId]) { terminated = trainCities[trainId] == trainMaxCities[trainId]; } else { ! terminated = trainCities[trainId] > trainMaxCities[trainId] || ! (trainCities[trainId] + trainTowns[trainId] == trainMaxCombined[trainId]); } if (terminated) { log.debug ("RC: Train " + trainId + " has terminated: " + "cities = " + trainCities[trainId] + " towns = " + trainTowns[trainId] + ! "maxCities = " + trainMaxCities[trainId] + "maxCombined = " + trainMaxCombined[trainId]); } return terminated; } ! private void finalizeVertex(int trainId, boolean evaluate) { ! log.debug("RC: No more edges found for " + trainId); if (trainId == finalTrain) { if (evaluate) evaluateResults(); --- 346,376 ---- if (trainTownsCostNothing[trainId]) { terminated = trainCities[trainId] == trainMaxCities[trainId]; + } else if (trainTowns[trainId] == 0) { + // default train + terminated = trainCities[trainId] + trainTowns[trainId] == trainMaxCities[trainId]; } else { ! // plus trains ! int townDiff = trainMaxTowns[trainId] - trainTowns[trainId]; ! if (townDiff > 0) { ! terminated = false; ! } else if (townDiff == 0) { ! terminated = trainCities[trainId] == trainMaxCities[trainId]; ! } else { // negative townDiff, thus too many towns already visited ! terminated = trainCities[trainId] == trainMaxCities[trainId] + townDiff; ! } } if (terminated) { log.debug ("RC: Train " + trainId + " has terminated: " + "cities = " + trainCities[trainId] + " towns = " + trainTowns[trainId] + ! "maxCities = " + trainMaxCities[trainId] + "maxTowns = " + trainMaxTowns[trainId]); } return terminated; } ! private void finalizeVertex(int trainId, int vertexId, boolean evaluate) { ! log.debug("RC: No more edges found at " + vertexId + " for train " + trainId); ! ! if (!vertexCity[vertexId] && !vertexTown[vertexId]) return; ! if (trainId == finalTrain) { if (evaluate) evaluateResults(); *************** *** 335,347 **** int totalValue = 0; for (int j = 0; j <= finalTrain; j++) { - int trainValue; if (trainCities[j] + trainTowns[j] <= 1) { ! trainValue = 0; // one station is not enough } else { ! trainValue = trainCityValue[j] * trainMultiplyCities[j] + trainTownValue[j] * trainMultiplyTowns[j]; ! } ! totalValue += trainValue; ! log.debug("RC: Train " + j + " has value of " + trainValue); } // compare to current best result if (totalValue > currentBestValue) { --- 384,396 ---- int totalValue = 0; for (int j = 0; j <= finalTrain; j++) { if (trainCities[j] + trainTowns[j] <= 1) { ! log.debug("RC: Train " + j + " has no value / does not have 2+ stations"); } else { ! totalValue += trainCurrentValue[j]; ! log.debug("RC: Train " + j + " has value of " + trainCurrentValue); ! } } + log.debug("RC: current total value " + totalValue); + // compare to current best result if (totalValue > currentBestValue) { *************** *** 360,363 **** --- 409,457 ---- } + // predict revenues and returns true if best value can still be exceeded + private boolean predictRevenues(int trainId){ + int totalValue = 0; + + for (int j = 0; j <= finalTrain; j++) { + int trainValue; + if (j < trainId) { // train has run already => use realized values + trainValue = trainCurrentValue[j]; + } else if (j > trainId) { // train is in the future => use maximum values + trainValue = maxTrainRevenues[j]; + } else { // the current train + if (trainTownsCostNothing[trainId]) { + // still TODO + trainValue = 0; + } else if (trainTowns[trainId] == 0) { + // default train + trainValue = trainCurrentValue[j] + + maxCityRevenues[trainMaxCities[j] - trainCities[j]] * trainMultiplyCities[j]; + } else { + // plus trains + int townDiff = trainMaxTowns[trainId] - trainTowns[trainId]; + if (townDiff > 0) { + trainValue = trainCurrentValue[j] + + maxCityRevenues[trainMaxCities[j] - trainCities[j]] * trainMultiplyCities[j] + + maxTownRevenues[trainMaxTowns[j] - trainTowns[j]] * trainMultiplyTowns[j]; + } else if (townDiff == 0) { + trainValue = trainCurrentValue[j] + + maxCityRevenues[trainMaxCities[j] - trainCities[j]] * trainMultiplyCities[j]; + } else { // negative townDiff, thus too many towns already visited + trainValue = trainCurrentValue[j] + + maxCityRevenues[trainMaxCities[j] - trainCities[j] + townDiff] * trainMultiplyCities[j]; + } + } + } + log.debug("RC: Train " + j + " has value of " + trainValue); + totalValue += Math.min(trainValue, maxTrainRevenues[trainId]); + } + + boolean terminate = (totalValue < currentBestValue); + if (terminate) log.debug("Run terminated due to predicted value of " + totalValue); + + return terminate; + } + + @Override *************** *** 365,375 **** StringBuffer buffer = new StringBuffer(); ! buffer.append("vertexValue:" + Arrays.toString(vertexValue)); ! buffer.append("vertexCity:" + Arrays.toString(vertexCity)); ! buffer.append("vertexTown:" + Arrays.toString(vertexTown)); ! buffer.append("vertexEdges:" + Arrays.deepToString(vertexNeighbors)); ! buffer.append("edgeGreedy:" + Arrays.deepToString(edgeGreedy)); ! buffer.append("edgeDistance:" + Arrays.deepToString(edgeDistance)); ! buffer.append("startVertexes:" + Arrays.toString(startVertexes)); return buffer.toString(); --- 459,473 ---- StringBuffer buffer = new StringBuffer(); ! buffer.append("vertexValues:" + Arrays.toString(vertexValue) + "\n"); ! buffer.append("vertexCity:" + Arrays.toString(vertexCity) + "\n"); ! buffer.append("vertexTown:" + Arrays.toString(vertexTown) + "\n"); ! buffer.append("vertexEdges:" + Arrays.deepToString(vertexNeighbors) + "\n"); ! // buffer.append("edgeGreedy:" + Arrays.deepToString(edgeGreedy)); ! // buffer.append("edgeDistance:" + Arrays.deepToString(edgeDistance)); ! buffer.append("startVertexes:" + Arrays.toString(startVertexes) + "\n"); ! buffer.append("trainMaxCities:" + Arrays.toString(trainMaxCities) + "\n"); ! buffer.append("trainMaxTowns:" + Arrays.toString(trainMaxTowns) + "\n"); ! buffer.append("maxCityRevenues:" + Arrays.toString(maxCityRevenues) + "\n"); ! buffer.append("maxTownRevenues:" + Arrays.toString(maxTownRevenues) + "\n"); return buffer.toString(); Index: NetworkVertex.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/algorithms/NetworkVertex.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** NetworkVertex.java 12 Apr 2010 17:37:32 -0000 1.4 --- NetworkVertex.java 13 Apr 2010 23:21:12 -0000 1.5 *************** *** 1,4 **** --- 1,6 ---- package rails.algorithms; + import java.util.Collection; + import java.util.Comparator; import java.util.HashSet; import java.util.List; *************** *** 28,31 **** --- 30,35 ---- private final int side; + private PhaseI phase; + private boolean tokenable; private Set<PublicCompanyI> companiesHaveToken; *************** *** 33,36 **** --- 37,44 ---- public NetworkVertex(MapHex hex, Station station) { + this(hex, station, null); + } + + public NetworkVertex(MapHex hex, Station station, PhaseI phase) { this.type = VertexType.STATION; this.hex = hex; *************** *** 38,41 **** --- 46,51 ---- this.side = 0; + this.phase = phase; + String t = station.getType(); if (t.equals(Station.TOWN)){ *************** *** 71,74 **** --- 81,86 ---- this.station = null; this.side = (side % 6); + + this.phase = null; this.tokenable = false; this.companiesHaveToken = null; *************** *** 81,84 **** --- 93,98 ---- this.station = null; this.side = 0; + + this.phase = null; this.tokenable = false; this.companiesHaveToken = null; *************** *** 133,136 **** --- 147,162 ---- } + public int getValue() { + return getValue(this.phase); + } + + public PhaseI getPhase(){ + return phase; + } + + public void setPhase(PhaseI phase){ + this.phase = phase; + } + /** * Checks if a vertex is fully tokened *************** *** 201,203 **** --- 227,244 ---- } + public static final class ValueOrder implements Comparator<NetworkVertex> { + + public int compare(NetworkVertex vA, NetworkVertex vB) { + int result = -((Integer)vA.getValue()).compareTo(vB.getValue()); // compare by value, descending + if (result == 0) + result = vA.compareTo(vB); // otherwise use natural ordering + return result; + } + } + + public static void setPhaseForAll(Collection<NetworkVertex> vertexes, PhaseI phase) { + for (NetworkVertex v:vertexes) + v.setPhase(phase); + } + } Index: RevenueAdapter.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/algorithms/RevenueAdapter.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** RevenueAdapter.java 12 Apr 2010 17:37:32 -0000 1.1 --- RevenueAdapter.java 13 Apr 2010 23:21:12 -0000 1.2 *************** *** 2,5 **** --- 2,7 ---- import java.util.ArrayList; + import java.util.Arrays; + import java.util.Collections; import java.util.HashMap; import java.util.List; *************** *** 22,25 **** --- 24,28 ---- private List<NetworkVertex> vertexes; private List<NetworkEdge> edges; + private List<NetworkVertex> startVertexes; private List<NetworkTrain> trains; *************** *** 30,33 **** --- 33,37 ---- this.edges = new ArrayList<NetworkEdge>(graph.edgeSet()); this.trains = new ArrayList<NetworkTrain>(); + this.startVertexes = new ArrayList<NetworkVertex>(); } *************** *** 48,68 **** } public void populateRevenueCalculator(PublicCompanyI company, PhaseI phase){ if (rc == null) initRevenueCalculator(); ! // set vertexes for (int id=0; id < vertexes.size(); id++){ NetworkVertex v = vertexes.get(id); if (v.isHQ()) { ! // HQ is not added to list, but used to assign startVertexes ! List<NetworkVertex> hqNeighbors = Graphs.neighborListOf(graph, v); ! int[] startVertexes = new int[hqNeighbors.size()]; ! for (int j=0; j < hqNeighbors.size(); j++) { ! startVertexes[j] = vertexes.lastIndexOf(hqNeighbors.get(j)); ! } ! rc.setStartVertexes(startVertexes); } else { // prepare values ! int value = v.getValue(phase); boolean city = v.isCityType(); boolean town = v.isTownType(); --- 52,111 ---- } + + private int[] revenueList(List<NetworkVertex> vertexes, int maxLength) { + Collections.sort(vertexes, new NetworkVertex.ValueOrder()); + + int[] revenue = new int[maxLength + 1]; + revenue[0] = 0; + for (int j=1; j <= maxLength; j++) { + revenue[j] = revenue[j-1] + vertexes.get(j-1).getValue(); + } + + return revenue; + } + + public void activateRevenuePrediction() { + + // separate vertexes + List<NetworkVertex> cities = new ArrayList<NetworkVertex>(); + List<NetworkVertex> towns = new ArrayList<NetworkVertex>(); + for (NetworkVertex vertex: vertexes) { + if (vertex.isCityType()) cities.add(vertex); + if (vertex.isTownType()) towns.add(vertex); + } + + // check train lengths + int maxCityLength = 0, maxTownLength = 0; + for (NetworkTrain train: trains) { + maxCityLength = Math.max(maxCityLength, train.getCities()); + maxTownLength = Math.max(maxTownLength, train.getTowns()); + } + + // get max revenue results + int[] maxCityRevenues = revenueList(cities, maxCityLength); + int[] maxTownRevenues = revenueList(towns, maxTownLength); + + // set revenue results in revenue calculator + rc.setPredictionData(maxCityRevenues, maxTownRevenues); + } + + public void populateRevenueCalculator(PublicCompanyI company, PhaseI phase){ if (rc == null) initRevenueCalculator(); ! // set vertexes + + // Define ordering on vertexes by value + NetworkVertex.setPhaseForAll(vertexes, phase); + Collections.sort(vertexes, new NetworkVertex.ValueOrder()); + for (int id=0; id < vertexes.size(); id++){ NetworkVertex v = vertexes.get(id); if (v.isHQ()) { ! // HQ is not added to list, but used to assign startVertexes ! startVertexes.addAll(Graphs.neighborListOf(graph, v)); } else { // prepare values ! int value = v.getValue(); boolean city = v.isCityType(); boolean town = v.isTownType(); *************** *** 75,83 **** } } e[j] = -1; // stop rc.setVertex(id, value, city, town, e); } } ! // set edges for (int id=0; id < edges.size(); id++) { --- 118,136 ---- } } + // sort by value order + Arrays.sort(e, 0, j); e[j] = -1; // stop rc.setVertex(id, value, city, town, e); } } ! ! // set startVertexes ! int[] sv = new int[startVertexes.size()]; ! for (int j=0; j < startVertexes.size(); j++) { ! sv[j] = vertexes.lastIndexOf(startVertexes.get(j)); ! } ! Arrays.sort(sv); // sort by value order ! rc.setStartVertexes(sv); ! // set edges for (int id=0; id < edges.size(); id++) { *************** *** 115,120 **** String trainName = railsTrain.getName(); ! NetworkTrain networkTrain = new NetworkTrain(cities, towns, townsCostNothing, multiplyCities, multiplyTowns, trainName); ! trains.add(networkTrain); } --- 168,175 ---- String trainName = railsTrain.getName(); ! if (cities > 0 || towns > 0) { // protection against pullman ! NetworkTrain networkTrain = new NetworkTrain(cities, towns, townsCostNothing, multiplyCities, multiplyTowns, trainName); ! trains.add(networkTrain); ! } } *************** *** 147,150 **** --- 202,209 ---- } + public void addStartVertex(NetworkVertex v) { + startVertexes.add(v); + } + public Map<NetworkTrain, List<NetworkVertex>> getOptimalRun() { int[][] optimalRunRaw = rc.getOptimalRun(); Index: NetworkGraphBuilder.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/algorithms/NetworkGraphBuilder.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** NetworkGraphBuilder.java 12 Apr 2010 17:37:32 -0000 1.5 --- NetworkGraphBuilder.java 13 Apr 2010 23:21:12 -0000 1.6 *************** *** 20,23 **** --- 20,24 ---- import org.jgrapht.Graphs; import org.jgrapht.ext.JGraphModelAdapter; + import org.jgrapht.graph.Multigraph; import org.jgrapht.graph.SimpleGraph; import org.jgrapht.graph.Subgraph; *************** *** 163,173 **** for (TokenI token:tokens){ ! if (!(token instanceof BaseToken)) continue; ! TokenHolder holder = token.getHolder(); ! if (!(holder instanceof City)) continue; ! City city = (City)holder; ! MapHex hex = city.getHolder(); ! Station station = city.getRelatedStation(); ! NetworkVertex vertex = getVertex(hex, station); vertexes.add(vertex); // add connection to graph --- 164,169 ---- for (TokenI token:tokens){ ! NetworkVertex vertex = getVertex(token); ! if (vertex == null) continue; vertexes.add(vertex); // add connection to graph *************** *** 196,199 **** --- 192,205 ---- } + public NetworkVertex getVertex(TokenI token) { + if (!(token instanceof BaseToken)) return null; + TokenHolder holder = token.getHolder(); + if (!(holder instanceof City)) return null; + City city = (City)holder; + MapHex hex = city.getHolder(); + Station station = city.getRelatedStation(); + return getVertex(hex, station); + } + private NetworkVertex getVertex(MapHex hex, Station station) { return mapVertexes.get(hex.getName() + "." + -station.getNumber()); *************** *** 234,239 **** ! public static void optimizeGraph(Graph<NetworkVertex, NetworkEdge> graph) { while (removeVertexes(graph)); } --- 240,262 ---- ! public static Graph<NetworkVertex, NetworkEdge> optimizeGraph(Graph<NetworkVertex, NetworkEdge> graph) { ! ! // convert graph ! // Graph<NetworkVertex, NetworkEdge> graph = new Multigraph<NetworkVertex, NetworkEdge>(NetworkEdge.class); ! // Graphs.addGraph(graph, graphIn); ! ! // increase greedness ! for (NetworkEdge edge:graph.edgeSet()) { ! NetworkVertex source = edge.getSource(); ! NetworkVertex target = edge.getTarget(); ! if ((source.isSide() && graph.edgesOf(source).size() == 2 || source.isStation()) && ! target.isSide() && graph.edgesOf(target).size() == 2 || target.isStation()) { ! edge.setGreedy(true); ! } ! } ! while (removeVertexes(graph)); + + return graph; } *************** *** 243,265 **** boolean removed = false; for (NetworkVertex vertex:graph.vertexSet()) { ! if (!vertex.isSide()) continue; ! if (graph.edgesOf(vertex).size() == 1) { graph.removeVertex(vertex); removed = true; break; ! } else if (graph.edgesOf(vertex).size() == 2) { // vertex is not necessary ! // reconnect ! NetworkEdge[] edges = graph.edgesOf(vertex).toArray(new NetworkEdge[2]); ! NetworkVertex firstVertex = Graphs.getOppositeVertex(graph, edges[0], vertex); ! NetworkVertex secondVertex = Graphs.getOppositeVertex(graph, edges[1], vertex); ! boolean greedy = edges[0].isGreedy() || edges[1].isGreedy(); ! int distance = edges[0].getDistance() + edges[1].getDistance(); ! graph.addEdge(firstVertex, secondVertex, ! new NetworkEdge(firstVertex, secondVertex, greedy, distance)); ! // remove vertex graph.removeVertex(vertex); removed = true; break; } } --- 266,308 ---- boolean removed = false; for (NetworkVertex vertex:graph.vertexSet()) { ! Set<NetworkEdge> vertexEdges = graph.edgesOf(vertex); ! // remove singletons ! if (vertexEdges.size() == 0) { graph.removeVertex(vertex); removed = true; break; ! } ! ! // the following only for side vertexes ! if (!vertex.isSide()) continue; ! ! if (vertexEdges.size() == 1) { graph.removeVertex(vertex); removed = true; break; + } else if (vertexEdges.size() == 2) { // vertex is not necessary + NetworkEdge[] edges = vertexEdges.toArray(new NetworkEdge[2]); + if (edges[0].isGreedy() == edges[1].isGreedy()) { + if (!edges[0].isGreedy()) { + // two non greedy edges indicate a deadend + graph.removeVertex(vertex); + removed = true; + break; + } + // greedy case: + NetworkVertex firstVertex = Graphs.getOppositeVertex(graph, edges[0], vertex); + NetworkVertex secondVertex = Graphs.getOppositeVertex(graph, edges[1], vertex); + // merge greed edges if the vertexes are not already connected + if (edges[0].isGreedy() && !graph.containsEdge(firstVertex, secondVertex)) { + int distance = edges[0].getDistance() + edges[1].getDistance(); + graph.addEdge(firstVertex, secondVertex, + new NetworkEdge(firstVertex, secondVertex, true, distance)); + // remove vertex + graph.removeVertex(vertex); + removed = true; + break; + } + } } } Index: NetworkEdge.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/algorithms/NetworkEdge.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** NetworkEdge.java 12 Apr 2010 17:37:32 -0000 1.2 --- NetworkEdge.java 13 Apr 2010 23:21:12 -0000 1.3 *************** *** 7,11 **** private final NetworkVertex target; ! private final boolean greedy; private final int distance; --- 7,11 ---- private final NetworkVertex target; ! private boolean greedy; private final int distance; *************** *** 40,43 **** --- 40,47 ---- } + public void setGreedy(boolean greedy) { + this.greedy = greedy; + } + public int getDistance() { return distance; Index: NetworkTrain.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/algorithms/NetworkTrain.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** NetworkTrain.java 12 Apr 2010 17:37:32 -0000 1.1 --- NetworkTrain.java 13 Apr 2010 23:21:12 -0000 1.2 *************** *** 24,27 **** --- 24,39 ---- } + int getCities(){ + return cities; + } + + int getTowns() { + return towns; + } + + int calculateRevenue(int[] cityValues, int[] townValues) { + return cityValues[cities] * multiplyCities + townValues[towns] * multiplyTowns; + } + public String toString() { return trainName; |
From: Stefan F. <ste...@us...> - 2010-04-13 23:21:21
|
Update of /cvsroot/rails/18xx/rails/ui/swing In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv19400/rails/ui/swing Modified Files: ORPanel.java Log Message: Updated revenue calculation: Added revenue prediction and several bug fixes. Index: ORPanel.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/ui/swing/ORPanel.java,v retrieving revision 1.52 retrieving revision 1.53 diff -C2 -d -r1.52 -r1.53 *** ORPanel.java 12 Apr 2010 17:37:33 -0000 1.52 --- ORPanel.java 13 Apr 2010 23:21:13 -0000 1.53 *************** *** 10,14 **** import org.apache.log4j.Logger; ! import org.jgrapht.graph.SimpleGraph; import rails.algorithms.*; --- 10,14 ---- import org.apache.log4j.Logger; ! import org.jgrapht.Graph; import rails.algorithms.*; *************** *** 589,611 **** NetworkGraphBuilder nwGraph = new NetworkGraphBuilder(); nwGraph.generateGraph(mapManager.getHexesAsList()); ! SimpleGraph<NetworkVertex, NetworkEdge> graph; ! graph = nwGraph.getMapGraph(); if (companyName.equals("All")) { ! NetworkGraphBuilder.visualize(graph, "Map Network"); ! NetworkGraphBuilder.optimizeGraph(graph); ! NetworkGraphBuilder.visualize(graph, "Optimized Map Network"); } else { CompanyManagerI cm = gm.getCompanyManager(); PublicCompanyI company = cm.getCompanyByName(companyName); ! graph = nwGraph.getRailRoadGraph(company); NetworkGraphBuilder.visualize(graph, "Network of " + companyName); ! NetworkGraphBuilder.optimizeGraph(graph); NetworkGraphBuilder.visualize(graph, "Optimized Network of " + companyName); // revenue calculation example ! RevenueAdapter ra = new RevenueAdapter(graph); ! // get trains company.getPortfolio().getTrainList(); --- 589,619 ---- NetworkGraphBuilder nwGraph = new NetworkGraphBuilder(); nwGraph.generateGraph(mapManager.getHexesAsList()); ! Graph<NetworkVertex, NetworkEdge> mapGraph = nwGraph.getMapGraph(); if (companyName.equals("All")) { ! NetworkGraphBuilder.visualize(mapGraph, "Map Network"); ! mapGraph = NetworkGraphBuilder.optimizeGraph(mapGraph); ! NetworkGraphBuilder.visualize(mapGraph, "Optimized Map Network"); } else { CompanyManagerI cm = gm.getCompanyManager(); PublicCompanyI company = cm.getCompanyByName(companyName); ! Graph<NetworkVertex, NetworkEdge> graph = nwGraph.getRailRoadGraph(company); NetworkGraphBuilder.visualize(graph, "Network of " + companyName); ! graph = NetworkGraphBuilder.optimizeGraph(graph); NetworkGraphBuilder.visualize(graph, "Optimized Network of " + companyName); // revenue calculation example ! mapGraph = NetworkGraphBuilder.optimizeGraph(mapGraph); ! RevenueAdapter ra = new RevenueAdapter(mapGraph); ! // set tokens ! List<TokenI> tokens = company.getTokens(); ! for (TokenI token:tokens){ ! NetworkVertex vertex = nwGraph.getVertex(token); ! if (vertex != null) ra.addStartVertex(vertex); ! } ! // run on railroad graph, does not work so far, thus use map graph ! // RevenueAdapter ra = new RevenueAdapter(graph); ! // get trains company.getPortfolio().getTrainList(); *************** *** 616,622 **** while (anotherTrain) { // create results ra.populateRevenueCalculator(company, gm.getCurrentPhase()); log.info("Revenue Adapter:" + ra); - int revenueValue = ra.calculateRevenue(); log.info("Revenue Value:" + revenueValue); --- 624,631 ---- while (anotherTrain) { // create results + // ra.populateRevenueCalculator(company, gm.getPhaseManager().getPhaseByName("8")); ra.populateRevenueCalculator(company, gm.getCurrentPhase()); + ra.activateRevenuePrediction(); log.info("Revenue Adapter:" + ra); int revenueValue = ra.calculateRevenue(); log.info("Revenue Value:" + revenueValue); *************** *** 629,633 **** "Add another train to run?", JOptionPane.QUESTION_MESSAGE); ! if (trainsToAdd.equals("")) { anotherTrain = false; } else { --- 638,642 ---- "Add another train to run?", JOptionPane.QUESTION_MESSAGE); ! if (trainsToAdd == null || trainsToAdd.equals("")) { anotherTrain = false; } else { |
From: Stefan F. <ste...@us...> - 2010-04-12 17:37:46
|
Update of /cvsroot/rails/18xx/rails/algorithms In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv14735/rails/algorithms Modified Files: NetworkEdge.java NetworkVertex.java NetworkIterator.java NetworkGraphBuilder.java Added Files: NetworkTrain.java RevenueCalculator.java RevenueAdapter.java Log Message: Initial experimental version of revenue calculation --- NEW FILE: RevenueCalculator.java --- package rails.algorithms; import java.util.Arrays; import org.apache.log4j.Logger; final class RevenueCalculator { private final int nbVertexes; private final int maxNeighbors; private final int nbTrains; // static vertex data private final int[] vertexValue; private final boolean[] vertexCity; private final boolean[] vertexTown; private final int[][] vertexNeighbors; // start vertexes private int[] startVertexes; // static edge data private final boolean[][] edgeGreedy; private final int[][] edgeDistance; // dynamic edge data private final boolean[][] edgeUsed; // static train data private final int[] trainMaxCities; private final int[] trainMaxCombined; private final boolean[] trainTownsCostNothing; private final int[] trainMultiplyCities; private final int[] trainMultiplyTowns; // dynamic train data private final int[] trainCityValue; private final int[] trainTownValue; private final int[] trainCities; private final int[] trainTowns; private final boolean[][] trainVisited; private final int[][] trainVertexStack; private final int[] trainStackPos; private final int [] trainBottomPos; private final int [] trainStartEdge; // dynamic run data private int finalTrain; private int currentBestValue; private final int [][] currentBestRun; private int countVisits; private int countEdges; protected static Logger log = Logger.getLogger(RevenueCalculator.class.getPackage().getName()); public RevenueCalculator (int nbVertexes, int maxNeighbors, int nbTrains) { this.nbVertexes = nbVertexes; this.maxNeighbors = maxNeighbors; this.nbTrains = nbTrains; log.debug("RC defined: nbVertexes = " + nbVertexes + ", maxNeighbors = " + maxNeighbors + ", nbTrains = " + nbTrains); // initialize all required variables vertexValue = new int[nbVertexes]; vertexCity = new boolean[nbVertexes]; vertexTown = new boolean[nbVertexes]; vertexNeighbors = new int[nbVertexes][maxNeighbors]; edgeGreedy = new boolean[nbVertexes][nbVertexes]; edgeDistance = new int[nbVertexes][nbVertexes]; edgeUsed = new boolean[nbVertexes][nbVertexes]; trainCities = new int[nbTrains]; trainTowns = new int[nbTrains]; trainTownsCostNothing = new boolean[nbTrains]; trainMultiplyCities = new int[nbTrains]; trainMultiplyTowns = new int[nbTrains]; trainCityValue = new int[nbTrains]; trainTownValue = new int[nbTrains]; trainMaxCities = new int[nbTrains]; trainMaxCombined = new int[nbTrains]; trainVisited = new boolean[nbTrains][nbVertexes]; trainVertexStack = new int[nbTrains][nbVertexes]; trainStackPos = new int[nbTrains]; trainBottomPos = new int[nbTrains]; trainStartEdge = new int[nbTrains]; currentBestRun = new int[nbTrains][nbVertexes]; } void setVertex(int id, int value, boolean city, boolean town, int[]neighbors) { vertexValue[id] = value; vertexCity[id] = city; vertexTown[id] = town; vertexNeighbors[id] = neighbors; } void setStartVertexes(int[] startVertexes) { this.startVertexes = startVertexes; } void setEdge(int vertexLo, int vertexHi, boolean greedy, int distance) { edgeGreedy[vertexLo][vertexHi] = greedy; edgeDistance[vertexLo][vertexHi] = distance; } void setTrain(int id, int cities, int towns, boolean townsCostNothing, int multiplyCities, int multiplyTowns) { trainMaxCities[id] = cities; trainMaxCombined[id] = cities + towns; trainTownsCostNothing[id] = townsCostNothing; trainMultiplyCities[id] = multiplyCities; trainMultiplyTowns[id] = multiplyTowns; } int[][] getOptimalRun() { return currentBestRun; } int calculateRevenue(int startTrain, int finalTrain) { log.debug("RC: calculateRevenue trains from " + startTrain + " to " + finalTrain); this.finalTrain = finalTrain; runTrain(startTrain); return currentBestValue; } private void runTrain(int trainId) { log.debug("RC: startTrain " + trainId); // initialize the positions trainStackPos[trainId] = 0; trainBottomPos[trainId] = 0; // try all startVertexes for (int i=0; i < startVertexes.length; i++) { int vertexId = startVertexes[i]; log.debug("RC: Using startVertex nr. " + i + " for train " + trainId); encounterVertex(trainId, startVertexes[i], true); // and all edges of it boolean evaluateResult = true; for (int j = 0; j < maxNeighbors; j++) { int neighborId = vertexNeighbors[vertexId][j]; log.debug("RC: Testing Neighbor Nr. " + j + " of startVertex is " + neighborId); if (neighborId == -1) break; // no more neighbors if (travelEdge(vertexId, neighborId, true)) { evaluateResult = false; trainStartEdge[trainId] = j; // store edge nextVertex(trainId, neighborId, vertexId); } } // no more edges to find finalizeVertex(trainId, evaluateResult); encounterVertex(trainId, startVertexes[i], false); log.debug("RC: finished startVertex " + vertexId + " for train " +trainId); } log.debug("RC: finishTrain " + trainId); } private void startBottom(int trainId) { log.debug("RC: startBottom " +trainId); trainBottomPos[trainId] = trainStackPos[trainId]; // store the stack position where bottom starts log.debug("RC: Restart at bottom at stack position " + trainBottomPos[trainId]); // use startvertex int vertexId = trainVertexStack[trainId][0]; trainVertexStack[trainId][trainStackPos[trainId]++] = vertexId; // push to stack for (int j = trainStartEdge[trainId] + 1; j < maxNeighbors; j++) { int neighborId = vertexNeighbors[vertexId][j]; log.debug("RC: Testing Neighbor Nr. " + j + " of bottomVertex is " + neighborId); if (neighborId == -1) break; // no more neighbors if (trainVisited[trainId][neighborId]) { log.debug(" RC: Hex already visited"); continue; } if (travelEdge(vertexId, neighborId, true)) { nextVertex(trainId, neighborId, vertexId); } } // no more edges to find // finalizeVertex(trainId); trainStackPos[trainId]--; // pull from stack trainBottomPos[trainId] = 0; log.debug("RC: finished bottom of " + trainId); } /** * arrives at an unvisited vertex */ private void nextVertex(int trainId, int vertexId, int previousId) { // 1. add vertex to path and returns true if train terminated (if start = 0, otherwise it is a revisit of the start) encounterVertex(trainId, vertexId, true); boolean trainTerminated = trainTerminated(trainId); // 2a. visit neighbors, if train has not terminated boolean evaluateResult = true; if (!trainTerminated) { for (int j = 0; j < maxNeighbors; j++) { int neighborId = vertexNeighbors[vertexId][j]; log.debug("RC: Testing Neighbor Nr. " + j + " of " + vertexId + " is " + neighborId); if (neighborId == -1) break; // no more neighbors if (trainVisited[trainId][neighborId]) { log.debug("RC: Hex already visited"); continue; } if (travelEdge(vertexId, neighborId, edgeGreedy[previousId][vertexId])) { evaluateResult = false; nextVertex(trainId, neighborId, vertexId); } } // 2b. restart at startVertex for bottom part if (trainBottomPos[trainId] == 0 && (vertexCity[vertexId] || vertexTown[vertexId])){ startBottom(trainId); } } // 3. no more edges to visit from here => evaluate or start new train finalizeVertex(trainId, evaluateResult); // 4. then leave that vertex encounterVertex(trainId, vertexId, false); returnEdge(trainId); } private void encounterVertex(int trainId, int vertexId, boolean arrive) { log.debug("RC: EncounterVertex, trainId = " + trainId + " vertexId = " + vertexId + " arrive = " + arrive); // set visit to true if arriving, otherwise you leave trainVisited[trainId][vertexId] = arrive; if (arrive) { if (vertexCity[vertexId]) { trainCities[trainId]++; trainCityValue[trainId] += vertexValue[vertexId]; } else if (vertexTown[vertexId]) { trainTowns[trainId]++; trainTownValue[trainId] += vertexValue[vertexId]; } trainVertexStack[trainId][trainStackPos[trainId]++] = vertexId; // push to stack countVisits++; } else { if (vertexCity[vertexId]) { trainCities[trainId]--; trainCityValue[trainId] -= vertexValue[vertexId]; } else if (vertexTown[vertexId]) { trainTowns[trainId]--; trainTownValue[trainId] -= vertexValue[vertexId]; } trainStackPos[trainId]--; // pull from stack countVisits--; } log.debug("RC: Count Visits = " + countVisits); } private boolean travelEdge(int startVertex, int endVertex, boolean previousGreedy) { if (edgeUsed[startVertex][endVertex]) { log.debug("RC: Edge from " + startVertex + " to " + endVertex + " already used" ); return false; } else if (previousGreedy || edgeGreedy[startVertex][endVertex]) { log.debug("RC: Travel edge from " + startVertex + " to " + endVertex ); edgeUsed[startVertex][endVertex] = true; edgeUsed[endVertex][startVertex] = true; countEdges++; log.debug("RC: Count Edges = " + countEdges); return true; } else { log.debug("RC: Cannot travel from " + startVertex + " to " + endVertex + ", because of greedy rule"); return false; } } private void returnEdge(int trainId) { int stackPos = trainStackPos[trainId]; log.debug("RC: Tries to clear edge at stack position " + stackPos + " of train " + trainId); if (stackPos == 0) { log.debug("RC: Position zero has not to be cleared"); return; } if (stackPos == trainBottomPos[trainId]) { log.debug("RC: Replace start Vertex for bottom position"); } int startVertex = trainVertexStack[trainId][stackPos]; int endVertex = trainVertexStack[trainId][stackPos - 1]; if (edgeUsed[startVertex][endVertex]) { edgeUsed[startVertex][endVertex] = false; edgeUsed[endVertex][startVertex] = false; countEdges--; log.debug("RC: Cleared edge from " + startVertex + " to " + endVertex); log.debug("RC: Count Edges = " + countEdges); } else { log.debug ("RC: Error return edge not used: " + startVertex + " to " + endVertex); } } private boolean trainTerminated(int trainId) { boolean terminated; if (trainTownsCostNothing[trainId]) { terminated = trainCities[trainId] == trainMaxCities[trainId]; } else { terminated = trainCities[trainId] > trainMaxCities[trainId] || (trainCities[trainId] + trainTowns[trainId] == trainMaxCombined[trainId]); } if (terminated) { log.debug ("RC: Train " + trainId + " has terminated: " + "cities = " + trainCities[trainId] + " towns = " + trainTowns[trainId] + "maxCities = " + trainMaxCities[trainId] + "maxCombined = " + trainMaxCombined[trainId]); } return terminated; } private void finalizeVertex(int trainId, boolean evaluate) { log.debug("RC: No more edges found for " + trainId); if (trainId == finalTrain) { if (evaluate) evaluateResults(); } else { runTrain(trainId + 1); } } private void evaluateResults() { // sum to total value int totalValue = 0; for (int j = 0; j <= finalTrain; j++) { int trainValue; if (trainCities[j] + trainTowns[j] <= 1) { trainValue = 0; // one station is not enough } else { trainValue = trainCityValue[j] * trainMultiplyCities[j] + trainTownValue[j] * trainMultiplyTowns[j]; } totalValue += trainValue; log.debug("RC: Train " + j + " has value of " + trainValue); } // compare to current best result if (totalValue > currentBestValue) { currentBestValue = totalValue; // exceed thus deep copy of vertex stack for (int j = 0; j <= finalTrain; j++) for (int v = 0; v < nbVertexes; v++) if (v < trainStackPos[j]) currentBestRun[j][v] = trainVertexStack[j][v]; else { currentBestRun[j][v] = -1; // terminator break; } log.info("RC: Found better run with " + totalValue); } } @Override public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append("vertexValue:" + Arrays.toString(vertexValue)); buffer.append("vertexCity:" + Arrays.toString(vertexCity)); buffer.append("vertexTown:" + Arrays.toString(vertexTown)); buffer.append("vertexEdges:" + Arrays.deepToString(vertexNeighbors)); buffer.append("edgeGreedy:" + Arrays.deepToString(edgeGreedy)); buffer.append("edgeDistance:" + Arrays.deepToString(edgeDistance)); buffer.append("startVertexes:" + Arrays.toString(startVertexes)); return buffer.toString(); } } Index: NetworkIterator.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/algorithms/NetworkIterator.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** NetworkIterator.java 9 Apr 2010 17:49:31 -0000 1.2 --- NetworkIterator.java 12 Apr 2010 17:37:32 -0000 1.3 *************** *** 185,189 **** for (NetworkEdge edge : graph.edgesOf(vertex)) { ! if (previousColor == VisitColor.WHITE || edge.isAutoEdge()) { NetworkVertex oppositeV = Graphs.getOppositeVertex(graph, edge, vertex); --- 185,189 ---- for (NetworkEdge edge : graph.edgesOf(vertex)) { ! if (previousColor == VisitColor.WHITE || edge.isGreedy()) { NetworkVertex oppositeV = Graphs.getOppositeVertex(graph, edge, vertex); *************** *** 207,211 **** private void encounterVertex(NetworkVertex vertex, NetworkEdge edge) { VisitColor color = VisitColor.WHITE; ! if (vertex.isSide() && !edge.isAutoEdge()) color = VisitColor.YELLOW; putSeenData(vertex, color); --- 207,211 ---- private void encounterVertex(NetworkVertex vertex, NetworkEdge edge) { VisitColor color = VisitColor.WHITE; ! if (vertex.isSide() && !edge.isGreedy()) color = VisitColor.YELLOW; putSeenData(vertex, color); Index: NetworkVertex.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/algorithms/NetworkVertex.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** NetworkVertex.java 9 Apr 2010 17:49:31 -0000 1.3 --- NetworkVertex.java 12 Apr 2010 17:37:32 -0000 1.4 *************** *** 8,11 **** --- 8,12 ---- import rails.game.City; import rails.game.MapHex; + import rails.game.PhaseI; import rails.game.PublicCompanyI; import rails.game.Station; *************** *** 97,100 **** --- 98,114 ---- } + public boolean isTownType(){ + return isStation() && station.getType().equals(Station.TOWN); + } + + public boolean isCityType(){ + return isStation() && + (station.getType().equals(Station.CITY) || station.getType().equals(Station.OFF_MAP_AREA)); + } + + public boolean isOffBoardType() { + return isStation() && station.getType().equals(Station.OFF_MAP_AREA); + } + public MapHex getHex(){ return hex; *************** *** 108,111 **** --- 122,136 ---- return side; } + + public int getValue(PhaseI phase){ + if (isOffBoardType()) { + return hex.getCurrentOffBoardValue(phase); + } else if (isStation()) { + return station.getValue(); + } else { + return 0; + } + } + /** * Checks if a vertex is fully tokened --- NEW FILE: RevenueAdapter.java --- package rails.algorithms; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.jgrapht.Graph; import org.jgrapht.Graphs; import rails.game.PhaseI; import rails.game.PublicCompanyI; import rails.game.TrainI; public class RevenueAdapter { private Graph<NetworkVertex, NetworkEdge> graph; private RevenueCalculator rc; private int maxNeighbors; private List<NetworkVertex> vertexes; private List<NetworkEdge> edges; private List<NetworkTrain> trains; public RevenueAdapter(Graph<NetworkVertex, NetworkEdge> graph){ this.graph = graph; this.vertexes = new ArrayList<NetworkVertex>(graph.vertexSet()); this.edges = new ArrayList<NetworkEdge>(graph.edgeSet()); this.trains = new ArrayList<NetworkTrain>(); } public void initRevenueCalculator(){ if (rc == null) { // define the maximum number of vertexes maxNeighbors = 0; for (NetworkVertex vertex:vertexes) if (!vertex.isHQ()) maxNeighbors = Math.max(maxNeighbors, graph.edgesOf(vertex).size()); this.rc = new RevenueCalculator(vertexes.size(), ++maxNeighbors, trains.size()); // increase maxEdges to allow for cutoff } } public void refreshRevenueCalculator() { rc = null; } public void populateRevenueCalculator(PublicCompanyI company, PhaseI phase){ if (rc == null) initRevenueCalculator(); // set vertexes for (int id=0; id < vertexes.size(); id++){ NetworkVertex v = vertexes.get(id); if (v.isHQ()) { // HQ is not added to list, but used to assign startVertexes List<NetworkVertex> hqNeighbors = Graphs.neighborListOf(graph, v); int[] startVertexes = new int[hqNeighbors.size()]; for (int j=0; j < hqNeighbors.size(); j++) { startVertexes[j] = vertexes.lastIndexOf(hqNeighbors.get(j)); } rc.setStartVertexes(startVertexes); } else { // prepare values int value = v.getValue(phase); boolean city = v.isCityType(); boolean town = v.isTownType(); int j = 0, e[] = new int[maxNeighbors]; if (v.canCompanyRunThrough(company)) { for (NetworkVertex n:Graphs.neighborListOf(graph, v)){ if (!n.isHQ()) { e[j++] = vertexes.lastIndexOf(n); } } } e[j] = -1; // stop rc.setVertex(id, value, city, town, e); } } // set edges for (int id=0; id < edges.size(); id++) { // prepare values NetworkEdge e = edges.get(id); int vA = vertexes.lastIndexOf(e.getSource()); int vB = vertexes.lastIndexOf(e.getTarget()); boolean greedy = e.isGreedy(); int distance = e.getDistance(); rc.setEdge(vA, vB, greedy, distance); rc.setEdge(vB, vA, greedy, distance); } // set trains for (int id=0; id < trains.size(); id++) { NetworkTrain train = trains.get(id); train.addToRevenueCalculator(rc, id); } } public void addDefaultTrain(int cities) { String trainName = Integer.valueOf(cities).toString(); NetworkTrain train =new NetworkTrain(cities, 0, false, 1, 1, trainName); trains.add(train); } public void addTrain(TrainI railsTrain){ int cities = railsTrain.getMajorStops(); int towns = railsTrain.getMinorStops(); boolean townsCostNothing = (railsTrain.getTownCountIndicator() == 0); int multiplyCities = railsTrain.getCityScoreFactor(); int multiplyTowns = railsTrain.getTownScoreFactor(); String trainName = railsTrain.getName(); NetworkTrain networkTrain = new NetworkTrain(cities, towns, townsCostNothing, multiplyCities, multiplyTowns, trainName); trains.add(networkTrain); } public void addTrainByString(String trainString) { String t = trainString.trim(); int cities = 0; int towns = 0; boolean townsCostNothing = false; int multiplyCities = 1; int multiplyTowns = 1; if (t.equals("D")) { cities = 99; // diesel } else if (t.contains("+")) { cities = Integer.parseInt(t.split("\\+")[0]); // + train towns = Integer.parseInt(t.split("\\+")[1]); } else if (t.contains("E")) { // express train cities = Integer.parseInt(t.replace("E", "")); townsCostNothing = true; multiplyTowns = 0; } else if (t.contains("D")) { // double (express) train cities = Integer.parseInt(t.replace("D", "")); townsCostNothing = true; multiplyCities = 2; multiplyTowns = 0; } else { // default train cities = Integer.parseInt(t); } NetworkTrain networkTrain = new NetworkTrain(cities, towns, townsCostNothing, multiplyCities, multiplyTowns, t); trains.add(networkTrain); } public Map<NetworkTrain, List<NetworkVertex>> getOptimalRun() { int[][] optimalRunRaw = rc.getOptimalRun(); Map<NetworkTrain, List<NetworkVertex>> optimalRun = new HashMap<NetworkTrain, List<NetworkVertex>>(); for (int j=0; j < optimalRunRaw.length; j++) { List<NetworkVertex> runList = new ArrayList<NetworkVertex>(); for (int v=0; v < optimalRunRaw[j].length; v++) { int vertexId = optimalRunRaw[j][v]; if (vertexId == -1) break; runList.add(vertexes.get(vertexId)); } optimalRun.put(trains.get(j), runList); } return optimalRun; } public int calculateRevenue() { return calculateRevenue(0, trains.size() - 1); } public int calculateRevenue(int startTrain, int finalTrain) { if (startTrain < 0 || finalTrain >= trains.size() || startTrain > finalTrain) return -1; return rc.calculateRevenue(startTrain, finalTrain); } @Override public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append("RevenueCalculator:" + rc); buffer.append("Vertexes:" + vertexes); buffer.append("Edges:" + edges); return buffer.toString(); } } Index: NetworkGraphBuilder.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/algorithms/NetworkGraphBuilder.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** NetworkGraphBuilder.java 9 Apr 2010 17:49:31 -0000 1.4 --- NetworkGraphBuilder.java 12 Apr 2010 17:37:32 -0000 1.5 *************** *** 254,260 **** NetworkVertex firstVertex = Graphs.getOppositeVertex(graph, edges[0], vertex); NetworkVertex secondVertex = Graphs.getOppositeVertex(graph, edges[1], vertex); ! boolean autoEdge = edges[0].isAutoEdge() || edges[1].isAutoEdge(); graph.addEdge(firstVertex, secondVertex, ! new NetworkEdge(firstVertex, secondVertex, autoEdge)); // remove vertex graph.removeVertex(vertex); --- 254,261 ---- NetworkVertex firstVertex = Graphs.getOppositeVertex(graph, edges[0], vertex); NetworkVertex secondVertex = Graphs.getOppositeVertex(graph, edges[1], vertex); ! boolean greedy = edges[0].isGreedy() || edges[1].isGreedy(); ! int distance = edges[0].getDistance() + edges[1].getDistance(); graph.addEdge(firstVertex, secondVertex, ! new NetworkEdge(firstVertex, secondVertex, greedy, distance)); // remove vertex graph.removeVertex(vertex); Index: NetworkEdge.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/algorithms/NetworkEdge.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** NetworkEdge.java 4 Apr 2010 22:02:53 -0000 1.1 --- NetworkEdge.java 12 Apr 2010 17:37:32 -0000 1.2 *************** *** 7,16 **** private final NetworkVertex target; ! private final boolean autoEdge; ! public NetworkEdge(NetworkVertex source, NetworkVertex target, boolean autoEdge) { this.source = source; this.target = target; ! this.autoEdge = autoEdge; } --- 7,29 ---- private final NetworkVertex target; ! private final boolean greedy; ! private final int distance; ! ! public NetworkEdge(NetworkVertex source, NetworkVertex target, boolean greedy) { this.source = source; this.target = target; ! this.greedy = greedy; ! if (greedy) ! this.distance = 1; ! else ! this.distance = 0; ! } ! ! public NetworkEdge(NetworkVertex source, NetworkVertex target, boolean greedy, int distance) { ! this.source = source; ! this.target = target; ! this.greedy = greedy; ! this.distance = distance; } *************** *** 23,30 **** } ! public boolean isAutoEdge() { ! return autoEdge; } public String getConnection() { return source + " - >" + target; --- 36,47 ---- } ! public boolean isGreedy() { ! return greedy; } + public int getDistance() { + return distance; + } + public String getConnection() { return source + " - >" + target; *************** *** 34,41 **** // set to "" to faciltate visual graph public String toString() { ! if (!autoEdge) ! return "***"; else ! return ""; } } --- 51,59 ---- // set to "" to faciltate visual graph public String toString() { ! if (!greedy) ! return "*** / " + distance; else ! return "" + distance; } + } --- NEW FILE: NetworkTrain.java --- package rails.algorithms; public final class NetworkTrain { private final int cities; private final int towns; private final boolean townsCostNothing; private final int multiplyCities; private final int multiplyTowns; private final String trainName; NetworkTrain(int cities, int towns, boolean townsCostNothing, int multiplyCities, int multiplyTowns, String trainName) { this.cities = cities; this.towns = towns; this.townsCostNothing = townsCostNothing; this.multiplyCities = multiplyCities; this.multiplyTowns = multiplyTowns; this.trainName = trainName; } void addToRevenueCalculator(RevenueCalculator rc, int trainId) { rc.setTrain(trainId, cities, towns, townsCostNothing, multiplyCities, multiplyTowns); } public String toString() { return trainName; } } |
From: Stefan F. <ste...@us...> - 2010-04-12 17:37:42
|
Update of /cvsroot/rails/18xx/rails/ui/swing In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv14735/rails/ui/swing Modified Files: ORPanel.java Log Message: Initial experimental version of revenue calculation Index: ORPanel.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/ui/swing/ORPanel.java,v retrieving revision 1.51 retrieving revision 1.52 diff -C2 -d -r1.51 -r1.52 *** ORPanel.java 4 Apr 2010 22:02:53 -0000 1.51 --- ORPanel.java 12 Apr 2010 17:37:33 -0000 1.52 *************** *** 584,589 **** protected void executeNetworkInfo(String companyName) { ! ! MapManager mapManager = orUIManager.getGameUIManager().getGameManager().getMapManager(); NetworkGraphBuilder nwGraph = new NetworkGraphBuilder(); --- 584,589 ---- protected void executeNetworkInfo(String companyName) { ! GameManagerI gm = orUIManager.getGameUIManager().getGameManager(); ! MapManager mapManager = gm.getMapManager(); NetworkGraphBuilder nwGraph = new NetworkGraphBuilder(); *************** *** 592,603 **** graph = nwGraph.getMapGraph(); ! if (!companyName.equals("All")) { ! CompanyManagerI cm = orUIManager.getGameUIManager().getGameManager().getCompanyManager(); PublicCompanyI company = cm.getCompanyByName(companyName); graph = nwGraph.getRailRoadGraph(company); } - NetworkGraphBuilder.visualize(graph, "Network of " + companyName); - NetworkGraphBuilder.optimizeGraph(graph); - NetworkGraphBuilder.visualize(graph, "Optimized Network of " + companyName); } --- 592,640 ---- graph = nwGraph.getMapGraph(); ! if (companyName.equals("All")) { ! NetworkGraphBuilder.visualize(graph, "Map Network"); ! NetworkGraphBuilder.optimizeGraph(graph); ! NetworkGraphBuilder.visualize(graph, "Optimized Map Network"); ! } else { ! CompanyManagerI cm = gm.getCompanyManager(); PublicCompanyI company = cm.getCompanyByName(companyName); graph = nwGraph.getRailRoadGraph(company); + + NetworkGraphBuilder.visualize(graph, "Network of " + companyName); + NetworkGraphBuilder.optimizeGraph(graph); + NetworkGraphBuilder.visualize(graph, "Optimized Network of " + companyName); + + // revenue calculation example + RevenueAdapter ra = new RevenueAdapter(graph); + + // get trains + company.getPortfolio().getTrainList(); + for (TrainI train:company.getPortfolio().getTrainList()) + ra.addTrain(train); + + boolean anotherTrain = true; + while (anotherTrain) { + // create results + ra.populateRevenueCalculator(company, gm.getCurrentPhase()); + log.info("Revenue Adapter:" + ra); + + int revenueValue = ra.calculateRevenue(); + log.info("Revenue Value:" + revenueValue); + log.info("Revenue run:" + ra.getOptimalRun()); + JOptionPane.showMessageDialog(orWindow, "RevenueValue = " + revenueValue + + "\n RevenueRun = " + ra.getOptimalRun()); + + String trainsToAdd = + JOptionPane.showInputDialog(orWindow, "Another train", + "Add another train to run?", + JOptionPane.QUESTION_MESSAGE); + if (trainsToAdd.equals("")) { + anotherTrain = false; + } else { + ra.addTrainByString(trainsToAdd); + ra.refreshRevenueCalculator(); + } + } } } |
From: Erik V. <ev...@us...> - 2010-04-11 15:49:55
|
Update of /cvsroot/rails/18xx/data/1835 In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv16112/data/1835 Modified Files: Map.xml Log Message: Added OperatingRound methods isBlockedForTileLays() and isBlockedForTokenLays(). The former replaces the existing isBLocked() (for privates still in operation). The latter is new and covers various cases where unlaid home bases prevent other companies to lay base tokens on a hex. Index: Map.xml =================================================================== RCS file: /cvsroot/rails/18xx/data/1835/Map.xml,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** Map.xml 31 Jan 2010 22:15:58 -0000 1.9 --- Map.xml 11 Apr 2010 15:49:47 -0000 1.10 *************** *** 34,38 **** <Hex name="E15" tile="0" cost="50"/> <Hex name="E17" tile="0"/> ! <Hex name="E19" tile="-806" city="Berlin"/> <Hex name="E21" tile="-143" orientation="3"/> <Hex name="F4" tile="-1"/> --- 34,38 ---- <Hex name="E15" tile="0" cost="50"/> <Hex name="E17" tile="0"/> ! <Hex name="E19" tile="-806" city="Berlin" unlaidHomeBlocksTokens="no"/> <Hex name="E21" tile="-143" orientation="3"/> <Hex name="F4" tile="-1"/> *************** *** 93,97 **** <Hex name="L2" tile="-1"/> <Hex name="L4" tile="0"/> ! <Hex name="L6" tile="-807" city="Ludwigshafen/Mannheim"/> <Hex name="L8" tile="-2"/> <Hex name="L10" tile="0"/> --- 93,97 ---- <Hex name="L2" tile="-1"/> <Hex name="L4" tile="0"/> ! <Hex name="L6" tile="-807" city="Ludwigshafen/Mannheim" unlaidHomeBlocksTokens="yes"/> <Hex name="L8" tile="-2"/> <Hex name="L10" tile="0"/> |
From: Erik V. <ev...@us...> - 2010-04-11 15:49:55
|
Update of /cvsroot/rails/18xx/rails/game/specific/_1835 In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv16112/rails/game/specific/_1835 Modified Files: OperatingRound_1835.java Log Message: Added OperatingRound methods isBlockedForTileLays() and isBlockedForTokenLays(). The former replaces the existing isBLocked() (for privates still in operation). The latter is new and covers various cases where unlaid home bases prevent other companies to lay base tokens on a hex. Index: OperatingRound_1835.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/specific/_1835/OperatingRound_1835.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** OperatingRound_1835.java 8 Apr 2010 21:25:51 -0000 1.2 --- OperatingRound_1835.java 11 Apr 2010 15:49:47 -0000 1.3 *************** *** 71,74 **** --- 71,75 ---- } + /* public boolean layBaseToken(LayBaseToken action) { *************** *** 90,93 **** --- 91,95 ---- } } + */ protected void newPhaseChecks() { |
From: Erik V. <ev...@us...> - 2010-04-11 15:49:55
|
Update of /cvsroot/rails/18xx/data/1830 In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv16112/data/1830 Modified Files: Map.xml Log Message: Added OperatingRound methods isBlockedForTileLays() and isBlockedForTokenLays(). The former replaces the existing isBLocked() (for privates still in operation). The latter is new and covers various cases where unlaid home bases prevent other companies to lay base tokens on a hex. Index: Map.xml =================================================================== RCS file: /cvsroot/rails/18xx/data/1830/Map.xml,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** Map.xml 8 Nov 2009 14:46:16 -0000 1.14 --- Map.xml 11 Apr 2010 15:49:47 -0000 1.15 *************** *** 37,41 **** <Hex name="E7" tile="-1" impassable="F8"/> <Hex name="E9" tile="-7" orientation="4"/> ! <Hex name="E11" tile="-20" label="OO"/> <Hex name="E13" tile="0"/> <Hex name="E15" tile="0"/> --- 37,41 ---- <Hex name="E7" tile="-1" impassable="F8"/> <Hex name="E9" tile="-7" orientation="4"/> ! <Hex name="E11" tile="-20" label="OO" unlaidHomeBlocksTokens="yes"/> <Hex name="E13" tile="0"/> <Hex name="E15" tile="0"/> |
From: Erik V. <ev...@us...> - 2010-04-11 15:49:55
|
Update of /cvsroot/rails/18xx/rails/ui/swing In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv16112/rails/ui/swing Modified Files: ORUIManager.java Log Message: Added OperatingRound methods isBlockedForTileLays() and isBlockedForTokenLays(). The former replaces the existing isBLocked() (for privates still in operation). The latter is new and covers various cases where unlaid home bases prevent other companies to lay base tokens on a hex. Index: ORUIManager.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/ui/swing/ORUIManager.java,v retrieving revision 1.64 retrieving revision 1.65 diff -C2 -d -r1.64 -r1.65 *** ORUIManager.java 9 Apr 2010 17:49:31 -0000 1.64 --- ORUIManager.java 11 Apr 2010 15:49:47 -0000 1.65 *************** *** 674,678 **** tile.getColourName().equalsIgnoreCase(Tile.YELLOW_COLOUR_NAME) // Does not apply to the current company's home hex(es) ! && !hex.getHexModel().isHome(orComp) // Does not apply to special tile lays && !isUnconnectedTileLayTarget(hex); --- 674,678 ---- tile.getColourName().equalsIgnoreCase(Tile.YELLOW_COLOUR_NAME) // Does not apply to the current company's home hex(es) ! && !hex.getHexModel().isHomeFor(orComp) // Does not apply to special tile lays && !isUnconnectedTileLayTarget(hex); |
From: Erik V. <ev...@us...> - 2010-04-11 15:49:55
|
Update of /cvsroot/rails/18xx In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv16112 Modified Files: LocalisedText.properties Log Message: Added OperatingRound methods isBlockedForTileLays() and isBlockedForTokenLays(). The former replaces the existing isBLocked() (for privates still in operation). The latter is new and covers various cases where unlaid home bases prevent other companies to lay base tokens on a hex. Index: LocalisedText.properties =================================================================== RCS file: /cvsroot/rails/18xx/LocalisedText.properties,v retrieving revision 1.127 retrieving revision 1.128 diff -C2 -d -r1.127 -r1.128 *** LocalisedText.properties 9 Apr 2010 07:20:27 -0000 1.127 --- LocalisedText.properties 11 Apr 2010 15:49:47 -0000 1.128 *************** *** 39,42 **** --- 39,43 ---- BankHas=The Bank has {0}. BankSizeIs=Bank size is {0} + BaseTokenSlotIsReserved=Base token slot is reserved BidTooHigh=Bid too high, player has only {0} free for bidding BidTooLow=Bid too low, minimum is {0} |
From: Erik V. <ev...@us...> - 2010-04-11 15:49:55
|
Update of /cvsroot/rails/18xx/rails/game In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv16112/rails/game Modified Files: City.java OperatingRound.java MapHex.java PrivateCompany.java Log Message: Added OperatingRound methods isBlockedForTileLays() and isBlockedForTokenLays(). The former replaces the existing isBLocked() (for privates still in operation). The latter is new and covers various cases where unlaid home bases prevent other companies to lay base tokens on a hex. Index: OperatingRound.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/OperatingRound.java,v retrieving revision 1.121 retrieving revision 1.122 diff -C2 -d -r1.121 -r1.122 *** OperatingRound.java 28 Mar 2010 20:14:20 -0000 1.121 --- OperatingRound.java 11 Apr 2010 15:49:47 -0000 1.122 *************** *** 516,519 **** --- 516,524 ---- break; } + + if (!isTokenLayAllowed (operatingCompany, hex, station)) { + errMsg = LocalText.getText("BaseTokenSlotIsReserved"); + break; + } if (!hex.hasTokenSlotsLeft(station)) { *************** *** 534,538 **** break; } ! if (action != null) { List<MapHex> locations = action.getLocations(); --- 539,543 ---- break; } ! if (action != null) { List<MapHex> locations = action.getLocations(); *************** *** 2505,2508 **** --- 2510,2549 ---- } + /** Reports if a tile lay is allowed by a certain company on a certain hex + * <p> + * This method can be used both in retricting possible actions + * and in validating submitted actions. + * <p> Currently, only a few standard checks are included. + * This method can be extended to perform other generic checks, + * such as if a route exists, + * and possibly in subclasses for game-specific checks. + * @param company The company laying a tile. + * @param hex The hex on which a tile is laid. + * @param orientation The orientation in which the tile is laid (-1 is any). + */ + protected boolean isTileLayAllowed (PublicCompanyI company, + MapHex hex, int orientation) { + return !hex.isBlockedForTileLays(); + } + + /** Reports if a token lay is allowed by a certain company on a certain hex and city + * <p> + * This method can be used both in retricting possible actions + * and in validating submitted actions. + * <p> Currently, only a few standard checks are included. + * This method can be extended to perform other generic checks, + * such as if a route exists, + * and possibly in subclasses for game-specific checks. + * + * @param company The company laying a tile. + * @param hex The hex on which a tile is laid. + * @param station The number of the station/city on which the token + * is to be laid (0 if any or immaterial). + */ + protected boolean isTokenLayAllowed (PublicCompanyI company, + MapHex hex, int station) { + return !hex.isBlockedForTokenLays(company, station); + } + /** * Can the company buy a train now? Index: City.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/City.java,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** City.java 31 Jan 2010 22:22:28 -0000 1.10 --- City.java 11 Apr 2010 15:49:47 -0000 1.11 *************** *** 130,133 **** --- 130,137 ---- return tokens.size() < slots; } + + public int getTokenSlotsLeft () { + return slots - tokens.size(); + } public boolean removeToken(TokenI token) { Index: MapHex.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/MapHex.java,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** MapHex.java 9 Apr 2010 17:49:31 -0000 1.41 --- MapHex.java 11 Apr 2010 15:49:47 -0000 1.42 *************** *** 90,94 **** * null as default implies false - see isBlocked() */ ! private BooleanState isBlockedState = null; protected Map<PublicCompanyI, City> homes; --- 90,105 ---- * null as default implies false - see isBlocked() */ ! private BooleanState isBlockedForTileLays = null; ! ! /** ! * Is the hex initially blocked for token lays (e.g. when a home base ! * must first be laid)? <p> ! * NOTE:<br>null means: blocked unless there is more free space than unlaid home bases,<br> ! * false means: blocked unless there is any free space.<br> ! * This makes a difference for 1835 Berlin, which is home to PR, but ! * the absence of a PR token does not block the third slot ! * when the green tile is laid. ! */ ! private BooleanState isBlockedForTokenLays = null; protected Map<PublicCompanyI, City> homes; *************** *** 178,181 **** --- 189,196 ---- infoText += " " + cityName; } + + if (tag.getAttributeAsString("unlaidHomeBlocksTokens") != null) { + setBlockedForTokenLays(tag.getAttributeAsBoolean("unlaidHomeBlocksTokens", false)); + } } *************** *** 729,732 **** --- 744,756 ---- token.moveTo(city); update(); + + if (isHomeFor(company) + && isBlockedForTokenLays != null + && isBlockedForTokenLays.booleanValue()) { + // Assume that there is only one home base on such a tile, + // so we don't need to check for other ones + isBlockedForTokenLays.set(false); + } + return true; } *************** *** 882,886 **** } ! public boolean isHome(PublicCompanyI company) { boolean result = homes != null && homes.get(company) != null; return result; --- 906,910 ---- } ! public boolean isHomeFor(PublicCompanyI company) { boolean result = homes != null && homes.get(company) != null; return result; *************** *** 902,912 **** /** ! * @return Returns the isBlocked. */ ! public boolean isBlocked() { ! if (isBlockedState == null) return false; else ! return isBlockedState.booleanValue(); } --- 926,936 ---- /** ! * @return Returns false if no tiles may yet be laid on this hex. */ ! public boolean isBlockedForTileLays() { ! if (isBlockedForTileLays == null) return false; else ! return isBlockedForTileLays.booleanValue(); } *************** *** 914,926 **** * @param isBlocked The isBlocked to set (state variable) */ ! public void setBlocked(boolean isBlocked) { ! if (isBlockedState == null) ! isBlockedState = new BooleanState("isBlocked", isBlocked); else ! isBlockedState.set(isBlocked); } public boolean isUpgradeableNow() { ! if (isBlocked()) { log.debug("Hex " + name + " is blocked"); return false; --- 938,950 ---- * @param isBlocked The isBlocked to set (state variable) */ ! public void setBlockedForTileLays(boolean isBlocked) { ! if (isBlockedForTileLays == null) ! isBlockedForTileLays = new BooleanState(name+"_IsBlockedForTileLays", isBlocked); else ! isBlockedForTileLays.set(isBlocked); } public boolean isUpgradeableNow() { ! if (isBlockedForTileLays()) { log.debug("Hex " + name + " is blocked"); return false; *************** *** 944,947 **** --- 968,1010 ---- } + /** + * @return Returns false if no base tokens may yet be laid on this hex and station. + * NOTE: this method currently only checks for prohibitions caused + * by the presence of unlaid hoem base tokens. + * It does NOT (yet) check for free space. + */ + public boolean isBlockedForTokenLays(PublicCompanyI company, int cityNumber) { + if (isHomeFor(company)) + // Company can always lay a home base + return false; + else if (isBlockedForTokenLays != null) { + // if true: token lay blocked because a required home base is not yet laid + // if false: token lay allowed if there is any free space + // Free space is not checked here (yet) + return isBlockedForTokenLays.booleanValue(); + } else if (homes != null && !homes.isEmpty()) { + // Check if this token lay does not block an unlaid home base + for (City city : homes.values()) { + if (cityNumber == city.getNumber() + // Assume that a city is never home to more than one company + && city.getTokens().isEmpty() + && city.getTokenSlotsLeft() < 2) { + return true; + } + } + } + return false; + } + + /** + * @param isBlocked The isBlocked to set (state variable) + */ + public void setBlockedForTokenLays(boolean isBlocked) { + if (isBlockedForTokenLays == null) + isBlockedForTokenLays = new BooleanState(name+"_IsBlockedForTokenLays", isBlocked); + else + isBlockedForTokenLays.set(isBlocked); + } + public boolean hasOffBoardValues() { return offBoardValues != null && offBoardValues.length > 0; Index: PrivateCompany.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/PrivateCompany.java,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** PrivateCompany.java 21 Mar 2010 17:43:50 -0000 1.39 --- PrivateCompany.java 11 Apr 2010 15:49:47 -0000 1.40 *************** *** 134,138 **** MapHex hex = mapManager.getHex(hexName); blockedHexes.add(hex); ! hex.setBlocked(true); } } --- 134,138 ---- MapHex hex = mapManager.getHex(hexName); blockedHexes.add(hex); ! hex.setBlockedForTileLays(true); } } *************** *** 288,292 **** if (blockedHexes != null) { for (MapHex hex : blockedHexes) { ! hex.setBlocked(false); } } --- 288,292 ---- if (blockedHexes != null) { for (MapHex hex : blockedHexes) { ! hex.setBlockedForTileLays(false); } } |
From: Erik V. <ev...@us...> - 2010-04-11 15:49:55
|
Update of /cvsroot/rails/18xx/rails/ui/swing/hexmap In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv16112/rails/ui/swing/hexmap Modified Files: GUIHex.java Log Message: Added OperatingRound methods isBlockedForTileLays() and isBlockedForTokenLays(). The former replaces the existing isBLocked() (for privates still in operation). The latter is new and covers various cases where unlaid home bases prevent other companies to lay base tokens on a hex. Index: GUIHex.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/ui/swing/hexmap/GUIHex.java,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -d -r1.40 -r1.41 *** GUIHex.java 9 Apr 2010 07:20:27 -0000 1.40 --- GUIHex.java 11 Apr 2010 15:49:47 -0000 1.41 *************** *** 359,363 **** } ! if (getHexModel().isBlocked()) { List<PrivateCompanyI> privates = GameManager.getInstance().getCompanyManager().getAllPrivateCompanies(); --- 359,363 ---- } ! if (getHexModel().isBlockedForTileLays()) { List<PrivateCompanyI> privates = GameManager.getInstance().getCompanyManager().getAllPrivateCompanies(); |
From: Erik V. <ev...@us...> - 2010-04-09 21:26:20
|
Update of /cvsroot/rails/18xx/rails/game In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv4492/rails/game Modified Files: StockRound.java GameManager.java GameManagerI.java Log Message: 1835: higher certificate limit if 80% owned. Index: GameManager.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/GameManager.java,v retrieving revision 1.98 retrieving revision 1.99 diff -C2 -d -r1.98 -r1.99 *** GameManager.java 4 Apr 2010 22:02:53 -0000 1.98 --- GameManager.java 9 Apr 2010 21:26:12 -0000 1.99 *************** *** 1180,1184 **** } ! public int getPlayerCertificateLimit() { return playerCertificateLimit.intValue(); } --- 1180,1184 ---- } ! public int getPlayerCertificateLimit(Player player) { return playerCertificateLimit.intValue(); } Index: GameManagerI.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/GameManagerI.java,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** GameManagerI.java 28 Mar 2010 20:14:20 -0000 1.32 --- GameManagerI.java 9 Apr 2010 21:26:12 -0000 1.33 *************** *** 10,14 **** import rails.game.correct.CorrectionType; import rails.game.model.ModelObject; - import rails.game.move.AddToList; import rails.game.move.MoveStack; import rails.game.move.MoveableHolder; --- 10,13 ---- *************** *** 170,174 **** public String getGameOption (String key); ! public int getPlayerCertificateLimit(); public void setPlayerCertificateLimit(int newLimit); public ModelObject getPlayerCertificateLimitModel (); --- 169,173 ---- public String getGameOption (String key); ! public int getPlayerCertificateLimit(Player player); public void setPlayerCertificateLimit(int newLimit); public ModelObject getPlayerCertificateLimitModel (); Index: StockRound.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/StockRound.java,v retrieving revision 1.72 retrieving revision 1.73 diff -C2 -d -r1.72 -r1.73 *** StockRound.java 2 Apr 2010 20:03:54 -0000 1.72 --- StockRound.java 9 Apr 2010 21:26:12 -0000 1.73 *************** *** 735,739 **** currentPlayer.getName() + LocalText.getText("WouldExceedCertLimit", ! String.valueOf(gameManager.getPlayerCertificateLimit())); break; } --- 735,739 ---- currentPlayer.getName() + LocalText.getText("WouldExceedCertLimit", ! String.valueOf(gameManager.getPlayerCertificateLimit(currentPlayer))); break; } *************** *** 1364,1368 **** // Over the total certificate hold Limit? ! if (player.getPortfolio().getCertificateCount() > gameManager.getPlayerCertificateLimit()) return true; --- 1364,1368 ---- // Over the total certificate hold Limit? ! if (player.getPortfolio().getCertificateCount() > gameManager.getPlayerCertificateLimit(player)) return true; *************** *** 1386,1390 **** if (comp.hasFloated() && comp.getCurrentSpace().isNoCertLimit()) return true; ! if (player.getPortfolio().getCertificateCount() + number > gameManager.getPlayerCertificateLimit()) return false; return true; --- 1386,1390 ---- if (comp.hasFloated() && comp.getCurrentSpace().isNoCertLimit()) return true; ! if (player.getPortfolio().getCertificateCount() + number > gameManager.getPlayerCertificateLimit(player)) return false; return true; |
From: Erik V. <ev...@us...> - 2010-04-09 21:26:20
|
Update of /cvsroot/rails/18xx/rails/game/specific/_1835 In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv4492/rails/game/specific/_1835 Modified Files: GameManager_1835.java Log Message: 1835: higher certificate limit if 80% owned. Index: GameManager_1835.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/specific/_1835/GameManager_1835.java,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** GameManager_1835.java 8 Apr 2010 21:23:47 -0000 1.6 --- GameManager_1835.java 9 Apr 2010 21:26:11 -0000 1.7 *************** *** 64,66 **** --- 64,77 ---- return prFormStartingPlayer; } + + public int getPlayerCertificateLimit(Player player) { + int limit = playerCertificateLimit.intValue(); + for (PublicCompanyI company : companyManager.getAllPublicCompanies()) { + if (company.getTypeName().equalsIgnoreCase("Major") + && company.getPresident() == player + && player.getPortfolio().getShare(company) >= 80) limit++; + } + return limit; + } + } |
From: Erik V. <ev...@us...> - 2010-04-09 21:26:20
|
Update of /cvsroot/rails/18xx/rails/ui/swing In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv4492/rails/ui/swing Modified Files: GameStatus.java Log Message: 1835: higher certificate limit if 80% owned. Index: GameStatus.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/ui/swing/GameStatus.java,v retrieving revision 1.46 retrieving revision 1.47 diff -C2 -d -r1.46 -r1.47 *** GameStatus.java 2 Apr 2010 20:03:54 -0000 1.46 --- GameStatus.java 9 Apr 2010 21:26:12 -0000 1.47 *************** *** 753,757 **** setIPOCertButton(i, false); setPoolCertButton(i, false); ! setPlayerCertButton (i, actorIndex, false); if (compCanHoldOwnShares) setTreasuryCertButton(i, false); } --- 753,757 ---- setIPOCertButton(i, false); setPoolCertButton(i, false); ! for (j=0; j < np; j++) setPlayerCertButton (i, j, false); if (compCanHoldOwnShares) setTreasuryCertButton(i, false); } |
From: Stefan F. <ste...@us...> - 2010-04-09 17:51:07
|
Update of /cvsroot/rails/18xx/data/1830 In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv27094/data/1830 Modified Files: Game.xml CompanyManager.xml Log Message: Added 1830 variant Pere Marquette Index: CompanyManager.xml =================================================================== RCS file: /cvsroot/rails/18xx/data/1830/CompanyManager.xml,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** CompanyManager.xml 21 Mar 2010 17:43:50 -0000 1.36 --- CompanyManager.xml 9 Apr 2010 17:50:59 -0000 1.37 *************** *** 102,106 **** <Home hex="A19"/> </Company> ! <StartPacket roundClass="rails.game.StartRound_1830"> <Bidding initial="5" minimum="5" increment="1"/> <Item name="SVNRR" type="Private" basePrice="20"/> --- 102,112 ---- <Home hex="A19"/> </Company> ! <IfOption name="Variant" value="Pere Marquette"> ! <Company name="PM" type="Public" tokens="3" fgColour="FFFF00" bgColour="000080" ! longname="Pere Marquette"> ! <Home hex="E5"/> ! </Company> ! </IfOption> ! <StartPacket roundClass="rails.game.StartRound_1830"> <Bidding initial="5" minimum="5" increment="1"/> <Item name="SVNRR" type="Private" basePrice="20"/> Index: Game.xml =================================================================== RCS file: /cvsroot/rails/18xx/data/1830/Game.xml,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** Game.xml 21 Mar 2010 17:43:50 -0000 1.34 --- Game.xml 9 Apr 2010 17:50:59 -0000 1.35 *************** *** 16,19 **** --- 16,20 ---- See GamesList.xml for the real ones. --> + <GameOption name="Variant" values="Basegame,Pere Marquette" default="Basegame" /> <GameOption name="NoMapMode" type="toggle" default="no" /> <GameOption name="BeginnerGame" type="toggle" default="no" /> *************** *** 42,50 **** </Component> <Component name="PlayerManager" class="rails.game.PlayerManager"> ! <Players number="2" cash="1200" certLimit="28"/> ! <Players number="3" cash="800" certLimit="20"/> ! <Players number="4" cash="600" certLimit="16"/> ! <Players number="5" cash="480" certLimit="13"/> ! <Players number="6" cash="400" certLimit="11"/> </Component> <Component name="Bank" class="rails.game.Bank"> --- 43,61 ---- </Component> <Component name="PlayerManager" class="rails.game.PlayerManager"> ! <IfOption name="Variant" value="Basegame"> ! <Players number="2" cash="1200" certLimit="28"/> ! <Players number="3" cash="800" certLimit="20"/> ! <Players number="4" cash="600" certLimit="16"/> ! <Players number="5" cash="480" certLimit="13"/> ! <Players number="6" cash="400" certLimit="11"/> ! </IfOption> ! <IfOption name="Variant" value="Pere Marquette"> ! <Players number="2" cash="1200" certLimit="32"/> ! <Players number="3" cash="800" certLimit="22"/> ! <Players number="4" cash="600" certLimit="17"/> ! <Players number="5" cash="480" certLimit="14"/> ! <Players number="6" cash="400" certLimit="12"/> ! <Players number="7" cash="360" certLimit="11"/> ! </IfOption> </Component> <Component name="Bank" class="rails.game.Bank"> *************** *** 90,93 **** --- 101,107 ---- <Attributes amount="2"/> </IfOption> + <IfOption name="Variant" value="Pere Marquette"> + <Attributes amount="3"/> + </IfOption> </Train> <Train name="D" majorStops="99" cost="1100" startPhase="D" |
From: Stefan F. <ste...@us...> - 2010-04-09 17:51:07
|
Update of /cvsroot/rails/18xx/data In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv27094/data Modified Files: GamesList.xml Log Message: Added 1830 variant Pere Marquette Index: GamesList.xml =================================================================== RCS file: /cvsroot/rails/18xx/data/GamesList.xml,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** GamesList.xml 12 Mar 2010 17:15:05 -0000 1.30 --- GamesList.xml 9 Apr 2010 17:50:59 -0000 1.31 *************** *** 34,37 **** --- 34,38 ---- in a dropdown the first item is always the default). --> + <Option name="Variant" values="Basegame,Pere Marquette" default="Basegame" /> <Option name="NoMapMode" type="toggle" default="no" /> <Option name="WithOptional6Train" type="toggle" default="no"/> |
From: Stefan F. <ste...@us...> - 2010-04-09 17:49:39
|
Update of /cvsroot/rails/18xx/rails/game In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv26622/rails/game Modified Files: MapHex.java Log Message: Updated Lay Tile and Token Hints Index: MapHex.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/game/MapHex.java,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -d -r1.40 -r1.41 *** MapHex.java 28 Mar 2010 17:05:55 -0000 1.40 --- MapHex.java 9 Apr 2010 17:49:31 -0000 1.41 *************** *** 939,942 **** --- 939,947 ---- } + public boolean isUpgradeableNow(PhaseI currentPhase) { + return (isUpgradeableNow() & !this.getCurrentTile().getValidUpgrades(this, + currentPhase).isEmpty()); + } + public boolean hasOffBoardValues() { return offBoardValues != null && offBoardValues.length > 0; |
From: Stefan F. <ste...@us...> - 2010-04-09 17:49:39
|
Update of /cvsroot/rails/18xx/rails/algorithms In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv26622/rails/algorithms Modified Files: NetworkVertex.java NetworkIterator.java NetworkGraphBuilder.java Log Message: Updated Lay Tile and Token Hints Index: NetworkVertex.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/algorithms/NetworkVertex.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** NetworkVertex.java 9 Apr 2010 07:20:27 -0000 1.2 --- NetworkVertex.java 9 Apr 2010 17:49:31 -0000 1.3 *************** *** 108,119 **** return side; } ! public boolean isFullyTokened(){ ! return tokenable && companiesHaveToken.size() == tokenSlots; } ! public boolean hasCompanyToken(PublicCompanyI company) { return !(company == null) && companiesHaveToken.contains(company); } public String printTokens(){ --- 108,141 ---- return side; } ! /** ! * Checks if a vertex is fully tokened ! * If it cannot be tokened, always returns false ! */ public boolean isFullyTokened(){ ! return tokenable && companiesHaveToken.size() >= tokenSlots; } ! ! /** ! * Checks if a public company can pass through a vertex ! */ ! public boolean canCompanyRunThrough(PublicCompanyI company) { ! return !isFullyTokened() || companiesHaveToken.contains(company); ! } ! ! /** ! * Checks if a vertex contains a token of the given public company ! */ public boolean hasCompanyToken(PublicCompanyI company) { return !(company == null) && companiesHaveToken.contains(company); } + + /** + * Checks if a given company can add a token + * + */ + public boolean canCompanyAddToken(PublicCompanyI company) { + return (tokenable && companiesHaveToken.size() < tokenSlots && company != null && + !companiesHaveToken.contains(company)); + } public String printTokens(){ Index: NetworkIterator.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/algorithms/NetworkIterator.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** NetworkIterator.java 4 Apr 2010 22:02:53 -0000 1.1 --- NetworkIterator.java 9 Apr 2010 17:49:31 -0000 1.2 *************** *** 181,185 **** private void addUnseenChildrenOf(NetworkVertex vertex, VisitColor previousColor) { ! if (vertex.isFullyTokened() && !vertex.hasCompanyToken(company)) return; for (NetworkEdge edge : graph.edgesOf(vertex)) { --- 181,185 ---- private void addUnseenChildrenOf(NetworkVertex vertex, VisitColor previousColor) { ! if (company != null && !vertex.canCompanyRunThrough(company)) return; for (NetworkEdge edge : graph.edgesOf(vertex)) { Index: NetworkGraphBuilder.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/algorithms/NetworkGraphBuilder.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** NetworkGraphBuilder.java 9 Apr 2010 07:20:27 -0000 1.3 --- NetworkGraphBuilder.java 9 Apr 2010 17:49:31 -0000 1.4 *************** *** 92,97 **** log.debug("Track: " + track); NetworkEdge edge = new NetworkEdge(startVertex, endVertex, false); ! mapGraph.addEdge(startVertex, endVertex, edge); ! log.debug("Added edge " + edge.getConnection()); } --- 92,101 ---- log.debug("Track: " + track); NetworkEdge edge = new NetworkEdge(startVertex, endVertex, false); ! if (startVertex == endVertex) { ! log.error("Track " + track + " on hex " + hex + "has identical start/end"); ! } else { ! mapGraph.addEdge(startVertex, endVertex, edge); ! log.debug("Added edge " + edge.getConnection()); ! } } *************** *** 219,226 **** public static List<MapHex> getStationHexes(Graph<NetworkVertex, NetworkEdge> graph, ! boolean tokenable){ List<MapHex> hexes = new ArrayList<MapHex>(); for(NetworkVertex vertex:graph.vertexSet()) { ! if (vertex.isStation() && !(tokenable && vertex.isFullyTokened())) { hexes.add(vertex.getHex()); } --- 223,230 ---- public static List<MapHex> getStationHexes(Graph<NetworkVertex, NetworkEdge> graph, ! PublicCompanyI company){ List<MapHex> hexes = new ArrayList<MapHex>(); for(NetworkVertex vertex:graph.vertexSet()) { ! if (vertex.canCompanyAddToken(company)) { hexes.add(vertex.getHex()); } |
From: Stefan F. <ste...@us...> - 2010-04-09 17:49:38
|
Update of /cvsroot/rails/18xx/rails/ui/swing In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv26622/rails/ui/swing Modified Files: ORUIManager.java Log Message: Updated Lay Tile and Token Hints Index: ORUIManager.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/ui/swing/ORUIManager.java,v retrieving revision 1.63 retrieving revision 1.64 diff -C2 -d -r1.63 -r1.64 *** ORUIManager.java 9 Apr 2010 07:20:27 -0000 1.63 --- ORUIManager.java 9 Apr 2010 17:49:31 -0000 1.64 *************** *** 189,200 **** nextSubStep = ORUIManager.SELECT_HEX_FOR_TILE; mapPanel.setAllowedTileLays(allowedTileLays); ! // generate network graph to indicate the allowed tiles ! hexUpgrades = NetworkGraphBuilder.getMapHexes(getCompanyGraph()); ! for (MapHex hex:hexUpgrades) { ! if (hex.isUpgradeableNow()){ GUIHex guiHex = map.getHexByName(hex.getName()); ! guiHex.setSelectable(true); } } } --- 189,234 ---- nextSubStep = ORUIManager.SELECT_HEX_FOR_TILE; mapPanel.setAllowedTileLays(allowedTileLays); ! // if hexupgrades is not null, then remove indicators ! if (hexUpgrades != null) { ! for (MapHex hex:hexUpgrades) { GUIHex guiHex = map.getHexByName(hex.getName()); ! guiHex.setSelectable(false); ! } ! } ! ! // check actions for allowed hexes ! boolean mapHexes = false; ! hexUpgrades = new ArrayList<MapHex>(); ! for (LayTile layTile:allowedTileLays) { ! switch (layTile.getType()) { ! case (LayTile.GENERIC): ! mapHexes = true; ! break; ! case (LayTile.SPECIAL_PROPERTY): ! SpecialPropertyI sp = layTile.getSpecialProperty(); ! if (sp == null || !(sp instanceof SpecialTileLay) || ! ((SpecialTileLay)sp).requiresConnection()) ! break; ! case (LayTile.LOCATION_SPECIFIC): ! if (layTile.getLocations() != null) ! hexUpgrades.addAll(layTile.getLocations()); ! } ! } ! ! // standard upgrades ! if (mapHexes) { ! // generate network graph to indicate the allowed tiles ! List<MapHex> mapHexUpgrades = NetworkGraphBuilder.getMapHexes(getCompanyGraph()); ! for (MapHex hex:mapHexUpgrades) { ! if (hex.isUpgradeableNow(gameUIManager.getCurrentPhase())) ! hexUpgrades.add(hex); } } + + // activate upgrades + for (MapHex hex:hexUpgrades) { + GUIHex guiHex = map.getHexByName(hex.getName()); + guiHex.setSelectable(true); + } } *************** *** 202,209 **** nextSubStep = ORUIManager.SELECT_HEX_FOR_TOKEN; mapPanel.setAllowedTokenLays(allowedTokenLays); ! // generate network graph to indicate the token lays ! hexUpgrades = NetworkGraphBuilder.getStationHexes(getCompanyGraph(), true); ! for (MapHex hex:hexUpgrades) { ! if (hex.hasTokenSlotsLeft()){ GUIHex guiHex = map.getHexByName(hex.getName()); guiHex.setSelectable(true); --- 236,267 ---- nextSubStep = ORUIManager.SELECT_HEX_FOR_TOKEN; mapPanel.setAllowedTokenLays(allowedTokenLays); ! // if hexupgrades is not null, then remove indicators ! if (hexUpgrades != null) { ! for (MapHex hex:hexUpgrades) { ! GUIHex guiHex = map.getHexByName(hex.getName()); ! guiHex.setSelectable(false); ! } ! } ! ! // check actions for allowed hexes ! boolean mapHexes = false; ! hexUpgrades = new ArrayList<MapHex>(); ! for (LayToken layToken:allowedTokenLays) { ! SpecialPropertyI sp = layToken.getSpecialProperty(); ! if (sp == null) { ! mapHexes = true; ! } else if (layToken.getLocations() != null) ! hexUpgrades.addAll(layToken.getLocations()); ! } ! ! // standard tokens ! if (mapHexes) { ! // generate network graph to indicate the token lays ! hexUpgrades = NetworkGraphBuilder.getStationHexes(getCompanyGraph(), orComp); ! for (LayToken layToken:allowedTokenLays) { ! if (layToken.getLocations() != null) ! hexUpgrades.addAll(layToken.getLocations()); ! } ! for (MapHex hex:hexUpgrades) { GUIHex guiHex = map.getHexByName(hex.getName()); guiHex.setSelectable(true); |
From: Stefan F. <ste...@us...> - 2010-04-09 07:20:35
|
Update of /cvsroot/rails/18xx/rails/ui/swing In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv9545/rails/ui/swing Modified Files: StatusWindow.java GameUIManager.java ORUIManager.java Log Message: Added Tile and Token location hints Some minor fixes Index: StatusWindow.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/ui/swing/StatusWindow.java,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** StatusWindow.java 4 Apr 2010 22:02:53 -0000 1.42 --- StatusWindow.java 9 Apr 2010 07:20:27 -0000 1.43 *************** *** 699,703 **** StringBuilder report = new StringBuilder(); for (String s:gameReport) { ! report.insert(0, s); JOptionPane.showMessageDialog(this, report, --- 699,703 ---- StringBuilder report = new StringBuilder(); for (String s:gameReport) { ! report.insert(0, s + "\n"); JOptionPane.showMessageDialog(this, report, Index: ORUIManager.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/ui/swing/ORUIManager.java,v retrieving revision 1.62 retrieving revision 1.63 diff -C2 -d -r1.62 -r1.63 *** ORUIManager.java 28 Mar 2010 17:05:56 -0000 1.62 --- ORUIManager.java 9 Apr 2010 07:20:27 -0000 1.63 *************** *** 7,11 **** --- 7,15 ---- import org.apache.log4j.Logger; + import org.jgrapht.graph.SimpleGraph; + import rails.algorithms.NetworkEdge; + import rails.algorithms.NetworkGraphBuilder; + import rails.algorithms.NetworkVertex; import rails.game.*; import rails.game.action.*; *************** *** 46,49 **** --- 50,54 ---- public List<LayTile> allowedTileLays = new ArrayList<LayTile>(); public List<TileI> tileUpgrades; + private List<MapHex> hexUpgrades; private boolean tokenLayingEnabled = false; *************** *** 121,124 **** --- 126,138 ---- } + private SimpleGraph<NetworkVertex, NetworkEdge> getCompanyGraph(){ + MapManager mapManager = gameUIManager.getGameManager().getMapManager(); + NetworkGraphBuilder nwGraph = new NetworkGraphBuilder(); + nwGraph.generateGraph(mapManager.getHexesAsList()); + SimpleGraph<NetworkVertex, NetworkEdge> graph = + nwGraph.getRailRoadGraph(orComp); + return graph; + } + public <T extends PossibleAction> void setMapRelatedActions(List<T> actions) { *************** *** 137,169 **** } if (allowedTileLays.size() > 0) { nextSubStep = ORUIManager.SELECT_HEX_FOR_TILE; mapPanel.setAllowedTileLays(allowedTileLays); ! } else { ! if (tileLayingEnabled) { ! /* Finish tile laying step */ ! if (selectedHex != null) { ! selectedHex.removeTile(); ! selectedHex.setSelected(false); ! mapPanel.getMap().repaint(selectedHex.getBounds()); ! selectedHex = null; } } } ! if (allowedTokenLays.size() > 0) { nextSubStep = ORUIManager.SELECT_HEX_FOR_TOKEN; mapPanel.setAllowedTokenLays(allowedTokenLays); ! } else { ! if (tokenLayingEnabled) { ! /* Finish token laying step */ ! if (selectedHex != null) { ! selectedHex.removeToken(); ! selectedHex.setSelected(false); ! mapPanel.getMap().repaint(selectedHex.getBounds()); ! selectedHex = null; } } ! } setLocalStep(nextSubStep); --- 151,214 ---- } + // moved the check for finishing steps to the beginning + if (allowedTileLays.size() == 0 && tileLayingEnabled) { + /* Finish tile laying step */ + if (selectedHex != null) { + selectedHex.removeTile(); + selectedHex.setSelected(false); + mapPanel.getMap().repaint(selectedHex.getBounds()); + selectedHex = null; + } + // remove selectable indications + for (MapHex hex:hexUpgrades) { + GUIHex guiHex = map.getHexByName(hex.getName()); + guiHex.setSelectable(false); + mapPanel.getMap().repaint(guiHex.getBounds()); + } + hexUpgrades = null; + } + + if (allowedTokenLays.size() == 0 && tokenLayingEnabled) { + /* Finish token laying step */ + if (selectedHex != null) { + selectedHex.removeToken(); + selectedHex.setSelected(false); + mapPanel.getMap().repaint(selectedHex.getBounds()); + selectedHex = null; + } + // remove selectable indications + for (MapHex hex:hexUpgrades) { + GUIHex guiHex = map.getHexByName(hex.getName()); + guiHex.setSelectable(false); + mapPanel.getMap().repaint(guiHex.getBounds()); + } + hexUpgrades = null; + } + if (allowedTileLays.size() > 0) { nextSubStep = ORUIManager.SELECT_HEX_FOR_TILE; mapPanel.setAllowedTileLays(allowedTileLays); ! // generate network graph to indicate the allowed tiles ! hexUpgrades = NetworkGraphBuilder.getMapHexes(getCompanyGraph()); ! for (MapHex hex:hexUpgrades) { ! if (hex.isUpgradeableNow()){ ! GUIHex guiHex = map.getHexByName(hex.getName()); ! guiHex.setSelectable(true); } } } ! if (allowedTokenLays.size() > 0) { nextSubStep = ORUIManager.SELECT_HEX_FOR_TOKEN; mapPanel.setAllowedTokenLays(allowedTokenLays); ! // generate network graph to indicate the token lays ! hexUpgrades = NetworkGraphBuilder.getStationHexes(getCompanyGraph(), true); ! for (MapHex hex:hexUpgrades) { ! if (hex.hasTokenSlotsLeft()){ ! GUIHex guiHex = map.getHexByName(hex.getName()); ! guiHex.setSelectable(true); } } ! } setLocalStep(nextSubStep); Index: GameUIManager.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/ui/swing/GameUIManager.java,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -d -r1.45 -r1.46 *** GameUIManager.java 4 Apr 2010 22:02:53 -0000 1.45 --- GameUIManager.java 9 Apr 2010 07:20:27 -0000 1.46 *************** *** 606,628 **** JFileChooser jfc = new JFileChooser(); String filename; ! if (providedName != null) filename = providedName; ! else { filename = saveDirectory + "/" + gameManager.getGameName() + "_" + saveDateTimeFormat.format(new Date()) + saveSuffix + ".txt"; ! File proposedFile = new File(filename); ! jfc.setSelectedFile(proposedFile); ! if (jfc.showSaveDialog(statusWindow) == JFileChooser.APPROVE_OPTION) { ! File selectedFile = jfc.getSelectedFile(); ! String filepath = selectedFile.getPath(); ! saveDirectory = selectedFile.getParent(); ! if (!selectedFile.getName().equalsIgnoreCase(proposedFile.getName())) { ! providedName = filepath; ! } ! exportAction.setFilepath(filepath); ! processOnServer(exportAction); } } } --- 606,628 ---- JFileChooser jfc = new JFileChooser(); String filename; ! if (providedName != null) { filename = providedName; ! } else { filename = saveDirectory + "/" + gameManager.getGameName() + "_" + saveDateTimeFormat.format(new Date()) + saveSuffix + ".txt"; + } ! File proposedFile = new File(filename); ! jfc.setSelectedFile(proposedFile); ! if (jfc.showSaveDialog(statusWindow) == JFileChooser.APPROVE_OPTION) { ! File selectedFile = jfc.getSelectedFile(); ! String filepath = selectedFile.getPath(); ! saveDirectory = selectedFile.getParent(); ! if (!selectedFile.getName().equalsIgnoreCase(proposedFile.getName())) { ! providedName = filepath; } + exportAction.setFilepath(filepath); + processOnServer(exportAction); } } |
From: Stefan F. <ste...@us...> - 2010-04-09 07:20:35
|
Update of /cvsroot/rails/18xx In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv9545 Modified Files: LocalisedText.properties Log Message: Added Tile and Token location hints Some minor fixes Index: LocalisedText.properties =================================================================== RCS file: /cvsroot/rails/18xx/LocalisedText.properties,v retrieving revision 1.126 retrieving revision 1.127 diff -C2 -d -r1.126 -r1.127 *** LocalisedText.properties 8 Apr 2010 21:25:51 -0000 1.126 --- LocalisedText.properties 9 Apr 2010 07:20:27 -0000 1.127 *************** *** 170,173 **** --- 170,174 ---- ERROR=Error EXCHANGED=exchanged + EXPORT=Export Map EndOfOperatingRound=\nEnd of Operating Round {0} EnterRevenue=Enter the earnings of the operating company *************** *** 298,301 **** --- 299,303 ---- NamesTrain={0} names {1}-train as {2} NegativeAmountNotAllowed=Negative amount {0} not allowed + NetworkInfo=Network Info NEW=New NewGame=New Game |
From: Stefan F. <ste...@us...> - 2010-04-09 07:20:35
|
Update of /cvsroot/rails/18xx/rails/algorithms In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv9545/rails/algorithms Modified Files: NetworkVertex.java NetworkGraphBuilder.java Log Message: Added Tile and Token location hints Some minor fixes Index: NetworkVertex.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/algorithms/NetworkVertex.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** NetworkVertex.java 4 Apr 2010 22:02:53 -0000 1.1 --- NetworkVertex.java 9 Apr 2010 07:20:27 -0000 1.2 *************** *** 37,41 **** this.side = 0; ! if (station.getBaseSlots() == 0){ this.tokenable = false; } else { --- 37,42 ---- this.side = 0; ! String t = station.getType(); ! if (t.equals(Station.TOWN)){ this.tokenable = false; } else { *************** *** 52,59 **** } } ! if (tokens == null) ! this.companiesHaveToken = null; ! else { ! this.companiesHaveToken = new HashSet<PublicCompanyI>(); for (TokenI token:tokens) { if (token instanceof BaseToken) { --- 53,58 ---- } } ! this.companiesHaveToken = new HashSet<PublicCompanyI>(); ! if (tokens != null) { for (TokenI token:tokens) { if (token instanceof BaseToken) { Index: NetworkGraphBuilder.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/algorithms/NetworkGraphBuilder.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** NetworkGraphBuilder.java 8 Apr 2010 21:23:14 -0000 1.2 --- NetworkGraphBuilder.java 9 Apr 2010 07:20:27 -0000 1.3 *************** *** 208,211 **** --- 208,233 ---- } + public static List<MapHex> getMapHexes(Graph<NetworkVertex, NetworkEdge> graph){ + List<MapHex> hexes = new ArrayList<MapHex>(); + for(NetworkVertex vertex:graph.vertexSet()) { + if (vertex.isStation() || vertex.isSide()) { + hexes.add(vertex.getHex()); + } + } + return hexes; + } + + public static List<MapHex> getStationHexes(Graph<NetworkVertex, NetworkEdge> graph, + boolean tokenable){ + List<MapHex> hexes = new ArrayList<MapHex>(); + for(NetworkVertex vertex:graph.vertexSet()) { + if (vertex.isStation() && !(tokenable && vertex.isFullyTokened())) { + hexes.add(vertex.getHex()); + } + } + return hexes; + } + + public static void optimizeGraph(Graph<NetworkVertex, NetworkEdge> graph) { while (removeVertexes(graph)); |
From: Stefan F. <ste...@us...> - 2010-04-09 07:20:35
|
Update of /cvsroot/rails/18xx/rails/ui/swing/hexmap In directory sfp-cvsdas-4.v30.ch3.sourceforge.com:/tmp/cvs-serv9545/rails/ui/swing/hexmap Modified Files: GUIHex.java Log Message: Added Tile and Token location hints Some minor fixes Index: GUIHex.java =================================================================== RCS file: /cvsroot/rails/18xx/rails/ui/swing/hexmap/GUIHex.java,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** GUIHex.java 28 Mar 2010 17:05:55 -0000 1.39 --- GUIHex.java 9 Apr 2010 07:20:27 -0000 1.40 *************** *** 40,43 **** --- 40,44 ---- protected GeneralPath innerHexagon; protected static final Color highlightColor = Color.red; + protected static final Color upgradableColor = Color.magenta; protected Point center; /** x and y coordinates on the map */ *************** *** 89,92 **** --- 90,94 ---- // Selection is in-between GUI and rails.game state. private boolean selected; + private boolean selectable; protected static Logger log = *************** *** 224,228 **** if (selected) { currentGUITile.setScale(SELECTED_SCALE); ! } else { currentGUITile.setScale(NORMAL_SCALE); provisionalGUITile = null; --- 226,230 ---- if (selected) { currentGUITile.setScale(SELECTED_SCALE); ! } else if (!isSelectable()) { currentGUITile.setScale(NORMAL_SCALE); provisionalGUITile = null; *************** *** 234,237 **** --- 236,253 ---- } + public void setSelectable(boolean selectable) { + this.selectable = selectable; + if (selectable) { + currentGUITile.setScale(SELECTED_SCALE); + } else { + currentGUITile.setScale(NORMAL_SCALE); + provisionalGUITile = null; + } + } + + public boolean isSelectable() { + return selectable; + } + static boolean getAntialias() { return antialias; *************** *** 296,301 **** Color terrainColor = Color.WHITE; ! if (isSelected()) { ! g2.setColor(highlightColor); g2.fill(hexagon); --- 312,320 ---- Color terrainColor = Color.WHITE; ! if (isSelected() || isSelectable()) { ! if (isSelected()) ! g2.setColor(highlightColor); ! else ! g2.setColor(upgradableColor); g2.fill(hexagon); |