Skip to content

Commit 26eca3d

Browse files
committed
Merge branch 'master' of https://github.com/Rails-18xx/Rails
2 parents a751fef + 6f3fdde commit 26eca3d

File tree

120 files changed

+15547
-3614
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

120 files changed

+15547
-3614
lines changed

Changelog.md

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,36 @@
1-
# Rails-18xx 2.3 Release
1+
# Rails-18xx 2.4 Release
22
This release is meant to show the current state of the Rails-18xx implementation.
33

44
Due to different reasons Rails-18xx 2.0 and 2.1 have not been release as production releases. We hope that the audience
55
finds the release usefull. As usual we welcome bug reports and save games that show the affected states of the game.
66

77
We would like to **thank** the various bug reporters and the developers who have contributed over the years for one
88
feature or ground breaking work.
9+
Please take note that to run Rails-18xx as a JAR directly you need to install a JDK with Java V11 as minimum. The game comes with its own JRE compiled in.
910

11+
Please dont use the .bat from earlier versions.
1012

11-
## New Features
13+
**Using the installer on Windows and the same directory as previous installations, will overwrite everything in that directory.**
1214

13-
* Notification of Moves via Slack
14-
* Notification of Moves via Discord
15-
* Autoloading and Autopolling for near time gaming allowing you to reload the save game that has changed during turns
16-
* Direct Revenue Allocation for various Contracts possible
17-
* State of Direct Revenue Allocation is static towards company operations budget (no Half pay) - Workaround you half the allocation and add the rest to normal revenue distribution
18-
* Installers for Windows, Mac OS, Linux (Redhat)
15+
We would like to **thank** the varios bug reporters and the developers who have contributed over the years for one feature or ground breaking work.
1916

2017
## New games
2118

2219
* 18Scan
23-
* Steam over Holland
20+
* Steam over Holland implemented by Erik Vos.
2421

2522
## Status of Games
26-
23+
* Implementation of 18Chesapeake started, needs playtesting, bug reports welcome
24+
* Implementation of 1837 - Have a look but be prepared that it might break...
25+
* Open Topics in 1837 Implementation:
26+
* Coal Minors merging round implementation not always working as intended..
2727

2828
## Bug Fixes
29-
30-
* 1856 : Various Bugs
31-
* 1835 : Berlin to Berlin not counts for revenue anymore
32-
* 1880 : Fix for tile #235, Fix for Investor display, broken in 2.2.2
33-
29+
* Various svg-Tiles werent configured correctly which lead to graphic error while resizing or moving the map. Issue reported for 18NL/18TN by Lou Jerkich; Fixes done for 1837 1880 and 18Chesapeake
30+
31+
## Issues fixed:
32+
* #342
33+
* #338
34+
* #329
35+
* #326
36+
* #320

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ plugins {
1515
// https://openjfx.io/openjfx-docs/#gradle
1616
id 'org.openjfx.javafxplugin' version '0.0.9'
1717
// https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-gradle/
18-
id 'org.sonarqube' version '3.0'
18+
id 'org.sonarqube' version '3.1.1'
1919
// used by SonarQube for code coverage
2020
id 'jacoco'
2121
}

src/main/java/net/sf/rails/algorithms/NetworkVertex.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import net.sf.rails.game.*;
88
import net.sf.rails.ui.swing.hexmap.*;
99

