Update analyzer.py, commander.py and three other files
This commit is contained in:
parent
939215ef5e
commit
fbfa08020b
@ -1,7 +1,28 @@
|
||||
from nullptr.models.marketplace import Marketplace
|
||||
from nullptr.models.jumpgate import Jumpgate
|
||||
from nullptr.models.system import System
|
||||
from dataclasses import dataclass
|
||||
|
||||
@dataclass
|
||||
class SearchNode:
|
||||
system: System
|
||||
parent: 'SearchNode'
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self.system.symbol)
|
||||
|
||||
def path(self):
|
||||
result = []
|
||||
n = self
|
||||
while n is not None:
|
||||
result.append(n.system)
|
||||
n = n.parent
|
||||
result.reverse()
|
||||
return result
|
||||
|
||||
def __repr__(self):
|
||||
return self.system.symbol
|
||||
|
||||
class Analyzer:
|
||||
def __init__(self, store):
|
||||
self.store = store
|
||||
@ -15,28 +36,22 @@ class Analyzer:
|
||||
def get_jumpgate(self, system):
|
||||
gates = self.store.all_members(system, Jumpgate)
|
||||
return next(gates, None)
|
||||
|
||||
def find_path(self, orig, to):
|
||||
if orig == to: return []
|
||||
jg = self.get_jumpgate(orig)
|
||||
if jg is None:
|
||||
print(f'{orig} no jg')
|
||||
return None
|
||||
best_distance = orig.distance(to)
|
||||
best_hop = None
|
||||
for hop_str in jg.systems:
|
||||
hop = self.store.get(System, hop_str)
|
||||
if hop is None:
|
||||
print(f'{hop_str} hopnon')
|
||||
continue
|
||||
dist = hop.distance(to)
|
||||
if dist < best_distance:
|
||||
best_distance = dist
|
||||
best_hop = hop
|
||||
if best_hop is None:
|
||||
print('nobest')
|
||||
return None
|
||||
print(best_hop, best_distance)
|
||||
tail = self.find_path(best_hop, to)
|
||||
if tail is None: return None
|
||||
return [best_hop] + tail
|
||||
|
||||
|
||||
def find_path(self, orig, to, depth=100):
|
||||
if depth < 1: return None
|
||||
if type(orig) == System:
|
||||
orig = set([SearchNode(orig,None)])
|
||||
result = [n for n in orig if n.system==to]
|
||||
if len(result) > 0:
|
||||
return result[0].path()
|
||||
dest = set()
|
||||
for o in orig:
|
||||
jg = self.get_jumpgate(o.system)
|
||||
if jg is None: continue
|
||||
for s in jg.systems:
|
||||
system = self.store.get(System, s)
|
||||
if system is None: continue
|
||||
dest.add(SearchNode(system, o))
|
||||
if len(dest) == 0: return None
|
||||
return self.find_path(dest, to, depth-1)
|
||||
|
@ -87,5 +87,7 @@ class Commander(CommandLine):
|
||||
def do_path(self):
|
||||
orig = self.ask_obj(System, 'from: ')
|
||||
dest = self.ask_obj(System, 'to: ')
|
||||
# orig = self.store.get(System, 'X1-KS52')
|
||||
# dest = self.store.get(System, 'X1-DA90')
|
||||
path = self.analyzer.find_path(orig, dest)
|
||||
pprint(path)
|
||||
|
@ -12,7 +12,10 @@ class Base:
|
||||
self.symbol = symbol
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self.symbol)
|
||||
return hash((str(type(self)), self.symbol))
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.symbol == other.symbol and type(self) == type(other)
|
||||
|
||||
def seta(self, attr, d, name=None):
|
||||
if name is None:
|
||||
|
@ -21,4 +21,4 @@ class System(Base):
|
||||
return f'atlas/{sector}/{symbol[0:1]}/{self.symbol}.{self.ext()}'
|
||||
|
||||
def distance(self, other):
|
||||
return sqrt((self.x - other.x) ** 2 + (self.y - other.y) ** 2)
|
||||
return int(sqrt((self.x - other.x) ** 2 + (self.y - other.y) ** 2))
|
||||
|
@ -71,6 +71,7 @@ class Store:
|
||||
self.data[typ][symbol] = obj
|
||||
if issubclass(typ, SystemMember):
|
||||
system_str = obj.system()
|
||||
|
||||
if system_str not in self.system_members:
|
||||
self.system_members[system_str] = set()
|
||||
self.system_members[system_str].add(obj)
|
||||
@ -101,6 +102,8 @@ class Store:
|
||||
def all_members(self, system, typ=None):
|
||||
if type(system) == System:
|
||||
system = system.symbol
|
||||
if system not in self.system_members:
|
||||
return
|
||||
for m in self.system_members[system]:
|
||||
if typ is None or type(m) == typ:
|
||||
yield m
|
||||
|
Loading…
Reference in New Issue
Block a user