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.marketplace import Marketplace
from nullptr.models.jumpgate import Jumpgate from nullptr.models.jumpgate import Jumpgate
from nullptr.models.system import System 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: class Analyzer:
def __init__(self, store): def __init__(self, store):
self.store = store self.store = store
@ -15,28 +36,22 @@ class Analyzer:
def get_jumpgate(self, system): def get_jumpgate(self, system):
gates = self.store.all_members(system, Jumpgate) gates = self.store.all_members(system, Jumpgate)
return next(gates, None) return next(gates, None)
def find_path(self, orig, to):
if orig == to: return [] def find_path(self, orig, to, depth=100):
jg = self.get_jumpgate(orig) if depth < 1: return None
if jg is None: if type(orig) == System:
print(f'{orig} no jg') orig = set([SearchNode(orig,None)])
return None result = [n for n in orig if n.system==to]
best_distance = orig.distance(to) if len(result) > 0:
best_hop = None return result[0].path()
for hop_str in jg.systems: dest = set()
hop = self.store.get(System, hop_str) for o in orig:
if hop is None: jg = self.get_jumpgate(o.system)
print(f'{hop_str} hopnon') if jg is None: continue
continue for s in jg.systems:
dist = hop.distance(to) system = self.store.get(System, s)
if dist < best_distance: if system is None: continue
best_distance = dist dest.add(SearchNode(system, o))
best_hop = hop if len(dest) == 0: return None
if best_hop is None: return self.find_path(dest, to, depth-1)
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

View File

@ -87,5 +87,7 @@ class Commander(CommandLine):
def do_path(self): def do_path(self):
orig = self.ask_obj(System, 'from: ') orig = self.ask_obj(System, 'from: ')
dest = self.ask_obj(System, 'to: ') 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) path = self.analyzer.find_path(orig, dest)
pprint(path) pprint(path)

View File

@ -12,7 +12,10 @@ class Base:
self.symbol = symbol self.symbol = symbol
def __hash__(self): 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): def seta(self, attr, d, name=None):
if name is 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()}' return f'atlas/{sector}/{symbol[0:1]}/{self.symbol}.{self.ext()}'
def distance(self, other): 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 self.data[typ][symbol] = obj
if issubclass(typ, SystemMember): if issubclass(typ, SystemMember):
system_str = obj.system() system_str = obj.system()
if system_str not in self.system_members: if system_str not in self.system_members:
self.system_members[system_str] = set() self.system_members[system_str] = set()
self.system_members[system_str].add(obj) self.system_members[system_str].add(obj)
@ -101,6 +102,8 @@ class Store:
def all_members(self, system, typ=None): def all_members(self, system, typ=None):
if type(system) == System: if type(system) == System:
system = system.symbol system = system.symbol
if system not in self.system_members:
return
for m in self.system_members[system]: for m in self.system_members[system]:
if typ is None or type(m) == typ: if typ is None or type(m) == typ:
yield m yield m