10+
import net.sf.rails.util.Util;
1011
import org.apache.commons.lang3.StringUtils;
1112
import org.slf4j.Logger;
1213
import org.slf4j.LoggerFactory;
@@ -94,8 +95,7 @@ private NetworkVertex(VertexType type, String name) {
9495
/** factory method for virtual vertex
9596
*/
9697
public static NetworkVertex getVirtualVertex(VertexType type, String name) {
97-
NetworkVertex vertex = new NetworkVertex(type, name);
98-
return vertex;
98+
return new NetworkVertex(type, name);
9999
}
100100

101101
void addToRevenueCalculator(RevenueCalculator rc, int vertexId) {

src/main/java/net/sf/rails/algorithms/RevenueAdapter.java

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
* RevenueAdapter links the revenue algorithm to Rails.
3232
*/
3333
public final class RevenueAdapter implements Runnable {
34+
35+
int specialRevenue;
36+
3437
private static final Logger log = LoggerFactory.getLogger(RevenueAdapter.class);
3538

3639
// define VertexVisitSet
@@ -589,14 +592,22 @@ private List<RevenueTrainRun> convertRcRun(int[][] rcRun) {
589592

590593
public int calculateRevenue() {
591594
// allows (one) dynamic modifiers to have their own revenue calculation method
592-
// TODO: Still to be added
595+
// TODO: Still to be added - beware: it is used differently in 1837
596+
// (see RunToCoalMineModifier).
593597
// if (hasDynamicCalculator) {
594598
// return revenueManager.revenueFromDynamicCalculator(this);
599+
// For 1837 we need to do both!
600+
specialRevenue = revenueManager.revenueFromDynamicCalculator(this);
595601
// } else { // otherwise standard calculation
596-
return calculateRevenue(0, trains.size() - 1);
602+
return calculateRevenue(0, trains.size() - 1);
597603
// }
598604
}
599605

606+
// Another way to get the special revenue
607+
public void setSpecialRevenue (int value) {
608+
specialRevenue = value;
609+
}
610+
600611
public int calculateRevenue(int startTrain, int finalTrain) {
601612
if (startTrain < 0 || finalTrain >= trains.size() || startTrain > finalTrain) {
602613
return 0;
@@ -606,10 +617,15 @@ public int calculateRevenue(int startTrain, int finalTrain) {
606617
rc.initRuns(startTrain, finalTrain);
607618
rc.executePredictions(startTrain, finalTrain);
608619
int value = rc.calculateRevenue(startTrain, finalTrain);
620+
609621
return value;
610622
}
611623

612-
public List<RevenueTrainRun> getOptimalRun() {
624+
public int getSpecialRevenue() {
625+
return specialRevenue;
626+
}
627+
628+
public List<RevenueTrainRun> getOptimalRun() {
613629
if (optimalRun == null) {
614630
optimalRun = convertRcRun(rc.getOptimalRun());
615631
if (hasDynamicModifiers) {
@@ -630,6 +646,7 @@ int dynamicEvaluation() {
630646
int value = 0;
631647
if (hasDynamicModifiers) {
632648
value = revenueManager.evaluationValue(this.getCurrentRun(), false);
649+
specialRevenue = revenueManager.getSpecialRevenue();
633650
}
634651
return value;
635652
}
@@ -649,14 +666,16 @@ public void addRevenueListener(RevenueListener listener) {
649666
this.revenueListener = listener;
650667
}
651668

652-
void notifyRevenueListener(final int revenue, final boolean finalResult) {
669+
void notifyRevenueListener(final int revenue, final int specialRevenue, final boolean finalResult) {
653670
if (revenueListener == null) return;
654671

655672
EventQueue.invokeLater(
656673
new Runnable() {
657674
public void run() {
658675
//listener could have deregistered himself in the meantime
659-
if (revenueListener != null) revenueListener.revenueUpdate(revenue, finalResult);
676+
if (revenueListener != null) {
677+
revenueListener.revenueUpdate(revenue, specialRevenue, finalResult);
678+
}
660679
}
661680
});
662681
}

src/main/java/net/sf/rails/algorithms/RevenueCalculator.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ abstract class RevenueCalculator {
5353
protected final int [] trainStartEdge;
5454
protected final int[] trainDistance; // keeps track of distance travelled (for H-trains)
5555

56+
int specialRevenue;
57+
5658
// static bonus data
5759
protected final int [] bonusValue;
5860
protected final boolean [][] bonusActiveForTrain; // dimensions: bonus x train
@@ -264,14 +266,14 @@ final String getStatistics() {
264266
return statistics.toString();
265267
}
266268

267-
private void notifyRevenueAdapter(final int revenue, final boolean finalResult) {
269+
private void notifyRevenueAdapter(final int revenue, final int specialRevenue, final boolean finalResult) {
268270
String modifier;
269271
if (finalResult)
270272
modifier = "final";
271273
else
272274
modifier = "new best";
273275
log.debug("Report {} result of {} after {}", modifier, revenue, getStatistics());
274-
revenueAdapter.notifyRevenueListener(revenue, finalResult);
276+
revenueAdapter.notifyRevenueListener(revenue, specialRevenue, finalResult);
275277
}
276278

277279
private int[] bestRevenues(final int[] values, final int length) {
@@ -399,7 +401,7 @@ final int calculateRevenue(final int startTrain, final int finalTrain) {
399401
runTrain(startTrain);
400402

401403
// inform revenue listener via adapter
402-
notifyRevenueAdapter(currentBestValue, true);
404+
notifyRevenueAdapter(currentBestValue, specialRevenue, true);
403405

404406
return currentBestValue;
405407
}
@@ -526,7 +528,10 @@ protected final void evaluateResults() {
526528
// }
527529
}
528530

529-
if (callDynamicModifiers) totalValue += revenueAdapter.dynamicEvaluation();
531+
if (callDynamicModifiers) {
532+
totalValue += revenueAdapter.dynamicEvaluation();
533+
specialRevenue = revenueAdapter.getSpecialRevenue();
534+
}
530535

531536
nbEvaluations++;
532537
log.debug("RC: current total value {}", totalValue);
@@ -547,7 +552,8 @@ protected final void evaluateResults() {
547552
}
548553
log.debug("RC: Found better run with {}", totalValue);
549554
// inform revenue listener via adapter
550-
notifyRevenueAdapter(currentBestValue, false);
555+
// special revenue only to be reported with the final result
556+
notifyRevenueAdapter(currentBestValue, specialRevenue, false);
551557
}
552558
}
553559

src/main/java/net/sf/rails/algorithms/RevenueCalculatorModifier.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ public interface RevenueCalculatorModifier {
77
* If several dynamic modifier have their own method, their prediction values are added up.
88
* @return optimal value
99
*/
10-
public int calculateRevenue(RevenueAdapter revenueAdpater);
10+
public int calculateRevenue(RevenueAdapter revenueAdapter);
1111

12-
12+
public int getSpecialRevenue();
1313

1414
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
package net.sf.rails.algorithms;
22

33
public interface RevenueListener {
4-
public void revenueUpdate(int revenue, boolean finalResult);
4+
public void revenueUpdate(int revenue, int specialRevenue, boolean finalResult);
55
}

src/main/java/net/sf/rails/algorithms/RevenueManager.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
*/
2626
public final class RevenueManager extends RailsManager implements Configurable {
2727

28+
private int specialRevenue;
29+
2830
private static final Logger log = LoggerFactory.getLogger(RevenueManager.class);
2931

3032
// Modifiers that are configurable
@@ -200,6 +202,8 @@ boolean initDynamicModifiers(RevenueAdapter revenueAdapter) {
200202
* @return revenue from active calculator
201203
*/
202204
// FIXME: This does not fully cover all cases that needs the revenue from the calculator
205+
// EV: indeed, it used in a different way in 1837, so beware!
206+
// See RunToCoalMineModifier.
203207
int revenueFromDynamicCalculator(RevenueAdapter revenueAdapter) {
204208
return calculatorModifier.calculateRevenue(revenueAdapter);
205209

@@ -229,9 +233,16 @@ int evaluationValue(List<RevenueTrainRun> run, boolean optimal) {
229233
for (RevenueDynamicModifier modifier : activeDynamicModifiers) {
230234
value += modifier.evaluationValue(run, optimal);
231235
}
236+
if (calculatorModifier != null) {
237+
specialRevenue = calculatorModifier.getSpecialRevenue();
238+
}
232239
return value;
233240
}
234241

242+
public int getSpecialRevenue () {
243+
return specialRevenue;
244+
}
245+
235246
/**
236247
* @return total prediction value of dynamic modifiers
237248
*/

src/main/java/net/sf/rails/common/GuiDef.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ public enum Parm {
4242
NO_MAP_MODE,
4343
REVENUE_SUGGEST,
4444
ROUTE_HIGHLIGHT,
45-
PLAYER_ORDER_VARIES, HAS_SPECIAL_COMPANY_INCOME
45+
PLAYER_ORDER_VARIES,
46+
HAS_SPECIAL_COMPANY_INCOME
4647
}
4748

4849
/**

src/main/java/net/sf/rails/common/parser/Tag.java

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -276,18 +276,24 @@ private void parseSubTags(Element element) throws ConfigurationException {
276276
value = attribute.getNodeValue();
277277
attributes.put(name, value);
278278
}
279-
} else if ( "IfOption".equalsIgnoreCase(childTagName)) {
280-
Node nameAttr = nnp.getNamedItem("name");
281-
if (nameAttr == null)
282-
throw new ConfigurationException(
283-
"IfOption has no optionName attribute");
284-
name = nameAttr.getNodeValue();
285-
286-
Node parmAttr = nnp.getNamedItem("parm");
287-
if (parmAttr != null) {
288-
value = parmAttr.getNodeValue();
289-
Iterable<String> parameters = Splitter.on(XMLTags.VALUES_DELIM).split(value);
290-
name = GameOption.constructParameterisedName(name, ImmutableList.copyOf(parameters));
279+
} else if ("IfOption".equalsIgnoreCase(childTagName)
280+
|| "IfVariant".equalsIgnoreCase(childTagName)) {
281+
282+
if ("IfOption".equalsIgnoreCase(childTagName)) {
283+
Node nameAttr = nnp.getNamedItem("name");
284+
if (nameAttr == null)
285+
throw new ConfigurationException(
286+
"IfOption has no optionName attribute");
287+
name = nameAttr.getNodeValue();
288+
289+
Node parmAttr = nnp.getNamedItem("parm");
290+
if (parmAttr != null) {
291+
value = parmAttr.getNodeValue();
292+
Iterable<String> parameters = Splitter.on(XMLTags.VALUES_DELIM).split(value);
293+
name = GameOption.constructParameterisedName(name, ImmutableList.copyOf(parameters));
294+
}
295+
} else { // IfVariant
296+
name = "Variant";
291297
}
292298

293299
Node valueAttr = nnp.getNamedItem("value");

0 commit comments

Comments
 (0)