private TradeMapSystemCollection GetSystemsInJumpRange(TradeMap map, TradeMapSystem startSystem, TradeMapSystemCollection systemCollection, int jumpRange) { // Traverse outwards from the start system using links. // Build a collection of systems within the specified jump radius from the start system TradeMapSystemCollection seenSystems = new TradeMapSystemCollection(); if (!systemCollection.Contains(startSystem)) { systemCollection.Add(startSystem); } Stack <TradeMapSystem> systemStack = new Stack <TradeMapSystem>(); systemStack.Push(startSystem); Stack <TradeMapSystem> nextSystemStack; int jumpCount = 1; while (jumpCount <= jumpRange && systemStack.Count > 0) { // Start the next stack nextSystemStack = new Stack <TradeMapSystem>(); // Add all of the linked systems while (systemStack.Count > 0) { var thisSystem = systemStack.Pop(); if (seenSystems.Contains(thisSystem)) { continue; } foreach (var link in thisSystem.Links) { if (link.System == null) { continue; } if (link.System == startSystem) { continue; // Ignore it if it's start system } // Good link nextSystemStack.Push(link.System); if (!systemCollection.Contains(link.System)) { systemCollection.Add(link.System); } seenSystems.Add(thisSystem); } } // Done with stack, ready the next stack systemStack = nextSystemStack; jumpCount++; } return(systemCollection); }
private void HandleSellExecution(ParentOrder parentOrder, TradeExecution execution) { TradeOrder order = parentOrder.GetChildOrderByID(execution.OrderID); if (order == null) { Log.Error(string.Format("Cannot find trade order, orderID: {0}", execution.OrderID)); } else { if (string.IsNullOrWhiteSpace(order.Notes)) { Log.Warn("HandleSellExecution error. Cannot resolve execution level due to emtpy order notes"); } else { int exeLevel = int.Parse(order.Notes); TradeMap[exeLevel].CurrentQty -= execution.Shares; if (TradeMap[exeLevel].CurrentQty < 0) { //should not hit here Log.Error(string.Format("Negative CurrentQty detected. level: {0}, qty: {1}", exeLevel, TradeMap[exeLevel].CurrentQty)); } if (TradeMap[exeLevel].CurrentQty <= 0) { if (TradeMap.ContainsKey(CurrentLevel)) { TradeMap[CurrentLevel].WasFilledSellOnPartial = false; TradeMap[CurrentLevel].LastBuyPrice = 0; } CurrentLevel--; //TradeMap.Remove(CurrentLevel); //for (int i = CurrentLevel + 1; i <= ScaleLevel; i++) //{ // if (TradeMap.ContainsKey(i)) TradeMap.Remove(i); //} //if (CurrentLevel >= 0) //{ // GenerateTradeMapNextLevel(TradeMap[CurrentLevel].LastBuyPrice); //} } } Log.Info("After sld execution." + Util.PrintTradeMapCurrLvl(this)); } }
public TradeMap CheckSystemsCanTrade(TradeMap map) { foreach (var planet in map.Planets) { foreach (var system in map.Systems) { if (system.NamedObjects.Contains(planet.Name)) { system.CanTrade = true; } } } return(map); }
public TradeMap CompleteLinks(TradeMap map) { // Update the object links in system links foreach (var system in map.Systems) { foreach (var link in system.Links) { if (!string.IsNullOrEmpty(link.Name) && link.System == null) { // If there's a name in the link, and this link hasn't been completed yet, update it. // Search for the system foreach (var fSystem in map.Systems) { if (link.Name == fSystem.Name) { // Found match link.System = fSystem; // Update the opposite link on the other system, while we're here foreach (var fLink in fSystem.Links) { if (fLink.Name == system.Name) { fLink.System = system; } } } } } } } return(map); }
public RouteScannerResults Scan(TradeMap map, RouteScannerOptions options, CancellationToken ct) { if (_working) { throw new InvalidOperationException("Already working"); } _working = true; _log.Info("Starting route scan"); _ct = ct; _options = options; var r = new RouteScannerResults(); // Build a list of profitable runs // Loop through systems // Get list of systems within the max jump limit // Go through each system in the list, compare comodity prices // If the price is greater than the desired threshold, add it to the run list TradeMapSystemCollection systemCollection; List <string> validMapBoundSystems = new List <string>(); if (options.MapBounds.Count > 0) { // Gather map bounds systemCollection = new TradeMapSystemCollection(); foreach (var system in map.Systems) { foreach (var mapBound in options.MapBounds) { var mapBoundSystem = mapBound.Key.ToLower(); if (mapBoundSystem == system.Name.ToLower()) { validMapBoundSystems.Add(mapBoundSystem); GetSystemsInJumpRange(map, system, systemCollection, mapBound.Value); continue; } } } // Validate foreach (var mapBound in options.MapBounds) { if (!validMapBoundSystems.Contains(mapBound.Key.ToLower())) { throw new IndexOutOfRangeException($"Map bound system name isn't a known system '{mapBound.Key}'"); } } } else { // Do for all systems systemCollection = map.Systems; } for (var iSS = 0; iSS < systemCollection.Count; iSS++) { ct.ThrowIfCancellationRequested(); var startSystem = systemCollection[iSS]; if (!startSystem.CanTrade) { continue; // Don't care about system's that can't trade. } _log.Debug($"Scanning runs for system: {startSystem.Name}"); DoProgress(new ProgressEventArgs(iSS, map.Systems.Count, ProgressEventStatus.Working, $"Scanning runs for '{startSystem.Name}' ({iSS+1}/{systemCollection.Count})")); // Clear this system's runs, in case startSystem.Runs.Clear(); List <TradeMapSystem> seenSystems = new List <TradeMapSystem>(); List <TradeMapSystem> systemsInRange = new List <TradeMapSystem>(); Stack <TradeMapSystem> systemCheckStack = new Stack <TradeMapSystem>(); Stack <TradeMapSystem> systemCheckStackNext; // Add this system's links to the "to do" stack foreach (var link in startSystem.Links) { ct.ThrowIfCancellationRequested(); if (link.System == null) { continue; } if (link.System == startSystem) { continue; // Ignore it if it's start system } systemsInRange.Add(link.System); systemCheckStack.Push(link.System); } for (int jumpCount = 1; jumpCount <= options.RunMaxJumps; jumpCount++) { ct.ThrowIfCancellationRequested(); systemCheckStackNext = new Stack <TradeMapSystem>(); // Ready to compile the next list of jumps // Find new systems in the check stack while (systemCheckStack.Count > 0) { ct.ThrowIfCancellationRequested(); var destSystem = systemCheckStack.Pop(); // Check for profitable runs to this system if (destSystem.CanTrade) // Avoid systems that have comodity data, but can't actually trade { ScanForRuns(startSystem, destSystem, jumpCount, r.AllRuns, options); } // Check for jumps away from this system // but only if we're under the jump limit if (jumpCount < options.RunMaxJumps) { //_log.Debug($"{jumpCount} under jump limit {options.RunMaxJumps}, looking for more destinations"); foreach (var link in destSystem.Links) { if (link.System == null) { continue; } if (link.System == startSystem) { continue; // Ignore it if it's start system } if (seenSystems.Contains(link.System)) { continue; } // New system //_log.Debug($"Enquing system '{link.System.Name}'"); seenSystems.Add(link.System); systemsInRange.Add(link.System); systemCheckStackNext.Push(link.System); } } else { //_log.Debug($"Hit jump limit, not going further"); } } // Make the next stack the current stack systemCheckStack = systemCheckStackNext; } } // Scan for routes _log.Info("Starting scan for routes"); TradeMapSystemCollection systemsToRoute; if (options.StartSystems.Count == 0) { // No systems specified, do them all systemsToRoute = systemCollection; } else { // Systems are specified. // Resolve them to systems systemsToRoute = new TradeMapSystemCollection(); foreach (var system in map.Systems) { if (options.StartSystems.Contains(system.Name.ToLower())) { systemsToRoute.Add(system); } } } for (var iSS = 0; iSS < systemsToRoute.Count; iSS++) { ct.ThrowIfCancellationRequested(); var startSystem = systemsToRoute[iSS]; DoProgress(new ProgressEventArgs(iSS, systemsToRoute.Count, ProgressEventStatus.Working, $"Scanning routes for '{startSystem.Name}' ({iSS+1}/{systemsToRoute.Count})")); ScanForRoutes(startSystem, r.AllRoutes, options); } //DoProgress(new ProgressEventArgs(ProgressEventStatus.Complete, $"Route scanning complete")); _working = false; return(r); }
public RouteScannerResults Scan(TradeMap map, RouteScannerOptions options) { return(Scan(map, options, CancellationToken.None)); }
public void MapBuilder_SimpleRead() { var sampleDataRoot = new DefNode(); var sampleDataSystem1 = new DefNode(); sampleDataRoot.ChildNodes.Add(sampleDataSystem1); sampleDataSystem1.Tokens.Add("system").Add("Tarazed"); sampleDataSystem1.ChildNodes.Add(new DefNode() { Tokens = new DefTokenCollection().Add("belt").Add("1169") }); sampleDataSystem1.ChildNodes.Add(new DefNode() { Tokens = new DefTokenCollection().Add("link").Add("Enif") }); sampleDataSystem1.ChildNodes.Add(new DefNode() { Tokens = new DefTokenCollection().Add("trade").Add("Clothing").Add("305") }); sampleDataSystem1.ChildNodes.Add(new DefNode() { Tokens = new DefTokenCollection().Add("trade").Add("Electronics").Add("761") }); sampleDataSystem1.ChildNodes.Add(new DefNode() { Tokens = new DefTokenCollection().Add("trade").Add("Equipment").Add("395") }); sampleDataSystem1.ChildNodes.Add(new DefNode() { Tokens = new DefTokenCollection().Add("trade").Add("Food").Add("238") }); var sampleDataSystem2 = new DefNode(); sampleDataRoot.ChildNodes.Add(sampleDataSystem2); sampleDataSystem2.Tokens.Add("system").Add("Enif"); sampleDataSystem2.ChildNodes.Add(new DefNode() { Tokens = new DefTokenCollection().Add("belt").Add("1169") }); sampleDataSystem2.ChildNodes.Add(new DefNode() { Tokens = new DefTokenCollection().Add("link").Add("Tarazed") }); sampleDataSystem2.ChildNodes.Add(new DefNode() { Tokens = new DefTokenCollection().Add("link").Add("Sadalmelik") }); sampleDataSystem2.ChildNodes.Add(new DefNode() { Tokens = new DefTokenCollection().Add("trade").Add("Clothing").Add("361") }); sampleDataSystem2.ChildNodes.Add(new DefNode() { Tokens = new DefTokenCollection().Add("trade").Add("Electronics").Add("800") }); sampleDataSystem2.ChildNodes.Add(new DefNode() { Tokens = new DefTokenCollection().Add("trade").Add("Equipment").Add("485") }); sampleDataSystem2.ChildNodes.Add(new DefNode() { Tokens = new DefTokenCollection().Add("trade").Add("Food").Add("335") }); var sampleDataSystem3 = new DefNode(); sampleDataRoot.ChildNodes.Add(sampleDataSystem3); sampleDataSystem3.Tokens.Add("system").Add("Sadalmelik"); sampleDataSystem3.ChildNodes.Add(new DefNode() { Tokens = new DefTokenCollection().Add("belt").Add("1169") }); sampleDataSystem3.ChildNodes.Add(new DefNode() { Tokens = new DefTokenCollection().Add("link").Add("Enif") }); sampleDataSystem3.ChildNodes.Add(new DefNode() { Tokens = new DefTokenCollection().Add("trade").Add("Clothing").Add("361") }); sampleDataSystem3.ChildNodes.Add(new DefNode() { Tokens = new DefTokenCollection().Add("trade").Add("Electronics").Add("800") }); sampleDataSystem3.ChildNodes.Add(new DefNode() { Tokens = new DefTokenCollection().Add("trade").Add("Equipment").Add("485") }); sampleDataSystem3.ChildNodes.Add(new DefNode() { Tokens = new DefTokenCollection().Add("trade").Add("Food").Add("335") }); var resultMap = new TradeMapBuilder().Build(sampleDataRoot, CancellationToken.None); var expectedMap = new TradeMap(); var tradeSystem1 = new TradeMapSystem(); expectedMap.Systems.Add(tradeSystem1); tradeSystem1.Name = "Tarazed"; tradeSystem1.Comodities.Add(new TradeMapComodity { Name = "Clothing", Price = 305 }); tradeSystem1.Comodities.Add(new TradeMapComodity { Name = "Electronics", Price = 761 }); tradeSystem1.Comodities.Add(new TradeMapComodity { Name = "Equipment", Price = 395 }); tradeSystem1.Comodities.Add(new TradeMapComodity { Name = "Food", Price = 238 }); var tradeSystem2 = new TradeMapSystem(); expectedMap.Systems.Add(tradeSystem2); tradeSystem2.Name = "Enif"; tradeSystem2.Comodities.Add(new TradeMapComodity { Name = "Clothing", Price = 361 }); tradeSystem2.Comodities.Add(new TradeMapComodity { Name = "Electronics", Price = 800 }); tradeSystem2.Comodities.Add(new TradeMapComodity { Name = "Equipment", Price = 485 }); tradeSystem2.Comodities.Add(new TradeMapComodity { Name = "Food", Price = 335 }); var tradeSystem3 = new TradeMapSystem(); expectedMap.Systems.Add(tradeSystem3); tradeSystem3.Name = "Sadalmelik"; tradeSystem3.Comodities.Add(new TradeMapComodity { Name = "Clothing", Price = 361 }); tradeSystem3.Comodities.Add(new TradeMapComodity { Name = "Electronics", Price = 800 }); tradeSystem3.Comodities.Add(new TradeMapComodity { Name = "Equipment", Price = 485 }); tradeSystem3.Comodities.Add(new TradeMapComodity { Name = "Food", Price = 335 }); tradeSystem1.Links.Add(new TradeMapSystemLink() { Name = "Enif", System = tradeSystem2 }); tradeSystem2.Links.Add(new TradeMapSystemLink() { Name = "Tarazed", System = tradeSystem1 }); tradeSystem2.Links.Add(new TradeMapSystemLink() { Name = "Sadalmelik", System = tradeSystem3 }); tradeSystem3.Links.Add(new TradeMapSystemLink() { Name = "Enif", System = tradeSystem2 }); // TODO assert }
public TradeMap CreateMap(DefNode rootNode, CancellationToken ct) { var map = new TradeMap(); //foreach (var topNode in rootNode.ChildNodes) for (int iNode = 0; iNode < rootNode.ChildNodes.Count; iNode++) { ProgressEvents.DoEvent(this, new ProgressEventArgs(iNode, rootNode.ChildNodes.Count, ProgressEventStatus.Working, $"Reading node {iNode}/{rootNode.ChildNodes.Count}")); var topNode = rootNode.ChildNodes[iNode]; // Only care about "system" nodes if (topNode.Tokens.Count >= 2 && topNode.Tokens[0] == NODE_NAME_SYSTEM) { // Is a system node var newSystem = new TradeMapSystem(); newSystem.Name = topNode.Tokens[1].Trim(); // TODO handle blank system name foreach (var subNode in topNode.ChildNodes) { if (subNode.Tokens.Count >= 2 && subNode.Tokens[0] == NODE_NAME_LINK) { // TODO handle blank system name in link newSystem.Links.Add(new TradeMapSystemLink() { Name = subNode.Tokens[1].Trim() }); } if (subNode.Tokens.Count >= 3 && subNode.Tokens[0] == NODE_NAME_TRADE) { int tradePrice; if (!int.TryParse(subNode.Tokens[2].Trim(), out tradePrice)) { // TODO Handle bad number on trade price } else { // TODO handle empty comodity name newSystem.Comodities.Add(new TradeMapComodity() { Name = subNode.Tokens[1].Trim(), Price = tradePrice }); } } if (subNode.Tokens.Count >= 2 && subNode.Tokens[0] == NODE_NAME_OBJECT) { newSystem.NamedObjects.Add(subNode.Tokens[1].Trim()); } } newSystem.Name = newSystem.Name.Trim(); map.Systems.Add(newSystem); } else if (topNode.Tokens.Count >= 2 && topNode.Tokens[0] == NODE_NAME_PLANET) { // Is a planet // I was really annoyed when I found out that a bunch of systems in the map // have trade & comoddity information, but no planets to trade on. // I had to change the way I did things, shat me to tears :( var newPlanet = new TradeMapPlanet(); newPlanet.Name = topNode.Tokens[1].Trim(); foreach (var subNode in topNode.ChildNodes) { if (subNode.Tokens.Count >= 2 && subNode.Tokens[0] == NODE_NAME_SPACEPORT) { newPlanet.HasSpaceport = true; } } // Only save planets that have spaceports if (newPlanet.HasSpaceport) { map.Planets.Add(newPlanet); } } else { // skipping node I don't care about, like "galaxy" } } return(map); }