Skip to content

Commit

Permalink
Optimization and improvements to "nav" command
Browse files Browse the repository at this point in the history
Using '-vv' will output the direct distance left to the target (so you can see when you are having to go around to reach a destination)
  • Loading branch information
Oliver Smith committed Dec 5, 2014
1 parent 7740fc8 commit 79c654b
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 28 deletions.
2 changes: 2 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ TradeDangerous, Copyright (C) Oliver "kfsone" Smith, July 2014
==============================================================================

v6.1.5 Dec 04 2014
. (kfsone) "nav" with -vv will show direct distance left to destination
. (kfsone) Minor speed improvements to "nav"
. (kfsone) Startup optimizations,
. (kfsone) "update" command now always exposes supply and demand,
. (kfsone) "--supply" (-S) is now deprecated for "update" command,
Expand Down
104 changes: 76 additions & 28 deletions commands/nav_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from commands.parsing import MutuallyExclusiveGroup, ParseArgument
import math
from tradedb import System, Station
from tradeexcept import TradeException

######################################################################
# Parser config
Expand Down Expand Up @@ -43,26 +44,42 @@
######################################################################
# Helpers

######################################################################
# Perform query and populate result set

def run(results, cmdenv, tdb):
from commands.commandenv import ResultRow

srcSystem, dstSystem = cmdenv.origPlace, cmdenv.destPlace
if isinstance(srcSystem, Station):
srcSystem = srcSystem.system
if isinstance(dstSystem, Station):
dstSystem = dstSystem.system

maxLyPer = cmdenv.maxLyPer or tdb.maxSystemLinkLy
class NoRouteError(TradeException):
pass

cmdenv.DEBUG0("Route from {} to {} with max {} ly per jump.",
srcSystem.name(), dstSystem.name(), maxLyPer)

openList = { srcSystem: 0.0 }
def getRoute(cmdenv, tdb, srcSystem, dstSystem, maxLyPer):
openList = dict()
distances = { srcSystem: [ 0.0, None ] }

# Check for a direct route and seed the open list with the systems
# in direct-range of the origin.
for dstSys, distSq in tdb.genSystemsInRange(srcSystem, maxLyPer):
dist = math.sqrt(distSq)
distances[dstSys] = [ dist, srcSystem ]
if dstSys == dstSystem:
return [ srcSystem, dstSystem ], distances
openList[dstSys] = dist
# Is there only one system in the list?
if not openList:
raise NoRouteError(
"There are no systems within {}ly of {}.".format(
maxLyPer, srcSystem.name()
))

# Check whether the destination system has a connecting link
inRange = False
for dstSys, dist in tdb.genSystemsInRange(dstSystem, maxLyPer):
inRange = True
break
if not inRange:
raise NoRouteError(
"There are no systems within {}ly of {}.".format(
maxLyPer, dstSystem.name()
))
return None, None

# As long as the open list is not empty, keep iterating.
overshoot = (cmdenv.aggressiveness * 4) + 1
while openList:
Expand All @@ -76,7 +93,7 @@ def run(results, cmdenv, tdb):
openNodes, openList = openList, {}

gsir = tdb.genSystemsInRange
for (node, startDist) in openNodes.items():
for node, startDist in openNodes.items():
for (destSys, destDistSq) in gsir(node, maxLyPer):
destDist = math.sqrt(destDistSq)
dist = startDist + destDist
Expand All @@ -88,36 +105,64 @@ def run(results, cmdenv, tdb):
distNode[0], distNode[1] = dist, node
except KeyError:
distances[destSys] = [ dist, node ]
assert not destSys in openList or openList[destSys] > dist
openList[destSys] = dist

# Unravel the route by tracing back the vias.
route = [ dstSystem ]
try:
while route[-1] != srcSystem:
jumpEnd = route[-1]
while route[-1] != srcSystem:
jumpEnd = route[-1]
try:
jumpStart = distances[jumpEnd][1]
route.append(jumpStart)
except KeyError:
print("No route found between {} and {} with {}ly jump limit.".format(srcSystem.name(), dstSystem.name(), maxLyPer))
return
except KeyError:
raise NoRouteError(
"No route found between {} and {} "
"with {}ly jump limit.".format(
srcSystem.name(), dstSystem.name(), maxLyPer
))
return None, None
route.append(jumpStart)

return route, distances


######################################################################
# Perform query and populate result set

def run(results, cmdenv, tdb):
from commands.commandenv import ResultRow

srcSystem, dstSystem = cmdenv.origPlace, cmdenv.destPlace
if isinstance(srcSystem, Station):
srcSystem = srcSystem.system
if isinstance(dstSystem, Station):
dstSystem = dstSystem.system

maxLyPer = cmdenv.maxLyPer or tdb.maxSystemLinkLy

cmdenv.DEBUG0("Route from {} to {} with max {}ly per jump.",
srcSystem.name(), dstSystem.name(), maxLyPer)

route, distances = getRoute(cmdenv, tdb, srcSystem, dstSystem, maxLyPer)

results.summary = ResultRow(
fromSys=srcSystem,
toSys=dstSystem,
maxLy=maxLyPer,
)
lastHop, totalLy = None, 0.00

lastHop, totalLy, dirLy = None, 0.00, 0.00
route.reverse()
for hop in route:
jumpLy = (distances[hop][0] - distances[lastHop][0]) if lastHop else 0.00
totalLy += jumpLy
if cmdenv.detail:
dirLy = math.sqrt(dstSystem.distToSq(hop))
row = ResultRow(
action='Via',
system=hop,
jumpLy=jumpLy,
totalLy=totalLy
totalLy=totalLy,
dirLy=dirLy,
)
results.rows.append(row)
lastHop = hop
Expand Down Expand Up @@ -150,11 +195,14 @@ def render(results, cmdenv, tdb):
if cmdenv.detail:
rowFmt.addColumn("DistLy", '>', '7', '.2f',
key=lambda row: row.totalLy)
if cmdenv.detail > 1:
rowFmt.addColumn("DirLy", '>', 7, '.2f',
key=lambda row: row.dirLy)

if not cmdenv.quiet:
heading, underline = rowFmt.heading()
print(heading, underline, sep='\n')

for row in results.rows:
print(rowFmt.format(row))

Expand Down

0 comments on commit 79c654b

Please sign in to comment.