diff --git a/nullptr/analyzer.py b/nullptr/analyzer.py index 4b36a67..cc63255 100644 --- a/nullptr/analyzer.py +++ b/nullptr/analyzer.py @@ -3,6 +3,7 @@ from nullptr.models.jumpgate import Jumpgate from nullptr.models.system import System from nullptr.models.waypoint import Waypoint from dataclasses import dataclass +from nullptr.util import pprint from copy import copy class AnalyzerException(Exception): @@ -109,6 +110,7 @@ class Analyzer: mkts = [m.waypoint for m in self.store.all_members(orig.system, Marketplace)] cur = orig if orig == to: + return [] while cur != to: best = cur @@ -157,8 +159,8 @@ class Analyzer: prices[r] = [] prices[r].append({ 'wp': m.waypoint, - 'buy': p['buy'], - 'sell': p['sell'] + 'buy': p.buy, + 'sell': p.sell }) return prices diff --git a/nullptr/api.py b/nullptr/api.py index 9239cc2..6392591 100644 --- a/nullptr/api.py +++ b/nullptr/api.py @@ -121,6 +121,7 @@ class Api: units = min(units, fuel_avail) data = {'fromCargo': from_cargo, 'units': units } data = self.request('post', f'my/ships/{ship}/refuel', data) + self.log_transaction(data) if from_cargo: boxes = ceil(float(units) / 100) ship.take_cargo('FUEL', boxes) @@ -236,7 +237,18 @@ class Api: result = self.store.update_list('Survey', mg(data, 'surveys')) return result + ######## Commerce ######### + def log_transaction(self, data): + if not 'transaction' in data: return + typ = mg(data, 'transaction.tradeSymbol') + ppu = mg(data, 'transaction.pricePerUnit') + shipsym = mg(data, 'transaction.shipSymbol') + ship = self.store.get('Ship', shipsym) + units = mg(data, 'transaction.units') + act = mg(data,'transaction.type') + ship.log(f'{act} {units} of {typ} for {ppu} at {ship.location}') + def sell(self, ship, typ,units=None): if units is None: units = ship.get_cargo(typ) @@ -245,7 +257,7 @@ class Api: 'units': units } data = self.request('post', f'my/ships/{ship}/sell', data) - ship.log(f'sell {units} of {typ}') + self.log_transaction(data) if 'cargo' in data: ship.update(data) if 'agent' in data: @@ -258,7 +270,7 @@ class Api: 'units': amt } data = self.request('post', f'my/ships/{ship}/purchase', data) - ship.log(f'buy {amt} of {typ} at {ship.location}') + self.log_transaction(data) if 'cargo' in data: ship.update(data) if 'agent' in data: diff --git a/nullptr/commander.py b/nullptr/commander.py index 2fdfa30..8c8b9bf 100644 --- a/nullptr/commander.py +++ b/nullptr/commander.py @@ -184,7 +184,7 @@ class Commander(CommandLine): for w in r: wname = w.symbol.split('-')[2] - traits = ", ".join(w.traits()) + traits = ", ".join(w.itraits()) typ = w.type[0] if typ not in ['F','J'] and len(traits) == 0: continue @@ -542,3 +542,9 @@ class Commander(CommandLine): pprint(prices[resource.upper()]) else: pprint(prices) + + def do_path(self, waypoint_str): + if not self.has_ship(): return + w = self.resolve('Waypoint', waypoint_str) + p = self.analyzer.find_nav_path(self.ship.location, w, self.ship.fuel_capacity) + pprint(p) diff --git a/nullptr/models/base.py b/nullptr/models/base.py index db92485..aec041c 100644 --- a/nullptr/models/base.py +++ b/nullptr/models/base.py @@ -36,6 +36,9 @@ class Base: def __getstate__(self): return {k:v for k,v in self.__dict__.items() if not k.startswith('_')} + def dirty(self): + self.store.dirty(self) + @classmethod def ext(cls): raise NotImplementedError('no ext') diff --git a/nullptr/models/marketplace.py b/nullptr/models/marketplace.py index 834a916..f8f5f58 100644 --- a/nullptr/models/marketplace.py +++ b/nullptr/models/marketplace.py @@ -2,9 +2,29 @@ from .base import Base from time import time from nullptr.util import * -from dataclasses import field +from dataclasses import field, dataclass from nullptr.models import Waypoint +from typing import List, Tuple +SUPPLY = ['SCARCE','LIMITED','MODERATE','HIGH','ABUNDANT'] +ACTIVITY =['RESTRICTED','WEAK','GROWING','STRONG'] +class MarketEntry: + buy: int + sell: int + volume: int + supply: int + activity: int + history: List[Tuple[int, int, int, int, int, int]] = [] + + def add(self, buy, sell, volume, supply, activity): + self.buy = buy + self.sell = sell + self.volume = volume + self.supply = supply + self.activity = activity + self.history.append((int(time()), buy, sell, volume, supply, activity)) + + class Marketplace(Base): def define(self): self.imports:list = [] @@ -21,6 +41,21 @@ class Marketplace(Base): def is_fuel(self): return self.imports + self.exports + self.exchange == ['FUEL'] + + def record_prices(self, data): + for g in data: + symbol= mg(g, 'symbol') + if symbol in self.prices: + e = self.prices[symbol] + else: + e = self.prices[symbol] = MarketEntry() + buy = mg(g, 'purchasePrice') + sell = mg(g, 'sellPrice') + volume = mg(g, 'tradeVolumes') + supply = SUPPLY.index(mg(g, 'supply')) + activity = ACTIVITY.index(sg(g, 'activity','STRONG')) + e.add(buy, sell, volume, supply, activity) + self.dirty() def update(self, d): self.setlst('imports', d, 'imports', 'symbol') @@ -28,16 +63,7 @@ class Marketplace(Base): self.setlst('exchange', d, 'exchange', 'symbol') if 'tradeGoods' in d: self.last_prices = time() - prices = {} - for g in mg(d, 'tradeGoods'): - price = {} - symbol= mg(g, 'symbol') - price['symbol'] = symbol - price['buy'] = mg(g, 'purchasePrice') - price['sell'] = mg(g, 'sellPrice') - price['volume'] = mg(g, 'tradeVolume') - prices[symbol] = price - self.prices = prices + self.record_prices(mg(d, 'tradeGoods')) def buy_price(self, resource): if resource not in self.prices: diff --git a/nullptr/models/waypoint.py b/nullptr/models/waypoint.py index b336a5a..041b218 100644 --- a/nullptr/models/waypoint.py +++ b/nullptr/models/waypoint.py @@ -32,7 +32,7 @@ class Waypoint(Base): def ext(self): return 'way' - def traits(self): + def itraits(self): traits = [] if self.type == 'JUMP_GATE': traits.append('JUMP') @@ -54,4 +54,9 @@ class Waypoint(Base): if 'STRIPPED' in self.traits: traits.append('STRIPPED') return traits - \ No newline at end of file + + def f(self, detail=1): + r = self.symbol + if detail > 3: + r += f'\n{self.x} {self.y}' + return r \ No newline at end of file