Update analyzer.py, commander.py and three other files

This commit is contained in:
Richard Bronkhorst 2023-06-14 15:37:48 +02:00
parent 939215ef5e
commit fbfa08020b
5 changed files with 50 additions and 27 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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:

View File

@ -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))

View File

@ -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