diff --git a/pom.xml b/pom.xml
index b374879..20dec21 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
de.srsoftware
web4rail
- 0.11.4
+ 0.11.5
Web4Rail
jar
Java Model Railway Control
diff --git a/src/main/java/de/srsoftware/web4rail/PathFinder.java b/src/main/java/de/srsoftware/web4rail/PathFinder.java
new file mode 100644
index 0000000..71f4336
--- /dev/null
+++ b/src/main/java/de/srsoftware/web4rail/PathFinder.java
@@ -0,0 +1,116 @@
+package de.srsoftware.web4rail;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+import java.util.Vector;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import de.srsoftware.web4rail.Plan.Direction;
+import de.srsoftware.web4rail.actions.Action.Context;
+import de.srsoftware.web4rail.moving.Train;
+import de.srsoftware.web4rail.tiles.Block;
+
+public class PathFinder extends BaseClass{
+ private static final Logger LOG = LoggerFactory.getLogger(PathFinder.class);
+
+ private static TreeMap> availableRoutes(Context context,HashSet visitedRoutes){
+ TreeMap> availableRoutes = new TreeMap>();
+
+ String inset = "";
+ for (int i=0; i> forwardRoutes = availableRoutes(forwardContext,visitedRoutes);
+ visitedRoutes.remove(routeCandidate);
+ if (forwardRoutes.isEmpty()) continue; // the candidate does not lead to a block, from which routes to the destination exist
+ Entry> entry = forwardRoutes.lastEntry();
+ LOG.debug("{}→ The following routes have connections to {}:",inset,destination);
+ for (Route rt: entry.getValue()) LOG.debug("{} - {}",inset,rt.shortName());
+ priority += entry.getKey()-10;
+ }
+ }
+
+ List routeSet = availableRoutes.get(priority);
+ if (isNull(routeSet)) {
+ routeSet = new Vector();
+ availableRoutes.put(priority, routeSet);
+ }
+ routeSet.add(routeCandidate);
+ if (routeCandidate.endBlock() == destination) break; // direct connection to destination discovered, quit search
+ }
+ LOG.debug("{}→ Routes from {}: {}",inset,block,availableRoutes.isEmpty()?"none":"");
+ for (Entry> entry : availableRoutes.entrySet()) {
+ LOG.debug("{} - Priority {}:",inset,entry.getKey());
+ for (Route r : entry.getValue()) {
+ LOG.debug("{} - {}",inset,r.shortName());
+ }
+ }
+ return availableRoutes;
+ }
+
+ public static Route chooseRoute(Context context) {
+ TreeMap> availableRoutes = PathFinder.availableRoutes(context,new HashSet());
+ if (availableRoutes.isEmpty()) return null;
+ Entry> entry = availableRoutes.lastEntry();
+ List preferredRoutes = entry.getValue();
+ Route selectetRoute = preferredRoutes.get(random.nextInt(preferredRoutes.size()));
+ LOG.debug("Chose \"{}\" with priority {}.",selectetRoute,entry.getKey());
+
+ return selectetRoute;
+ }
+
+}
diff --git a/src/main/java/de/srsoftware/web4rail/Route.java b/src/main/java/de/srsoftware/web4rail/Route.java
index f3fb852..0bd6879 100644
--- a/src/main/java/de/srsoftware/web4rail/Route.java
+++ b/src/main/java/de/srsoftware/web4rail/Route.java
@@ -70,7 +70,7 @@ public class Route extends BaseClass{
private Vector contacts;
private boolean disabled = false;
private Block endBlock = null;
- private Direction endDirection;
+ public Direction endDirection;
private int id;
private Vector path;
private Vector signals;
@@ -683,4 +683,9 @@ public class Route extends BaseClass{
}
return message;
}
+
+ public String shortName() {
+ String[] parts = name().split("-");
+ return parts[0].trim()+"–"+parts[parts.length-1].trim();
+ }
}
diff --git a/src/main/java/de/srsoftware/web4rail/actions/Action.java b/src/main/java/de/srsoftware/web4rail/actions/Action.java
index 62373b0..0c25c71 100644
--- a/src/main/java/de/srsoftware/web4rail/actions/Action.java
+++ b/src/main/java/de/srsoftware/web4rail/actions/Action.java
@@ -2,6 +2,7 @@ package de.srsoftware.web4rail.actions;
import java.io.IOException;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.TreeMap;
@@ -15,6 +16,7 @@ import de.srsoftware.tools.Tag;
import de.srsoftware.web4rail.Application;
import de.srsoftware.web4rail.BaseClass;
import de.srsoftware.web4rail.Plan;
+import de.srsoftware.web4rail.Plan.Direction;
import de.srsoftware.web4rail.Route;
import de.srsoftware.web4rail.Window;
import de.srsoftware.web4rail.moving.Train;
@@ -40,6 +42,7 @@ public abstract class Action extends BaseClass {
public Route route = null;
public Train train = null;
public Block block = null;
+ public Direction direction = null;
public Context(Contact c) {
contact = c;
@@ -66,8 +69,12 @@ public abstract class Action extends BaseClass {
if (isSet(train)) {
if (isNull(route)) route = train.route;
setBlock(train.currentBlock());
- }
-
+ setDirection(train.direction());
+ }
+ }
+
+ private void setDirection(Direction dir) {
+ direction = dir;
}
private void setBlock(Block block) {
diff --git a/src/main/java/de/srsoftware/web4rail/moving/Train.java b/src/main/java/de/srsoftware/web4rail/moving/Train.java
index bee5f4b..06982c8 100644
--- a/src/main/java/de/srsoftware/web4rail/moving/Train.java
+++ b/src/main/java/de/srsoftware/web4rail/moving/Train.java
@@ -13,7 +13,6 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.SortedSet;
-import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;
@@ -25,6 +24,7 @@ import de.keawe.tools.translations.Translation;
import de.srsoftware.tools.Tag;
import de.srsoftware.web4rail.Application;
import de.srsoftware.web4rail.BaseClass;
+import de.srsoftware.web4rail.PathFinder;
import de.srsoftware.web4rail.Plan;
import de.srsoftware.web4rail.Plan.Direction;
import de.srsoftware.web4rail.Range;
@@ -172,56 +172,6 @@ public class Train extends BaseClass implements Comparable {
showTrace();
}
- private static Route chooseRoute(Context context) {
- TreeMap> availableRoutes = availableRoutes(context);
- if (availableRoutes.isEmpty()) return null;
- Entry> entry = availableRoutes.firstEntry();
- List preferredRoutes = entry.getValue();
- Route selectetRoute = preferredRoutes.get(random.nextInt(preferredRoutes.size()));
- LOG.debug("Chose \"{}\" with priority {}.",selectetRoute,entry.getKey());
-
- return selectetRoute;
- }
-
- private static TreeMap> availableRoutes(Context context){
- TreeMap> availableRoutes = new TreeMap>();
-
- boolean error = false;
- if (isNull(context.block)) {
- LOG.warn("{}.availableRoutes called without context.block!",Train.class.getSimpleName());
- error = true;
- }
- if (isNull(context.train)) {
- LOG.warn("{}.availableRoutes called without context.train!",Train.class.getSimpleName());
- error = true;
- }
- if (error) return availableRoutes;
-
- Collection routes = context.block.routes();
-
- for (Route rt : routes) {
- if (rt.path().firstElement() != context.block) continue; // routen, die nicht vom aktuellen Block starten sind bubu
- int priority = 0;
- if (rt == context.route) priority-=10; // möglichst andere Route als zuvor wählen // TODO: den Routen einen "last-used" Zeitstempel hinzufügen, und diesen mit in die Priorisierung einbeziehen
- if (isSet(context.train.direction) && rt.startDirection != context.train.direction) { // Route startet entgegen der aktuellen Fahrtrichtung des Zuges
- if (!context.train.pushPull) continue; // Zug kann nicht wenden
- if (!context.block.turnAllowed) continue; // Wenden im Block nicht gestattet
- priority -= 5;
- }
- if (!rt.isFreeFor(context.train)) continue; // Route ist nicht frei
- if (!rt.allowed(context)) continue; // Zug darf auf Grund einer nicht erfüllten Bedingung nicht auf die Route
-
- List routeSet = availableRoutes.get(priority);
- if (isNull(routeSet)) {
- routeSet = new Vector();
- availableRoutes.put(priority, routeSet);
- }
- routeSet.add(rt);
- }
-
- return availableRoutes;
- }
-
@Override
public int compareTo(Train o) {
return name().compareTo(o.toString());
@@ -622,10 +572,10 @@ public class Train extends BaseClass implements Comparable {
public String start() throws IOException {
if (isNull(currentBlock)) return t("{} not in a block",this);
- Context context = isSet(route) ? new Context( route ) : new Context( this);
- if (isSet(context.route)) context.route.reset(); // reset route previously chosen
+ if (isSet(route)) route.reset(); // reset route previously chosen
- route = chooseRoute(context);
+ Context context = new Context(this);
+ route = PathFinder.chooseRoute(context);
if (isNull(route)) return t("No free routes from {}",currentBlock);
if (!route.lock()) return t("Was not able to lock {}",route);
@@ -706,4 +656,8 @@ public class Train extends BaseClass implements Comparable {
public Block currentBlock() {
return currentBlock;
}
+
+ public Block destination() {
+ return destination;
+ }
}
diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Block.java b/src/main/java/de/srsoftware/web4rail/tiles/Block.java
index c7ed3ee..5bfa94c 100644
--- a/src/main/java/de/srsoftware/web4rail/tiles/Block.java
+++ b/src/main/java/de/srsoftware/web4rail/tiles/Block.java
@@ -293,7 +293,7 @@ public abstract class Block extends StretchableTile{
@Override
public String toString() {
- return getClass().getSimpleName()+"("+name+") @ ("+x+","+y+")";
+ return name + " @ ("+x+","+y+")";
}
@Override
diff --git a/src/main/java/de/srsoftware/web4rail/tiles/Tile.java b/src/main/java/de/srsoftware/web4rail/tiles/Tile.java
index f1cc716..ff07205 100644
--- a/src/main/java/de/srsoftware/web4rail/tiles/Tile.java
+++ b/src/main/java/de/srsoftware/web4rail/tiles/Tile.java
@@ -240,7 +240,7 @@ public abstract class Tile extends BaseClass{
Tag routeList = new Tag("ol");
for (Route route : routes) {
String json = new JSONObject(Map.of(REALM,ROUTE,ID,route.id(),ACTION,ACTION_PROPS,CONTEXT,REALM_PLAN+":"+id())).toString().replace("\"", "'");
- Tag li = new Tag("span").attr("onclick","return request("+json+");").content(route.name()+(route.isDisabled()?" ["+t("disabled")+"]" : "")+NBSP).addTo(new Tag("li").clazz("link"));
+ Tag li = new Tag("span").attr("onclick","return request("+json+");").content(route.shortName()+(route.isDisabled()?" ["+t("disabled")+"]" : "")+NBSP).addTo(new Tag("li").clazz("link"));
Map params = Map.of(REALM,REALM_ROUTE,ID,route.id(),ACTION,ACTION_DROP,Tile.class.getSimpleName(),id());
new Button(t("delete route"),params).addTo(li);
li.addTo(routeList);