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