summaryrefslogtreecommitdiff
path: root/backend-go/internal/core/pathfinder_aux.go
blob: 171ffe8be1660d3d08d29346353f0d70a53a4c23 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package core

type LegMetrics struct {
	Weight float64
	Time   float64
	Risk   float64
}

// BuildTradeLegMetrics computes travel metrics for all legs needed by trades
func BuildTradeLegMetrics(graph *Graph, shipLocation int, trades []Trade) map[[2]int]*LegMetrics {
	sourceTargets := make(map[int]map[int]bool)
	
	sourceTargets[shipLocation] = make(map[int]bool)
	for _, t := range trades {
		if _, ok := sourceTargets[shipLocation]; !ok {
			sourceTargets[shipLocation] = make(map[int]bool)
		}
		sourceTargets[shipLocation][t.FromStation] = true

		if _, ok := sourceTargets[t.FromStation]; !ok {
			sourceTargets[t.FromStation] = make(map[int]bool)
		}
		sourceTargets[t.FromStation][t.ToStation] = true
	}

	metrics := make(map[[2]int]*LegMetrics)

	for source, targets := range sourceTargets {
		dijkstraRes := graph.SingleSourceDijkstra(source)
		
		for target := range targets {
			if source == target {
				metrics[[2]int{source, target}] = &LegMetrics{Weight: 0, Time: 0, Risk: 0}
				continue
			}

			if res, ok := dijkstraRes[target]; ok {
				metrics[[2]int{source, target}] = &LegMetrics{
					Weight: res.TotalWeight,
					Time:   res.TotalTime,
					Risk:   res.TotalRisk,
				}
			} else {
				metrics[[2]int{source, target}] = nil
			}
		}
	}
	return metrics
}

// Pathfinder filters trades that lack paths and calculates NetProfit
func Pathfinder(trades []Trade, graph *Graph, shipLocation int) []Trade {
	var validTrades []Trade
	for _, t := range trades {
		_, hasFrom := graph.Adj[t.FromStation]
		_, hasTo := graph.Adj[t.ToStation]
		if hasFrom && hasTo {
			validTrades = append(validTrades, t)
		}
	}

	if len(validTrades) == 0 {
		return validTrades
	}

	metrics := BuildTradeLegMetrics(graph, shipLocation, validTrades)

	var profitable []Trade
	for i := range validTrades {
		sourceToFrom, ok1 := metrics[[2]int{shipLocation, validTrades[i].FromStation}]
		fromToTo, ok2 := metrics[[2]int{validTrades[i].FromStation, validTrades[i].ToStation}]

		if ok1 && ok2 && sourceToFrom != nil && fromToTo != nil {
			totalCost := sourceToFrom.Weight + fromToTo.Weight
			netProfit := validTrades[i].GrossProfit - totalCost
			
			if netProfit > 0 {
				validTrades[i].NetProfit = &netProfit
				profitable = append(profitable, validTrades[i])
			}
		}
	}

	return profitable
}